Subscription Commerce Architecture: Building for Recurring Revenue at Scale
Subscriptions look simple in a product meeting: customer pays monthly, gets the thing, cancels whenever. We've built enough of these to tell you the gap between that description and the actual implementation is enormous. Dunning logic, proration on mid-cycle upgrades, failed payment retry schedules, jurisdiction-specific tax rules, pause flows — none of this is hard in isolation, but all of it has to work together reliably, every billing cycle, indefinitely.
Subscription state machine. Transitions are triggered by billing events, user actions, and dunning outcomes — all of which need explicit handling in your system.
Why existing commerce platforms fall short
Magento, Shopify, and WooCommerce are built around point-in-time transactions. Subscriptions are different: a subscription has state that persists and changes — active, past-due, paused, canceled — and that state has to stay consistent across your storefront, billing provider, ERP, and fulfillment system simultaneously. When any of those drifts out of sync, you're either charging someone who canceled or not charging someone who should be paying. Both are bad.
Platform plugins get you through basic cases — monthly recurring charge, cancel at period end, maybe a free trial. They fall apart on anything beyond that. Mid-cycle plan changes, multi-item subscriptions where items renew on different schedules, custom pause logic, partial months on annual plans. If your subscription model has any real complexity, you need a billing layer you actually own and can debug.
Billing engine: build vs. buy
This is the core call. Stripe Billing, Chargebee, and Recurly exist specifically to handle the hard parts: proration math, dunning sequences, tax calculation by jurisdiction, invoice generation, payment method management. They integrate with most payment providers and the APIs are solid. They're not cheap — you're looking at 0.5–1% of recurring revenue depending on volume and tier — but that cost includes a lot of edge cases you don't have to discover the hard way.
The case for building your own: you have billing logic that genuinely can't be modeled in the off-the-shelf tools, compliance requirements that rule out third-party data processors, or volume where the percentage fee is actually material to unit economics. We've seen one or two situations where building made sense. Most teams should use Chargebee or Stripe Billing and spend the saved engineering time on things that differentiate their product.
Dunning: where most teams leave money behind
Dunning is the process of recovering failed subscription charges — retries, customer notifications, escalating prompts to update payment info. Cards decline for a lot of reasons that have nothing to do with the customer actually wanting to cancel: temporary bank holds, expired cards that auto-updated but the token didn't propagate, soft declines that clear on a retry an hour later.
A retry-once-then-cancel approach loses a real chunk of recoverable revenue. The pattern that works: retry on a schedule (something like day 1, day 3, day 7, day 14), send an email at each failure, and give customers a direct link to update their payment method. Recovery rates vary a lot by business and customer base — we've seen anywhere from 10% to over 30% of failed charges recovered with a proper dunning sequence. The engineering effort is modest. Not doing it is a permanent, compounding leak.
Upgrade, downgrade, and pause flows
Mid-cycle plan changes are where billing logic gets fiddly. If someone upgrades on day 15 of a 30-day billing cycle, they owe a prorated amount for the remainder of the period. Simple enough in principle, but you need this calculation to be consistent across annual plans, plans with different billing anchor dates, and plans that have add-ons with their own pricing. Write it down, get it reviewed, and test the edge cases explicitly — proration errors compound and are annoying to reconcile after the fact.
Pause flows reduce cancellations. Subscribers who'd otherwise cancel often accept "skip a month" if the option is visible. The implementation question is what "paused" means concretely: does a paused subscriber get the next shipment? Do they retain account access? Are they charged a reduced amount or nothing? These decisions need to be made upfront because they affect your fulfillment integration, your access control logic, and your billing setup. There's no clean universal answer — depends on your model.
The reporting gap
Transaction-based e-commerce reporting doesn't translate to subscriptions. MRR, net revenue retention, churn by cohort, LTV — these require a data model that tracks subscription state over time, not just point-of-charge records. Build this from day one. If you skip it and come back later, reconstructing historical subscription state from payment records is genuinely painful and never quite accurate.
Next step
Working on a complex commerce system?
We help engineering teams design, build, and scale high-load platforms — with a clear process and predictable delivery.
Let's talk