n8n Failed Payment Recovery: A Smart Dunning Ladder for Stripe
Build n8n failed payment recovery that times its dunning ladder to Stripe's own retries, sends card-update links, and hands off lost accounts to winback.
Your customer didn't leave. Their card did. It expired, or hit a limit, or the bank flagged a recurring charge it didn't recognize, and Stripe quietly logged a invoice.payment_failed. Nobody clicked cancel. But if nothing chases that failure, the subscription lapses anyway, and you've lost a customer who wanted to stay.
That's involuntary churn, and n8n failed payment recovery is the automation that gets most of it back. The popular Stripe-recovery templates catch the failure and fire off a couple of emails. That's a start. It also ignores the one thing that decides whether recovery works: timing the outreach to when the card is actually likely to clear.
This is a different job from the broad Stripe-events workflows and from voluntary-churn prevention. Those handle customers deciding to leave. This handles customers leaving by accident.
What You Can Automate in Payment Recovery
The recovery steps worth wiring:
- Catching the
invoice.payment_failedwebhook the instant it fires - Confirming it's an auto-charged subscription, not a one-off
- Logging the failure with the customer, amount, and attempt number
- Sending a staged dunning ladder timed to Stripe's retry schedule
- Including a one-click card-update link in every email
- Detecting a successful retry and stopping the ladder immediately
- Handing off unrecoverable accounts to customer success or winback
- Tracking recovery rate so you know what the ladder is actually saving
The ladder and the stop condition are the two pieces the ranking templates get wrong. Both matter.
The Payment Recovery Pipeline
The shape of a recovery that respects Stripe's own retry logic:
Failure event → Verify → Log → Dunning ladder → Detect success → Recover or hand off
A concrete run:
Stripe Trigger v1 (event: invoice.payment_failed)
→ If v2: confirm subscription auto-charge (not a manual invoice)
→ Google Sheets v4: log failure, attempt #, customer, amount
→ Switch v3: route by attempt number (1st / mid / final)
→ 1st: soft nudge email + card-update link
→ Wait v1.1: hold to mid-window
→ If v2: check invoice.paid? stop : send firmer email
→ Wait v1.1: hold to final-window
→ If v2: still unpaid? → Slack v2 handoff + tag churned
The If check after each Wait is the stop condition. Stripe's Smart Retries may succeed on their own between your emails, and the worst thing a dunning ladder can do is keep emailing a customer who already paid. Check invoice.paid before every send.
Stripe's Smart Retries reattempt a failed charge over several days, scheduled around when the issuing bank is most likely to approve. The popular n8n recovery templates send two emails on a fixed daily cron, blind to that schedule. Ride alongside Stripe instead: nudge on the first failure, push the card-update link mid-window when a retry is imminent, and send the final notice just before cancellation. The timing is the recovery.
Step-by-Step Breakdown
1. Catch and verify the failure
The Stripe Trigger node fires on invoice.payment_failed. First check: is this a recurring subscription charge or a one-off invoice? The dunning ladder only applies to the former. The FlyCode-style templates do verify this, and it's the one thing they get right.
2. Log the attempt
Append the customer, amount, attempt number, and timestamp. The attempt number drives which rung of the ladder fires next, so it has to be reliable. Read the prior failures for this customer before deciding the stage.
3. Send the right rung
A first failure gets a soft, low-pressure nudge: "your last payment didn't go through, no action needed yet, here's how to update your card if you'd like." A mid-window failure gets firmer and leads with the card-update link. The final notice is direct: the subscription cancels on this date unless the card is updated.
4. Check for success before every send
Between rungs, the workflow waits. Before it sends the next email, it checks whether the invoice has since been paid, by your email or by Stripe's own retry. If it's paid, the ladder stops. Cleanly.
5. Hand off the unrecoverable
When the final window closes and the charge still hasn't cleared, don't just end the execution. Tag the account as involuntarily churned, post to Slack so customer success knows, and optionally schedule a winback touch after a cooling-off period.
Implementation Patterns That Hold Up
Pattern 1: The check-then-send guard. Every rung confirms the invoice is still unpaid before emailing.
If v2 (condition):
// re-fetch the invoice from Stripe by id
$json.invoice.status === 'open' // still unpaid → send
// status 'paid' → route to stop branch, end the ladder
Skipping this guard is how a customer who paid yesterday gets a "your payment failed" email today. That's the message that makes someone cancel on purpose.
Pattern 2: The card-update link, every time. A dunning email without a one-click way to fix the card is just nagging. Generate a Stripe billing-portal or update-card link and put it in every rung. Recovery rates live and die on how few clicks it takes to fix the card.
Pattern 3: The give-up handoff. When recovery fails, the workflow's last act is to make the loss visible and recoverable. Tag the account, alert a human, and queue a winback. An involuntarily churned customer is the warmest winback lead you'll ever have, because they never wanted to leave. The templates that just stop throw that away.
n8n Nodes You'll Use Most
| Node | Purpose |
|---|---|
n8n-nodes-base.stripeTrigger | Catch the invoice.payment_failed event |
n8n-nodes-base.if | Verify subscription charge, check paid status |
n8n-nodes-base.switch | Route by attempt number to the right rung |
n8n-nodes-base.wait | Hold between rungs, timed to Stripe's retries |
n8n-nodes-base.httpRequest | Re-fetch invoice status, generate the update link |
n8n-nodes-base.googleSheets | Log failures and recovery outcomes |
n8n-nodes-base.slack | Hand off unrecoverable accounts to a human |
The If nodes are doing the quiet, important work here. One verifies the event is in scope; the others stop the ladder the moment the money arrives. Get those wrong and you'll email customers who already paid.
Getting Started
- Wire the Stripe Trigger to
invoice.payment_failedand verify scope. Subscription auto-charges only. Manual invoices route elsewhere. - Build the failure log with a reliable attempt count. The count drives the ladder, so it has to be right.
- Write the three rungs. Soft, firm, final. Put a card-update link in all three.
- Add the check-then-send guard before every email. Re-fetch the invoice, confirm it's still open. This is non-negotiable.
- Time the Waits to Stripe's retry window, not a daily cron. Ride alongside the retries instead of talking over them.
- Build the handoff. Tag, alert, and queue winback when recovery fails. The lost charge is a warm lead, not a dead end.
The Smart Subscription Manager ships the Stripe-side plumbing this recovery flow leans on: it fetches active subscriptions straight from the Stripe API, analyzes them with AI, and reports to Slack while logging trends to Google Sheets — the same subscription-fetch-and-alert backbone you need to track which recoveries are working. It's part of The Complete n8n Templates Bundle, a one-time lifetime license to the whole catalog (plus every template added later) if you run more than one of these subscription automations.
A caveat on deliverability: a dunning email that lands in spam recovers nothing. Send these from a verified domain with proper authentication, and keep the subject lines plain. "Update your payment details" beats anything that reads like marketing, because the customer needs to actually see it.
If recovery is part of a wider retention effort, the n8n SaaS subscription churn prevention guide covers the voluntary side, and the n8n Stripe automation workflow maps the rest of the Stripe event surface this trigger lives in.
Build the check-then-send guard before anything else. A ladder that emails paid customers does more damage than no ladder at all. Get the stop condition right, then make the rungs persuasive.
See more finance templates →Common questions
What is involuntary churn and how does n8n help recover it?
How should a dunning email sequence be timed in n8n?
What happens in n8n when a payment can't be recovered?
Get the workflow templates this guide is built on
Import-ready n8n JSON, step-by-step setup, and tested end-to-end. One-time payment, own it forever.
Get 3 tested n8n templates, free
The full customer package for three real catalog templates — workflow JSON, step-by-step setup guide, credential checklist. Built through the same live-instance release process as everything we sell. Plus new templates and automation guides in your inbox. No spam, unsubscribe anytime.
- 01Smart To-Do List ManagerPre-built n8n workflow template that automates productivity with OpenAI. Live in about 10 minutes.$14
- 02Email Follow-Up AutomatorPre-built n8n workflow template that automates crm with OpenAI. Live in about 15 minutes.$12
- 03Market Trend AnalyzerPre-built n8n workflow template that automates data processing with OpenAI. Live in about 10 minutes.$14
More automation guides

n8n Accounts Payable Automation: 3-Way Match and Approval Routing
Most accounts payable content shows you the easy half. A vendor emails an invoice, an AI node reads the amount, you match it against a purchase order, you pay. The n8n.io invoice-PO matching template…

n8n Payroll Automation: Reconcile and Sign Off Before Payslips Go Out
The payroll demos all stop at the satisfying part. Pull employee data from a sheet, calculate net pay with an AI node, generate a PDF, email it out. Beautiful. Then payroll runs for real, a contractor…

n8n Data Enrichment Workflow: Cache, Fallback, Retry
Enrichment is where API bills sneak up on you. Every lead that needs a company size, a tech stack, or a verified email is a paid lookup, and a naive workflow re-buys data it already has every time it…