This workflow corresponds to n8n.io template #17213 — we link there as the canonical source.
This workflow follows the Gmail → Google Sheets recipe pattern — see all workflows that pair these two integrations.
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 →
{
"id": "HuI9bILbe4M37b5n",
"meta": {
"builderVariant": "mcp",
"aiBuilderAssisted": true
},
"name": "Stripe Payment \u2192 AI-Personalized PDF with Human Approval",
"tags": [
{
"id": "ihTBspI245ExkFXz",
"name": "stripe",
"createdAt": "2026-07-16T04:49:38.936Z",
"updatedAt": "2026-07-16T04:49:38.936Z"
},
{
"id": "FpF0WUxxGoK09fhl",
"name": "openai",
"createdAt": "2025-06-07T04:12:57.942Z",
"updatedAt": "2025-06-07T04:12:57.942Z"
},
{
"id": "KwmRVM489bZhigLH",
"name": "content-generation",
"createdAt": "2025-12-23T11:08:46.824Z",
"updatedAt": "2025-12-23T11:08:46.824Z"
},
{
"id": "I1DNyYeKjF5IHwS9",
"name": "uw",
"createdAt": "2026-07-18T07:01:04.417Z",
"updatedAt": "2026-07-18T07:01:04.417Z"
}
],
"nodes": [
{
"id": "2bf56992-36a8-4642-9e31-611a120f1e14",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
2416
],
"parameters": {
"width": 480,
"height": 672,
"content": "## Stripe payment \u2192 personalised PDF (human-gated)\n\n### How it works\n\n1. Listens to Stripe payment notifications via webhook. \n2. Normalizes and processes data to gather customer information. \n3. Uses OpenAI's API to create personalized content for the customer. \n4. Converts created content to a PDF automatically. \n5. Handles data storage, review status updates, and necessary notifications.\n\n### Setup steps\n\n- [ ] Set up Stripe webhook URL\n- [ ] Configure Google Sheets access\n- [ ] Set up OpenAI API key and endpoint\n- [ ] Configure PDFShift API credentials\n- [ ] Set up Gmail access for sending emails\n- [ ] Integrate Slack for notification delivery\n\n### Customization\n\nAdjust API endpoints and credentials for different services as needed."
},
"typeVersion": 1
},
{
"id": "7928c203-e07b-40c5-82dc-6bf1fc1d1f06",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
944,
2352
],
"parameters": {
"color": 7,
"width": 704,
"height": 272,
"content": "## Stripe payment processing\n\nHandles the Stripe webhook and normalizes payload data."
},
"typeVersion": 1
},
{
"id": "3ef02372-631a-4515-b086-e717284dcaa1",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1728,
2272
],
"parameters": {
"color": 7,
"width": 960,
"height": 288,
"content": "## Order verification and personalization\n\nReads order details and personalizes content using OpenAI."
},
"typeVersion": 1
},
{
"id": "de185d5b-f6de-40e0-b723-2697f80d6b2a",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2768,
2144
],
"parameters": {
"color": 7,
"width": 448,
"height": 704,
"content": "## Convert to PDF and notifications\n\nConverts personalized content to PDF and sends emails/notifications."
},
"typeVersion": 1
},
{
"id": "a0b5617a-18bd-421d-b2bc-3550946c6357",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1728,
2576
],
"parameters": {
"color": 7,
"height": 304,
"content": "## Handle missing emails\n\nProcesses cases where customer email is missing."
},
"typeVersion": 1
},
{
"id": "ad0ea5de-51d2-48f0-a503-79b093d65380",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
944,
2816
],
"parameters": {
"color": 7,
"width": 704,
"height": 272,
"content": "## Approval process\n\nProcesses approval of content, sending final emails if approved."
},
"typeVersion": 1
},
{
"id": "b059f908-4aab-4d60-b3a5-3086dea2d08c",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1728,
2912
],
"parameters": {
"color": 7,
"width": 448,
"height": 496,
"content": "## Final PDF delivery\n\nHandles final email delivery of PDFs if approved."
},
"typeVersion": 1
},
{
"id": "0fedae72-5c29-48da-ac98-99a7d691399e",
"name": "Stripe Payment Trigger",
"type": "n8n-nodes-base.webhook",
"position": [
992,
2464
],
"parameters": {
"path": "upwork-stripe-pdf-order",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "2d9555d2-9261-41a7-9960-9204e07cca80",
"name": "Set Payment Details",
"type": "n8n-nodes-base.set",
"position": [
1248,
2464
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "e1",
"name": "stripe_event",
"type": "string",
"value": "={{ $json.body?.type ?? $json.type ?? \"\" }}"
},
{
"id": "e2",
"name": "payment_id",
"type": "string",
"value": "={{ $json.body?.data?.object?.id ?? $json.data?.object?.id ?? $json.id ?? \"\" }}"
},
{
"id": "e3",
"name": "email",
"type": "string",
"value": "={{ ($json.body?.data?.object?.customer_email ?? $json.data?.object?.customer_email ?? $json.customer_email ?? \"\").toLowerCase() }}"
},
{
"id": "e4",
"name": "amount",
"type": "number",
"value": "={{ $json.body?.data?.object?.amount_total ?? $json.data?.object?.amount_total ?? 0 }}"
},
{
"id": "e5",
"name": "currency",
"type": "string",
"value": "={{ $json.body?.data?.object?.currency ?? $json.data?.object?.currency ?? \"usd\" }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "e6337c70-23b4-4b9b-a872-a5150f147945",
"name": "Check Customer Email",
"type": "n8n-nodes-base.if",
"position": [
1504,
2464
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "c1",
"operator": {
"type": "string",
"operation": "notEmpty"
},
"leftValue": "={{ $json.email }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "ce82fad5-fc04-428e-a92a-0eef3526d199",
"name": "Fetch Orders from Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
1776,
2384
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Z03sKhTK3ngMdlMIvg6paTIZQGf4vAm52nBZRSZpphU/edit#gid=0",
"cachedResultName": "Orders"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1Z03sKhTK3ngMdlMIvg6paTIZQGf4vAm52nBZRSZpphU",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Z03sKhTK3ngMdlMIvg6paTIZQGf4vAm52nBZRSZpphU/edit?usp=drivesdk",
"cachedResultName": "PDF Orders"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "9a352ec3-69c3-47b6-835e-1951cdb99a58",
"name": "Find Order by Email",
"type": "n8n-nodes-base.code",
"position": [
2032,
2384
],
"parameters": {
"jsCode": "const payment = $('Set Payment Details').first().json;\nconst rows = $input.all().map(i => i.json);\nconst email = String(payment.email || '').toLowerCase();\nconst order = rows.find(r => String(r.email || '').toLowerCase() === email) || {};\nreturn [{ json: { ...payment, order, full_name: order.full_name || order.name || '', product: order.product || '', form_answers: order.form_answers || JSON.stringify(order) } }];"
},
"typeVersion": 2
},
{
"id": "7f38e15f-991d-4b21-b319-fa628442e60e",
"name": "Post to OpenAI API",
"type": "n8n-nodes-base.httpRequest",
"position": [
2288,
2384
],
"parameters": {
"url": "https://api.openai.com/v1/chat/completions",
"method": "POST",
"options": {},
"jsonBody": "={{ JSON.stringify({ model: \"gpt-4o-mini\", temperature: 0.4, response_format: { type: \"json_object\" }, messages: [ { role: \"system\", content: \"You generate personalised PDF content. Return strict JSON with keys: title, body_html, summary.\" }, { role: \"user\", content: \"Customer: \" + JSON.stringify($json) } ] }) }}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "openAiApi"
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "c004cbf0-f39e-477e-a95b-b0ea4a719738",
"name": "Render AI Content as HTML",
"type": "n8n-nodes-base.code",
"position": [
2544,
2384
],
"parameters": {
"jsCode": "const ai = $input.first().json;\nconst base = $('Find Order by Email').first().json;\nconst text = ai.choices?.[0]?.message?.content || '{}';\nlet content;\ntry { content = JSON.parse(text); } catch (e) {\n const m = text.match(/\\{[\\s\\S]*\\}/);\n content = m ? JSON.parse(m[0]) : { title: 'Document', body_html: text, summary: '' };\n}\nconst title = content.title || 'Your personalised document';\nconst body = content.body_html || content.body || '';\nconst html = '<!doctype html><html><head><meta charset=\"utf-8\"><title>' + title + '</title></head><body><h1>' + title + '</h1>' + body + '<hr/><p>Payment: ' + (base.payment_id||'') + ' \u00b7 ' + (base.email||'') + '</p></body></html>';\nreturn [{ json: {\n ...base,\n ai_title: title,\n ai_summary: content.summary || '',\n html,\n hitl_status: 'pending_review',\n tag: 'upwork',\n}}];"
},
"typeVersion": 2
},
{
"id": "7f4d41de-1543-4318-96fa-a168ea06de62",
"name": "Convert HTML to PDF",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
2816,
2384
],
"parameters": {
"url": "https://api.pdfshift.io/v3/convert/pdf",
"method": "POST",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
},
"jsonBody": "={{ JSON.stringify({ source: $json.html, sandbox: true }) }}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth"
},
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "c4e25687-56dd-43f0-aa40-7f37e85c0637",
"name": "Send Acknowledgement Email",
"type": "n8n-nodes-base.gmail",
"onError": "continueRegularOutput",
"position": [
3072,
2272
],
"parameters": {
"sendTo": "={{ $('Render AI Content as HTML').item.json.email }}",
"message": "={{ \"Thanks! Your personalised document for payment \" + $('Render AI Content as HTML').item.json.payment_id + \" is being prepared. You will receive it after a quick human review.\" }}",
"options": {},
"subject": "We received your order \u2014 review in progress",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "34c03c60-1c3c-4c1e-b110-b5f0847e18eb",
"name": "Set Email Missing Status",
"type": "n8n-nodes-base.set",
"position": [
1776,
2704
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "s1",
"name": "status",
"type": "string",
"value": "skipped_no_email"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "955a4520-ca2e-4e25-81f9-b53f4b652a26",
"name": "Add to Review Queue",
"type": "n8n-nodes-base.googleSheets",
"position": [
3072,
2464
],
"parameters": {
"columns": {
"value": {
"email": "={{ $('Render AI Content as HTML').item.json.email }}",
"status": "pending_review",
"ai_title": "={{ $('Render AI Content as HTML').item.json.ai_title }}",
"created_at": "={{ $now.toISO() }}",
"payment_id": "={{ $('Render AI Content as HTML').item.json.payment_id }}"
},
"schema": [
{
"id": "payment_id",
"type": "string",
"display": true,
"required": false,
"displayName": "payment_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "email",
"type": "string",
"display": true,
"required": false,
"displayName": "email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "ai_title",
"type": "string",
"display": true,
"required": false,
"displayName": "ai_title",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "created_at",
"type": "string",
"display": true,
"required": false,
"displayName": "created_at",
"defaultMatch": false,
"canBeUsedToMatch": false
}
],
"mappingMode": "defineBelow"
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "ReviewQueue"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1Z03sKhTK3ngMdlMIvg6paTIZQGf4vAm52nBZRSZpphU",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Z03sKhTK3ngMdlMIvg6paTIZQGf4vAm52nBZRSZpphU/edit?usp=drivesdk",
"cachedResultName": "PDF Orders"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "7be224d1-782d-4aab-911b-ded4ee68a26a",
"name": "Notify Staff via Slack",
"type": "n8n-nodes-base.slack",
"onError": "continueRegularOutput",
"position": [
3072,
2672
],
"parameters": {
"text": "={{ \"PDF HITL review needed for \" + $('Render AI Content as HTML').item.json.email + \" / \" + $('Render AI Content as HTML').item.json.payment_id + \". Approve via webhook path pdf-approve.\" }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "name",
"value": "#general",
"cachedResultName": "general"
},
"otherOptions": {
"includeLinkToWorkflow": true
},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "25ddeae7-050f-4243-b6e1-ce63a5b586fa",
"name": "Final Approval Trigger",
"type": "n8n-nodes-base.webhook",
"position": [
992,
2928
],
"parameters": {
"path": "upwork-pdf-approve",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "f4353721-4fd6-40b8-98d7-e62582ca3e92",
"name": "Set Approval Payload",
"type": "n8n-nodes-base.set",
"position": [
1248,
2928
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a1",
"name": "payment_id",
"type": "string",
"value": "={{ $json.body?.payment_id ?? $json.payment_id ?? \"\" }}"
},
{
"id": "a2",
"name": "approved",
"type": "boolean",
"value": "={{ $json.body?.approved ?? $json.approved ?? false }}"
},
{
"id": "a3",
"name": "email",
"type": "string",
"value": "={{ $json.body?.email ?? $json.email ?? \"\" }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "565bdcfa-c393-43f0-9d07-d56c75bf9168",
"name": "Check Approval Status",
"type": "n8n-nodes-base.if",
"position": [
1504,
2928
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "ap1",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.approved }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.2
},
{
"id": "d6291cfc-4557-409c-9585-ebbf86ab0902",
"name": "Email Final PDF to Customer",
"type": "n8n-nodes-base.gmail",
"position": [
1776,
3024
],
"parameters": {
"sendTo": "={{ $json.email }}",
"message": "={{ \"Approved document for payment \" + $json.payment_id + \". Attach PDF from storage/Drive in production.\" }}",
"options": {},
"subject": "Your personalised document",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "8a2a064d-1eeb-4512-90e4-2d2bf3772305",
"name": "Update Review Status in Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
2032,
3024
],
"parameters": {
"columns": {
"value": {
"email": "={{ $('Set Approval Payload').item.json.email }}",
"status": "sent",
"sent_at": "={{ $now.toISO() }}",
"payment_id": "={{ $('Set Approval Payload').item.json.payment_id }}"
},
"schema": [
{
"id": "payment_id",
"type": "string",
"display": true,
"required": false,
"displayName": "payment_id",
"defaultMatch": true,
"canBeUsedToMatch": true
},
{
"id": "email",
"type": "string",
"display": true,
"required": false,
"displayName": "email",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "status",
"type": "string",
"display": true,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": false
},
{
"id": "sent_at",
"type": "string",
"display": true,
"required": false,
"displayName": "sent_at",
"defaultMatch": false,
"canBeUsedToMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"payment_id"
]
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "ReviewQueue"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1Z03sKhTK3ngMdlMIvg6paTIZQGf4vAm52nBZRSZpphU",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Z03sKhTK3ngMdlMIvg6paTIZQGf4vAm52nBZRSZpphU/edit?usp=drivesdk",
"cachedResultName": "PDF Orders"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "45e18232-3099-4c6e-9e16-056d1c2da05e",
"name": "Set Not Approved Status",
"type": "n8n-nodes-base.set",
"position": [
1776,
3248
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "r1",
"name": "status",
"type": "string",
"value": "not_approved"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": true,
"executionOrder": "v1"
},
"versionId": "a20615e3-c67e-4146-97d8-66fc3b6a1567",
"nodeGroups": [],
"connections": {
"Post to OpenAI API": {
"main": [
[
{
"node": "Render AI Content as HTML",
"type": "main",
"index": 0
}
]
]
},
"Convert HTML to PDF": {
"main": [
[
{
"node": "Send Acknowledgement Email",
"type": "main",
"index": 0
},
{
"node": "Add to Review Queue",
"type": "main",
"index": 0
},
{
"node": "Notify Staff via Slack",
"type": "main",
"index": 0
}
]
]
},
"Find Order by Email": {
"main": [
[
{
"node": "Post to OpenAI API",
"type": "main",
"index": 0
}
]
]
},
"Set Payment Details": {
"main": [
[
{
"node": "Check Customer Email",
"type": "main",
"index": 0
}
]
]
},
"Check Customer Email": {
"main": [
[
{
"node": "Fetch Orders from Sheets",
"type": "main",
"index": 0
}
],
[
{
"node": "Set Email Missing Status",
"type": "main",
"index": 0
}
]
]
},
"Set Approval Payload": {
"main": [
[
{
"node": "Check Approval Status",
"type": "main",
"index": 0
}
]
]
},
"Check Approval Status": {
"main": [
[
{
"node": "Email Final PDF to Customer",
"type": "main",
"index": 0
}
],
[
{
"node": "Set Not Approved Status",
"type": "main",
"index": 0
}
]
]
},
"Final Approval Trigger": {
"main": [
[
{
"node": "Set Approval Payload",
"type": "main",
"index": 0
}
]
]
},
"Stripe Payment Trigger": {
"main": [
[
{
"node": "Set Payment Details",
"type": "main",
"index": 0
}
]
]
},
"Fetch Orders from Sheets": {
"main": [
[
{
"node": "Find Order by Email",
"type": "main",
"index": 0
}
]
]
},
"Render AI Content as HTML": {
"main": [
[
{
"node": "Convert HTML to PDF",
"type": "main",
"index": 0
}
]
]
},
"Email Final PDF to Customer": {
"main": [
[
{
"node": "Update Review Status in Sheets",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleSheetsOAuth2ApihttpBasicAuthopenAiApislackOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow receives Stripe payment webhooks, looks up the customer’s order in Google Sheets, generates personalized HTML content with OpenAI, converts it to a PDF using PDFShift, then queues the request for human approval and delivers the final document via Gmail with Slack…
Source: https://n8n.io/workflows/17213/ — 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.
This workflow automates HR onboarding by capturing new hires via a webhook, saving them to Google Sheets, emailing a Slack invite via Gmail, and notifying managers in Slack, then listening for Slack t
Who is this for? This template is ideal for event organizers, conference managers, and community teams who need an automated participant management system. Perfect for workshops, conferences, meetups,
Streamline and standardize your entire client onboarding process with a single end-to-end automation. 🚀📋 This workflow captures detailed client intake data via webhook, automatically creates a fully s
Human Approval AI Response. Uses httpRequest, slack, gmail, googleSheets. Webhook trigger; 20 nodes.
This workflow receives an HR offboarding webhook, validates and enriches the employee record, suspends the user in Google Workspace, deactivates the user in Slack, looks up the matching HubSpot contac