Skip to main content
Engineering Guide · 2026

Subscription Billing Implementation Guide 2026: Stripe, Paddle & More

A complete engineering and product guide to building robust subscription billing — covering proration, dunning, metered usage, VAT, revenue recognition, and choosing the right billing platform for your SaaS.

March 2026·26 min read·Codazz Engineering

Why Subscription Billing Is Surprisingly Hard

Subscription billing feels like it should be a solved problem — charge a card every month, done. In reality, billing systems are one of the most complex domains in SaaS engineering. A single subscription can touch proration, tax calculation, dunning sequences, refunds, plan changes, trial management, revenue recognition, and real-time usage metering — all at once.

When a customer upgrades from a $49/month plan to a $149/month plan on day 18 of a 30-day billing cycle, you need to: charge them for the remaining 12 days at the $149 rate, credit them for unused days on the $49 plan, apply the net to their next invoice, update your revenue recognition schedules, and send them a prorated receipt — all while ensuring their access is upgraded instantly. Miss any step and you have an angry customer or an accounting nightmare.

Beyond edge cases, the cost of getting billing wrong is enormous. Failed payments alone cause significant revenue leakage — payments fail for reasons the customer never intended: expired cards, insufficient funds, bank-side fraud blocks, network timeouts. This "involuntary churn" is one of the most underappreciated revenue drains in the SaaS industry.

$48B+
lost to subscription churn annually across SaaS industry
40%
of SaaS churn is involuntary — caused by failed payments, not customer intent
9.6%
of SaaS revenue lost annually to failed payment / involuntary churn
3.5×
higher LTV when dunning sequences recover a previously failed payment

Beyond failed payments, subscription billing complexity includes: tax compliance across 50+ jurisdictions (EU VAT, US sales tax nexus, AU GST, Canadian GST/HST), currency handling, refund processing, dunning email sequences, plan change proration, metered usage aggregation, deferred revenue accounting, and integration with ERP/accounting systems. The good news: modern billing platforms handle most of this — if you choose and configure them correctly.

Billing Platform Comparison: Stripe vs Paddle vs Chargebee vs Recurly vs Zuora

Choosing the right billing platform is a foundational architectural decision that is expensive to reverse. Here is a detailed comparison of the five major players in 2026, covering merchant-of-record status, transaction fees, tax handling, pricing, and ideal use case.

PlatformMerchant of RecordTransaction FeeVAT / TaxPricingBest ForGlobal Reach
Stripe BillingNo — you are MoR0.5% on Starter; 0.8% on ScaleStripe Tax add-on (~0.5% per transaction)Pay-as-you-goDev-first teams, full control195+ countries
PaddleYes — Paddle is MoR5% + $0.50 per transactionIncluded — Paddle handles all VAT/GST/sales taxRevenue share modelB2C SaaS, global tax compliance200+ countries
ChargebeeNo — sits on top of Stripe/Braintree$0 txn fee (plan-based pricing)Chargebee Tax (Avalara integration)$599–$2,000+/moMid-market SaaS, complex billing logic180+ countries
RecurlyNo — sits on top of payment gateways0.9% of revenueAvalara AvaTax integration$249–$2,000+/moB2C subscriptions, high volume160+ countries
ZuoraNoEnterprise custom pricingZuora Tax (Avalara)Enterprise contract onlyEnterprise SaaS, complex quotingGlobal

Merchant of Record (MoR) explained: When Paddle or Lemon Squeezy is the MoR, they appear on the customer's bank statement, handle all VAT/sales tax remittance globally, and absorb chargeback liability. You receive the net amount. This dramatically simplifies compliance for indie developers and small SaaS teams but costs more in transaction fees. Stripe, Chargebee, and Recurly make you the MoR — you are responsible for tax compliance in every jurisdiction where you have nexus.

Lemon Squeezy (now owned by Stripe) is another popular MoR option for indie developers, with a simple 5% + $0.50 per transaction fee and built-in affiliate system. For most early-stage SaaS companies with global ambitions and under $1M ARR, Paddle or Lemon Squeezy often provides the best balance of simplicity and compliance. Above $1M ARR with complex billing needs, Stripe Billing with Stripe Tax becomes cost-effective. Enterprise companies with CPQ (configure-price-quote) requirements typically graduate to Zuora.

Stripe Billing Deep Dive

Stripe Billing is the most developer-friendly and extensible subscription billing system available. Understanding its object model is essential before building on top of it.

Object Hierarchy: Products → Prices → Subscriptions

Stripe's billing model is organized as a three-level hierarchy. A Product represents what you are selling (e.g., "Pro Plan", "Enterprise Plan"). A Price defines how you charge for that product — amount, currency, interval, and billing type. A Subscription links a Customer to one or more Prices and manages the recurring billing lifecycle.

Product
What you sell. Name, description, metadata. Can have multiple Prices attached.
Price
How you charge. Amount, currency, interval (month/year), billing scheme (per_unit, tiered, metered).
Customer
Who you charge. Stores payment methods, tax IDs, billing address, credit balance.
Subscription
Active recurring agreement. Links Customer + Price(s). Manages billing cycle, trial, status.
Invoice
Billing record. Auto-created each cycle. Line items from subscription + usage records.

Price Types

  • Flat rate$49/month — fixed price regardless of usage or seats.
  • Per seat (per_unit)$15/user/month — multiply unit amount by quantity. Quantity updated when seats change.
  • Metered (usage-based)Price based on reported usage events. Aggregated at end of billing period into invoice.
  • TieredVolume or graduated pricing — different rates at different usage thresholds.
  • One-timeNon-recurring charge. Can be added to a subscription invoice as an add-on.

Creating a Subscription — Node.js Example

// Create a subscription with a 14-day free trial
const subscription = await stripe.subscriptions.create(({
customer: customer.id,
items: [{ price: priceId }],
trial_period_days: 14,
payment_settings: {
save_default_payment_method: 'on_subscription',
},
automatic_tax: { enabled: true },
expand: ['latest_invoice.payment_intent'],
});
// Enable Customer Portal for self-serve management
const portalSession = await stripe.billingPortal.sessions.create(({
customer: customer.id,
return_url: 'https://yourapp.com/dashboard',
});

Stripe Meters API (Usage-Based Billing — GA 2025)

Stripe's Meters API (released to general availability in mid-2025) replaces the older Usage Records API with a more robust, idempotent event-driven system. Instead of reporting a cumulative usage count, you emit discrete events that Stripe aggregates according to the meter's aggregation type.

Critical Webhooks to Handle

customer.subscription.createdProvision access, send welcome email, set trial end date in your DB.
customer.subscription.updatedHandle plan change: update feature flags, adjust seat count, refresh entitlements.
customer.subscription.deletedDeprovision access, trigger offboarding flow, export user data if requested.
invoice.payment_succeededMark payment received, send receipt, reset dunning state, extend access.
invoice.payment_failedTrigger dunning sequence: email customer, schedule retries, optionally restrict features.
invoice.finalizedInvoice is locked and sent to customer. Good time to post to accounting system.
customer.subscription.trial_will_endFires 3 days before trial ends. Prompt to add payment method.

Always validate webhook signatures using stripe.webhooks.constructEvent() and handle idempotency — Stripe may retry webhooks for up to 72 hours. Store processed event IDs and skip duplicates. Use a queue (SQS, BullMQ) rather than processing webhooks inline to avoid timeout failures.

Dunning Management: Recovering Failed Payments

"Dunning" is the process of communicating with customers and retrying payment collection after an initial payment failure. It is one of the highest ROI activities in subscription billing — recovering even 30-40% of failed payments translates directly to ARR that would otherwise vanish silently.

Payment failures fall into two categories: hard declines (stolen card, account closed — do not retry) and soft declines (insufficient funds, do not honor temporarily, card network timeout — retry is appropriate). Your dunning logic must distinguish between them.

Stripe Smart Retries vs Manual Retry Schedule

Stripe Smart Retries (Recommended)

ML-powered retry scheduling that analyzes the optimal time to retry based on card network signals, time of day, day of week, and historical recovery patterns. Stripe's data shows Smart Retries recover 38% more failed payments than fixed retry schedules.

  • 3–4 retry attempts over 7 days
  • Adaptive timing based on card type
  • Avoids retry storms (all at midnight)
  • Enable: set smart_retries: true in subscription settings
Manual Retry Schedule (Fallback)

When you need full control over retry timing (e.g., custom business rules), define your own schedule via the Stripe API or Chargebee/Recurly dunning settings.

  • Day 0: Initial failure — soft notification
  • Day 3: First retry + email reminder
  • Day 7: Second retry + stronger email
  • Day 14: Third retry + final warning
  • Day 28: Final retry or cancel subscription

Dunning Email Sequence

Day 0
Action required: payment issue
Soft, helpful. Explain what happened, link to update payment. No blame.
Day 3
Reminder: update your payment method
Friendly reminder. Highlight what they will lose access to. Prominent CTA button.
Day 14
Final notice: account at risk of suspension
Urgent but not threatening. Offer 1-click payment update. Offer downgrade or pause option.
Day 28
Your subscription has been paused / canceled
Compassionate, easy reactivation. Preserve data. Invite them back anytime.

Pause vs Cancel Flow

Before hard-canceling a subscription, offer the customer a pause option. Stripe supports pausing billing (but not access) for up to 3 months. Many users who would otherwise churn will take the pause — and resume paying without any intervention from your team. Implement this in your cancellation flow as a "Take a break?" option shown before the final cancellation confirmation.

Account Updater: Stripe automatically contacts card networks to get updated card details when a card expires or is replaced. Enable this in your Stripe Dashboard — it silently recovers many cards that would otherwise hard-fail without the customer ever knowing there was an issue. Reduces involuntary churn from card expiry by ~15-20%.

Metered / Usage-Based Billing

Usage-based billing (UBB) — where customers pay based on what they consume rather than a flat subscription rate — is the fastest growing pricing model in SaaS. Companies like Twilio, Cloudflare, AWS, and Stripe itself pioneered it; now it is table stakes for API businesses and increasingly popular for AI and analytics SaaS.

Stripe's Meters API (GA 2025) provides a production-ready infrastructure for usage-based billing. The architecture involves three components: a Meter definition (what you are measuring and how to aggregate it), Meter Events (individual usage occurrences you report), and a metered Price (how much each unit costs, attached to a subscription).

Stripe Meters API Workflow

1. Create Meter
stripe.billing.meters.create()
Define event_name, aggregation (sum / max / last_during_period), and key fields to filter on.
2. Create Metered Price
billing_scheme: "per_unit"
Create a Price with usage_type: "metered", attach to your Product, set unit_amount.
3. Report Events
stripe.billing.meterEvents.create()
Emit events as they happen in your system. Idempotent: include an idempotency key to prevent double-counting.
4. Invoice Auto-generated
invoice.finalized webhook
At end of billing period, Stripe aggregates events, generates invoice line item, charges customer.

Aggregation Types

sum
Total all events. Best for API call counts, messages sent, rows processed.
max
Highest value reported in period. Best for peak concurrent users, max storage.
last_during_period
Final reported value. Best for seat counts, current active users at end of month.

Real-World Examples

API SaaS (like 0x Protocol)API calls$0.002 per callaggregation: sum
Emit event on every authenticated API request. Include customer_id and endpoint for granular filtering.
CDN / Edge (like Cloudflare)GB transferred$0.01 per GBaggregation: sum
Aggregate bytes at edge, flush to billing system in 1-minute batches. Never lose events.
Collaboration SaaS (like Notion)Active seats$15/seat/monthaggregation: last_during_period
Report seat count nightly. Last value wins — customers only pay for seats active at month-end.

Implement usage alerts proactively — notify customers at 80% and 100% of any included usage threshold. This reduces bill shock churn (customers who cancel after seeing an unexpected invoice) and creates natural upsell opportunities. Stripe's usage-based billing allows defining soft and hard caps at the Price level.

Proration Logic: Handling Plan Changes Correctly

Proration is the calculation of partial-period charges and credits when a customer changes plans mid-billing-cycle. Getting this wrong creates customer service tickets, accounting errors, and trust issues. Stripe handles proration automatically — but you must understand which behavior to configure for each scenario.

Upgrade (Mid-Cycle)

Customer upgrades from $49/mo to $149/mo on day 18 of a 30-day cycle (12 days remaining).

  • Credit: 12/30 × $49 = $19.60 unused old plan
  • Charge: 12/30 × $149 = $59.60 new plan remainder
  • Net charge immediately: $59.60 − $19.60 = $40.00
  • Next invoice: full $149/mo on renewal date
Downgrade (Mid-Cycle)

Customer downgrades from $149/mo to $49/mo on day 18 of a 30-day cycle (12 days remaining).

  • Credit: 12/30 × $149 = $59.60 unused old plan
  • Charge: 12/30 × $49 = $19.60 new plan remainder
  • Net credit: $59.60 − $19.60 = $40.00 applied to next invoice
  • No immediate charge — credit balance carries forward

Stripe proration_behavior Options

'create_prorations'Default. Creates proration invoice items immediately. Customer charged/credited on current or next invoice.
'always_invoice'Creates proration items AND immediately finalizes and pays an invoice. Good for upgrades where you want instant charge.
'none'No proration. Plan change takes effect at next renewal. Best for downgrade UX — do not charge/credit mid-cycle.

Edge case — upgrade on last day of billing cycle: If a customer upgrades on the last day of the cycle, the prorated charge for "remaining days" is nearly zero (1/30 × price difference). This means they get the upgraded plan for almost a full month before being charged the full new price. Decide upfront whether this is acceptable or if you want to use 'always_invoice' to ensure immediate billing and a clean monthly cycle reset.

Revenue Recognition: ASC 606 & IFRS 15 for SaaS

Revenue recognition is an accounting principle that determines when you can record revenue on your income statement. For SaaS companies, this is governed by ASC 606 (US GAAP) and IFRS 15 (international). Getting this right is critical for: accurate financial reporting, investor due diligence, and avoiding accounting restatements.

The core principle: recognize revenue when (or as) performance obligations are satisfied. For subscriptions, you are delivering ongoing access to software — so revenue is recognized ratably (evenly) over the subscription period, not all at once when payment is received.

Annual subscription paid upfront
Recognize 1/12 of the amount each month. The remaining 11/12 is Deferred Revenue on the balance sheet.
Monthly subscription
Recognize the full monthly amount in the month it is earned. Simpler — billing and recognition align.
One-time setup fee
Recognize at the point of delivery (when setup is complete), not spread over the subscription term.
Refund issued
Reverse the previously recognized revenue. Reduce revenue on P&L for the period the refund is processed.

Stripe Revenue Recognition

Stripe's Revenue Recognition add-on automatically generates GAAP-compliant journal entries for all Stripe transactions. It handles deferred revenue waterfall schedules, plan changes, refunds, and disputes — eliminating the manual spreadsheet reconciliation that kills finance teams at $1M+ ARR.

Accounting System Integration

QuickBooks Online
Synder or Zapier → auto-sync Stripe charges, refunds, payouts into QBO as transactions.
Xero
Synder or native Stripe-Xero integration → daily reconciliation of Stripe payouts.
NetSuite
Native Stripe Connector for NetSuite (official, real-time, supports multi-entity).
Sage Intacct
Stripe + Sage Intacct via Workato or custom API integration for enterprise finance teams.

Global Tax Compliance for SaaS

Tax compliance is the silent killer of SaaS companies that scale internationally without legal guidance. The rules differ by country, by product type (digital goods vs software vs services), by B2B vs B2C, and by revenue threshold. Here is a practical breakdown of the major jurisdictions you will encounter.

🇺🇸United States — Sales Tax

No federal sales tax. Each state sets its own rules. "Economic nexus" created by $100K revenue OR 200+ transactions in a state per year. Once nexus is established, you must register, collect, and remit sales tax in that state. SaaS is taxable in ~35 states (definitions vary — "prewritten software" vs "custom software" vs "SaaS" treated differently by state).

Tool: Use Stripe Tax or TaxJar to automate nexus tracking and calculation across all 50 states.
🇪🇺European Union — VAT

VAT rates range from 17% (Luxembourg) to 27% (Hungary). If you sell B2C digital services to EU customers, you must register for VAT OSS (One Stop Shop) once you exceed €10,000 in EU cross-border sales. B2B sales: apply reverse charge (customer self-accounts for VAT with their VAT number). Always collect and validate VAT IDs from B2B customers.

Tool: Paddle handles EU VAT entirely as MoR. With Stripe, enable Stripe Tax and collect customer VAT IDs via Stripe Customer Portal.
🇨🇦Canada — GST/HST/QST

Federal GST at 5%. Provinces with HST (Ontario, BC, etc.) add provincial portion for combined rates of 12-15%. Quebec charges QST separately (9.975%). Register when annual worldwide taxable supplies exceed $30,000 CAD. Non-resident digital service providers supplying B2C customers in Canada must register even without a physical presence.

Tool: Stripe Tax supports Canadian GST/HST/QST calculation automatically with customer location detection.
🇦🇺Australia — GST

Flat 10% GST on all digital services sold to Australian consumers. Register for GST if you make more than AUD $75,000 in annual turnover in Australia. Non-resident suppliers can register through the ATO's simplified GST registration system. B2B supplies to GST-registered businesses use reverse charge.

Tool: Paddle handles AU GST as MoR. Stripe Tax supports AU GST calculation.
🇮🇳India — GST & GSTIN

Indian GST at 18% on digital services (OIDAR — Online Information and Database Access or Retrieval services). Foreign suppliers must register under the simplified GST registration for OIDAR services. Collect GSTIN (GST Identification Number) from B2B customers — allows them to claim input tax credit. Display GSTIN on invoices.

Tool: Build GSTIN collection into checkout flow. Validate GSTIN via GST API before issuing B2B invoice.

Recommendation for early-stage startups: Use Paddle or Lemon Squeezy (Merchant of Record) to avoid all tax registration and remittance complexity until you reach $500K-$1M ARR and have a dedicated finance/legal team. The 5% transaction fee is cheaper than the cost of tax compliance infrastructure and risk of non-compliance penalties.

SaaS Billing Analytics: Metrics That Matter

Your billing system is also your most accurate business intelligence source. The metrics derived from subscription data — not website analytics — are what investors look at and what drive strategic decisions. Here are the key metrics every SaaS team must track, with formulas.

MRR (Monthly Recurring Revenue)
Σ (monthly_plan_price × active_subscribers)
Normalize annual plans to monthly (ARR ÷ 12). Exclude one-time charges. The single most important SaaS health metric.
ARR (Annual Recurring Revenue)
MRR × 12
Preferred by investors. Only include truly recurring revenue — exclude professional services and one-time fees.
MRR Churn Rate
(MRR lost from cancellations ÷ Beginning MRR) × 100
Target: <2% monthly for SMB SaaS, <0.5% for enterprise. 2% monthly = 22% annual churn — most companies can absorb this but not grow fast.
Net Revenue Retention (NRR)
(Beginning MRR + Expansion MRR − Contraction MRR − Churned MRR) ÷ Beginning MRR × 100
NRR > 100% means existing customers grow faster than they churn. Best-in-class SaaS: 120%+ NRR. Required for Series A+ fundraising.
LTV (Customer Lifetime Value)
ARPU ÷ Monthly Churn Rate
Or: Average contract value × average contract length. LTV:CAC ratio of 3:1+ is the standard investment-grade benchmark.
Expansion MRR
MRR added from existing customers (upgrades, seat additions, overages)
Healthy SaaS shows 15-25% of new MRR coming from existing customers. Leading indicator of product value and land-and-expand motion.

Analytics Tools

ChartMogul
Best-in-class SaaS metrics. Native Stripe integration. Cohort analysis, MRR movements, LTV. Free up to $10K MRR.
Baremetrics
Real-time Stripe analytics. Forecasting, benchmark data vs industry. $129/mo starting.
ProfitWell (by Paddle)
Free MRR analytics with paid add-ons for dunning (Retain) and price optimization (Pricing). Now integrated with Paddle.
Stripe Revenue Dashboard
Built into Stripe Dashboard. Limited but free. Good for quick MRR snapshots, not deep cohort analysis.

Frequently Asked Questions

Q: Should I use Stripe or Paddle for my SaaS?
It depends on your primary pain point. If global tax compliance is a headache and you want to focus on building product, Paddle (Merchant of Record) is the faster path — they handle EU VAT, US sales tax, and AU GST for you. You receive the net amount and never deal with tax registration in 50 jurisdictions. If you need maximum customization, developer control, and plan to build complex billing logic (metered usage, multi-currency, enterprise contracts), Stripe Billing is the right choice. Add Stripe Tax to handle VAT/GST automatically. Most companies under $500K ARR benefit from Paddle's simplicity; above that, the economics often favor Stripe.
Q: How do I handle VAT for EU customers?
Two approaches: (1) Use Paddle as your Merchant of Record — Paddle collects and remits EU VAT on your behalf. You see net revenue and never touch VAT. (2) Handle it yourself with Stripe: enable Stripe Tax (one flag in the API), collect customer location and VAT IDs at checkout, Stripe calculates and includes VAT on invoices automatically. You still need to register for EU VAT OSS if you exceed €10,000 in B2C cross-border sales. For B2B EU customers, always collect and validate their VAT number to apply the reverse charge mechanism (no VAT charged).
Q: What is the best way to implement a free trial?
Use a credit card upfront trial (not a no-card trial) for the best conversion rates. Set trial_period_days on the Stripe subscription. The customer adds their card at signup, the trial runs, and billing starts automatically — no action required. Send a "trial ending in 3 days" email (triggered by customer.subscription.trial_will_end webhook). For usage-based products, consider a credit-based trial (e.g., $100 free usage credits) rather than a time-limited trial — this aligns the trial experience with how they will actually pay.
Q: How do I reduce involuntary churn from failed payments?
Five tactics in order of impact: (1) Enable Stripe Smart Retries — ML-powered retries recover 38% more payments than fixed schedules. (2) Enable Account Updater — silently refreshes expired card details via card networks. (3) Send proactive dunning emails with a one-click payment update link — personalized, not generic. (4) Offer a subscription pause (1-3 months) as an alternative to cancellation in your dunning flow. (5) Implement Plaid Link or card scanning to make it easy for customers to update payment method on mobile. Dunning tools like ProfitWell Retain or Chargebee's dunning module can add another 5-10% recovery.
Q: Do I need to charge sales tax in the US?
Yes, in many states — but only once you cross the economic nexus threshold. Most states use $100,000 in revenue or 200 transactions per year as the trigger. Once you have nexus in a state, you must register, collect, and remit sales tax in that state. SaaS taxability varies: some states tax SaaS as "prewritten software", others exempt it. Use Stripe Tax or TaxJar to automate nexus tracking and calculation. Do not wait until you have nexus in 30 states before addressing this — it is much easier to set up compliance infrastructure early than to deal with back taxes.

Need Help Architecting Your Billing System?

Codazz has helped 30+ SaaS companies design and implement subscription billing systems — from Stripe Billing setup to metered usage engines to global tax compliance. Book a free 30-minute billing architecture review.

Book Free Billing Architecture Review