How to Recover Failed Payments on Stripe: A Complete Guide for SaaS Founders
Every month, a percentage of your Stripe charges fail silently — and most founders don't even have a system to deal with it. This guide changes that.
Executive Summary (TL;DR)
- •4–7% of subscription transactions fail every month — most customers don't know it happened.
- •Stripe Smart Retries recovers 15–22% of failed payments. A dedicated dunning setup recovers 40–60%.
- •The failure type (soft decline vs. expired card vs. SCA) dictates your recovery strategy — one-size-fits-all doesn't work.
- •The fastest wins: listen for the invoice.payment_failed webhook, send a tailored email within 1 hour, link directly to the payment update page.
Why Do Stripe Payments Fail?
Before you can recover a failed payment, you need to understand why it failed. This isn't academic — the reason for the failure completely determines what you should do next.
Stripe groups declines into three meaningful categories. Most founders treat them all the same. That's the first mistake.
Type 1: Soft Declines
Recovery: 50–70%What it is: A temporary failure. The card is valid, the customer still has it, but the charge couldn't go through right now. Common causes: insufficient funds at billing time, daily transaction limit, or a temporary bank block.
Stripe error codes: insufficient_funds, do_not_honor, card_velocity_exceeded
Recovery strategy
Send a friendly nudge within 24 hours. No blame, no urgency theater. The customer probably doesn't know the charge failed. Stripe will retry automatically — your email is the human layer on top.
Type 2: Hard Declines
Recovery: 30–45%What it is: A permanent failure. The card is genuinely gone — expired, canceled, reported lost or stolen, or the account was closed. Retrying the same card will never work.
Stripe error codes: expired_card, lost_card, stolen_card, card_declined (permanent)
Recovery strategy
You need a new card on file. The email must make it dead simple — link directly to the Stripe billing portal or a hosted payment update page. Every extra click kills conversion. Subject line and CTA are everything here.
Type 3: SCA / 3D Secure Failures
Recovery: High with correct approachWhat it is: Strong Customer Authentication (SCA) is mandated by European banking regulations (PSD2) and is growing globally. When a bank requires the customer to complete a 3D Secure challenge and they don't, the payment fails.
Stripe error codes: authentication_required, payment_intent_authentication_failure
Recovery strategy
Do NOT retry the charge server-side — it will fail again. Create a new PaymentIntent that requires customer action and email them a secure link to complete verification. This is the most under-handled failure type in bootstrapped SaaS, and one of the easiest to recover with the right setup.
What Stripe Does by Default (And Why It's Not Enough)
If you're using Stripe Billing, you already have Smart Retries turned on. It uses machine learning to pick the optimal time to retry a failed charge — typically across a 4-week window. It's genuinely useful.
But it only retries the charge. The customer is never notified. Their access may get suspended out of the blue, they get frustrated and confused, and they churn — not because they wanted to, but because the silence felt like abandonment.
Stripe Smart Retries only
15–22%
recovery rate
- ✗ Customer never notified
- ✗ No failure-type awareness
- ✗ Expired cards can't be retried
- ✗ No card update link generated
Smart Retries + Dunning emails
40–60%
recovery rate
- ✓ Customer informed immediately
- ✓ Email tailored to failure type
- ✓ Direct payment update link
- ✓ SCA handled correctly
The gap between 22% and 60% isn't magic — it's just communication. Customers don't churn because their card fails. They churn because nobody told them what happened and made it easy to fix it.
Want the full breakdown? See our Stripe Smart Retries vs. dedicated dunning comparison.
The 5-Step Recovery Playbook
Here's the exact process for recovering a failed Stripe payment. This is what a good dunning system does automatically — and what you can do manually until you have one.
Listen for the invoice.payment_failed webhook
This is the trigger for everything. When Stripe fires this event, you get the customer's details, the invoice amount, the failure code, and the subscription status — all in one payload. Set up your webhook endpoint before anything else.
See the full technical guide to the invoice.payment_failed webhook for implementation details.
Classify the failure type
Read the last_payment_error.decline_code from the webhook payload. Is it a soft decline, a hard decline, or an SCA failure? Each one needs a different response — don't send the same email to everyone.
Send a failure-specific email within 1 hour
Speed matters. Recovery rates drop significantly after 24 hours. The customer is most likely to act while the failure is fresh and their access is still active. The email should be empathetic, brief, and include a direct link to fix the problem — not just a link to your settings page.
Retry strategically (not blindly)
For soft declines, let Stripe's Smart Retries handle the timing — it's good at this. For hard declines, don't retry until the customer has added a new card. For SCA failures, don't retry server-side at all — send the customer a link to complete authentication.
Set a clear grace period before cancellation
Configure Stripe's subscription settings to give customers 7–14 days after failure before the subscription cancels. This is your dunning window. Communicate the deadline clearly in your emails — not as a threat, but as helpful information. Once the subscription hits canceled status, recovery requires a full win-back campaign.
How to Set Up Stripe Webhooks for Payment Recovery
The whole recovery system starts with one event: invoice.payment_failed. When Stripe fires this webhook, you get everything you need — customer info, failure code, invoice amount, subscription status.
At minimum, your webhook handler should:
- Verify the Stripe signature (always — don't skip this)
- Extract the
customer,subscription, andlast_payment_errorobjects - Classify the failure type from
decline_code - Trigger your recovery email based on that classification
- Log the event for your dunning dashboard
Want the full technical walkthrough?
Our webhook guide covers the complete implementation: endpoint setup, signature verification, payload parsing, decline code classification, and idempotency handling. With production-ready code examples.
Read the webhook guide →Recovery Email Templates by Failure Type
The email is your most powerful recovery tool — but only if it's matched to the failure type. A generic "your payment failed" email treats an expired card the same as a temporary bank block. That's a missed opportunity.
Here's the principle: tell the customer exactly what happened (in plain language), what it means for their account, and what they need to do. One clear call to action. No corporate tone. Sound like a founder, not a billing system.
📬
Soft decline
Friendly nudge. No alarm. “Happens all the time — your bank likely blocked it temporarily.”
💳
Expired card
Clear ask. Direct link to billing portal. Deadline reminder without being threatening.
🔐
SCA failure
Explain what 3D Secure is in human terms. Link to complete the verification — 10 seconds to fix.
Get the full templates
Our email generator has copy-ready templates for all three failure types, plus guidance on subject lines, timing, and what to include in each email. Free to use.
Open the email generator →For a deeper dive into WHY each line of a dunning email works, see our companion post: Dunning Email Examples That Actually Work.
How Much Revenue Can You Actually Recover?
Let's be concrete. Say you have 300 subscribers at $49/month. That's $14,700 MRR. At a 5% failure rate, you're seeing roughly 15 failed charges per billing cycle — about $735 at risk.
With no dunning system (just Stripe defaults): you recover maybe 3–4 of those. The other 11–12 customers silently churn. That's ~$580/month in lost MRR — or roughly $7,000 annually — from a problem that's entirely fixable.
4–7%
of subscriptions fail every billing cycle
15–22%
recovered by Stripe alone
40–60%
recovered with dunning + email
The gap between 22% and 60% recovery is real. On a $14,700 MRR business, that gap is worth roughly $2,600–$4,000 per year in revenue you're currently leaving on the table.
Model your own numbers
The Lost MRR Calculator lets you simulate exactly what you're losing — and what you could recover — based on your real MRR, subscriber count, and failure rate.
Open the calculator →The Automated Approach: Using Dunning Lite
Building all of this yourself — webhook handling, failure classification, email templates, retry logic, a reporting dashboard — takes real time. It's doable, but it's also not why you started your SaaS.
Dunning Lite is the tool I built to handle this automatically. It connects to your Stripe account via OAuth, listens for the invoice.payment_failed webhook, classifies the failure type, and sends a recovery email within minutes of the charge failing.
What Dunning Lite does
Connects to Stripe in under 2 minutes — no code required
Listens for invoice.payment_failed webhooks in real time
Classifies the failure as soft, hard, or SCA
Sends an AI-crafted, humanized recovery email matched to the failure type
Logs all events in a dashboard — you always know what's been sent and recovered
Honest about where we are
Dunning Lite is in Early Access. Right now it sends one email per failed payment. Multi-step sequences (day 1, day 3, day 7) are on the roadmap. Even with a single well-timed email, founders report meaningful recovery — because the competition is silence and zero emails.
Pricing is $29/month flat. No commission on recovered revenue, no usage tiers, no surprises. You pay the same whether you recover $500 or $50,000. Early adopters lock in at the founding rate.
Frequently Asked Questions
How long does Stripe give me to recover a failed payment?
By default, Stripe's retry window runs for up to 4 weeks. You can configure the subscription behavior in your Stripe Billing settings — specifically the "Manage failed payments" section. Setting a 7–14 day grace period before cancellation gives you a reasonable dunning window while not letting delinquent accounts accumulate indefinitely.
What's the best time to send a dunning email after a failed payment?
As fast as possible — ideally within 1 hour of the failure. The customer's access is still active, the issue is fresh, and they're most likely to take action before any rationalization sets in. Recovery rates drop significantly after 24 hours.
For hard declines, urgency matters more than timing — you need a new card, not just a retry. For SCA failures, send immediately: the verification link you generate has a limited validity window.
Can I build this myself instead of using a tool?
Yes — the webhook guide covers the full DIY implementation. Realistic time investment: 1–2 days for a solid first version, plus ongoing maintenance. If your MRR is above ~$2K and you're billing monthly, the ROI of a $29/month tool versus your development time is straightforward math.
Does Dunning Lite work with Stripe Billing and Stripe Connect?
Dunning Lite connects via Stripe Connect (OAuth) to your Stripe account. It works with any Stripe Billing setup that uses subscriptions and invoices — which covers the vast majority of SaaS products on Stripe. It uses read-only access; we never touch your billing configuration.
What happens if a customer fails multiple times in a row?
Right now, Dunning Lite sends one email per invoice payment failure — so if Stripe retries and fails again, it sends another. Multi-step sequences (a crafted cadence across day 1, 3, 7) are on the roadmap. For most bootstrapped SaaS, one well-timed email is a meaningful upgrade from zero emails.
Stop losing customers to failed payments
Dunning Lite connects to Stripe in minutes. The moment a payment fails, we send a recovery email personalized to the failure type. $29/month flat. No commission. Early Access now open.