The 4 main reasons Stripe payments fail (and how to fix each one)
Analysis of the 4 most common causes of Stripe payment failures for SaaS companies, with concrete solutions for each.
When a Stripe payment fails, the API returns a very specific error code. But many SaaS teams treat every failure the same way: a generic email, a retry 24h later, and that's it. That's a mistake. Each failure reason deserves a different response — and that distinction is precisely what takes a recovery rate from 40% to 70%.
1. Expired card (expired_card) — 35% of failures
This is reason number one. The customer's card has been replaced by their bank and the old one has expired. This typically happens 2–3 years after signup.
Wrong response: retry the payment. It will never work — the card is dead.
Right response: immediately send a clear email ("your card has expired") with a unique link to an update page (Stripe Customer Portal or equivalent). Conversion rates on this type of campaign exceed 65% within 10 days.
2. Insufficient funds (insufficient_funds) — 20% of failures
The customer has a valid card, but their account is overdrawn at the time of the charge. This is typical at month-end.
Right response: retry 3–5 days later, ideally early next month. Retries on this failure type convert at over 60% with zero customer action. No need for an aggressive email — a simple informational message is enough.
3. 3D Secure declined (authentication_required) — 15% of failures
Since PSD2 (SCA) in Europe, many recurring payments need strong authentication. If the customer hasn't authorized the payment (often because they missed their bank's notification), the charge is declined.
Right response: send an email inviting the customer to manually complete the payment (via a Stripe Checkout link with SCA built in). That forces authentication and unblocks not only the current payment but also future recurring charges.
4. Card declined by issuer (card_declined) — 15% of failures
This is the catch-all: the bank declines without a specific reason. It can be fraud detection, a cap reached, a frozen card, or just a temporary network error.
Right response: retry once at D+2, then if the failure persists, contact the customer by email inviting them to check with their bank or use another card.
The remaining 15%
The rest splits between lost/stolen cards (lost_card, stolen_card), processing errors, invalid postal codes, and a few rare cases. For these, the strategy is the same as card_declined: retry + email.
The fundamental principle
A good dunning system does NOT treat every failure the same way. It uses the Stripe error code to route each case to the right sequence: pure retry, "update your card" email, or "authenticate this payment" email. That level of personalization is the difference between mediocre dunning and dunning that recovers 70% of your involuntary churn.
RecoverFlow handles all of this automatically
Our rules engine automatically inspects the decline_code returned by Stripe and applies the right strategy for each case. You don't have to configure anything: best practices are already implemented, and you can customize them if needed.