Stripe Dunning Emails: Why One Message Never Works

stripe dunning emails

Stripe Dunning Emails: Why One Message Never Works

6 min readApril 9, 2026

The Core Mistake in Stripe Dunning Emails

Most SaaS companies send the same dunning email whether a customer's card expired or they just didn't have enough money in their account that day. This seems efficient. It's actually the reason your recovery rate stays stuck at 30-40%.

The problem is simple: these are two completely different situations that require completely different responses from your customer. One requires the customer to update their payment information. The other just needs them to wait while Stripe retries the charge. Treating them the same confuses customers and wastes their time.

When you send a generic "your payment failed, please update your card" message to someone whose card just had insufficient funds, you're asking them to do something that won't solve the problem. They'll log in, see the same card number on file, wonder what they're supposed to change, and leave. Meanwhile, Stripe's smart retry logic is already working in the background. You just created work for a customer that didn't need to do anything.

Understanding the Two Types of Payment Failures

Stripe's decline codes fall into two categories, though Stripe doesn't explicitly label them this way.

Timing problems include insufficient_funds, do_not_honor, and issuer_not_available. These happen when the customer's card is valid, they have money, but something about that specific moment caused the decline. Maybe their account balance was temporarily low. Maybe their bank's fraud system got nervous about the charge. Maybe the issuing bank's system was down for maintenance.

These failures resolve themselves. Stripe knows this. That's why Stripe automatically retries the charge multiple times over the next two weeks. Your job isn't to get the customer to fix something. Your job is to make sure they know you're handling it and they don't need to panic.

Communication problems include expired_card, incorrect_cvc, and card_declined due to a changed card number. No amount of retrying will fix these. The payment method itself needs to be updated. Only the customer can do that. Stripe can't retry its way out of an expired card.

This distinction matters because it changes what you ask the customer to do.

What Happens When You Get the Message Wrong

Let's look at what actually happens when you send the wrong dunning email.

Say a customer's card gets declined with insufficient_funds on Monday morning. This happens all the time—they paid a bunch of bills over the weekend and their balance dipped lower than expected. Stripe will retry the charge on Tuesday. It'll probably work.

But on Monday afternoon, they get your dunning email saying "Your payment failed. Please update your payment information immediately or your account will be suspended."

They log into your app. They look at their payment settings. The card on file is correct—same number, same expiration date. They're confused. What are they supposed to update? They don't have another card to add. They just got paid last week; money isn't the issue.

Now they're thinking about canceling. Not because they can't pay you, but because dealing with this feels broken. They'll probably reach out to support. Your support team will explain that Stripe is retrying and everything's fine. The customer will wonder why you sent them a panicked email if everything was fine.

The next day, Stripe retries the charge. It goes through. You've successfully recovered the payment while creating a completely unnecessary support ticket and making your customer question whether you know what you're doing.

Writing Dunning Emails for Timing Problems

When the decline code indicates a timing problem, your dunning email should communicate three things clearly.

First, what happened. "Your payment didn't go through this time" works better than "your payment failed" because it doesn't sound permanent.

Second, what you're doing about it. "We'll automatically retry in the next few days" tells them you're handling it. They don't need to do anything right now.

Third, what they should do if it keeps happening. "If this charge fails again, we'll let you know and you can update your card then" gives them a clear next step without creating false urgency.

The tone should be calm. You're letting them know something happened, but you're on it. This isn't an emergency. Most of these charges will succeed on retry.

Writing Dunning Emails for Communication Problems

When the decline code indicates a communication problem, your dunning email needs to be direct and action-oriented.

First, what the specific problem is. "Your card on file expired" or "Your payment method was declined" tells them exactly what needs to be fixed.

Second, what they need to do. "Please add a new payment method" gives them a clear action. Include a direct link to your billing page, not your general settings.

Third, what happens if they don't. "Your account will be paused in 5 days" creates real urgency because this time it's warranted. No retry is going to fix an expired card. They actually do need to take action.

The tone should be more urgent without being hostile. This is fixable, but only they can fix it, and they need to do it soon.

The Recovery Rate Impact

When you split your dunning emails by failure type, you'll see two things happen.

First, your support tickets about failed payments will drop. Customers stop logging in to "update" cards that don't need updating. They stop asking why they got an urgent email when everything's fine. Your support team stops explaining how payment retries work.

Second, your actual recovery rate improves. Not because you changed what Stripe does—Stripe was always going to retry those timing-based failures. But because when you do need the customer to take action, your message is clearer. They know exactly what's wrong and exactly what to do. There's no confusion about whether they need to update their card or wait for a retry.

The improvement isn't dramatic. You're not going to jump from 40% to 80% recovery. But you'll typically see recovery rates improve by 10-15 percentage points, and your support load drops by about a third. That's meaningful when you're dealing with hundreds or thousands of failed payments per month.

The Takeaway

Every failed payment comes with a decline code from Stripe. That code tells you whether this is a timing problem or a communication problem. Your dunning email should match the problem type. Send calm, informative messages for timing problems where Stripe's retry logic will likely work. Send clear, urgent messages for communication problems where only the customer can fix the issue. Treating all failures the same wastes your customers' time and your support team's time while leaving money on the table.

Free diagnostic

See exactly what's happening in your Stripe account

Connect your Stripe account and get a breakdown of every failed payment — which ones can be retried, which ones need customer outreach, and how much is recoverable. Takes 5 minutes. No credit card required until we recover $49.

Run free diagnostic