This workflow corresponds to n8n.io template #13693 — we link there as the canonical source.
This workflow follows the Google Sheets → HTTP Request 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "94414a4d-4c70-41f0-9e3c-0f6b572c4545",
"name": "\ud83d\udccb Flow Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
48,
-528
],
"parameters": {
"width": 620,
"height": 392,
"content": "## \ud83d\udcda WhatsApp Course Enrollment & Payment Automation\n\n**How it works:**\n1. Student sends *courses* on WhatsApp \u2192 gets a list of available courses\n2. Student sends *enroll <course code>* \u2192 gets course details + payment link (Razorpay/Stripe)\n3. Student sends *pay <course code>* \u2192 payment link is generated and sent\n5. Student sends *mystatus* \u2192 sees their enrollment history\n\n**Credentials needed:** WATI, OpenAI API Key (Header Auth), Google Sheets OAuth2, Razorpay (HTTP Request \u2014 easy REST API, no SDK needed)"
},
"typeVersion": 1
},
{
"id": "4e437211-1ecc-4e32-8190-df06305684c3",
"name": "Sticky \u2013 Trigger & Route",
"type": "n8n-nodes-base.stickyNote",
"position": [
672,
80
],
"parameters": {
"color": 7,
"width": 412,
"height": 530,
"content": "### 1\ufe0f\u20e3 Trigger & Route\n**WATI Trigger** listens for all incoming WhatsApp messages.\n**Route Message Switch** checks the keyword:\n- `courses` \u2192 show course catalogue\n- `enroll <code>` \u2192 show course details + payment CTA\n- `pay <code>` \u2192 generate Razorpay payment link\n- `mystatus` \u2192 show enrollment history\n- anything else \u2192 help message"
},
"typeVersion": 1
},
{
"id": "3050e692-5b05-4692-95b9-587007819210",
"name": "Sticky \u2013 Catalogue & Enroll",
"type": "n8n-nodes-base.stickyNote",
"position": [
1184,
-208
],
"parameters": {
"color": 7,
"width": 880,
"height": 498,
"content": "### 2\ufe0f\u20e3 Course Catalogue & Enroll Intent\n**Google Sheets \u2013 Read Courses** fetches the master course list.\n**Build Catalogue Code** formats all courses into a WhatsApp-friendly list with codes, prices and duration.\n**Enroll Intent Code** parses the course code from the message, fetches course details and sends a summary with a payment CTA button."
},
"typeVersion": 1
},
{
"id": "76a3dbf3-a38a-473c-9888-979374e5e678",
"name": "Sticky \u2013 Payment",
"type": "n8n-nodes-base.stickyNote",
"position": [
1184,
320
],
"parameters": {
"color": 7,
"width": 1120,
"height": 354,
"content": "### 3\ufe0f\u20e3 Payment Link Generation\n**Parse Pay Code** extracts course code + student phone from the message.\n**Sheets \u2013 Read Course** fetches price and course name for the code.\n**Razorpay \u2013 Create Payment Link** calls Razorpay REST API to generate a unique short payment URL.\n**Sheets \u2013 Log Pending** saves a pending enrollment row.\n**WATI \u2013 Send Payment Link** sends the unique URL to the student."
},
"typeVersion": 1
},
{
"id": "02da57a8-6c42-4bc8-be49-def53ed7050a",
"name": "Sticky \u2013 Status",
"type": "n8n-nodes-base.stickyNote",
"position": [
1184,
704
],
"parameters": {
"color": 7,
"width": 628,
"height": 308,
"content": "### 5\ufe0f\u20e3 Enrollment Status\n**Sheets \u2013 Read Enrollments** fetches all rows for this student's phone.\n**Build Status Code** formats a clean history: course name, status, date and expiry.\n**WATI \u2013 Send Status** replies with the formatted enrollment card."
},
"typeVersion": 1
},
{
"id": "48e98355-d800-491c-857e-e1ddf8417c5d",
"name": "Route Message",
"type": "n8n-nodes-base.switch",
"position": [
928,
320
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Browse Courses",
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.text.toLowerCase().trim() }}",
"rightValue": "courses"
}
]
},
"renameOutput": true
},
{
"outputKey": "Enroll Intent",
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "startsWith"
},
"leftValue": "={{ $json.text }}",
"rightValue": "enroll "
}
]
},
"renameOutput": true
},
{
"outputKey": "Pay",
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "startsWith"
},
"leftValue": "={{ $json.text }}",
"rightValue": "pay "
}
]
},
"renameOutput": true
},
{
"outputKey": "My Status",
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.text.toLowerCase().trim() }}",
"rightValue": "mystatus"
}
]
},
"renameOutput": true
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"typeVersion": 3
},
{
"id": "73dc20f1-add7-4078-a090-1c50bb96f2ae",
"name": "Google Sheets \u2013 Read Courses",
"type": "n8n-nodes-base.googleSheets",
"position": [
1232,
-48
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk/edit#gid=0",
"cachedResultName": "Courses"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk/edit?usp=drivesdk",
"cachedResultName": "Wati - course"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "f506aaa9-d18e-40dc-8edd-d5d66c1bae1f",
"name": "Build Course Catalogue",
"type": "n8n-nodes-base.code",
"position": [
1440,
-48
],
"parameters": {
"jsCode": "// Build Course Catalogue Message\n// Reads all courses from Sheets and formats into WhatsApp message\n\nconst rows = $input.all();\nconst phone = $('Wati Trigger').first().json.waId|| $('WATI Trigger').item.json.from;\nconst senderName = $('Wati Trigger').first().json.senderName|| 'there';\n\nif (!rows || rows.length === 0) {\n return [{ json: {\n phone,\n catalogueMessage: '\ud83d\udcda No courses available right now. Please check back later!'\n }}];\n}\n\n// Group courses by category\nconst categories = {};\nfor (const row of rows) {\n const cat = row.json.category || 'General';\n if (!categories[cat]) categories[cat] = [];\n categories[cat].push(row.json);\n}\n\nconst lines = [\n `\ud83d\udc4b Hi *${senderName}!*`,\n `\ud83d\udcda *Available Courses*`,\n ''\n];\n\nfor (const [cat, courses] of Object.entries(categories)) {\n lines.push(`\u2501\u2501 *${cat.toUpperCase()}* \u2501\u2501`);\n for (const c of courses) {\n const price = c.price ? `\u20b9${parseFloat(c.price).toLocaleString('en-IN')}` : 'Free';\n const duration = c.duration || 'N/A';\n lines.push(`\ud83d\udccc *${c.name}*`);\n lines.push(` Code: \\`${c.code}\\` | ${price} | ${duration}`);\n lines.push(` ${c.shortDesc || ''}`);\n lines.push('');\n }\n}\n\nlines.push('\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501');\nlines.push('To enroll in a course, send:');\nlines.push('*enroll <code>*');\nlines.push('Example: *enroll PY101*');\n\nreturn [{ json: { phone, catalogueMessage: lines.join('\\n') } }];"
},
"typeVersion": 2
},
{
"id": "dedf0307-9c54-4437-be7f-06ba1700a5a0",
"name": "Parse Enroll Intent",
"type": "n8n-nodes-base.code",
"position": [
1232,
128
],
"parameters": {
"jsCode": "// Parse Enroll Intent\n// Input: 'enroll PY101'\n// Fetches course details and builds a detail card with payment CTA\n\nconst text = ($json.text || '').trim();\nconst phone = $json.waId || $json.from || 'unknown';\nconst senderName = $json.senderName || 'Student';\n\nconst courseCode = text.replace(/^enroll\\s+/i, '').trim().toUpperCase();\n\nif (!courseCode) {\n return { json: {\n phone,\n enrollMessage: '\u26a0\ufe0f Please provide a course code.\\nExample: *enroll PY101*'\n }};\n}\n\nreturn { json: { phone, senderName, courseCode } };"
},
"typeVersion": 2
},
{
"id": "4c0b1737-658d-42e4-9209-9d1069aff2ec",
"name": "Google Sheets \u2013 Read Course Detail",
"type": "n8n-nodes-base.googleSheets",
"position": [
1440,
128
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk/edit#gid=0",
"cachedResultName": "Courses"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk/edit?usp=drivesdk",
"cachedResultName": "Wati - course"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "ee05fc85-e4bc-4e61-aa52-4a2e0277622a",
"name": "Build Enroll Detail Card",
"type": "n8n-nodes-base.code",
"position": [
1664,
128
],
"parameters": {
"jsCode": "// Build Enrollment Detail Card\n// Shows full course info and payment CTA\n\nconst phone = $('Parse Enroll Intent').item.json.phone;\nconst senderName = $('Parse Enroll Intent').item.json.senderName;\nconst courseCode = $('Parse Enroll Intent').item.json.courseCode;\n\nconst allRows = $input.all();\nconst course = allRows.find(r => (r.json.code || '').toUpperCase() === courseCode);\n\nif (!course) {\n return [{ json: {\n phone,\n enrollMessage: `\u274c *Course not found: ${courseCode}*\\n\\nSend *courses* to see all available courses.`\n }}];\n}\n\nconst c = course.json;\nconst price = c.price ? `\u20b9${parseFloat(c.price).toLocaleString('en-IN')}` : 'Free';\n\nconst lines = [\n `\ud83d\udcd8 *${c.name}*`,\n `\ud83c\udff7\ufe0f Code: ${c.code}`,\n '',\n `\ud83d\udcdd *Description:*`,\n c.description || c.shortDesc || 'No description available.',\n '',\n `\u23f1\ufe0f *Duration:* ${c.duration || 'N/A'}`,\n `\ud83d\udc68\u200d\ud83c\udfeb *Instructor:* ${c.instructor || 'TBA'}`,\n `\ud83d\udcc5 *Starts:* ${c.startDate || 'Rolling Admission'}`,\n `\ud83d\udcb0 *Price:* ${price}`,\n '',\n '\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501',\n `\u2705 To proceed with payment, send:`,\n `*pay ${c.code}*`\n];\n\nreturn [{ json: { phone, enrollMessage: lines.join('\\n'), courseCode } }];"
},
"typeVersion": 2
},
{
"id": "371b0662-841a-4e8b-b69d-1936d037156a",
"name": "Parse Pay Command",
"type": "n8n-nodes-base.code",
"position": [
1216,
480
],
"parameters": {
"jsCode": "// Parse Pay Command\n// Input: 'pay PY101'\nconst text = ($json.text || '').trim();\nconst phone = $json.waId || $json.from || 'unknown';\nconst senderName = $json.senderName || 'Student';\nconst courseCode = text.replace(/^pay\\s+/i, '').trim().toUpperCase();\n\nif (!courseCode) {\n return { json: { phone, error: 'No course code. Send: pay <code>' } };\n}\n\nreturn { json: { phone, senderName, courseCode } };"
},
"typeVersion": 2
},
{
"id": "ba5690e8-9a85-4dee-87c0-41192cab98da",
"name": "Google Sheets \u2013 Read Course for Payment",
"type": "n8n-nodes-base.googleSheets",
"position": [
1392,
480
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk/edit#gid=0",
"cachedResultName": "Courses"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk/edit?usp=drivesdk",
"cachedResultName": "Wati - course"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "04b50ab2-7254-48ca-9807-aae59f265519",
"name": "Prepare Razorpay Payload",
"type": "n8n-nodes-base.code",
"position": [
1568,
480
],
"parameters": {
"jsCode": "// Prepare Razorpay Payment Link Request\n// Finds the course and builds the payload for Razorpay API\n\nconst phone = $('Parse Pay Command').item.json.phone;\nconst senderName = $('Parse Pay Command').item.json.senderName;\nconst courseCode = $('Parse Pay Command').item.json.courseCode;\n\nconst allRows = $input.all();\nconst course = allRows.find(r => (r.json.code || '').toUpperCase() === courseCode);\n\nif (!course) {\n return [{ json: {\n phone, courseCode,\n paymentError: `\u274c Course *${courseCode}* not found. Send *courses* to see the list.`\n }}];\n}\n\nconst c = course.json;\nconst amountPaise = Math.round(parseFloat(c.price || 0) * 100); // Razorpay uses paise\n\n// Razorpay Payment Link API payload\nconst razorpayPayload = {\n amount: amountPaise,\n currency: 'INR',\n accept_partial: false,\n description: `Enrollment: ${c.name} (${courseCode})`,\n customer: {\n name: senderName,\n contact: `+${phone}`\n },\n notify: { sms: false, email: false },\n reminder_enable: false,\n notes: {\n courseCode: courseCode,\n phone: phone,\n courseName: c.name\n },\n callback_url: 'https://YOUR_N8N_INSTANCE/webhook/razorpay-payment-confirm',\n callback_method: 'get'\n};\n\nreturn [{ json: {\n phone, senderName, courseCode,\n courseName: c.name,\n price: c.price,\n razorpayPayload\n}}];"
},
"typeVersion": 2
},
{
"id": "2978187b-5374-429e-be9b-144cd5aab500",
"name": "Razorpay \u2013 Create Payment Link",
"type": "n8n-nodes-base.httpRequest",
"position": [
1744,
480
],
"parameters": {
"url": "https://api.razorpay.com/v1/payment_links",
"method": "POST",
"options": {},
"jsonBody": "={{ JSON.stringify($('Prepare Razorpay Payload').item.json.razorpayPayload) }}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth"
},
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "2703d441-b8c1-4c2c-b961-89759aa7662b",
"name": "Google Sheets \u2013 Log Pending Enrollment",
"type": "n8n-nodes-base.googleSheets",
"position": [
1920,
480
],
"parameters": {
"columns": {
"value": {
"phone": "={{ $('Prepare Razorpay Payload').item.json.phone }}",
"amount": "={{ $('Prepare Razorpay Payload').item.json.price }}",
"status": "Pending",
"timestamp": "={{ new Date().toISOString() }}",
"courseCode": "={{ $('Prepare Razorpay Payload').item.json.courseCode }}",
"courseName": "={{ $('Prepare Razorpay Payload').item.json.courseName }}"
},
"schema": [
{
"id": "timestamp",
"type": "string",
"display": true,
"required": false,
"displayName": "timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "phone",
"type": "string",
"display": true,
"required": false,
"displayName": "phone",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "sendername",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "sendername",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "courseCode",
"type": "string",
"display": true,
"required": false,
"displayName": "courseCode",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "courseName",
"type": "string",
"display": true,
"required": false,
"displayName": "courseName",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "amount",
"type": "string",
"display": true,
"required": false,
"displayName": "amount",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "paymentlinkId",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "paymentlinkId",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "paymentlinkUrl",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "paymentlinkUrl",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1298930809,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk/edit#gid=1298930809",
"cachedResultName": "Enrollments"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk/edit?usp=drivesdk",
"cachedResultName": "Wati - course"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "05c70fca-fc54-4f64-843d-2963af2ce12e",
"name": "Google Sheets \u2013 Read Enrollments",
"type": "n8n-nodes-base.googleSheets",
"position": [
1216,
816
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1298930809,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk/edit#gid=1298930809",
"cachedResultName": "Enrollments"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1exDoOoCBRKLcz_O1kS5hJRVDsAIhhJo6hRsFRJuDpKk/edit?usp=drivesdk",
"cachedResultName": "Wati - course"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "cefc9436-56a5-42e1-8a42-94cbb2d08610",
"name": "Build Enrollment Status",
"type": "n8n-nodes-base.code",
"position": [
1408,
816
],
"parameters": {
"jsCode": "// Build Enrollment Status Message\n// Shows all enrolled and pending courses for this student\n\nconst phone = $('Wati Trigger').first().json.waId|| $('WATI Trigger').item.json.from;\nconst senderName = $('Wati Trigger').first().json.senderName || 'Student';\nconst allRows = $input.all();\n\nconst myRows = allRows.filter(r => r.json.phone === phone);\n\nif (myRows.length === 0) {\n return [{ json: {\n phone,\n statusMessage: `\ud83d\udccb *No enrollments found, ${senderName}!*\\n\\nSend *courses* to browse available courses.\\nSend *enroll <code>* to get started!`\n }}];\n}\n\nconst enrolled = myRows.filter(r => r.json.status === 'Enrolled');\nconst pending = myRows.filter(r => r.json.status === 'Pending');\n\nconst lines = [\n `\ud83d\udccb *My Enrollments*`,\n `\ud83d\udc64 *${senderName}*`,\n ''\n];\n\nif (enrolled.length > 0) {\n lines.push(`\u2705 *Active Enrollments (${enrolled.length})*`);\n for (const r of enrolled) {\n const date = r.json.timestamp ? new Date(r.json.timestamp).toLocaleDateString('en-IN') : 'N/A';\n lines.push(` \ud83d\udcd8 *${r.json.courseName || r.json.courseCode}*`);\n lines.push(` Code: ${r.json.courseCode} | Enrolled: ${date}`);\n lines.push(` Payment ID: ${r.json.paymentId || 'N/A'}`);\n lines.push('');\n }\n}\n\nif (pending.length > 0) {\n lines.push(`\u23f3 *Pending Payments (${pending.length})*`);\n for (const r of pending) {\n lines.push(` \ud83d\udcd9 *${r.json.courseName || r.json.courseCode}*`);\n lines.push(` Code: ${r.json.courseCode} | Amount: \u20b9${r.json.amount}`);\n lines.push(` Send *pay ${r.json.courseCode}* to complete payment`);\n lines.push('');\n }\n}\n\nlines.push('\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501');\nlines.push('Send *courses* to explore more courses! \ud83d\udcda');\n\nreturn [{ json: { phone, statusMessage: lines.join('\\n') } }];"
},
"typeVersion": 2
},
{
"id": "2207fe23-d8f7-4be6-a8a0-a0e2af757db1",
"name": "Send a text message",
"type": "n8n-nodes-wati.wati",
"position": [
1680,
-48
],
"parameters": {
"target": "={{ $('Wati Trigger').item.json.waId }}",
"messageText": "={{ $json.catalogueMessage }}"
},
"credentials": {
"watiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "5d28bb5a-cd67-4bfd-bc44-e40d8d28b049",
"name": "Send a text message1",
"type": "n8n-nodes-wati.wati",
"position": [
1872,
128
],
"parameters": {
"target": "={{ $('Wati Trigger').item.json.waId }}",
"messageText": "={{ $json.enrollMessage }}"
},
"credentials": {
"watiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "1923700f-aded-41ac-9577-316b060661ca",
"name": "Send a text message2",
"type": "n8n-nodes-wati.wati",
"position": [
2112,
480
],
"parameters": {
"target": "={{ $('Wati Trigger').item.json.waId }}",
"messageText": "={{ $('Razorpay \u2013 Create Payment Link').item.json.short_url }} Kindly pay to this url"
},
"credentials": {
"watiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "9f93ad64-fa9c-4fa3-a2c1-85982a058bd1",
"name": "Send a text message3",
"type": "n8n-nodes-wati.wati",
"position": [
1616,
816
],
"parameters": {
"target": "={{ $('Wati Trigger').item.json.waId }}",
"messageText": "={{ $json.statusMessage }}"
},
"credentials": {
"watiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "597bb20e-c39e-4c2e-a8e8-ada8b96bf3b8",
"name": "Wati Trigger",
"type": "n8n-nodes-wati.watiTrigger",
"position": [
720,
368
],
"parameters": {
"event": "messageReceived"
},
"credentials": {
"watiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1,
"alwaysOutputData": true
}
],
"connections": {
"Wati Trigger": {
"main": [
[
{
"node": "Route Message",
"type": "main",
"index": 0
}
]
]
},
"Route Message": {
"main": [
[
{
"node": "Google Sheets \u2013 Read Courses",
"type": "main",
"index": 0
}
],
[
{
"node": "Parse Enroll Intent",
"type": "main",
"index": 0
}
],
[
{
"node": "Parse Pay Command",
"type": "main",
"index": 0
}
],
[
{
"node": "Google Sheets \u2013 Read Enrollments",
"type": "main",
"index": 0
}
]
]
},
"Parse Pay Command": {
"main": [
[
{
"node": "Google Sheets \u2013 Read Course for Payment",
"type": "main",
"index": 0
}
]
]
},
"Parse Enroll Intent": {
"main": [
[
{
"node": "Google Sheets \u2013 Read Course Detail",
"type": "main",
"index": 0
}
]
]
},
"Build Course Catalogue": {
"main": [
[
{
"node": "Send a text message",
"type": "main",
"index": 0
}
]
]
},
"Build Enrollment Status": {
"main": [
[
{
"node": "Send a text message3",
"type": "main",
"index": 0
}
]
]
},
"Build Enroll Detail Card": {
"main": [
[
{
"node": "Send a text message1",
"type": "main",
"index": 0
}
]
]
},
"Prepare Razorpay Payload": {
"main": [
[
{
"node": "Razorpay \u2013 Create Payment Link",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets \u2013 Read Courses": {
"main": [
[
{
"node": "Build Course Catalogue",
"type": "main",
"index": 0
}
]
]
},
"Razorpay \u2013 Create Payment Link": {
"main": [
[
{
"node": "Google Sheets \u2013 Log Pending Enrollment",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets \u2013 Read Enrollments": {
"main": [
[
{
"node": "Build Enrollment Status",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets \u2013 Read Course Detail": {
"main": [
[
{
"node": "Build Enroll Detail Card",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets \u2013 Log Pending Enrollment": {
"main": [
[
{
"node": "Send a text message2",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets \u2013 Read Course for Payment": {
"main": [
[
{
"node": "Prepare Razorpay Payload",
"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.
googleSheetsOAuth2ApihttpBasicAuthwatiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Transform your educational business with a fully automated mobile storefront. This workflow manages the entire student journey—from browsing course catalogues to secure payment processing and enrollment tracking—all within WhatsApp by combining WATI, Razorpay, and Google Sheets.
Source: https://n8n.io/workflows/13693/ — 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.
checkProcess(old). Uses googleSheets, httpRequest, telegram, @n-octo-n/n8n-nodes-json-database. Event-driven trigger; 40 nodes.
Transform your lead list into an AI-powered calling machine. This workflow automates your entire cold calling process using Vapi's conversational AI to initiate calls, qualify leads, capture detailed
Type in Slack. Walk away. Get a professional PDF report and a structured Excel fix sheet delivered to Google Drive and posted back in your Slack thread — fully automated, zero manual work.
This template monitors Google Drive folder for new files, extracts text from PDFs, images, text files, CSVs, and Google Docs., reads images with meta/llama-3.2-11b-vision-instruct, structures the resu
This workflow provides a complete solution for handling Telegram Stars payments, invoicing and refunds using n8n. It automates the process of sending invoices, managing pre-checkout approvals, recordi