n8n + Stripe: automating failed-payment follow-ups with AI
Published 25 July 2026 · 6 min read
A card payment fails, quietly, behind the scenes in Stripe. Without a follow-up, a share of those customers never come back to update their payment method: that's involuntary churn, revenue lost for reasons that have nothing to do with dissatisfaction — just an expired card or a maxed-out limit. n8n can listen to these Stripe events in real time and trigger an AI-personalized follow-up, instead of waiting for the next manual accounting export. This guide builds that workflow end to end: webhook, security, duplicate prevention, and automated drafting.
Why connect n8n to Stripe webhooks
Stripe exposes a real-time event stream for everything billing-related: successful payment, failed payment, cancelled subscription, overdue invoice. Instead of exporting a report every week and following up by hand, an n8n workflow triggered by webhook reacts within the minute after the failure — right when the customer still has the context fresh (they just tried to pay, a bank notification probably landed at the same time). It's the same principle already at work in the automatic follow-up workflow for incomplete cases in the Compliance & Audit Pack: detect an incomplete state, follow up at the right moment, log every send.
The Stripe Trigger node: which events to listen for
n8n ships a native Stripe Trigger node dedicated to listening for Stripe webhooks, without going through a generic Webhook node. For a payment follow-up use case, three events cover the essentials:
invoice.payment_failed: a charge attempt on an invoice (often a subscription) failed — the most common case, fired automatically on every Stripe retry.charge.failed: a one-off payment (single purchase, no subscription) failed.customer.subscription.deleted: the subscription was eventually cancelled after several consecutive failures — a signal that a gentle follow-up is already too late, and a different approach is needed (a win-back offer rather than a payment reminder).
In the node's configuration panel, your endpoint's Signature Secret must be filled in: Stripe issues a per-endpoint secret (whsec_...) that n8n uses to verify the request genuinely comes from Stripe rather than a third party that guessed the URL. It's the same principle as the HMAC verification detailed in our guide on securing n8n webhooks — never process a payment event without verifying its signature first.
Avoiding duplicates: Stripe retries its webhooks
If your n8n workflow takes more than a few seconds to respond, or a transient error occurs, Stripe retries delivery of the same event on an automatic schedule. Without protection, a customer then gets two or three identical follow-ups for the same payment incident — annoying at best, spam-like at worst. The fix is idempotency: every Stripe event carries a unique identifier (event.id) that you insert into a Supabase table with a UNIQUE constraint. If the insert fails because the identifier already exists, the workflow stops cleanly without sending a second email. The mechanics behind this — common to all webhooks, not just Stripe's — are covered in our guide on n8n webhook idempotency.
Drafting the follow-up with AI instead of a generic email
A generic follow-up email ("Your payment failed, please update your card") converts, but less well than a message that accounts for context: exact amount, product involved, customer history (first follow-up or third). This is where a Basic LLM Chain connected to Claude or GPT adds real value over a static template: the prompt receives the Stripe event's metadata (customer name, amount, product, number of attempts already made) and generates a short, factual message with no guilt-tripping tone, on the same principle as the AI email drafting workflows already used for other use cases. A Stripe link to update the payment method (invoice.hosted_invoice_url or a customer portal link) rounds out the message.
Concretely, the node chain looks like this:
- Stripe Trigger — listens for
invoice.payment_failed. - Check idempotency — Supabase, insert
event.idwith a uniqueness constraint; stop if duplicate. - Fetch customer history — Supabase, number of follow-ups already sent to this customer over the last 30 days (to avoid over-messaging).
- Generate the message — Basic LLM Chain, prompt with amount, product, number of attempts, tone adjusted to history.
- Send the email — Email or Gmail node, with the payment-method update link.
- Log it — Supabase, a full record of the follow-up (date, amount, status) for future reporting.
Log instead of following up blindly
Without logging, there's no way to know how many follow-ups a customer has already received, or to produce a monthly report on the recovery rate of failed payments. A dedicated Supabase table — with the Stripe customer ID, the amount, the follow-up date, and its status — covers both needs. Our n8n ↔ Supabase connection guide covers setting up this kind of table, and the principle connects directly to the GDPR audit trail: any automated communication sent to a customer should be traceable, if only to answer a later complaint.
For high-stakes payments (an annual subscription, a large B2B account), a parallel Slack alert alongside the automated email lets a human step in before a second automatic follow-up goes out — the same principle as human approval before a sensitive action already recommended for other workflows with direct commercial impact.
What the research says about follow-up effectiveness
The idea that a personalized follow-up converts better than a generic reminder isn't just marketing intuition. A study by Hallsworth, List, Metcalfe, and Vlaev published in 2017 in the Journal of Public Economics (see on Google Scholar) measured, across more than 200,000 UK taxpayers in default, the effect of reminder letters rewritten with social-norm messages instead of standard administrative text: the payment rate increased significantly with the personalized version. The context (taxes) differs from a SaaS invoice, but the behavioral mechanism — a reminder that speaks to the recipient rather than to an administrative category — carries over directly to a Stripe payment follow-up drafted on the fly by AI instead of a fixed template.
Best practices and limits
A few guardrails worth respecting before shipping this workflow to production:
- Cap the frequency: three follow-ups max over 10-15 days is a reasonable pace; beyond that, the risk of cancellation or complaint outweighs the conversion gain.
- Don't duplicate Stripe's Smart Retries: Stripe already automatically retries the charge on an optimized schedule (a native feature, enabled in the Dashboard). The n8n workflow handles communication, not the charge retry itself.
- Respect consent: these emails are transactional (tied to an ongoing contract), so generally outside the scope of marketing consent — but check your GDPR legal basis, in the same spirit as our guide on handling GDPR requests.
- Test with real Stripe events in test mode before going to production, via the
stripe trigger invoice.payment_failedStripe CLI command or by simulating the call as described in our guide on testing n8n webhooks locally.
Going further
This workflow illustrates a broader principle: wiring an LLM to a well-chosen business event turns a repetitive task (chasing unpaid invoices) into a process that runs on its own, with better conversion than a generic template. The Compliance & Audit Pack (€149) already ships the automatic follow-up pattern with Supabase logging — the same architecture, applied to incomplete cases rather than Stripe payments, ready to adapt. And for an AI that also handles triaging your incoming emails alongside these outgoing follow-ups, the Inbox AI Pack (€79) and the Complete FlowKit Bundle (€269) cover the rest of the chain.
FAQ
Frequently asked questions
Does the Stripe Trigger node need a publicly exposed server?
Yes, like any webhook: Stripe must be able to reach your n8n instance over HTTPS from the internet. On n8n Cloud, the URL is provided automatically. Self-hosted, you need a domain name with a valid certificate (see our guide on going HTTPS with Traefik or Caddy); to test locally before wiring up the real endpoint, a tunnel like ngrok is enough, exactly as for testing any n8n webhook locally.
How do you avoid following up twice for the same client if Stripe resends the event?
Stripe retries a webhook if your endpoint doesn't respond 200 quickly, so the same event can arrive more than once. The fix is the same as for any webhook: store the event's unique identifier (event.id) in a table with a uniqueness constraint, and silently skip any event already seen before triggering the follow-up.
Does this automation replace Stripe's Smart Retries?
No, it complements them. Stripe's Smart Retries automatically retry the card charge on an optimized schedule, on the payment side. The workflow described here handles communication: it notifies the customer, explains the situation, and gives them a link to update their payment method — something Stripe doesn't do natively beyond a generic email.
Bundle FlowKit Complet
€269