Stripe's built-in receipts are fine. But the moment you want to send a branded confirmation email, add an order summary, trigger a download link, or write to your own database — you're out of luck without code.
n8n fixes this cleanly. Here's the exact workflow I use to intercept every successful Stripe payment and fire a custom receipt, all with built-in nodes and zero paid integrations.
What the workflow does
- Stripe Trigger — payment_intent.succeeded — listens for confirmed payments in real time
- HTTP Request — fetch charge details — pulls the full charge object (customer email, amount, description, metadata) via the Stripe API
- Set — format receipt data — builds the receipt fields: formatted amount, item name, order ID, timestamp
- Gmail / Resend — send receipt email — fires a personalised receipt to the customer email from the charge
- Google Sheets — log order — appends a row to your orders sheet (timestamp, customer, amount, order ID, status)
- Error — notify on failure — if any node fails, logs to an error sheet and optionally sends you a Slack DM
The whole thing runs in under 2 seconds from payment confirmation to receipt in inbox.
Why not just use Stripe's built-in receipt?
Three reasons I switched:
- Branding — Stripe's receipt looks like Stripe's, not yours. Custom email = your logo, your tone, your support link.
- Download delivery — if you're selling digital products, you need to attach or link the file in the confirmation. Stripe can't do this natively.
- Your own records — the Sheets log gives you a single source of truth you own, outside Stripe's dashboard. Useful for refund tracking, VAT records, or feeding a CRM.
Setup steps
- Import the JSON — Workflows → Import from clipboard in n8n
-
Stripe credential — create a Restricted Key in Stripe dashboard with
charges:readandpayment_intents:readpermissions. Paste into n8n's Stripe credential. -
Webhook endpoint — copy the production webhook URL from the Stripe Trigger node. Add it in Stripe Dashboard → Developers → Webhooks → Add endpoint. Select
payment_intent.succeeded. -
Gmail or Resend credential — connect whichever you use. The email node is pre-wired to
{{customerEmail}}from the Set node. -
Google Sheets — point the Sheets node at a spreadsheet with columns:
timestamp,customer_email,amount,description,order_id,status - Activate — flip the workflow to Active. Every successful payment now triggers the full chain.
Total setup time: under 15 minutes the first time.
The thing most tutorials miss: idempotency
Stripe can fire the same webhook event more than once (retries on timeout, network blips). Without a deduplication check, one payment can generate two receipts and two log rows.
The workflow handles this: before appending to Sheets, it looks up the payment_intent_id in the log. If it already exists, it skips. One receipt per payment, guaranteed.
Get the JSON
Drop a comment below and I'll paste the full workflow JSON. Free to use, MIT-style — import it and adapt it to your setup.
I packaged this workflow alongside two others (Lead Capture → CRM, Form → Sheets + Slack) into a Workflow Starter Pack with full setup docs and test checklists for each. $29 one-time if you want the full set with docs.
What do you use for post-payment automation? Curious what setups others are running.
Top comments (2)
As promised — here's the Stripe workflow JSON. Import via Workflows → Import from clipboard in n8n. Swap YOUR_SHEET_ID and connect Stripe + Gmail credentials:
The full pack with deduplication + error logging pre-wired is at pirateprentice.gumroad.com/l/sxcoe if you want it ready to go.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.