Services

How to Build a Subscription Billing System: Mandates, Failed-Charge Retries, Downgrades and Retention

2026.09.03 · 31 views
How to Build a Subscription Billing System: Mandates, Failed-Charge Retries, Downgrades and Retention

The hard part is never the first payment. It is the thirteenth — and 217 zombie subscriptions is what happens when nobody defines what follows a failed charge.

Share:

Month 14, and the client discovered 217 zombie subscriptions

An online-course client had been running subscriptions for 14 months with 1,842 active subscribers on the books. Reconciliation revealed that 217 of those cards had expired long ago. The system retried three times, failed, and then did nothing — members kept logging in and watching courses while no money arrived. At NT$690 a month, that is roughly NT$1.8 million a year. The payment gateway was not at fault. The system had simply never defined what happens after a charge fails. The hard part of subscriptions is never collecting the first payment. It is collecting the thirteenth.

When it fits, and when it doesn't

Build a subscription systemDon't build one yet
Online courses or content memberships needing monthly access gatingHigh-ticket B2B closing 3–5 deals a year (an e-quote is enough)
SaaS or tools with clearly tiered plansUnder 50 customers, all known personally (transfers plus a spreadsheet is cheaper)
Physical subscription boxes where fulfilment scheduling ties to billingRules differ per customer — that is contract management, not subscriptions
Gyms or clinics with session packs needing remaining-count controlOne annual plan, low volume (manual invoicing costs less)
Multi-tier plans requiring upgrades, downgrades and prorationNobody has paid a second month yet (validate with manual billing first)

Alternatives matrix

OptionCost bandStrengthsWeaknesses
ECPay / NewebPay recurringBuild NT$80k–150k; processing ~2.75%–3.5% per ECPay's published ratesLocal support, convenience-store and ATM rails, complete e-invoice integrationPlan changes and proration must be hand-built; less API flexibility
Stripe BillingBuild NT$100k–200k; official rates plus Billing surchargePlans, trials, proration and dunning built in; mature webhooksLimited local payment rails; account setup more involved for Taiwan entities
Packaged SaaS (Chargebee, Paddle)US$0–599+/mo plus revenue shareNo build; reporting and tax handling includedData lives outside; cost scales linearly with revenue; limited customisation
Self-built engine (Laravel Cashier)Build NT$180k–350kFull control of rules; deep integration with existing membershipDunning, reconciliation and tax logic are yours to maintain; heavy first-year ops

For most Taiwanese SMBs the sweet spot is a local gateway for money movement plus a self-built subscription state machine for rules.

Full process breakdown (with tools and deliverables)

  • Phase 1: Plans and rules (3–5 days) | Tools: Figma, Notion | Deliverables: plan matrix (plan / cycle / price / entitlements / change rules) and state machine diagram (trial → active → past due → grace → paused → cancelled). Writing code before this is settled is the source of every later rewrite.
  • Phase 2: Mandate and recurring charge integration (5–8 days) | Tools: ECPay recurring API or Laravel Cashier | Deliverables: mandate creation, charge execution, idempotent webhook handling (a resent notification must not double-post).
  • Phase 3: Dunning (4–6 days) | Tools: Laravel Queue, SendGrid or Amazon SES, LINE Messaging API | Deliverables: retry schedule (D+1 / D+3 / D+7), three-stage notification copy, automatic entitlement downgrade after grace.
  • Phase 4: Upgrades, downgrades and proration (3–5 days) | Deliverables: a proration rules document plus unit tests for cross-month, cross-year and refund cases.
  • Phase 5: Invoicing and reconciliation (4–6 days) | Tools: e-invoice API, Metabase | Deliverables: monthly auto-issue, void and credit-note flows, daily reconciliation report (system receivable vs gateway received).
  • Phase 6: Customer self-service (3–5 days) | Deliverables: change card, switch plan, download invoices, self-cancel with a retention step.
  • Phase 7: UAT and launch (3–5 days) | Tools: Sentry, UptimeRobot | Deliverables: test-card scenario list, billing-day load test, monitoring and alerts.

Total: roughly 25–40 working days.

Real cost breakdown

  • Development: NT$180,000–350,000 depending on tier count and whether physical fulfilment scheduling is included
  • Payment processing: roughly 2.75%–3.5% on recurring charges — about NT$140k–175k per year at NT$5M revenue
  • E-invoicing: roughly NT$0.5–1.5 per invoice, or NT$6,000–20,000 annually on a flat plan
  • Email delivery: NT$300–1,500/month; dunning volume pushes you up tiers
  • SMS or LINE push: NT$0.7–2.0 per message; three dunning stages against a 5% failure rate is a standing cost
  • Hidden cost 1: manual dunning. What auto-retry cannot rescue still needs roughly 4–8 support hours a month
  • Hidden cost 2: reconciliation variance investigation — about 3–6 hours a month for the first three months
  • Hidden cost 3: the card-expiry wave — 5%–8% of cards expire naturally each year, and without proactive reminders that is straight churn
  • Ongoing maintenance: NT$8,000–20,000/month, covering gateway API updates and tax rule changes

Reality vs client expectation

  • Expectation: "Wire up the gateway and money collects itself." | Reality: the gateway only reports success or failure. Retry, notification, downgrade and retention are all logic you write — about 35% of total effort.
  • Expectation: "Cancelling means deleting the record." | Reality: cancellation splits into immediate versus end-of-period, and invoice plus tax records must be retained. Deleting breaks reconciliation and refunds.
  • Expectation: "Upgrading is just a different price." | Reality: mid-cycle changes require prorating unused days and issuing a difference invoice or credit note, with different rules across month and year boundaries. This is the most error-prone section.
  • Expectation: "Receiving the webhook means it's handled." | Reality: gateways resend notifications. Without idempotency you double-post revenue and double-issue invoices.

Common traps and how to avoid them

  • Trap 1: no downgrade path after failed payment. → Define the grace period (7 days is a reasonable default) and automatic downgrade in the state machine on day one.
  • Trap 2: webhooks without an idempotency key. → Use the gateway's transaction ID as a unique key with a database unique index; ignore duplicates outright.
  • Trap 3: every charge lands on the 1st. → Distribute billing dates by subscription start date, or you will hit gateway rate limits every month.
  • Trap 4: no card-expiry reminders. → Notify at 30 and 7 days before expiry. This is the highest-ROI dunning logic there is.
  • Trap 5: invoice issued, order refunded. → Build the credit-note flow and give "invoiced but unpaid" its own column in the reconciliation report.
  • Trap 6: cancellation buried too deep. → Consumer protection rules and platform policies both prohibit obstructive cancellation. Put the exit in plain sight and use retention offers (pause a month, downgrade) instead.
  • Trap 7: testing only with success cards. → Run the full flow with the gateway's declined, insufficient-funds and expired-card test numbers.

Success metrics and the first 90 days

  • Day 30: charge success rate (healthy above 92%), webhook processing failures (should be zero), reconciliation variance (under 0.5% of revenue). Focus: eliminate variance sources.
  • Day 60: dunning recovery rate (healthy at 25%–40%) and card update rate. Focus: tune retry intervals and notification copy.
  • Day 90: monthly churn (under 5% for content subscriptions), retention conversion on the cancel page, upgrade rate. Focus: replace a bare cancel button with pause / downgrade / cancel.

Decision checklist

  • ☐ We have at least 50 people who paid a second month
  • ☐ We have five or fewer plans and the rules are the same for everyone
  • ☐ We can state exactly what happens on day 7 after a failed charge
  • ☐ We need upgrades, downgrades and proration
  • ☐ We need a trial period (free or discounted)
  • ☐ We must issue e-invoices with void and credit-note support
  • ☐ Someone can spend 4 hours a month on dunning exceptions
  • ☐ Our customers mostly use local payment rails
  • ☐ Customers need to update their card themselves
  • ☐ We need pause, not just cancel
  • ☐ We will run the declined-card scenarios before launch
  • ☐ The daily reconciliation report has a named recipient
  • ☐ Projected revenue absorbs roughly 3% in processing fees

Eight or more: build it. Four or fewer: validate with packaged SaaS or manual billing first.

FAQ

Local gateway or Stripe Billing?

It depends where the customers are. Domestic customers needing convenience-store and ATM rails and local e-invoicing: use the local gateway. Overseas customers, complex plans and proration, a team comfortable with English docs: Stripe. Running both is viable but reconciliation must be written separately, adding roughly 20% to cost.

How many retries after a failed charge?

Three to four is standard, at D+1, D+3 and D+7, paired with three-stage notifications. Beyond four, returns diminish and some issuers treat high-frequency failures as anomalous. What matters is not the count but that every retry ships with a notification the customer can act on.

How long does this take, and can we ship a simplified version?

The full build is 25–40 working days. A simplified version — one monthly plan, dunning limited to "notify on failure plus downgrade after 7 days", no proration — runs 12–15 days. But design the complete state machine in version one; retrofitting it later touches the data model.

How do I check an existing system for zombie subscriptions?

Run a reconciliation query joining subscriptions whose entitlement is active against their most recent successful charge, and surface any whose last success predates one billing cycle plus the grace period. This is usually the most alarming table your first reconciliation produces.

Next step

Our subscription billing build starts at NT$180,000 and covers the plan matrix, state machine design, recurring gateway integration, dunning flow and daily reconciliation report. If you already have a system live, we also run a standalone subscription health check to surface zombie subscriptions and reconciliation gaps.

Share: