Overview
What I built
Backend architecture and multi-tenancy
Stripe subscription lifecycle
- Trial periods and their expiry behaviour
- Failed payment handling and retry states
- Cancellations, including what a company retains after cancelling
- Plan changes with upgrade proration
- Webhook handling to keep platform state in sync with Stripe as the source of truth
- Company-level access control driven by subscription status
Real-time communication and video
Outcome
- Stack: Laravel, CodeIgniter, MySQL, Stripe, Firebase
- Ownership: Multi-tenant backend, Stripe subscription lifecycle, and Firebase messaging
- Scope: Integrated CRM, scheduling, and invoicing logic
Related articles
- Stripe Connect with Laravel: Platform Payments Guide
- Stripe Subscription Webhooks in Laravel: Source of Truth
- Laravel Stripe Subscription Plan Changes and Proration
- Idempotent Webhook Handling in Laravel (Stripe)
- Laravel Multi-Tenant Scoping: Queries Global Scopes Miss
- MySQL Composite Index Order for Multi-Tenant Laravel Apps
- Roles vs Permissions in Multi-Company Laravel SaaS
- CodeIgniter to Laravel Migration Without a Rewrite