How to Automate Stripe Overdue Invoice → 4-Level Escalation Sequence with n8n
If you run a SaaS business or any subscription product on Stripe, you already know the ugly truth: a meaningful slice of your monthly revenue is quietly sitting in overdue invoices. Cards expire, paym
If you run a SaaS business or any subscription product on Stripe, you already know the ugly truth: a meaningful slice of your monthly revenue is quietly sitting in overdue invoices. Cards expire, payments fail, and invoices slip past due while nobody on your team notices until the churn report lands. Manually chasing every overdue invoice doesn't scale, and generic Stripe dunning emails treat a customer who's 3 days late the same as one who's 45 days late. This guide shows you how to build a smarter, tiered collections system in n8n — a daily workflow that scans Stripe for overdue invoices and sends the exact right message based on how far past due each one is.
The problem: flat dunning leaves money on the table
Stripe's built-in Smart Retries and email reminders are fine as a baseline, but they're blunt. Every failed or unpaid invoice gets the same tone regardless of severity. That's a mistake for two reasons.
First, a customer 2 days overdue is usually a benign card issue — an aggressive "final notice" email there damages goodwill and can trigger a cancellation you didn't need. Second, a customer 40 days overdue needs human intervention and a firm deadline, not a friendly nudge that gets ignored again. When escalation is flat, early-stage delinquents get over-pressured and late-stage ones get under-pressured. Both cost you money.
What actually recovers revenue is a graduated sequence: gentle reminder early, a firmer warning next, a final notice with a hard consequence, and finally a hand-off to a human for accounts that have gone truly cold. The logic isn't complicated — it's just tedious and error-prone to run by hand every single day. That's exactly the kind of work you hand to n8n.
The solution: a 4-level escalation engine
The workflow runs once a day on a schedule. It pulls every open, past-due invoice from Stripe, calculates how many days each one is overdue, and routes it into one of four escalation levels:
- Level 1 — Reminder (1–7 days past due): a soft, friendly email. "Looks like your payment didn't go through — here's your link to update it."
- Level 2 — Warning (8–20 days): a firmer email that references the earlier notice and mentions that service may be affected.
- Level 3 — Final notice (21–35 days): a direct email with a concrete deadline and consequence (suspension, cancellation).
- Level 4 — Collections alert (35+ days): stop emailing and post a Slack alert to your finance or ops channel so a human takes over.
Each invoice hits exactly one branch per run, so a customer never receives two conflicting messages on the same day. The result is a collections pipeline that behaves like a thoughtful ops person — but runs on autopilot and never forgets.
Step-by-step setup in n8n
Here's how to assemble the workflow node by node. You'll need your Stripe API key and a Slack app token (or incoming webhook) ready.
1. Schedule Trigger. Add a Schedule Trigger node set to run once daily — 9:00 AM in your business timezone works well, so emails land during working hours. Use the "Days" interval with "Trigger at Hour" set to 9.
2. Fetch overdue invoices. Add an HTTP Request node (or the native Stripe node if you prefer) calling GET https://api.stripe.com/v1/invoices with query parameters status=open and a reasonable limit like 100. Authenticate with a Header Auth credential (Authorization: Bearer sk_live_...). If you have high invoice volume, enable pagination by looping on the has_more and starting_after cursor fields so you don't miss anything past the first page.
3. Filter to genuinely past-due. Add a Code node to iterate the returned invoices and compute days overdue. Stripe gives you due_date as a Unix timestamp; compare it to now:
const days = Math.floor((Date.now()/1000 - item.json.due_date) / 86400);
Keep only invoices where days >= 1 and amount_remaining > 0. Attach the computed daysOverdue value to each item so downstream nodes can route on it. Discard invoices with no due_date (those are charge-automatically invoices Stripe retries on its own).
4. Route by severity with a Switch node. Add a Switch node with four output branches keyed on daysOverdue: rules for 1–7, 8–20, 21–35, and a fallback for 35+. The Switch cleanly separates the four escalation levels without nested IF nodes.
5. Send the right message per branch. On branches 1–3, add an email node — Send Email (SMTP), Gmail, or your ESP of choice. Craft a distinct template per level and personalize it with expression fields: {{ $json.customer_name }}, {{ $json.amount_remaining / 100 }}, and critically the Stripe-hosted payment link {{ $json.hosted_invoice_url }} so the customer can pay in one click. On branch 4, add a Slack node posting to your #collections channel with the customer name, amount, invoice ID, and days overdue so a human can decide whether to call, suspend, or write it off.
6. (Optional) Log the action. Append a Google Sheets or Postgres node at the end of each branch to record which invoice got which level on which date. This gives you an audit trail and prevents confusion if a customer disputes ever being contacted.
Configuration details that matter
A few settings separate a workflow that works from one that quietly misfires:
- Use the invoice's
due_date, notcreated. Net-30 invoices aren't overdue on day one. Routing off creation date will spam customers who are perfectly on time. - Amounts are in cents. Always divide
amount_remainingby 100 before showing it, or you'll email someone that they owe $4,900 instead of $49. - Set the Switch to "Stop" mode, not "Send to all matching." You want one branch per invoice, not overlapping sends.
- Use
hosted_invoice_urlfor the pay link. It's a secure Stripe-hosted page that always reflects the current balance — no need to build your own checkout. - Rate-limit gently. If you process hundreds of invoices, add a small
Waitor batch your email node to stay under your ESP's send limits.
The benefits: recovered revenue on autopilot
Once this is live, the payoff compounds. You recover a meaningful percentage of failed payments that would otherwise churn — most involuntary churn is just expired cards, and a timely, well-worded reminder with a one-click link fixes it. Your team stops manually cross-referencing Stripe against a spreadsheet every morning. Late-stage accounts get surfaced to a human at exactly the right moment instead of rotting unnoticed for months.
Just as important, your early reminders stay friendly, which protects the relationship with customers who simply had a card hiccup. You get firm where firmness works and gentle where gentleness works — the graduated approach that's proven to outperform flat dunning. And because it runs daily, no invoice ever falls through the cracks; the moment one crosses a threshold, it's actioned the next morning.
Common pitfalls to avoid
Double-sending across days. If you don't track state, a customer 8 days overdue gets a Level 2 email today, and another tomorrow, and every day after until they pay. Fix this by logging sends and either checking the log before sending, or narrowing each level to a single trigger day (e.g., send Level 2 only when daysOverdue === 8) so each escalation fires exactly once.
Ignoring already-paid invoices. Always filter on status=open and amount_remaining > 0. Stripe's list can include invoices that were just paid; emailing a paying customer a "final notice" is a fast way to lose them.
Hardcoding the API key in the node. Store your Stripe secret in n8n's credential manager, never in a raw HTTP node field. Use restricted keys with read-only invoice access where possible.
Forgetting timezones. The Schedule Trigger uses the instance timezone. Set it explicitly in n8n settings so 9 AM means 9 AM for your customers, not UTC.
Testing on live data. Point at Stripe test mode first and use your own email as the customer address until you've watched all four branches fire correctly. One misrouted "we're canceling your account" email to real customers erases weeks of goodwill.
Build it once, test it thoroughly, and this workflow becomes one of the highest-ROI automations in your stack — quietly pulling stuck revenue back into your account every single morning.
Ja construimos isso pra voce
Nao comece do zero. O Stripe Overdue Invoice → 4-Level Escalation Sequence e um workflow n8n pronto para instalar — conecta suas ferramentas em minutos, sem codigo.
Instalar por $59 →