This workflow corresponds to n8n.io template #8030 — we link there as the canonical source.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"nodes": [
{
"id": "3c9c65d5-e8ef-472b-994f-14d67bf92479",
"name": "Setup Instructions",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"width": 280,
"height": 200,
"content": "\ud83d\udcb0 **SETUP REQUIRED:**\n\n1. **Stripe Webhook:**\n - Go to Stripe Dashboard \u2192 Webhooks\n - Add endpoint with webhook URL below\n - Select event: payment_intent.succeeded\n\n2. **Gmail Setup:**\n - Connect Gmail OAuth in credentials\n - Emails sent from your Gmail account\n\n3. **Customize Invoice:**\n - Update company name in 'Generate Invoice HTML'\n - Modify invoice template as needed\n\n\ud83c\udfaf Invoices auto-generated as PDF attachments!"
},
"typeVersion": 1
},
{
"id": "9d2296bf-2617-4b8c-9d5b-ff87e3cf8360",
"name": "Stripe Payment Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
0,
224
],
"parameters": {
"path": "stripe-webhook",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 1
},
{
"id": "25314ce6-fbec-41b1-9328-2e075eb658a2",
"name": "Normalize Payment Data",
"type": "n8n-nodes-base.code",
"position": [
208,
224
],
"parameters": {
"jsCode": "// Normalize Stripe payment data\nconst event = $input.first().json;\nconst paymentIntent = event.data?.object || event;\n\n// Only proceed if this is a successful payment\nif (event.type !== 'payment_intent.succeeded' && event.type !== 'charge.succeeded') {\n console.log('Not a successful payment event, skipping...');\n return null;\n}\n\n// Extract payment and customer details\nconst normalizedData = {\n payment_id: paymentIntent.id,\n amount: paymentIntent.amount / 100, // Convert from cents\n currency: paymentIntent.currency?.toUpperCase() || 'USD',\n customer_email: paymentIntent.receipt_email || paymentIntent.billing_details?.email || '',\n customer_name: paymentIntent.billing_details?.name || 'Valued Customer',\n payment_date: new Date(paymentIntent.created * 1000).toISOString(),\n description: paymentIntent.description || 'Service Payment',\n invoice_number: `INV-${Date.now()}`,\n status: 'paid'\n};\n\n// Validate required fields\nif (!normalizedData.customer_email) {\n throw new Error('Customer email is required for invoice generation');\n}\n\nconsole.log('Normalized Payment Data:', normalizedData);\n\nreturn {\n json: normalizedData\n};"
},
"typeVersion": 2
},
{
"id": "8439384c-a885-4ad5-bc5d-e587b667fe61",
"name": "Generate Invoice HTML",
"type": "n8n-nodes-base.code",
"position": [
400,
224
],
"parameters": {
"jsCode": "// Generate HTML invoice content\nconst data = $input.first().json;\n\nconst invoiceHTML = `\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <style>\n body { font-family: Arial, sans-serif; margin: 40px; }\n .header { text-align: center; margin-bottom: 40px; }\n .invoice-details { margin: 30px 0; }\n .amount { font-size: 24px; font-weight: bold; color: #2E7D32; }\n table { width: 100%; border-collapse: collapse; margin: 20px 0; }\n th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }\n .footer { margin-top: 50px; text-align: center; color: #666; }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <h1>INVOICE</h1>\n <h2>Your Company Name</h2>\n </div>\n \n <div class=\"invoice-details\">\n <p><strong>Invoice #:</strong> ${data.invoice_number}</p>\n <p><strong>Date:</strong> ${new Date(data.payment_date).toLocaleDateString()}</p>\n <p><strong>Payment ID:</strong> ${data.payment_id}</p>\n </div>\n \n <div>\n <h3>Bill To:</h3>\n <p><strong>${data.customer_name}</strong></p>\n <p>${data.customer_email}</p>\n </div>\n \n <table>\n <thead>\n <tr>\n <th>Description</th>\n <th>Amount</th>\n <th>Status</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>${data.description}</td>\n <td class=\"amount\">${data.currency} ${data.amount.toFixed(2)}</td>\n <td style=\"color: green; font-weight: bold;\">PAID</td>\n </tr>\n </tbody>\n </table>\n \n <div class=\"footer\">\n <p>Thank you for your business!</p>\n <p>This invoice was automatically generated.</p>\n </div>\n</body>\n</html>\n`;\n\nreturn {\n json: {\n ...data,\n invoice_html: invoiceHTML,\n filename: `invoice_${data.invoice_number}.pdf`\n }\n};"
},
"typeVersion": 2
},
{
"id": "7cb20e9e-dec4-4c7b-9029-05f3ddd5ef0a",
"name": "Send Invoice Email",
"type": "n8n-nodes-base.gmail",
"position": [
608,
224
],
"parameters": {
"message": "Dear {{ $json.customer_name }},\\n\\nThank you for your payment! Please find your invoice attached.\\n\\nPayment Details:\\n- Amount: {{ $json.currency }} {{ $json.amount }}\\n- Payment ID: {{ $json.payment_id }}\\n- Date: {{ $json.payment_date }}\\n\\nBest regards,\\nYour Company Name",
"options": {
"attachmentsUi": {
"attachmentsBinary": [
{
"property": "invoice_pdf"
}
]
}
},
"subject": "Invoice {{ $json.invoice_number }} - Payment Confirmation"
},
"typeVersion": 2.1
}
],
"connections": {
"Generate Invoice HTML": {
"main": [
[
{
"node": "Send Invoice Email",
"type": "main",
"index": 0
}
]
]
},
"Normalize Payment Data": {
"main": [
[
{
"node": "Generate Invoice HTML",
"type": "main",
"index": 0
}
]
]
},
"Stripe Payment Webhook": {
"main": [
[
{
"node": "Normalize Payment Data",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically generates a PDF invoice every time a successful payment is received in Stripe, then emails the invoice to the customer via Gmail. Perfect for freelancers, SaaS businesses, and service providers who want to automate billing without manual effort.…
Source: https://n8n.io/workflows/8030/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
AP Invoice — 01 Orchestrator. Uses postgres, httpRequest, quickbooks, slack. Webhook trigger; 42 nodes.
How It Works Trigger: Watches for new emails in Gmail with PDF/image attachments. OCR: Sends the attachment to OCR.space API (https://ocr.space/OCRAPI) to extract invoice text. Parsing: Extracts key f
This workflow automates the entire process of receiving a product/service order, checking or creating a customer in QuickBooks Online (QBO), generating an invoice, and emailing it — all triggered by a
Tired of the standard, boring invoices from QuickBooks Online? This workflow completely automates the process of creating beautiful, custom-branded PDF invoices and emailing them directly to your clie
Automated QuickBooks Invoice to Custom PDF & Email