Every month, a predictable percentage of your subscribers' payment cards will fail. Not because those customers decided to leave. Not because they are unhappy with your product. Their card expired. Their bank flagged an unusual charge. Their company issued new corporate cards and the IT department deactivated the old ones. Their account hit a spending limit. The customer relationship is intact — the billing mechanism just broke.

This is involuntary churn, and for most subscription businesses it accounts for 20–40% of total customer loss. It is also the most recoverable form of churn that exists: the customer wants to stay subscribed. You just need to fix the payment before the grace period expires and the subscription cancels automatically.

The gap between businesses that handle this well and those that rely on default Stripe dunning is approximately 15–20 percentage points of recovery rate. On a business losing six customers per month to payment failures, that gap is the difference between recovering two of them and recovering three. Over a year, that is twelve additional customers retained — at essentially zero marginal cost beyond the one-time setup investment.

20–40%
of SaaS churn is involuntary — customers who never chose to leave
40%+
recovery rate with optimised dunning vs 20–25% with default Stripe
1–2 hrs
to set up a complete recovery system that runs on autopilot indefinitely

What you will learn in this guide

  • Why default Stripe dunning leaves 15–20 percentage points of recovery on the table
  • What each decline code means and the optimal response to each
  • How to structure the three-email recovery sequence for maximum completion rates
  • The proactive prevention strategy that stops failures before they happen
  • How to handle the edge cases that most implementations miss
  • The math: what optimised recovery is actually worth to your business

📋 In this article

The problem with default Stripe dunning

Stripe's built-in dunning is better than nothing. It retries failed payments on a configurable schedule and sends a notification email. For founders who have not thought about payment recovery at all, turning on Stripe's smart retries is a meaningful improvement over doing nothing.

The problem is precision. Stripe's default retry schedule is generic — it does not vary based on why the payment failed. A card that expired six months ago and an account that temporarily hit its spending limit get the same retry cadence, the same email template, and the same grace period before cancellation. This is optimised for none of the individual failure types and suboptimal for all of them.

The difference between generic and precise recovery is not academic. When you map your retry strategy to the specific decline code for each failed payment, you stop wasting retries on cards that literally cannot succeed (expired cards), you time retries correctly for cash flow failures (insufficient funds), and you handle sensitive situations (compromised cards) with the care they require rather than with the same automated email you send for a processing error.

⚠️ The hidden cost of generic dunning

When you retry an expired card five times on the default schedule, you are burning retry attempts that will never succeed, potentially triggering the customer's bank to flag your subscription as suspicious (repeated declined transactions can trigger fraud flags), and delaying the card update outreach that is the only thing that will actually recover this payment. Generic dunning does not just underperform — it sometimes actively makes recovery harder.

Stripe decline codes: what each one means and what to do

Every failed Stripe payment comes with a decline code. This is not a detail to log and ignore — it is the most actionable piece of data in your entire payment recovery process. The decline code tells you exactly why the payment failed, which tells you exactly what strategy gives you the best chance of recovery.

Decline code What happened Recovery strategy Email approach Recovery rate
insufficient_fundsAccount has insufficient balance right nowWait 5–7 days, retry near payday. Max 3 retries.Soft notification — no alarm language55–70% with payday timing
expired_cardCard passed its expiry dateNo retries — immediately escalate to card updateImmediate, direct, helpful. Link to payment update.40–60% with fast outreach
card_declinedBank declined — often temporary restrictionRetry at 24h, then day 7. If still failing, card update.Moderate urgency35–50%
do_not_honorBank blanket decline — usually clears automaticallyRetry in 48 hoursSoft notification only50–65% on second attempt
processing_errorTechnical failure on Stripe or bank infrastructureRetry within 24 hours — almost always resolvesUsually no email needed85–95% on retry
card_velocity_exceedCard hit spending limit (common on corporate cards)Retry end of month when limits resetHeads-up with expected retry date40–55%
fraudulent / stolenCard reported as compromisedNo retries. Wait for customer contact.Empathetic, not standard dunning — if at all20–35% (customer must initiate)

The insufficient_funds strategy in detail

Insufficient funds is typically the most common decline code for consumer-facing SaaS and lower-price-point B2B products. The money will almost certainly be available — the timing is just wrong. Retrying immediately after this failure accomplishes nothing. Retrying on day three or day five is marginally better. Retrying around the customer's payday is substantially better.

Most employees in most countries get paid on a predictable schedule: the 1st of the month, the 15th, every two weeks on Friday, or similar. A payment that fails on the 23rd of the month is probably failing because the customer's account is low near the end of the billing cycle. A retry on the 1st or 2nd of the following month — when the paycheck has cleared — will succeed in a substantial proportion of cases that a day-3 retry would miss.

This means your retry schedule for insufficient_funds should include a payday-timing attempt. Retainly handles this automatically by scheduling retries around common payday dates when it detects this decline code.

The expired_card strategy in detail

Expired cards are where the most recovery value is left on the table by generic dunning. The moment you see an expired_card decline code, retrying is counterproductive — the card literally cannot be charged regardless of when you try. The only action that will recover this subscription is getting the customer to add a new payment method.

The speed of your outreach matters significantly here. Customers who receive a card update request within 24 hours of the failure update their cards at roughly twice the rate of customers who receive the request three to four days later. There is a recency window: the customer is more likely to be thinking about their card, more likely to have their new card information accessible, and more likely to be engaged with your product in the immediate aftermath of a billing event.

The email for an expired card failure should be different from your standard payment failure email. It should acknowledge specifically that the card expired (not just that the payment failed), explain that updating will immediately restore access, and link directly to a payment update page. The tone should be helpful and matter-of-fact, not alarming. Most customers with expired cards simply forgot the card was about to expire — they are not in a financial crisis, they just need a low-friction update path.

The three-email recovery sequence

Email timing and content are the human layer of your recovery system — the communications that complement the automated retries and make it easy for customers to take action when a retry alone will not solve the problem.

Email Timing Tone Key element Typical resolution rate
First noticeDay 1 (immediately)Helpful, low-urgencyDirect link — no login required35–45% resolve here
Follow-upDay 5–7Moderate urgency, specific date"Account affected on [date]" — concrete deadlineAdditional 25–35% resolve
Final warningDay 10–12Personal, mentions data"Your data and progress are at risk" — loss framingAdditional 10–15% resolve

Three emails over twelve days is the right cadence for most SaaS businesses. Fewer emails leaves resolution rate on the table — a meaningful percentage of customers only act on the final warning. More emails tips into harassment territory and starts generating spam complaints, which damages deliverability for your entire email domain.

The single most important technical requirement: no login needed

Every recovery email must link directly to a payment update page that does not require the customer to log in. This single requirement is worth belaboring because it is the most commonly violated best practice in payment recovery, and the impact of getting it wrong is severe.

The typical customer receiving a payment failure email is not sitting at a computer with your product open in a tab. They are reading email on their phone, probably during a commute or a break. The psychological state they are in — mildly annoyed, wanting to resolve this quickly and move on — is exactly the state where any additional friction causes abandonment.

A link that says "Update payment method" and takes the customer to a login page introduces at minimum three additional steps: enter email, enter password (or trigger a password reset), navigate to billing settings. Studies of online checkout flow consistently show that each additional step reduces completion rates by 10–20%. Your three-step login process is eliminating 40–60% of customers who would have updated their card if the link had taken them directly to the update form.

Stripe's hosted invoice pages handle this correctly — they include a tokenised link that opens directly on the payment update page without requiring login. Alternatively, you can build a custom payment update page that uses Stripe.js and passes a time-limited token in the URL parameter. Either approach eliminates the login friction and dramatically improves update completion rates.

✅ What a good recovery email CTA looks like

Good: "Update payment method →" linking to a pre-authenticated update page. Customer clicks, lands on update form, enters new card details, done. Approximately 60 seconds total.

Bad: "Update payment method →" linking to your login page. Customer clicks, sees login form, maybe logs in, navigates to account settings, navigates to billing, finds the payment update option. Many customers abandon here.

Proactive prevention: card expiry outreach

The highest-ROI intervention in your entire payment recovery stack is an email you send before any payment fails. Stripe provides card expiration dates for every card on file — you know, 30 to 60 days in advance, which customers are about to have their payment card expire and will cause a failure on their next billing cycle.

A proactive card expiry email, sent 30 days before the expiry date, prevents 30–50% of expiry-related payment failures. The economics are extraordinary: one email template, configured once, triggers automatically based on card expiry data, and permanently reduces one of the most predictable and preventable sources of involuntary churn.

The copy for this email should be positive and practical, not alarming. "Your card on file expires next month — take 30 seconds to update it and keep your subscription running without interruption." Functional, specific, non-alarming. This is not a crisis communication; it is helpful account maintenance. Customers appreciate proactive communication that prevents problems rather than reactive communication that announces them.

Strategy When Effect Setup effort
Expiry warning (30 days)30 days before card expiresPrevents 30–50% of expiry failuresOne-time setup
Expiry warning (7 days)7 days before card expiresCatches customers who missed the 30-day emailOne-time setup
Annual billing reminder14 days before annual renewalReduces surprise large-charge declinesOne-time setup

Annual renewal billing failures deserve a specific mention. Annual subscriptions involve larger charge amounts — often 10–12x the monthly equivalent. Banks are more likely to flag large, infrequent charges as potentially fraudulent or unusual. A reminder email 14 days before an annual renewal — "Your annual subscription renews on [date] for €[amount]. We wanted to give you a heads-up" — serves two purposes: it prevents declined charges from customers whose banks would flag the amount, and it reduces the support tickets from customers who were surprised by a large charge they had forgotten about.

The corporate card problem

B2B SaaS businesses face a specific payment failure pattern that consumer-facing businesses largely do not: corporate card lifecycle events. When an employee with a company card subscription leaves the company, their card is deactivated. When a company changes banks or credit card providers, all their corporate cards are replaced simultaneously. When a corporate card hits its spending limit — common near end-of-quarter — all subscriptions charged to that card fail at the same time.

These failures look like card_declined or card_velocity_exceeded in your Stripe logs, but the underlying cause is different from an individual card issue. The right response is different too: rather than a personal payment failure email, these situations often warrant a communication addressed to the account's billing contact (which may be different from the user whose card failed) or a more direct prompt to add a company payment method.

If your SaaS product is positioned at businesses rather than individuals, investing in a billing contacts feature — the ability to designate a specific billing email address that receives all payment communications, separate from the account owner's login email — dramatically improves recovery rates for these corporate card scenarios. Retainly's Billing Contacts API supports this pattern.

The math: what optimised recovery is worth

Let us run the numbers on a concrete scenario to make the ROI of optimised payment recovery tangible.

Scenario Monthly failures Default recovery (25%) Optimised (42%) Difference (annual)
200 customers, €100/mo avg4 (2% failure rate)1 recovered/mo1.7 recovered/mo+8 customers / +€9,600 LTV
500 customers, €200/mo avg10 (2% failure rate)2.5 recovered/mo4.2 recovered/mo+20 customers / +€48,000 LTV
1,000 customers, €150/mo avg20 (2% failure rate)5 recovered/mo8.4 recovered/mo+41 customers / +€73,800 LTV

LTV is calculated at 12 months average remaining lifetime. The setup investment to move from default to optimised recovery is one to two hours of configuration work. For any of the scenarios above, the break-even point on that setup investment is measured in days, not months.

What happens to customers who churn despite recovery efforts

Not every failed payment will be recovered, even with an optimised process. Some customers have genuinely stopped wanting your product and are passively churning — they see the payment failure notification and use it as an opportunity to let the subscription lapse without actively cancelling. Others are in situations where the underlying payment problem (card stolen, bank account closed, company bankrupt) cannot be resolved on your timeline.

Customers who churn through payment failure — as opposed to voluntary cancellation — should go into a different win-back sequence than customers who actively cancelled. They did not make a decision to leave; the billing system failed them. Their win-back email should reflect that: "Your account was paused due to a payment issue. All your data is still here. Here is how to get back in one click." No apology for the inconvenience of having to cancel (they did not cancel). No "we miss you" framing (it was not a decision). Just a frictionless reactivation path with a direct link.

Recover 40%+ of failed payments automatically

Retainly handles payment recovery with decline-code-specific retry logic, three-email sequences, and direct payment update links. Set it up once, runs on autopilot. Free to start.

Start for free →

Frequently asked questions

What is the difference between voluntary and involuntary churn?

Voluntary churn is when a customer actively cancels. Involuntary churn is when a subscription lapses due to a payment failure — the customer never intended to leave. Involuntary churn accounts for 20–40% of total SaaS churn, making payment recovery one of the highest-ROI retention investments available.

What is the average payment recovery rate for SaaS?

With default Stripe dunning, payment recovery rates average 20–25%. With optimised, decline-code-specific retry logic and well-timed recovery emails, recovery rates of 40–50% are achievable. The improvement comes primarily from matching the retry strategy and email approach to the specific reason the payment failed.

What should I do when Stripe returns an expired_card decline code?

Stop retrying immediately — an expired card cannot be charged regardless of when you try. Skip directly to sending a card update email with a direct link to a hosted payment update page. The faster you send this email after the failure, the higher the update rate. Customers who receive a card update request within 24 hours update their cards at roughly twice the rate of customers who receive it after 3–4 days.

What is dunning in SaaS?

Dunning refers to the process of communicating with customers whose payments have failed in order to recover the subscription. A dunning sequence typically includes automated payment retries on a scheduled timeline and a series of recovery emails prompting the customer to update their payment method.

Does Retainly handle payment recovery automatically?

Yes. Once connected to Stripe, Retainly detects each payment failure, reads the decline code, applies the appropriate retry schedule, and sends a three-email recovery sequence with direct payment update links. Everything runs on autopilot after initial setup.


Continue reading: How to Reduce SaaS Churn · Cancel Flow Best Practices · Win-Back Email Campaigns · SaaS Churn Rate Benchmarks 2026