Every SaaS founder knows about voluntary churn — customers who cancel because they're not seeing value. But there's a second, quieter type of churn that often goes untracked: involuntary churn from failed payments.
Industry data puts it at 30-40% of all subscription cancellations. For a $100K MRR business, that's roughly $3,500-$4,000 disappearing every month from credit cards that expired, bank fraud blocks, or exceeded limits — not because the customer wanted to leave.
Why Banks Decline Payment Attempts
Understanding why payments fail is the first step to recovering them:
| Reason | Frequency | Recoverable? |
|---|---|---|
| Insufficient funds | ~38% | Yes (retry end of month) |
| Card expired | ~25% | Yes (update request) |
| Fraud prevention block | ~18% | Yes (customer contacts bank) |
| Card reported lost/stolen | ~12% | No (new card needed) |
| Bank-side technical error | ~7% | Yes (retry within 24h) |
The key insight: most failures are temporary. A retry at the right time recovers the revenue.
The Optimal Retry Schedule
Don't retry immediately and aggressively — that triggers fraud detection and makes the situation worse. The optimal dunning schedule:
- Day 0: Immediate retry (catches temporary errors)
- Day 3: Second retry (most cards refreshed by now)
- Day 7: Third retry with email notification
- Day 15: Final attempt + escalation email
Each retry should use intelligent payment routing — try a different payment processor if the primary fails, or use card updater services to get updated card details automatically.
Building a Dunning Email Sequence
The email sequence matters as much as the retry schedule. Tone progression:
Email 1 (Day 3 — No-blame)
Subject: Quick update on your [Product] subscription
Hi {{name}},
We had trouble processing your payment for [Product]. This happens
occasionally — usually a temporary bank issue.
We'll automatically retry in a few days. No action needed.
Email 2 (Day 7 — Helpful)
Subject: Action needed: Update your payment details
Hi {{name}},
We've been unable to process your [Product] subscription payment.
Your account will remain active for 7 more days.
Update your payment details here: [LINK]
Email 3 (Day 14 — Urgency)
Subject: Your [Product] account will be suspended tomorrow
Hi {{name}},
This is a final reminder. Your account will be suspended in 24 hours
unless you update your payment details.
We'd hate to lose you — here's a one-click update link: [LINK]
The three-email sequence typically recovers 18-25% of failed payments before the account suspends.
Implementing Retry Logic with Stripe
// Stripe webhook handler for payment failures
app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), async (req, res) => {
const event = stripe.webhooks.constructEvent(
req.body,
req.headers['stripe-signature'],
process.env.STRIPE_WEBHOOK_SECRET
);
if (event.type === 'invoice.payment_failed') {
const invoice = event.data.object;
const attemptCount = invoice.attempt_count;
// Schedule next retry based on attempt number
const retryDelays = [0, 3, 7, 15]; // days
const nextDelay = retryDelays[attemptCount] || null;
if (nextDelay !== null) {
await scheduleRetry(invoice.subscription, nextDelay);
await sendDunningEmail(invoice.customer, attemptCount);
} else {
await suspendSubscription(invoice.subscription);
await sendFinalNotice(invoice.customer);
}
}
res.json({ received: true });
});
Measuring Recovery Rate
Track these metrics to optimise your dunning process:
- Recovery rate: % of failed payments recovered before suspension
- Recovery revenue: total MRR recovered per month
- Time to recovery: median days from failure to successful payment
- Email-to-update CTR: click-through on payment update links
A well-implemented dunning system typically achieves 15-25% recovery rate. Tools like ChurnGuard automate the entire process — retry scheduling, email sequences, recovery tracking — with zero code integration required.
Don't let payment failures become silent cancellations. The revenue is there; you just need to ask for it at the right time.
Top comments (1)
This is such an overlooked area
A lot of teams focus on retries and dunning but still miss the user side of the story
From the dashboard it looks like churn or failed payments
But you don’t really know what the user experienced in that moment
Tools like Flidget can help add that missing context
So you can understand whether it was a payment issue confusion or actual intent to leave
Feels like combining both could significantly improve recovery rates