Multi-tenant SaaS / Retail
2 min readHisabKarLay: one POS, many tenants
1,200+ merchants on a shared Laravel stack
Shops needed the same POS — sales, stock, invoices, JazzCash — without sharing each other’s data or spinning up a new server per client.
- My contribution
- Backend engineering & integrations
- Scope
- Tenant isolation, async jobs, live payments
- Stack
- Laravel / MySQL / JazzCash / Nginx
01 /The problem
A naive build would copy the app for every merchant. That explodes ops: patches, Nginx vhosts, database dumps, and payment credentials all drift. The product only works if one codebase can host many businesses and still feel private.
Checkout also had to take JazzCash in production, not a demo form — so tenant isolation had to survive real payment callbacks and queued jobs, not just CRUD screens.
02 /What shipped
Custom Laravel middleware resolves the tenant on every request, then scopes queries so stock, invoices, and users never leak across shops. Background queues and schedulers run the heavy work (reports, invoices, gateway sync) off the request path so the till stays snappy at peak hours.
JazzCash is wired for live traffic: sandbox first, then production credentials per tenant where required. Nginx fronts the app with a deployment path that does not require a new box when a merchant signs up.
03 /Result
One product, many isolated businesses — live JazzCash checkout, tenant-safe invoices, and a stack that can take another merchant without a rebuild. That is the difference between a POS demo and a SaaS.
The takeaway
One codebase. Isolated businesses. A checkout built for real transactions.