A lot of subscription churn has nothing to do with whether people like the product. The card expired, the account was short two days before payday, or the bank flagged a recurring charge it didn’t recognize. That’s a billing event, not a breakup. Yet most brands treat it with one generic “your payment failed” email and whatever retry schedule the billing app shipped with.
The fix is to run dunning by decline code. Every failed charge comes back with a reason. That reason should decide three things: whether you retry at all, when you retry, and what you tell the customer. In this post we lay out the code-to-retry-to-message playbook we use with subscription brands, with numbers from our client and discovery calls.
Key Takeaways
- Split churn into voluntary and involuntary before you try to fix it. Most dashboards blend them, and every app defines churn differently.
- Soft declines (insufficient funds, generic declines) are worth retrying, about every other day and timed near the 1st and 15th, when semi-monthly paychecks land.
- Hard declines (lost, stolen, invalid card) need a new payment method, not another retry. Retrying them wastes attempts that card networks limit.
- Use one dunning flow driven by a decline-code property, not one flow per code. The billing tool often doesn’t pass the reason to your email platform, so check that first.
- Measure recovery as recovered ÷ failed for each month’s failures. Two brands we spoke with recovered 27% and 42%, and the gaps we found were in setup.
Why is involuntary churn a separate problem?
Involuntary churn is a subscriber lost because a payment failed, not because they chose to cancel. It belongs in its own line of your churn rate. The fixes are completely different. Voluntary churn is about product, value and cadence. Involuntary churn is about payment rails, retry logic and copy.
Most brands can’t see the split. One kitchen-appliance brand put it plainly on a call in May: “Every app’s got a different definition” of churn. Some subscription tools count a cancellation only when a subscriber clicks cancel. Others close the subscription after the last failed retry and log it under a generic reason. If your weekly report shows one churn number, you can’t tell whether a bad month came from the product or from a bank.
Here’s the formula we use:
Involuntary churn share = subscriptions cancelled after max retries ÷ all subscriptions cancelled in the period
Run it monthly, from your billing platform’s cancellation export, not from a dashboard tile. Then attach dollars to it with MRR: the monthly value of subscriptions lost to failed payments. That’s the number to compare with your acquisition budget. In our five retention metrics, this shows up as revenue at risk. Dunning is the cheapest way to win part of it back, because these customers never decided to leave.
Plan length matters too. On a call in August 2025, a history-letter subscription founder argued that monthly subscribers last for years. Our counterpoint: longer prepaid plans bring cash up front and fewer billing events, so fewer chances for a card to fail. Both can be true. Measure tenure by plan before you change the offer.
What does a decline code actually tell you?
A decline code is the issuer’s (or processor’s) reason a charge failed, and it sorts failures into ones a retry can fix and ones it can’t. Stripe’s documentation is a useful reference even if you bill through another platform. It lists codes such as insufficient_funds, expired_card, incorrect_cvc, lost_card, stolen_card and the catch-all generic_decline (Stripe decline codes).
Two details in those docs matter for messaging:
- Hard declines don’t get retried. Stripe won’t automatically retry codes such as
lost_card,stolen_card,incorrect_numberandtransaction_not_allowed. Scheduled retries only execute once the customer adds a new payment method (Stripe Smart Retries docs). - Some reasons should never reach the customer. For
lost_card,stolen_cardandfraudulent, Stripe says not to report the specific reason. Present it as a generic decline instead. Your copy should never say “your card was reported stolen.”
Card networks also cap how hard you can push. Visa’s rules broadly prohibit more than 15 retries of a single payment over 30 calendar days. Visa began charging a fee on excessive retries on April 1, 2021 (Stripe Support). Check your processor’s current limits before you raise retry counts. Every retry spent on a hard decline is a retry you can’t spend on a soft decline that might clear.
The decline-code playbook
This is the routing table we hand to subscription clients. It came together across calls with a wellness gummies brand, a tea brand, an at-home health-testing subscription and a book-and-coffee box between December 2025 and May 2026.
| Failure type | Example codes | Retry? | Retry timing | Message to the customer | Channel |
|---|---|---|---|---|---|
| Insufficient funds | insufficient_funds, withdrawal_count_limit_exceeded | Yes | Every other day, aim attempts at the 1st and 15th | Plain and respectful: “your payment didn’t go through, we’ll try again on [date]”, plus an update link | Email, then SMS after a few attempts |
| Generic decline | generic_decline, do_not_honor | Yes | Aggressive, every other day, inside the network cap | ”Your bank declined the charge. A quick call to them usually fixes it, or switch to another card or PayPal” | Email, then SMS |
| Expired card | expired_card | Only after an update | Run the account updater first | ”Your card on file expired. Update it in 30 seconds” | Email + site banner |
| Incorrect details | incorrect_cvc, incorrect_zip | After an update | Retry once details change | ”The card details we have don’t match. Re-enter them here” | |
| Lost / stolen / fraud | lost_card, stolen_card, fraudulent | No | Never retry | Generic: “We couldn’t process your payment. Please add a new payment method” |
Three rules sit on top of the table:
- Keep every retry inside 28 days. A tea brand we work with set this rule so a recovered customer stays on a monthly rhythm instead of sliding into next month’s charge.
- Don’t retry fraud-suspected charges. Same tea brand, same call. It burns network goodwill and an attempt.
- Fix the account-updater gap. A re-issued card often comes with a billing-address or ZIP change, which triggers failures until the updater catches it.
When should you retry a soft decline?
Retry soft declines about every other day, and make sure some attempts land near the 1st and 15th of the month. That’s when semi-monthly paychecks arrive, and that’s when “insufficient funds” turns into “approved.”
We’ve seen the payday effect in client data. In May 2026, a tea brand we work with saw recovery spike on the attempts that landed near the 1st and 15th. In April, we worked through insufficient-funds rules with an at-home health-testing subscription: retry every other day, up to 15 times a month, timed to paydays. The plan also added PayPal as a fallback, because PayPal can draw on more than one funding source.
Compare that with the defaults. Stripe’s recommended Smart Retries setting is 8 tries within 2 weeks (Stripe Smart Retries docs). That’s a reasonable starting point. But a two-week window can miss the next payday entirely. A personalized-nutrition subscription we spoke with in November 2025 was running only 5 retry attempts. In December, we advised a book-and-coffee box to retry insufficient-funds and generic declines up to about 10 times, every other day. Other codes got 7 or 8 attempts.
The trade-off is real. More attempts mean more network scrutiny and more “your payment failed” messages. So cap the count, space the attempts, and never spend them on hard declines.
How do you match the message to the code?
Send one dunning flow, with the decline code stored as a profile property, and branch the copy on it. Don’t build five separate flows. A tea-brand operator told us in May, “I have 180 flows.” Adding five more is how dunning logic ends up broken and unmaintained.
Before you write a word of copy, check that the reason actually reaches your email platform. In May 2026, an at-home health-testing subscription found that its Stripe-to-Klaviyo integration didn’t pass the failure reason at all. The flow only knew “payment failed.” Without the code, every customer gets the same vague email. The fix is usually a small webhook or custom event that writes the decline code to the Klaviyo profile. Then check that the flow actually fires.
Watch for ownership conflicts too. In March 2026, a history-letter subscription found that its billing platform’s built-in smart dunning forced the platform’s own basic emails. It also blocked the brand’s 11-reason Klaviyo dunning flow. The team was running both in parallel, which makes it impossible to tell which one recovers anything. Our advice: test the platform’s version alone for about five weeks, measure recovery, then decide. Two senders on the same failed charge means double emails and no clean read.
What the copy should do, by code:
- Insufficient funds: be transparent and calm. Say when you’ll try again. Many customers would rather know than get a surprise retry.
- Generic decline: tell them the bank declined it and that a quick call to the bank often fixes it. Offer a second payment method in the same email.
- Expired card or wrong details: make the update link the whole email. One button, pre-filled login if your platform supports it.
- Lost, stolen or fraud: never say why. Ask for a new payment method and leave it there.
Where does recovery actually come from?
Recovery comes from four places: retries that clear, customers who update a card, card-updater services, and backup payment methods. Most brands only measure the total, so they can’t tell which lever is working.
Here are two recovery rates from our calls. They were measured as recovered ÷ failed for one batch of failures. Client results are specific outcomes, not typical or guaranteed.
The wellness gummies brand called its rate “very low.” It was running one generic flow at the time. That’s why we built the code-based playbook above with it. The nutrition brand was further along, but it had only 5 retry attempts and 137 subscriptions still sitting in dunning. Those are the two most common gaps we see: no code routing, and a retry schedule nobody has touched since setup.
Two other levers came up in May calls:
- Run the account updater before cards fail. A former subscription e-commerce executive described running the updater against the whole customer database ahead of renewals. Not after a decline. His reasoning: “why pay to lose a sub when it’s 10¢?” He also mapped error codes by card BIN, the first digits that identify the issuing bank. And he used more than one payment gateway.
- Look at failures by bank. Two brands ran BIN-level analysis on their failed payments. One found a large cluster on a single prepaid-card program. That points to a funding problem with prepaid cards, not a product problem, and it changes the message and the retry timing.
How should you measure dunning?
Track four numbers monthly, by cohort of failures, not as a running total:
| Metric | Formula | Why it matters |
|---|---|---|
| Failure rate | Failed renewal charges ÷ renewal charges attempted | Rising failures can mean an issuer, gateway or fraud-filter change |
| Recovery rate | Recovered ÷ failed, for that month’s failures | The headline dunning number |
| Recovery by source | Share recovered by retry, card update, updater, backup method | Tells you which lever to invest in |
| Involuntary churn share | Cancelled after max retries ÷ all cancellations | Keeps billing losses out of your product story |
Then translate recovered subscriptions into LTV. A recovered subscriber isn’t worth one order. They’re worth the rest of their expected tenure. That’s why a recovered payment usually beats a new subscriber at the same cost: there’s no CAC attached.
One caution on offers. Some brands put a discount in the final dunning email. Keep it for customers whose history earns it, and track whether it changes behavior at the next renewal. We’ve written about why perks beat discounts for subscribers. The same logic applies here.
What to do this week
- Export last month’s cancellations from your billing platform. Count how many closed after max retries. That’s your involuntary churn share.
- Pull the decline codes for last month’s failed charges and group them into the five rows of the table above. Write down the top three.
- Check that the code reaches your ESP. Trigger a test failure, then look at the customer’s Klaviyo profile. If there’s no decline reason on it, fix that before you rewrite copy.
- Change the retry schedule for soft declines to every other day, inside 28 days, and make sure attempts land near the 1st and 15th. Stay under your processor’s retry cap.
- Stop retrying hard declines. Lost, stolen and fraud-flagged charges get a new-payment-method request and generic wording.
- Pick one sender. If your billing app and your ESP both send dunning emails, turn one off for five weeks and measure recovery.
- Set a monthly recovery report with the four metrics above, and review it with your retention rate numbers, not in a separate silo.
Failed payments are a billing problem. Treat them like one.
A subscriber whose card bounced didn’t stop loving the product. They hit a bank rule, a payday gap or an expired card. Route each failure by its code, retry the ones that can clear, ask the rest for a new card, and say exactly what happened. It’s the cheapest retention work most subscription brands aren’t doing yet.
