dunlo
Back to blog
dunning strategymrrdunlo

How to Build a SaaS Dunning Strategy

3 min read

Why most dunning is broken

"Dunning" is one of those words founders learn from a Baremetrics post and immediately wish they hadn't. It sounds bureaucratic. It conjures a debt collector. The reality is more boring and much more lucrative: dunning is the system that recovers revenue when a customer's payment fails through no fault of their intent.

Most SaaS have one of two dunning setups. Either they have nothing — the processor retries a few times, sends a generic email, gives up — or they have something Frankensteined together over time, with a Zapier zap here and a custom email there, that nobody on the team fully understands. Both leak money.

This guide is the playbook we wish we'd had. Follow it end to end and you should expect to recover 5–8% of MRR you're currently losing, with a one-time setup cost of a few engineering days or one tool subscription.

The 5 stages of a real dunning workflow

Every effective dunning system has the same five stages. Most setups skip two or three of them.

Stage 1 — Prevention (before failure)

The cheapest recovered payment is the one that never failed. Two prevention tactics dominate:

  • Pre-expiry warnings — email customers 14 days before their card expires. About a third update proactively.
  • Card account updaters — automatically pull updated card data from Visa/MC networks when a card is reissued. Stripe offers this for free; turn it on.

Less common but high-leverage: when a customer changes their card in your app, prompt them to confirm the change is also reflected in any other tools they use. Friction is fine when it prevents future churn.

Stage 2 — Detection (within minutes of failure)

If you find out about a failed payment six days late, you've already lost the easy recovery window. Your detection should be:

  • Real-time — webhook-driven, not a daily email digest
  • Categorized — at minimum, by failure type bucket (recoverable / hard decline / authentication / other)
  • Routed — high-value customers get a Slack ping; low-value ones go straight to automated retries

The simplest detection setup is a Slack channel called #payment-failures with one message per event, formatted: "€X MRR failed — Customer Y — Reason Z — Retry attempt N". Founders who set this up all say the same thing: they didn't realize how often it was happening.

Stage 3 — Retry strategy (per failure type)

This is where most teams over-rely on their processor's defaults. Here's a retry policy that works:

Failure typeFirst retrySubsequent retriesStop after
Insufficient funds+3 days+7 days, +14 days3 attempts
Soft decline (do_not_honor)+1 day+5 days, +10 days3 attempts
Network / processor error+5 minutes+1 hour, +1 day3 attempts
Expired cardDon't retry — emailEmail only, then escalate
Hard decline (lost/stolen)Don't retry — email1 attempt after card update
Authentication (3DS / SCA)Trigger re-auth in app+2 days, +7 days3 attempts

Two principles to keep in mind:

  • Time of day matters. Bank processing is cleaner Tuesday through Thursday morning than Sunday night. The Stripe ML knows this; if you're rolling your own, copy the pattern.
  • Don't retry past 14–21 days. After that, your recovery rate falls below 2% and your processor reputation suffers.

Stage 4 — Communication (the email sequence)

The retry strategy is the engine; the emails are the steering wheel. A good sequence has four to five emails over 14 days, each with a distinct job:

  • Email 1 (T+0): Heads-up. Friendly, brief. "Your card on file didn't go through — we'll try again, but you can update it now."
  • Email 2 (T+3): Reminder. Explain that retries are continuing, make the update link prominent.
  • Email 3 (T+7): Direct. "Your account will be paused on [date] if we can't process the payment."
  • Email 4 (T+13): Final notice. Calm, clear, with a one-click update.
  • Email 5 (T+15, conditional): Win-back. "We had to pause your account. Here's how to come back."

We'll dive into copy in a separate post. The single most important rule: the call to action — update card — should be a one-click button that takes the customer to a hosted update page with their account context preserved. Asking them to log in, navigate to billing, find the card section, and update is a 60% drop-off.

Stage 5 — Escalation (high-value accounts)

Some customers are worth a human. Define a threshold — typically 3–5x your average MRR per account — above which a failed payment triggers a person to reach out, not just an email.

The script is short:

"Hey [name], saw a payment hiccup on your account this morning. Wanted to check in personally before we run the next retry — anything we can help with? Happy to jump on a call if useful."

This converts at extraordinary rates. The accounts that respond often weren't aware of the failure and update immediately. The ones that don't respond — you've now flagged them as at risk and your CSM can dig deeper.

Putting it together — a workflow you can copy

Here's the full workflow, ready to translate into your tool of choice:

  1. T-14 days before card expiry: send pre-expiry email
  2. T+0 (failure): log to dashboard, classify, decide retry
  3. T+0: send Email 1; if account > €500/mo, ping #high-value-failures Slack
  4. T+1 / T+3 / T+5 (depending on category): retry
  5. T+3: send Email 2 if still unpaid
  6. T+7: send Email 3; assign CSM if high-value
  7. T+10: final retry
  8. T+13: send Email 4 (final notice)
  9. T+15: pause account if still unpaid; send Email 5 (win-back)
  10. T+30: archive as fully churned; do not retry further

Common mistakes (and how to avoid them)

  • Treating all failures the same. The single biggest leak. Categorize by decline code.
  • Sending too many emails. Five over 14 days is the cap. More feels harassing and tanks deliverability.
  • Friction-heavy update flows. If updating the card takes more than two clicks, you've lost half your recoveries.
  • Retrying for too long. Past 21 days, recovery rate is microscopic and processor reputation suffers.
  • No win-back step. Customers whose card died often want to come back. Make it easy.
  • Not measuring. If you can't quote your recovery rate within 5%, you're flying blind.

Build vs buy — a framework

You can build all of this yourself. The question is whether you should.

A reasonable in-house build looks like: webhook listener (Lambda or worker) → state machine for retry logic → email template system → Slack integration → dashboard. Realistic timeline: 2–4 weeks of a senior engineer plus 4–8 hours/month of maintenance forever.

Or you pay €50–€200/month for a tool that does it. The math almost always favors buying when MRR is below €100k. Above that, the trade-off depends on how much you're customizing per-customer logic.

Measuring success

Track three numbers monthly:

  • Recovery rate — % of failed MRR eventually recovered. Healthy: 50–70%.
  • Time to recovery — median days from first failure to successful payment. Healthy: 3–7 days.
  • Involuntary churn rate — % of MRR lost to non-recovered failures. Healthy: under 2%.

Improvements compound. Going from 30% recovery rate to 60% on a €30k MRR business is roughly €350 of additional MRR per month, every month, forever. That's a €4,200 ARR uplift for one weekend of setup.

Where to start this week

  1. Pull a CSV of every failed payment in the last 90 days. Categorize them by decline code.
  2. Calculate your current recovery rate and time-to-recovery. Even rough numbers.
  3. Audit your existing dunning emails. Read them as a customer would.
  4. Decide one of: build it yourself in the next sprint, or evaluate a dedicated tool.
  5. Set up the Slack channel for high-value failures even if you do nothing else. The visibility alone changes behavior.

How Dunlo fits

Dunlo is what we built when we got tired of patching the workflow above. It runs the entire stack — categorized retries, custom email sequences, real-time alerts, recovery analytics — on top of Stripe. Setup is 5 minutes. Pricing is flat by MRR tier (no percentage of recovered revenue). It's free during beta if you want to skip the build.

dunning strategymrrdunlo