Guide
How to recover failed Stripe subscription payments
Short version: A large share of subscription churn is "involuntary," meaning payments that failed rather than customers who chose to leave. Much of it is recoverable if you read each decline code, retry only the recoverable ones on a sensible schedule, and email customers to update expired cards. This guide covers why payments fail, what to retry and what never to, retry timing, dunning emails, and how to measure recovery.
Why subscription payments fail
When a recurring charge fails, the reason is in the decline code. They fall into a few buckets, and the right response is different for each:
- Insufficient funds and other soft declines are temporary. The card is fine, the money just wasn't there at that moment. Highly recoverable by retrying at a better time.
- Expired cards need updating. A retry alone won't work; the customer has to enter a new card, or Stripe's Card Account Updater refreshes it.
- Processing and network errors are transient issuer or network problems. Recoverable with a short backoff and a retry.
- Hard declines cover stolen cards, lost cards, closed accounts, and revoked authorizations. These should not be retried. Repeatedly retrying a hard decline won't succeed and risks fees and disputes.
The single most important habit is to read the decline code and treat each category differently. Blindly retrying everything the same way is what wastes attempts and annoys customers.
What to retry, and what never to
- Retry: insufficient funds, temporary holds, processing errors, issuer timeouts.
- Don't retry: stolen or lost card, closed account, revoked authorization, confirmed fraud. Email the customer to update their card instead.
Retry timing that actually works
Timing matters more than the number of attempts.
- Insufficient funds: retry around common paydays (the 1st, the 15th, end of month) rather than a few hours later. The money is more likely to be there.
- Processing errors: a short backoff of a few hours, then a couple of spaced attempts.
- Space attempts out and cap them. Back-to-back retries look like abuse to card networks and increase dispute risk.
- Set a recovery window, commonly about two weeks. After that, stop and treat it as churned.
Dunning emails
Retries fix money problems. Emails fix card problems.
- For expired or failed cards, email the customer promptly with a clear link to update their payment method.
- Use a short sequence, for example day 0, day 3, and day 7, rather than a single email.
- Send them under your own brand so customers recognize them and act, instead of ignoring a message from a name they don't know.
Stripe's built-in tools, and where they stop
Stripe offers Smart Retries and basic Billing dunning, and the Card Account Updater refreshes some expired cards automatically. Turn these on, they genuinely help. What they don't do is classify each decline reason and react differently, or run branded, sequenced dunning tuned to why a payment failed. That gap is where the extra recovery lives.
Measuring recovery, and why attribution matters
- Recovery rate: recovered failed payments divided by total failed payments over a window.
- Attribution: only count a recovery if your action, a retry or a card-update email, actually caused it. Some payments come back on their own when a customer's balance refreshes. Counting those overstates your impact, and it matters even more if you use a tool that bills on results.
Build it yourself, or use a tool
You can build all of this on Stripe webhooks: listen for invoice.payment_failed, classify the decline, schedule retries, and send emails. It's very doable. It's just ongoing work to tune and maintain.
If you'd rather not, there are tools that do it for you. I built one, RecoverFlow, which connects through Stripe, classifies declines, retries and sends dunning emails automatically, and shows you a free 90-day backtest of what you've been losing before you commit to anything. There are other tools in the category too. The important part is that the problem is worth solving either way, because failed payments are usually the most fixable revenue leak a subscription business has.
A quick checklist
- Read the decline code on every failed charge
- Retry soft declines on a smart schedule; never retry hard declines
- Email customers immediately for expired or failed cards
- Cap and space retries to avoid disputes
- Set a recovery window, then stop
- Track attribution so you know what actually worked
Frequently asked questions
Doesn't Stripe already retry failed payments?
Stripe's Smart Retries help, but they're generic. Classifying each decline reason and reacting differently, payday-aware retries for insufficient funds, immediate card-update emails for expired cards, backoff for processing errors, recovers more, and the two approaches coexist fine.
What's the difference between a hard and a soft decline?
A soft decline is temporary (insufficient funds, a hold, a processing error) and is worth retrying. A hard decline (stolen or lost card, closed account) is permanent for that card and should not be retried. Ask the customer to update their card instead.
How long should I keep retrying a failed payment?
A common window is about two weeks with a handful of spaced attempts. Beyond that, retrying rarely helps and starts to look like abuse to card networks.
Will retrying failed payments cause chargebacks or disputes?
It can, if you retry hard declines or fire attempts back-to-back. Spacing attempts, capping them, and never retrying hard declines is what keeps dispute risk low.
Can I recover an expired card with a retry?
No. An expired card needs a new card number. Prompt the customer to update it (Stripe's Card Account Updater also refreshes some automatically), then the next charge can succeed.
Go deeper on any of this
Each of these takes one section of this guide and does it properly, with the Stripe documentation it came from linked at the bottom.
- The nine decline codes that stop retries dead: the exact list, rather than the rough "stolen or lost card" shorthand used above.
- How Stripe Smart Retries actually work: the real defaults, what you can configure, and when to turn it off.
- Is insufficient_funds a hard decline?: no, and a lot of published guidance says otherwise.
- Why retrying an expired card rarely works: and the preventative version that does.
- Stripe's own dunning emails: what you control, what you do not, and the 60 day log limit.
- Measuring involuntary churn: the formulas, from your own Stripe data.
- past_due vs unpaid vs canceled: what each status means and which one you get when retries run out.
- Which webhooks tell you a payment failed: the events, the invoice fields, and the attempt_count trap.
- Test cards for every decline scenario: including the one that only fails when charged.
- Stripe updates expired cards for you, sometimes: why that still leaves you a problem.
- What do_not_honor means: the most common decline nobody will explain to you.
- Recovering authentication_required: the one blocked code where the card is fine.
See what you're losing
Connect Stripe and get a free 90-day backtest of your failed payments, before you commit to anything.
Try the free backtest
Recover