DEV Community

Pirate Prentice
Pirate Prentice

Posted on

How to auto-send Stripe payment receipts using n8n (no paid nodes, free workflow)

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

  1. Stripe Trigger — payment_intent.succeeded — listens for confirmed payments in real time
  2. HTTP Request — fetch charge details — pulls the full charge object (customer email, amount, description, metadata) via the Stripe API
  3. Set — format receipt data — builds the receipt fields: formatted amount, item name, order ID, timestamp
  4. Gmail / Resend — send receipt email — fires a personalised receipt to the customer email from the charge
  5. Google Sheets — log order — appends a row to your orders sheet (timestamp, customer, amount, order ID, status)
  6. 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

  1. Import the JSON — Workflows → Import from clipboard in n8n
  2. Stripe credential — create a Restricted Key in Stripe dashboard with charges:read and payment_intents:read permissions. Paste into n8n's Stripe credential.
  3. 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.
  4. Gmail or Resend credential — connect whichever you use. The email node is pre-wired to {{customerEmail}} from the Set node.
  5. Google Sheets — point the Sheets node at a spreadsheet with columns: timestamp, customer_email, amount, description, order_id, status
  6. 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)

Collapse
 
pirateprentice profile image
Pirate Prentice

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:

{
  "name": "Stripe Payment Receipt",
  "nodes": [
    {"parameters":{"events":["payment_intent.succeeded"]},"name":"Stripe Trigger","type":"n8n-nodes-base.stripeTrigger","position":[240,300]},
    {"parameters":{"url":"=https://api.stripe.com/v1/charges/{{$json.data.object.latest_charge}}","authentication":"genericCredentialType","genericAuthType":"httpHeaderAuth","options":{}},"name":"Fetch Charge","type":"n8n-nodes-base.httpRequest","position":[460,300]},
    {"parameters":{"values":{"string":[{"name":"customerEmail","value":"={{$json.billing_details.email}}"},{"name":"amount","value":"={{($json.amount/100).toFixed(2)}} {{$json.currency.toUpperCase()}}"},{"name":"orderId","value":"={{$json.payment_intent}}"},{"name":"timestamp","value":"={{new Date().toISOString()}}"}]}},"name":"Format Data","type":"n8n-nodes-base.set","position":[680,300]},
    {"parameters":{"fromEmail":"you@yourdomain.com","toEmail":"={{$json.customerEmail}}","subject":"Your receipt","text":"Thank you! Order {{$json.orderId}} for {{$json.amount}} confirmed."},"name":"Send Receipt","type":"n8n-nodes-base.gmail","position":[900,220]},
    {"parameters":{"operation":"append","sheetId":"YOUR_SHEET_ID","range":"Sheet1!A:E","valueInputMode":"USER_ENTERED","values":{"values":[["={{$json.timestamp}}","={{$json.customerEmail}}","={{$json.amount}}","={{$json.orderId}}","paid"]]}},"name":"Log Order","type":"n8n-nodes-base.googleSheets","position":[900,380]}
  ],
  "connections":{"Stripe Trigger":{"main":[[{"node":"Fetch Charge","type":"main","index":0}]]},"Fetch Charge":{"main":[[{"node":"Format Data","type":"main","index":0}]]},"Format Data":{"main":[[{"node":"Send Receipt","type":"main","index":0},{"node":"Log Order","type":"main","index":0}]]}}
}
Enter fullscreen mode Exit fullscreen mode

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.