How to Set Up Dunning in Stripe
Set up dunning in Stripe by enabling Smart Retries, configuring your retry schedule to 28 days, and adding a multi-step email sequence for failed payments. Stripe's built-in dunning recovers about 35% of failures. Adding 3-4 timed emails with direct card-update links pushes recovery to 55% on average.
Dunning is the process of communicating with customers to collect failed payments before their subscription gets cancelled. The term comes from the 17th-century practice of "dunning". making persistent demands for payment of a debt. In the SaaS context, dunning means retry logic plus email sequences plus payment update flows that recover failed charges automatically, preventing involuntary churn. Stripe has built-in dunning features, but they're limited. See the dunning email benchmarks for how much more you can recover. Here's exactly what Stripe offers, what it doesn't, and how to fill the gaps. Use our dunning ROI calculator to estimate the impact for your business.
What dunning means for SaaS
A complete dunning system has four components:
- Retry logic. automatically re-attempt the charge at optimal times
- Customer communication. email sequences that notify the customer and provide a way to fix their payment
- Payment update flow; a hosted page or in-app form where the customer can enter new card details
- Escalation rules. what happens if all retries and emails fail (pause, cancel, or downgrade)
Stripe handles component 1 well. Component 2 is minimal. Components 3 and 4 require you to build or use a tool.
Stripe's built-in dunning options
All dunning configuration lives in Stripe Dashboard under Settings > Subscriptions and emails > Manage failed payments. Here's what you can configure:
Retry schedule
Stripe offers two retry modes:
- Smart Retries (recommended). Stripe's ML model picks the optimal retry time based on patterns across its network. You choose the retry window (up to 4 weeks) and how many times to retry (up to 4 times).
- Custom schedule. You manually set the retry days (e.g., retry after 1 day, 3 days, 5 days, 7 days). This gives you control but loses the ML optimization.
The recommended setup is Smart Retries with a 4-week window and 4 retry attempts. This gives Stripe the maximum flexibility to find a payment window that works.
Email notification
Stripe sends one email when a payment fails. You can enable or disable it under "Email customers when a payment fails." That's the extent of it. One email, one template, one chance. You can't customize the timing, the content, the subject line, or the sender name. You can't send follow-up emails. You can't segment by failure reason. The email includes a link to a Stripe-hosted page where the customer can update their payment method.
Subscription status after failure
You choose what happens when all retries are exhausted:
- Cancel the subscription; the subscription ends, customer loses access immediately
- Mark as unpaid; the subscription stays active but the invoice remains open (you handle access control)
- Leave as past_due; the subscription status becomes
past_dueand stays that way until you intervene
For most SaaS apps, "mark as unpaid" or "leave as past_due" is better than immediate cancellation because it gives you more time to recover the customer through your own dunning sequence.
Limitations of Stripe's dunning
Stripe's dunning is a starting point, not a solution. Here's what's missing:
- No multi-email sequence. one email recovers far less than a 4-6 email sequence
- No custom email content. You can't brand the email, change the copy, or match your product's voice
- No segmentation. every customer gets the same email regardless of their plan, tenure, or failure reason
- No in-app notifications. Stripe only emails; it can't show banners in your app
- No pre-dunning. Stripe doesn't warn customers before their card expires
- No recovery analytics. You can't see your dunning performance, recovery rate, or which emails converted
Setting up Stripe's built-in dunning
Even though it's limited, you should configure Stripe's dunning as your baseline. Here's the step-by-step:
- Go to Stripe Dashboard > Settings > Subscriptions and emails
- Under "Manage failed payments," enable Smart Retries
- Set the retry window to 4 weeks (maximum)
- Set retry attempts to 4
- Enable "Send emails when payments fail"; this turns on Stripe's single dunning email
- Under "If all retries fail," select "Mark the subscription as unpaid" (this keeps the subscription alive for your own recovery efforts)
- Under "Customer emails," enable the upcoming renewal reminder (sends 7 days before renewal)
- Click Save
Total time: 5 minutes. This gets you Smart Retries (about 35% recovery) plus one notification email. Better than nothing, but you'll want to add more layers.
Adding tool-assisted dunning
To go beyond Stripe's one-email limit, you have two options: build your own dunning system or use a dedicated dunning tool.
DIY dunning with webhooks
Register a webhook endpoint in Stripe Dashboard > Developers > Webhooks. Listen for these events:
invoice.payment_failed. triggers when any payment attempt failscustomer.subscription.updated. triggers when a subscription status changes (e.g., active → past_due)invoice.payment_succeeded. triggers when a retry succeeds (stop your dunning sequence)customer.subscription.deleted. triggers when the subscription is fully cancelled
When invoice.payment_failed fires, extract the customer ID and attempt_count from the event. Use the attempt count to decide which dunning email to send. Store dunning state in your database so you don't double-send. When invoice.payment_succeeded fires, mark the dunning sequence as resolved.
You'll also need a card update page. The fastest way is to create a Stripe Billing Portal session with stripe.billingPortal.sessions.create() and include that URL in your dunning emails. The customer clicks the link, updates their card on Stripe's hosted page, and Stripe automatically retries the failed invoice.
Build time: 15-25 hours for the webhook handler, email templates, scheduling logic, and card update flow. Plus ongoing maintenance.
Tool-assisted dunning
SaveMRR's Revenue Rescue engine plugs into your Stripe account and handles the complete dunning lifecycle: a 4-email sequence with tested copy, pre-dunning card expiry alerts, in-app payment banners via a JavaScript widget, and a recovery analytics dashboard. It works alongside Stripe's Smart Retries, not instead of them. Setup is a Stripe API key paste. No webhooks to manage, no email templates to write, no cron jobs to maintain. Starts at $19/month.
Webhook events reference
Here's a quick reference of every Stripe webhook event relevant to dunning:
invoice.payment_failed. payment attempt failed, trigger dunning emailinvoice.payment_succeeded. payment recovered, stop dunningcustomer.subscription.updated. subscription status changed (watch forpast_due)customer.subscription.deleted. subscription cancelled after all retries failedcustomer.source.expiring. card expiring soon, trigger pre-dunningpayment_method.automatically_updated. Stripe auto-updated the card via network updaterinvoice.upcoming. invoice will be created soon (useful for pre-charge reminders)
Next step
Before configuring dunning, find out how much you're actually losing to failed payments. SaveMRR's free Revenue Scan connects to your Stripe account (read-only) and shows your exact failed payment volume, recovery rate, and estimated revenue at risk. It takes 2 minutes and gives you the data you need to decide whether Stripe's built-in dunning is enough or whether you need a dedicated solution.
