Part IV: Recurring, Subscriptions & Complex Billing
Chapter 15 — Card Dunning: When Payments Fail (And How to Get Them Back)
It's February 1st, 8:47 AM. Alex Chen is halfway through his morning commute, headphones in, streaming his favorite playlist on MelodyBox. He has no idea that three seconds ago, MelodyBox's billing system tried to charge his Visa $9.99 for his monthly subscription — and his bank said no.
Insufficient funds. Decline code 51.
Alex's paycheck doesn't land until February 3rd. His checking account is running on fumes after rent cleared yesterday. He doesn't know any of this is happening. He's just listening to music.
But inside MelodyBox's systems, a clock just started ticking. The company has a narrow window to recover this payment before Alex becomes a statistic — one of the millions of subscribers lost every year not because they wanted to leave, but because their payment silently failed and nobody managed the recovery well.
This is involuntary churn, and it's one of the most expensive problems in subscription commerce. Unlike voluntary churn — where a customer deliberately cancels — involuntary churn happens when a payment method fails and the merchant can't collect. The customer didn't choose to leave. Their card just... didn't work that day.
For SaaS companies, streaming platforms, and subscription businesses, involuntary churn typically accounts for 20% to 40% of all churn. That's revenue walking out the door not because your product failed, but because your payment recovery did.
The system that fights involuntary churn is called dunning — a term borrowed from debt collection that, in modern payments, refers to the entire lifecycle of detecting a failed payment, classifying the failure, retrying the charge, communicating with the customer, and either recovering the payment or gracefully ending the relationship.
This chapter is your complete guide to building that system.

Taxonomy of Failures: Why Not All Declines Are Equal
When MelodyBox's billing system receives a decline from Alex's bank, the first question isn't "should we retry?" It's "what kind of failure is this?"
This distinction matters enormously, because retrying the wrong kind of decline doesn't just waste resources — it can trigger fines from the card networks, damage your merchant reputation, and in some cases constitute a violation of network rules.
Declines fall into three broad categories: hard declines, soft declines, and technical failures. Getting the classification right is the foundation of everything that follows.
Hard Declines: Stop Immediately
A hard decline means the issuer has definitively rejected the transaction, and no amount of retrying will change the outcome. The card is invalid, the account is closed, or the card has been reported lost or stolen.
When Bob Park's card comes back with decline code 41 (lost card) or code 14 (invalid card number), MelodyBox should not retry. The card is dead. Retrying a hard decline is like knocking on a door that's been bricked over — it won't open, and you'll annoy the neighbors.
Visa classifies these as Category 1 declines. Their rules are explicit: do not reattempt. Mastercard has equivalent guidance. Violating these rules can result in fees and, in extreme cases, placement in network monitoring programs that nobody wants to be in.
The correct response to a hard decline: stop retries immediately, notify the customer that their payment method needs updating, and provide a frictionless way to enter a new card.
Soft Declines: Retry With Strategy
A soft decline means the transaction could succeed under different circumstances. The account exists, the card is valid, but something temporary prevented approval. Insufficient funds (code 51), issuer temporarily unavailable (code 91), or exceeding the card's transaction limit (code 61) are all soft declines.
This is Alex's situation. His card is fine. His account is fine. He just doesn't have $9.99 in his checking account right now. In two days, after payday, he will.
Soft declines are where dunning strategy lives. The question isn't whether to retry — it's when, how often, and how to communicate with the customer in the meantime.
Technical Failures: Retry Immediately
Sometimes a transaction fails not because the issuer declined it, but because something in the plumbing broke. A network timeout. A gateway error. A connection drop between the acquirer and the card network. The issuer never even saw the request.
These technical failures are transient by nature. The correct response is to retry immediately, typically with exponential backoff — wait one second, then two, then four, then eight. If the infrastructure issue resolves (and it usually does within seconds to minutes), the retry succeeds.
The Decline Code Reference
Here's a practical reference for the most common decline codes and how to handle them:
| Code | Meaning | Category | Recommended Action |
|---|---|---|---|
| 05 | Do not honor | Soft (usually) | Retry after delay; may need customer to contact issuer |
| 14 | Invalid card number | Hard | Stop retries; request new payment method |
| 41 | Lost card | Hard | Stop retries; request new payment method |
| 43 | Stolen card | Hard | Stop retries; request new payment method |
| 51 | Insufficient funds | Soft | Retry with payday-aligned schedule |
| 54 | Expired card | Hard | Stop retries; check Account Updater first, then request update |
| 61 | Exceeds withdrawal limit | Soft | Retry next day or after limit resets |
| 65 | Activity limit exceeded | Soft | Retry after 24 hours |
| 91 | Issuer unavailable | Technical | Retry immediately with exponential backoff |
| 96 | System malfunction | Technical | Retry immediately with exponential backoff |
One important caveat: the generic code 05 ("do not honor") is maddeningly ambiguous. Issuers use it as a catch-all when they don't want to reveal the specific reason for a decline. Your best bet is to treat it as a soft decline on the first occurrence and escalate to customer notification if retries continue to fail.
Retry Strategies: From Fixed Schedules to Smart Retries
You've classified the decline. It's soft. Now what?
The naive approach is simple: try again in 24 hours. If it fails, try again the next day. Keep going for a week, then give up. This fixed schedule is easy to implement and sometimes works — but it leaves a lot of money on the table.
The problem? Not everyone gets paid on the same schedule. Alex Chen gets paid on the 1st and 15th. Chandra Rao in Bangalore receives her salary on the last business day of the month. A college student might have irregular deposits from gig work. A fixed daily retry schedule ignores all of this.
Fixed Schedule Retries
The simplest approach: retry at fixed intervals. Common patterns include every 24 hours for 3-5 days, or days 1, 3, 5, and 7 after the initial failure.
Fixed schedules are predictable and easy to reason about. Every subscription platform starts here. But they have a fundamental limitation: they're blind to why the decline happened and when recovery is most likely.
Segment-Aware Retries
A smarter approach analyzes the decline reason and adjusts timing accordingly. Insufficient funds? Wait for common payroll cycles — the 1st, 15th, or last day of the month. Card limit exceeded? Retry after midnight when daily limits reset. Issuer unavailable? Retry in an hour.
This is what MelodyBox does for Alex. The billing system sees code 51 (insufficient funds), checks that Alex's previous successful charges clustered around the 1st and 15th of each month, and schedules the next retry for February 3rd — two days out, aligned with his likely payday.
Attempt 3 on February 3rd succeeds. Alex never even noticed the interruption.

ML-Optimized Smart Retries
The most sophisticated approach uses machine learning to predict the optimal retry time for each individual customer. Stripe's Smart Retries, Adyen's Auto Rescue, and similar systems analyze historical payment patterns, time-of-day success rates, day-of-week patterns, and decline code histories to choose when to retry.
These systems can improve recovery rates by 5% to 15% compared to fixed schedules. They work by finding patterns that humans wouldn't spot: maybe charges at 6 AM succeed more often than charges at 3 PM for a specific issuer. Maybe Tuesday retries recover better than Monday retries for a specific BIN range.
The trade-off? You're handing control to a black box. If something goes wrong — if the model starts over-retrying or timing retries poorly — debugging is harder than with a rule-based system.
| Approach | Recovery Rate | Complexity | Best For |
|---|---|---|---|
| Fixed schedule (daily for 5 days) | Baseline | Low — simple cron job | Early-stage startups, low transaction volume |
| Segment-aware (decline code + pay cycle) | +5–10% over baseline | Medium — requires decline classification and customer segmentation | Growing subscription businesses with enough data to segment |
| ML-optimized (per-customer prediction) | +10–15% over baseline | High — requires ML pipeline, training data, monitoring | Large-scale platforms or via PSP-managed service (Stripe, Adyen) |
Most companies don't need to build their own ML retry system. If you're using a major PSP, their smart retry feature is probably good enough. The real gains come from getting the basics right first: classifying declines correctly, not retrying hard declines, and aligning retry timing with common payroll cycles.
Prevention: Card Updaters and Network Tokens
Here's a question worth asking: what if you could prevent a lot of these failures from happening in the first place?
Dana Novak's Visa expires in March. Without intervention, her March 1st renewal will fail with decline code 54 (expired card), triggering the full dunning cycle — retries, emails, the risk that Dana gets frustrated and doesn't bother updating her card.
But MelodyBox uses Visa Account Updater (VAU), and the story plays out very differently.
How Account Updaters Work
Every major card network runs an account updater service. Visa has VAU. Mastercard has Automatic Billing Updater (ABU). Amex has Cardrefresher. They all work on the same principle: your PSP periodically sends batch inquiries to the network asking "have any of these stored cards changed?"
The network checks with the issuing banks. If Dana's bank has issued her a new card (same account, new number or expiry), the updater service returns the updated credentials. Your PSP silently refreshes the stored card details. When Dana's March renewal runs, it authorizes against the new card. She never sees a dunning email. She never has to lift a finger.
This is prevention over cure, and it's remarkably effective. Account updaters can prevent 15% to 25% of the declines that would otherwise enter your dunning pipeline.
Network Tokens: Even Better Prevention
As we covered in Chapter 12, network tokens (specifically MPANs — merchant-scoped tokens) take this a step further. When a card is reissued, the network doesn't just update the credentials in a batch file — it automatically updates the token-to-FPAN mapping in the token vault. The merchant doesn't need to run batch inquiries or wait for a refresh cycle. The update happens as part of the token lifecycle, often before the old card even expires.
If MelodyBox uses network tokens for stored credentials, Dana's card reissue is handled automatically and in real-time. No batch inquiry needed. No timing gap where a charge might slip through before the update arrives.
The combination of account updaters and network tokens can eliminate a significant chunk of involuntary churn before the dunning system ever gets involved. Think of them as your first line of defense — the prevention layer that keeps your dunning system focused on the failures that can't be prevented.

Customer Communications: The Human Side of Dunning
Retries happen in the background. But when retries alone can't recover a payment, you need to bring the customer into the loop. And how you communicate matters as much as what you communicate.
The goal of dunning communications isn't to guilt or threaten. It's to help. Your customer probably doesn't know their payment failed. They certainly don't want to lose their subscription. Your job is to make it as easy as possible for them to fix the problem.
The Communication Cadence
| Timing | Trigger | Channel | Message Goal | Tone |
|---|---|---|---|---|
| Day 0 (initial failure) | First decline | Inform, provide update link | Friendly, low-urgency | |
| Day 3 | Second retry fails | Email + in-app banner | Remind, emphasize service continuity | Helpful, slightly more urgent |
| Day 5 | Third retry fails | Email + SMS | Escalate, warn of service interruption | Direct, empathetic |
| Day 7+ | Final retry fails | Email + push notification | Last chance before cancellation | Clear, no ambiguity |
What Good Dunning Emails Look Like
Here's an annotated template for the initial dunning email:
Notice what this email doesn't do: it doesn't use scary language ("YOUR ACCOUNT WILL BE TERMINATED"). It doesn't blame the customer. It doesn't over-explain what went wrong technically. It acknowledges the situation, reassures the customer their service continues, and provides a one-tap path to fix the problem.
SMS: Short, Actionable, Rare
SMS should be used sparingly — it's a high-attention channel, and overusing it feels invasive. Reserve it for the escalation stage (day 5+).
Keep it under 160 characters. Include the amount, the action, and the link. Nothing else.
Payment Links: Reduce Friction to Zero
The most important element in any dunning communication is the payment link — a one-click URL that takes the customer directly to a pre-filled payment update page. No login required. No navigating through settings menus. Just "tap, enter new card, done."
Every major PSP offers hosted payment link functionality. Use it. The fewer clicks between "I got this email" and "my card is updated," the higher your recovery rate.
The Dunning State Machine: Engineering the Lifecycle
If you're building a dunning system — or evaluating one — it helps to think of the subscription lifecycle as a state machine. Each subscription exists in exactly one state at any time, and specific events trigger transitions between states.
Here's the model MelodyBox uses:
Active is the happy state. The customer is paying, the service is running, everything is fine. Most subscriptions spend most of their time here.
At Risk is a pre-dunning state. The customer's card is approaching expiration, or the account updater flagged a potential issue. MelodyBox sends a proactive "heads up" notification. If the customer or the updater resolves the issue, the subscription returns to Active without ever entering the dunning cycle.
Past Due means a renewal payment has failed. The dunning engine is actively retrying and communicating. Each failed retry increments an attempt counter and may trigger escalating notifications. A successful retry transitions the subscription to Recovered.
Recovered is a brief transitional state: the payment succeeded after one or more retries. The system resets the attempt counter, clears any dunning flags, and transitions back to Active. From the customer's perspective, nothing happened.
Canceled means the dunning cycle exhausted all retries without recovering the payment, or the customer explicitly canceled during the dunning window. The subscription ends. Depending on business policy, MelodyBox might send a "win-back" email with a payment link, offering the customer a path to resubscribe.
The takeaway: one lifecycle, two clocks. The billing cycle keeps generating invoices on its fixed schedule, while the retry ladder inside Past Due runs on its own timeline — payday-aligned, decline-code-aware — and if both do their jobs, the customer never notices either.
Let's trace two paths through this state machine:
Alex Chen's path: Active → Past Due (Feb 1 decline) → Past Due (Feb 1 retry fails) → Recovered (Feb 3 retry succeeds) → Active. Total time in dunning: two days. Alex probably never noticed.
Bob Park's path: Active → Past Due (hard decline — lost card, code 41) → Canceled (retries stopped immediately per network rules). Bob receives a notification with a payment link. Three days later, he enters his new card and resubscribes: Canceled → Active.
Engineering Considerations
Building a reliable dunning state machine involves several engineering challenges that are easy to underestimate:
Idempotency keys. Every retry attempt must carry a unique idempotency key. Without one, a network timeout during a retry could lead to a double charge — the issuer processes the authorization, but the response doesn't reach your system, so you retry and charge the customer twice. Idempotency keys ensure that even if you send the same request multiple times, the payment is only processed once.
Webhook reliability. Your dunning system will receive payment status updates via webhooks from your PSP. Webhooks use at-least-once delivery — meaning you might receive the same event multiple times. Your system needs to deduplicate events by event ID. If you process the same "payment_succeeded" webhook twice, you might reset the dunning state prematurely or send duplicate confirmation emails.
Event ordering. Webhooks don't always arrive in order. A "payment_succeeded" event might arrive before the "payment_failed" event that preceded it, especially under network latency. Your state machine needs to handle out-of-order events gracefully — typically by checking timestamps or sequence numbers rather than blindly applying state transitions.
Concurrency. If your billing system runs retries on a schedule and a customer simultaneously updates their payment method, you might end up with two authorization attempts for the same invoice. Use database-level locking or optimistic concurrency control to ensure only one charge attempt is in flight at a time.
Compliance: The Rules of the Game
Retrying declined payments isn't a free-for-all. The card networks have specific rules about when, how often, and under what conditions you can reattempt a declined transaction. Violating these rules can result in fees, monitoring program enrollment, and in severe cases, the loss of your ability to process cards.
Visa's Reattempt Rules
Visa divides declines into two categories with very different retry rules:
Category 1 (hard declines): Do not reattempt. These include invalid account numbers (code 14), lost/stolen cards (codes 41, 43), and closed accounts. Visa's rules are clear: zero retries. A single reattempt can trigger a monitoring flag.
Category 2 (soft declines): You may reattempt, but with limits. Visa allows a maximum number of reattempts within a defined window (the specific limits are updated periodically in Visa's rules documentation). Each reattempt must be spaced appropriately — you can't hammer the issuer with 10 retries in 10 minutes.
Mastercard's MIT and Trace ID Framework
Mastercard takes a slightly different approach, focused on Merchant-Initiated Transactions (MITs) and Trace IDs.
When a customer first sets up a recurring payment, the initial transaction is a Customer-Initiated Transaction (CIT). This is when the cardholder is present, actively consenting, and (in Europe) completing Strong Customer Authentication. The network assigns a Trace ID to this initial CIT.
Every subsequent recurring charge — and every retry of a failed recurring charge — must reference that original Trace ID. This creates an unbroken chain from the customer's initial consent to every future charge, including dunning retries. If you lose the Trace ID or fail to include it, the network may decline the transaction or flag it as non-compliant.
Here's what this looks like in practice for Emma Weber, a MelodyBox subscriber in Berlin:
- Initial setup (CIT): Emma subscribes and enters her Mastercard. MelodyBox's PSP initiates a SetupIntent with a request for Strong Customer Authentication (SCA). Emma completes a 3D Secure challenge. The issuer approves and returns Trace ID TXN-001.
- Monthly renewal (MIT): Each month, MelodyBox charges Emma's card as a merchant-initiated transaction, referencing Trace ID TXN-001. No SCA required — the original authentication covers subsequent MITs.
- Dunning retry (MIT): If a monthly charge fails, the retry also references TXN-001. The Trace ID proves that this retry chain traces back to a customer-consented, SCA-authenticated initial setup.

Stored Credential Consent
All card networks require that merchants obtain and record explicit consent before storing a customer's credentials for future use. This isn't just good practice — it's a network rule. Your checkout flow must clearly communicate that the card will be stored, what it will be used for (recurring billing, one-click purchases, etc.), and how the customer can revoke consent.
When you initiate a stored-credential transaction, the authorization message must include the correct indicators: stored credential flag, MIT indicator (for merchant-initiated charges), and the transaction type (recurring, installment, etc.). Missing these flags is one of the most common compliance mistakes — and it leads to higher decline rates because issuers treat unflagged MITs with suspicion.
The Compliance Checklist
| Requirement | Network | What It Means |
|---|---|---|
| Do not retry Category 1 / hard declines | All networks | Stop immediately on invalid account, lost/stolen, closed account codes |
| Respect reattempt limits on soft declines | Visa, Mastercard | Don't exceed network-specified retry count and time window |
| Include MIT indicators on merchant-initiated charges | All networks | Flag recurring, installment, and retry transactions correctly |
| Reference Trace ID on all MITs | Mastercard | Chain every recurring charge and retry back to the original CIT |
| Obtain and record stored-credential consent | All networks | Explicit cardholder agreement before saving credentials |
| SCA on initial CIT (Europe) | Visa, Mastercard | 3D Secure authentication required for the first transaction under PSD2/SCA |
| PCI DSS compliance for stored credentials | All networks | Stored PANs or tokens handled per PCI requirements; prefer tokenization |
Measuring Success: KPIs, Reconciliation, and Continuous Improvement
You've built your dunning system. It's classifying declines, retrying intelligently, communicating with customers, and respecting network rules. How do you know if it's working?
The KPIs That Matter
| KPI | Formula | What It Tells You | Target |
|---|---|---|---|
| Recovery Rate | Recovered payments / Total failed payments | How effective is your dunning system overall? | 60–80% (varies by industry) |
| Involuntary Churn Rate | Subscriptions lost to payment failure / Total active subscriptions | How much revenue is leaking through payment failures? | Below 1–2% monthly |
| Time-to-Recovery (P50/P90) | Median and 90th percentile days from first failure to successful payment | How quickly are you recovering payments? | P50 under 3 days; P90 under 7 days |
| Retry Success Rate by Attempt | Successes at attempt N / Total attempts at N | Which retry attempt is most productive? Are later retries wasting resources? | Diminishing returns after attempt 3–4 |
| Customer Self-Recovery Rate | Payments recovered via customer-updated card / Total recoveries | How effective are your dunning emails and payment links? | 15–25% of recoveries |
| Duplicate Charge Incidence | Double-charged invoices / Total invoices processed | Is your idempotency working? Are webhook dedup and concurrency controls solid? | Zero (any is a bug) |
| Prevention Rate | Cards updated by Account Updater or token lifecycle before failure / Total cards approaching expiry or reissue | Is your prevention layer catching problems before they hit dunning? | 70%+ of expiring/reissuing cards caught |
MelodyBox's Q1 Review
Let's see how MelodyBox's dunning system performed in Q1:
Their recovery rate hit 62% — solid, but with room to improve. Most recoveries happened on the second or third retry. By the fifth retry, success rates dropped below 3%, suggesting those late attempts are mostly noise.
Time-to-recovery showed a P50 of two days and a P90 of six days. The P50 is excellent — most payments recover quickly, usually on a payday-aligned retry. The P90 is acceptable but highlights a long tail of stubborn failures that take nearly a week.
An A/B test comparing fixed daily retries against payday-aligned retries showed a 9% lift in recovery rate for the aligned approach. That's meaningful — thousands of dollars in recovered revenue per month from a simple scheduling change.
But the review also uncovered a problem: 14 duplicate charges in the quarter, traced to a race condition where a customer updating their card and a scheduled retry fired simultaneously, both succeeding. The fix? Adding a database-level lock on the invoice record before initiating any charge attempt, plus stricter idempotency key enforcement.
Reconciliation: Trust but Verify
Dunning introduces reconciliation complexity that your finance team needs to plan for. When a payment fails, is retried, and eventually succeeds three days later, the settlement timing shifts. The revenue shows up in a different settlement batch than expected. If your systems aren't reconciling at the invoice level — matching each expected charge to its actual settlement — discrepancies accumulate.
The reconciliation flow for dunning looks like this:
- Invoice created (expected charge date, amount, customer)
- Charge attempted → map to authorization ID
- Decline received → log decline code, timestamp, retry schedule
- Retry attempted → new authorization ID, same invoice ID
- Success → authorization ID enters clearing and settlement
- Settlement received → match settlement amount to invoice, reconcile timing gap
The key: every retry must reference the same internal invoice ID, even though each attempt generates a new authorization. Your reconciliation system joins on invoice ID, not authorization ID. This is how you catch duplicate charges, missed settlements, and timing discrepancies.
Continuous Improvement
Dunning isn't a set-and-forget system. The best subscription businesses treat it as a living product:
- A/B test retry schedules. Payday-aligned vs. fixed. Morning vs. evening. Three retries vs. five. Let the data tell you what works for your customer base.
- A/B test email copy and timing. Subject lines, tone, the placement of the payment link button — all of these affect click-through and recovery rates.
- Monitor decline code trends. A sudden spike in code 05 ("do not honor") from a specific issuer might indicate a fraud rule change, not a customer problem. A spike in code 54 (expired card) might mean your Account Updater integration missed a batch.
- Review network compliance regularly. Visa and Mastercard update their reattempt rules periodically. What was compliant last year might trigger fees this year. Build in a quarterly compliance review.

Card dunning sits at the intersection of payment engineering, customer experience, and network compliance. Done well, it recovers revenue that would otherwise silently disappear. Done poorly, it creates duplicate charges, triggers network fines, and annoys customers into canceling voluntarily — turning involuntary churn into the voluntary kind.
The foundation is straightforward: classify every decline correctly, retry soft declines with intelligent timing, prevent failures before they happen with account updaters and network tokens, communicate with customers like a helpful friend rather than a debt collector, and measure everything.
As we covered in Chapters 9 and 12, the card ecosystem is built on a web of rules, standards, and relationships between issuers, networks, acquirers, and merchants. Dunning is where those relationships get tested — where the carefully engineered authorization flow meets the messy reality of insufficient funds, expired cards, and customers who forgot to update their payment method after their bank sent them a new card.
Notice how much of this chapter leaned on one quiet assumption: that MelodyBox was allowed to charge Alex's card without him being present. That permission isn't automatic — it rests on a whole infrastructure of consent, mandates, and stored credentials. In Chapter 16, we'll pull that infrastructure apart and see exactly what happens when you tick the "remember my card" box.
Sources
- Visa Core Rules and Visa Product and Service Rules — Reattempt Guidelines
- Mastercard Transaction Processing Rules — MIT Framework and Trace ID Requirements
- PCI DSS v4.0.1 — Stored Credential and Tokenization Requirements
- Stripe Smart Retries documentation
- Adyen Auto Rescue documentation
- Recurly "State of Subscriptions" involuntary churn benchmarks