Skip to main content
Engineering 7 min read

Subscription Billing with Stripe: A SaaS Architecture Guide

Build subscription billing on Stripe without the costly mistakes. Webhooks, the subscription lifecycle, usage metering, and dunning, from a team that's shipped it.

BrotCode
Updated May 31, 2026
Subscription Billing with Stripe: A SaaS Architecture Guide

Billing Is Where SaaS Products Go to Die

Not with a dramatic crash. With a slow leak. A customer gets double-charged and loses trust.

An upgrade doesn’t prorate correctly, and finance spends three hours reconciling. A failed payment silently churns a customer who would’ve stayed.

This is why most teams build subscription billing on Stripe rather than rolling their own. Stripe handles the brutally hard parts: payment retries, tax calculation, invoicing, PCI compliance. Your job is to integrate it correctly.

We’ve built Stripe integrations for multiple SaaS platforms. This is what we wish someone had told us first.

Don’t Build Your Own Billing System

A subscription billing system is the software that runs your entire recurring-revenue lifecycle: creating subscriptions, charging customers on a schedule, prorating plan changes, retrying failed payments, generating invoices, and keeping tax and revenue records straight. That’s a lot of surface area.

This bears repeating. We’ve watched teams spend six months rebuilding what Stripe gives you out of the box. Subscription lifecycle management, proration, dunning, invoice generation, tax compliance. All of it. Already built.

77% of the largest software companies now use consumption-based pricing through platforms like Stripe. You’re not smarter than Stripe’s billing team. Use their infrastructure, spend your engineering time on your actual product.

If you’re new to SaaS architecture, our complete multi-tenant SaaS guide covers how billing fits into the bigger picture.

The Core Architecture

Your SaaS has two sources of truth for billing: Stripe and your database. They need to stay in sync. Always.

Stripe owns payment state: subscriptions, invoices, payment methods, charges. Your database owns business state: which tenant is on which plan, what features they can access, usage counters.

The bridge between them is webhooks. Stripe fires events for every billing action (subscription created, payment succeeded, invoice finalized). Your webhook handler updates your database accordingly.

Never poll Stripe’s API to check subscription status. That’s fragile and slow. Trust the webhooks.

Webhook Architecture That Won’t Break

Webhooks are the backbone. Get them wrong and your billing state drifts from reality. Here’s how to get them right.

Idempotency first. Stripe can (and will) send the same event multiple times. Your handler must process each event exactly once.

Store the event ID, check before processing.

Process asynchronously. Don’t do heavy work inside the webhook handler. Acknowledge the webhook with a 200 response immediately, then queue the actual processing.

Stripe retries on timeout, and if your handler takes too long, you’ll get duplicate events.

Handle out-of-order events. Stripe doesn’t guarantee delivery order. A subscription.updated event can arrive before subscription.created.

Your handler needs to be resilient to this.

Log everything. Every webhook received, every processing step, every state change. When billing goes wrong (and it will), these logs are the only way to diagnose what happened.

Subscription Lifecycle

The subscription lifecycle has more states than most developers expect.

A customer signs up and enters a trial period (or not). Trial converts to active subscription. Payments succeed or fail.

Failed payments trigger dunning: retry logic and reminder emails. Eventually the subscription is canceled, either by the customer or by exhausted retries.

Each transition fires a Stripe event. Each event needs a handler. Missing even one creates a gap where your system’s understanding of the subscription diverges from reality.

The transitions that trip people up: trial ending without a payment method on file, mid-cycle plan changes that require proration, and the gap between “subscription canceled” and “subscription actually expires at period end.”

Pricing Models

Per-seat pricing still dominates at 57% of SaaS companies, but it’s declining. Usage-based pricing now appears in 43% of models, up from 35% a year ago. Hybrid models are growing fastest, at 61%.

Stripe’s Meters API handles usage-based billing natively. Send usage events in real-time, and Stripe aggregates them for invoicing. No need to build your own metering pipeline.

If you’re building anything AI-flavored, this matters more than it used to. In early 2026 Stripe extended its metering tools specifically for AI usage: token counts, model API calls, agent tasks. If you’re charging per token or per workflow, the plumbing is already there.

For seat-based pricing, Stripe’s quantity-based subscriptions work well. Update the quantity when seats are added or removed. Stripe handles proration.

For tiered pricing, define your tiers in Stripe’s product catalog. Each tier maps to a price with specific features and limits. Your application checks the tenant’s active price to determine feature access.

Need help deciding which model fits your product? Our guide on how to price your SaaS product covers the strategic side.

Free Trials That Convert

Self-service trials convert at 15-25% for good products. Two approaches: card upfront or no card required.

Card upfront filters for serious buyers. Conversion rates are higher, but top-of-funnel is smaller. No card required gets more signups, but many will never convert.

We lean toward card upfront for B2B SaaS. The users who enter a card are genuinely evaluating your product. The ones who don’t were browsing.

Stripe handles trial periods natively. Set the trial duration on the subscription, and Stripe won’t charge until it ends. If no payment method is on file when the trial expires, the subscription moves to past_due. Handle that event.

Dunning: The Revenue You’re Leaving on the Table

Dunning management is the process of recovering failed subscription payments through automated retries, reminder emails, and a clear way for the customer to update their card. It’s how you fight involuntary churn.

Failed payments cause involuntary churn. Not because customers want to leave, but because their card expired or hit a limit.

Across subscription businesses, failed payments account for 20-40% of total churn. That’s a leak you can mostly plug.

Stripe’s Smart Retries use machine learning, trained on data across Stripe’s network, to retry payments at the moments most likely to succeed. Stripe reports they recover around 55% of failed payments on average. Enable it.

Beyond retries, send dunning emails. A 3-email sequence over 14 days is standard. First email: “your payment failed, please update your card.” Second: “your account will be downgraded in 7 days.” Third: “your account has been downgraded.”

Stripe Billing automates this entire sequence. The amount of revenue recovered from dunning alone can be 5-10% of your MRR. That’s not pocket change.

Upgrades, Downgrades, and Proration

Plan changes need to feel instant to the customer. Click upgrade, get access immediately. The billing details should sort themselves out.

Stripe handles proration automatically. If a customer upgrades mid-cycle, Stripe credits the unused portion of the old plan and charges the prorated amount for the new plan. Your webhook handler updates the tenant’s feature access when the subscription change event arrives.

Downgrades are trickier. We recommend applying downgrades at period end, not immediately. The customer paid for the current period; let them keep the features until renewal.

Connecting Billing to Your Tenant System

Every Stripe customer maps to a tenant in your database. Store the Stripe customer ID on your tenant record. When a webhook arrives, resolve the tenant from the Stripe customer ID and update accordingly.

Feature gating based on subscription tier is your application’s responsibility, not Stripe’s. Your middleware checks the tenant’s plan and enforces limits: API rate limits, storage quotas, user counts, feature flags.

Cache the subscription status. Don’t query Stripe (or even your database) on every request to check plan limits. Cache the tenant’s plan and features in Redis, and invalidate when a webhook updates them.

For how billing integrates with your broader authentication and access control system, see our guide on SaaS authentication: SSO, OAuth, and RBAC.

Testing Billing Without Losing Your Mind

Stripe’s test mode is your friend. Use it for every scenario: successful payments, failed payments, card declines, expired trials, plan changes, refunds. Every path that can happen in production should have a test in your CI pipeline.

Stripe’s test clocks let you simulate time. Fast-forward through trial periods, billing cycles, and dunning sequences without waiting. Worth its weight in gold.

One thing we always do: a full billing integration test that creates a tenant, subscribes them, processes a payment, upgrades them, and cancels. If that flow works end-to-end, you’re in good shape.

Our Billing Checklist

After several Stripe integrations, here’s what we verify before launch.

Webhook endpoint is idempotent and processes async. Every subscription lifecycle event has a handler. Dunning is configured with Smart Retries and email sequences.

Proration handles upgrades and downgrades correctly. Feature access updates within seconds of plan changes. Test coverage includes all payment failure scenarios.

Skip any of these and you’ll find out in production. With real money.


Building a SaaS product and need billing that works from day one? Let’s architect it together. We’ve integrated Stripe for multi-tenant platforms and know where the edge cases hide.

FAQ

What is a subscription billing system?
A subscription billing system is the software that runs the full recurring-revenue lifecycle: it creates subscriptions, charges customers on a schedule, handles plan changes and proration, retries failed payments, generates invoices, and keeps tax and revenue records. On Stripe, most of this is already built. Your job is to integrate it and keep your own database in sync.
What is dunning management?
Dunning management is the systematic process of recovering failed subscription payments: automated retries, reminder emails, and a clear path for the customer to update their card before access is cut off. It targets involuntary churn, where customers leave because a card expired, not because they wanted to. Failed payments drive 20-40% of total churn for subscription businesses, so good dunning is real revenue.
How do you build subscription billing on Stripe?
Let Stripe own payment state (subscriptions, invoices, charges) and let your database own business state (which tenant is on which plan). Bridge the two with webhooks, not polling. Make your webhook handler idempotent, process events asynchronously, and give every subscription lifecycle event a handler. Configure Smart Retries and a dunning email sequence, then test every path with Stripe's test clocks before launch.
How much does Stripe Billing cost?
Directionally, Stripe Billing adds around 0.7% per recurring transaction on top of standard payment processing fees as of 2026, which covers Smart Retries, dunning, quotes, and usage metering up to a high monthly event volume. Standard card processing is separate. Check Stripe's current pricing before you model your unit economics, since rates and inclusions change.
Share this article
SaaS billing architecture Stripe

Related Articles

Need help building this?

We turn complex technical challenges into production-ready solutions. Let's talk about your project.