Full-Stack Engineer · 2021 · 12 months
Building a multi-tenant LMS for 5,000+ students
Tutors needed independently branded academies without engineering involvement. I architected an isolated multi-tenant system with subscription billing, seven payment gateways, and live Zoom classes serving thousands of students.
Context
Each tutor wanted their own branded academy — custom domain, courses, subscriptions, and live classes — without waiting on engineering to spin up infrastructure per customer. The platform had to feel bespoke to every tenant while running from one codebase.
Constraints
- Strict tenant isolation — no tenant could ever see another's students, revenue, or content.
- Seven payment gateways across regions (PayPal, Stripe, Razorpay, Cashfree, Instamojo, PayUMoney, Flutterwave), each with its own webhook and reconciliation model.
- Live class scheduling integrated with Zoom, tied to subscription entitlements.
Approach
- Tenant-scoped data model with a shared schema and enforced tenant keys at the query layer, so isolation was structural rather than convention.
- A gateway abstraction normalized seven providers behind one billing interface, with webhooks reconciled into a single subscription state machine.
- Zoom API integration provisioned meetings on demand and gated access by subscription tier.
Architecture
A single Laravel application resolves the tenant from the request, scopes every query to it, and drives a Vue SPA. Billing and Zoom live behind provider-agnostic service interfaces.
Results
- 5,000+ students served across independently branded academies.
- Seven gateways unified behind one subscription lifecycle.
- Self-serve onboarding — tutors launched academies without engineering involvement.
What I'd do differently
I'd extract the gateway abstraction into a standalone package from day one; it was reusable well beyond this product and we recognized that only late.