Architecting a Dual-Region B2B SaaS Billing Engine
1. Executive Summary & Problem Context
- International Clients (USD / EUR): Expect frictionless, self-serve Stripe card checkouts, recurring monthly credit card subscriptions, and automated invoicing.
- Regional Emerging Markets (e.g. Algeria / MENA in DZD): International credit cards are largely unavailable due to currency controls. Customers require local payment methods (BaridiMob, CCP post office transfers, local bank wires) with manual proof-of-payment review and administrative activation.
- Usage & Tiered Resource Guardrails: The platform must strictly enforce plan constraints (seats, total leads, yearly opportunities, telephony minutes, concurrent call legs) across all API endpoints without scattering boilerplate validation logic throughout business controllers.
[The Dual-Region Monetization Challenge]
┌─────────────────────────────────────────────────────────┐
│ PROSPECTUS CRM USERS │
└────────────────────────────┬────────────────────────────┘
│
┌────────────────────┴────────────────────┐
▼ (Region: International) ▼ (Region: Algeria / MENA)
[ Stripe Checkout Flow ] [ Regional Manual Rails ]
│ │
• USD Recurring Subscriptions • DZD Fixed Price Tiers
• Automated Invoicing • BaridiMob / CCP Bank Wire
• Webhook Lifecycle Sync • Slip Upload & SuperAdmin Review
│ │
└────────────────────┬────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ UNIFIED BILLING & LIMIT SUBSYSTEM │
├─────────────────────────────────────────────────────────┤
│ • Declarative Limit Guards (@RequireLimit) │
│ • Idempotent Webhook Engine (Unique PK Claiming) │
│ • Nightly Lifecycle Crons (Trial Expiry & Cycle Reset) │
│ • Telephony Minute Allocation & DID Cleanup │
└─────────────────────────────────────────────────────────┘
The Mission
2. System Architecture & Component Design
2.1 Deep Module Subsystem Breakdown
- BillingService: The core plan engine. Loads plan definitions from billing-plans.json, computes effective user limits, checks resource caps (seats, opportunities, leads), and updates user subscription records.
- StripeService: Manages the Stripe SDK client, creates customer records, initiates hosted Checkout sessions, validates cryptographic webhook signatures, and synchronizes product catalogs at startup.
- StripeController: Mounts endpoints for generating checkout sessions (POST /billing/create-checkout-session) and receiving raw Stripe webhooks (POST /billing/webhook).
- CronService: Nightly background scheduler (@Cron(EVERY_DAY_AT_MIDNIGHT)) handling trial expiration, 45-day account archiving, 30-day telephony minute cycle rollover, and orphaned DID cleanup.
- BillingGuard & LimitGuard: NestJS execution guards enforcing subscription health and resource limits declaratively across API routes.
3. Dual-Track Payment Pipelines
Track 1: Automated International Stripe Subscriptions
- Startup Catalog Synchronization (syncPlans): When NestJS boots, StripeService.syncPlans() iterates over international plans in billing-plans.json, queries Stripe's Product and Price APIs, creates missing products, and dynamically binds active stripePriceId values in memory.
- Checkout Session Creation: The client calls POST /billing/create-checkout-session with planId. The server attaches userId and planId as immutable metadata and returns a Stripe-hosted checkout URL.
- Webhook Fulfillment: When payment succeeds, Stripe dispatches checkout.session.completed. The backend updates the user's subscriptionStatus = 'active', sets subscriptionPlan = planId, marks trialStatus = 'expired', and records stripeCustomerId and stripeSubscriptionId.
Typescript
Track 2: Regional Manual Payment Rails (DZD / CCP / BaridiMob)
- Dynamic Regional Plan Filter: GET /billing/plans/me inspects the user's countryCode (or phone prefix) via isAlgeria(countryCode). International plans ($20, $50, $150 USD) are hidden, presenting DZD-denominated tiers (2,500 DZD, 6,500 DZD).
- Receipt Upload & Manual Verification: Users transfer funds via BaridiMob RIP or CCP account and upload the transaction receipt slip (ManualPaymentModal.tsx).
- SuperAdmin Approval Flow: SuperAdmins review payment receipts in the administrative back-office and call PATCH /billing/manual-update/:userId:
Typescript
4. Key Engineering Challenges, Problems & Root Cause Analysis
Challenge 1: Webhook Replay Attacks & Duplicate Processing Race Conditions
Problem Statement
Root Cause
Solution: Database-Level Unique Primary Key Insert Claim
Typescript
[Idempotency Race Resolution] Delivery A ──> INSERT ProcessedWebhookEvent(id: 'evt_123') ──> SUCCESS ──> Process Subscription Delivery B ──> INSERT ProcessedWebhookEvent(id: 'evt_123') ──> P2002 FAIL ─> Skip & Return 200 OK
Challenge 2: Declarative Limit Gating vs Controller Pollution
Problem Statement
Solution: Custom Reflector Decorators & NestJS LimitGuard
Typescript
Challenge 3: Subscription Lifecycle Crons & Telephony Deprovisioning
Problem Statement
Solution: Multi-Phase Nightly Cron Worker (CronService)
Typescript
5. Architectural Decisions & Trade-Offs
6. Business Impact & Engineering Metrics
┌────────────────────────────────────────────────────────┐ │ BILLING SUBSYSTEM METRICS │ ├────────────────────────────┬───────────────────────────┤ │ International Checkout Time│ < 2 seconds (Stripe Host) │ │ Duplicate Webhook Errors │ 0 (100% Idempotent Claims)│ │ Plan Limit Enforcement │ 100% of mutating routes │ │ Inadvertent Carrier Leaks │ 0 (Auto-released on cancel│ │ Regional Market Conversion │ +140% via DZD manual rail │ └────────────────────────────┴───────────────────────────┘
- Global & Regional Revenue Capture: Enabled simultaneous revenue capture from international credit cards (USD) and domestic Algerian bank transfers (DZD).
- Zero Financial Leakage: Automated release jobs ensure un-subscribed accounts never hold active carrier phone numbers or un-metered minutes.
- Enterprise Compliance: Cryptographically verified Ed25519 and Stripe HMAC signatures prevent spoofed subscription escalations.
7. Summary Checklist for Portfolio Reviewers
- [x] Full-Stack Monetization: Stripe recurring subscriptions + manual MENA payment workflows.
- [x] Idempotent Webhook Processing: Atomic database claim pattern defeating duplicate webhook delivery races.
- [x] Declarative Architecture: Clean @RequireLimit NestJS decorator guards eliminating controller boilerplate.
- [x] Scheduled Automation: Nightly cron engine managing trial expiration, account archiving, and minute rollover.