This workflow corresponds to n8n.io template #6474 — 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 →
{
"id": "HRSrLncWtsjpThtX",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "bykhaisa",
"tags": [],
"nodes": [
{
"id": "4db560b9-9410-402e-a2dc-8d23f7a25139",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-32,
96
],
"parameters": {
"path": "makeup-booking",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "77858380-3f0b-43eb-b8cd-d1c6ce4ac6c7",
"name": "Process Booking",
"type": "n8n-nodes-base.set",
"position": [
192,
96
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "06763823-d778-4ce9-938f-c61677d1262f",
"name": "bookingId",
"type": "string",
"value": "=Khaisa_BOOK_{{ $json.body.nama }}-{{ $json.body.tanggal }}-{{ $json.body.jenisMakeup }}"
},
{
"id": "9be38ec2-23eb-4554-8a12-d6154cc13d59",
"name": "customerName",
"type": "string",
"value": "={{ $json.body.nama }}"
},
{
"id": "cad27706-3ab9-4be3-9000-cf8dc5fad37f",
"name": "whatsappNumber",
"type": "string",
"value": "={{ $json.body.noHp }}"
},
{
"id": "ccccaeda-e246-4005-b4ad-e8cf0a96715d",
"name": "eventDate",
"type": "string",
"value": "={{ $json.body.tanggal }}"
},
{
"id": "aca82216-f4cb-4c21-909a-85d8fb6d48aa",
"name": "eventTime",
"type": "string",
"value": "={{ $json.body.jam }}"
},
{
"id": "2edf7411-5924-4418-b168-7f15fcdadaf9",
"name": "location",
"type": "string",
"value": "={{ $json.body.tempatAcara }}"
},
{
"id": "fe9c718b-4109-4974-8170-f984dc0c0c72",
"name": "makeupType",
"type": "string",
"value": "={{ $json.body.jenisMakeup }}"
},
{
"id": "4ad1710c-47b8-46eb-a6c5-3791352059f8",
"name": "addOns",
"type": "string",
"value": "={{ $json.body.addOn }}"
},
{
"id": "1da023a8-5d47-4472-b0c6-3d67b4cf9d13",
"name": "paymentType",
"type": "string",
"value": "={{ $json.body.tipePembayaran }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "ffc2341f-eab0-4665-9167-fa1097b90108",
"name": "Calculate Price",
"type": "n8n-nodes-base.code",
"position": [
416,
96
],
"parameters": {
"jsCode": "// Loop over input items and calculate pricing for each booking\nfor (const item of $input.all()) {\n // Base pricing untuk setiap jenis makeup\n const basePrice = {\n 'Yudisium': 200000,\n 'Wisuda': 200000,\n 'Pendamping': 250000,\n 'Bridesmaid': 200000,\n 'Tunangan': 200000,\n 'Photoshoot': 200000,\n 'Prewedding': 200000,\n 'Party': 200000\n };\n \n const makeupType = item.json.makeupType;\n const serviceType = item.json.serviceType || '';\n const addOns = item.json.addOns || '';\n const paymentType = item.json.paymentType || '';\n \n // Format nomor WhatsApp - ubah 0 di awal menjadi 62\n let formattedWhatsapp = item.json.whatsappNumber || '';\n if (formattedWhatsapp.startsWith('0')) {\n formattedWhatsapp = '62' + formattedWhatsapp.substring(1);\n }\n // Hapus karakter non-numeric (spasi, dash, dll)\n formattedWhatsapp = formattedWhatsapp.replace(/[^0-9]/g, '');\n \n // Update nomor WhatsApp yang sudah diformat\n item.json.whatsappNumber = formattedWhatsapp;\n item.json.formattedWhatsapp = formattedWhatsapp;\n \n // Hitung base price berdasarkan jenis makeup\n let totalPrice = basePrice[makeupType] || 200000;\n \n // Tambah biaya transport untuk homeservice\n if (serviceType.toLowerCase().includes('homeservice')) {\n totalPrice += 50000; // Transport fee Rp 50,000\n }\n \n // Tambah biaya add-ons jika ada (10% dari base price)\n if (addOns && addOns.trim() !== '') {\n const addOnFee = Math.round(basePrice[makeupType] * 0.1);\n totalPrice += addOnFee;\n item.json.addOnFee = addOnFee;\n } else {\n item.json.addOnFee = 0;\n }\n \n // Logic untuk DP - jika payment type mengandung \"DP\" atau \"Booking\", set amount ke 50000\n let invoiceAmount = totalPrice;\n let isDP = false;\n \n if (paymentType.toLowerCase().includes('dp') || \n paymentType.toLowerCase().includes('booking')) {\n invoiceAmount = 50000;\n isDP = true;\n }\n \n // Format currency untuk display\n const formattedPrice = new Intl.NumberFormat('id-ID', {\n style: 'currency',\n currency: 'IDR',\n minimumFractionDigits: 0\n }).format(totalPrice);\n \n const formattedInvoiceAmount = new Intl.NumberFormat('id-ID', {\n style: 'currency',\n currency: 'IDR',\n minimumFractionDigits: 0\n }).format(invoiceAmount);\n \n // Format currency tanpa symbol untuk Xendit\n const priceForXendit = invoiceAmount.toString();\n \n // Tambahkan field pricing ke item\n item.json.basePrice = basePrice[makeupType] || 200000;\n item.json.transportFee = serviceType.toLowerCase().includes('homeservice') ? 50000 : 0;\n item.json.totalPrice = totalPrice;\n item.json.formattedPrice = formattedPrice;\n item.json.invoiceAmount = invoiceAmount;\n item.json.formattedInvoiceAmount = formattedInvoiceAmount;\n item.json.priceForXendit = priceForXendit;\n item.json.isDP = isDP;\n \n // Generate unique external ID untuk Xendit\n item.json.externalId = `MUA_${item.json.bookingId.replace('BOOK_', '')}`;\n \n // Generate invoice description dengan indikator DP jika applicable\n const dpIndicator = isDP ? ' (DP)' : '';\n item.json.invoiceDescription = `Makeup ${makeupType} - ${item.json.customerName} (${item.json.eventDate} ${item.json.eventTime})${dpIndicator}`;\n \n // Calculate expiry time (24 hours from now)\n const expiryTime = new Date();\n expiryTime.setHours(expiryTime.getHours() + 24);\n item.json.invoiceExpiry = expiryTime.toISOString();\n \n // Jika DP, hitung sisa pembayaran\n if (isDP) {\n item.json.remainingPayment = totalPrice - invoiceAmount;\n item.json.formattedRemainingPayment = new Intl.NumberFormat('id-ID', {\n style: 'currency',\n currency: 'IDR',\n minimumFractionDigits: 0\n }).format(item.json.remainingPayment);\n }\n}\nreturn $input.all();"
},
"typeVersion": 2
},
{
"id": "528354f5-b69e-417e-966b-ab26400d76b3",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
880,
16
],
"parameters": {
"options": {},
"respondWith": "allIncomingItems"
},
"typeVersion": 1.4
},
{
"id": "37b3137c-a724-465c-b6c3-a157f4e32b56",
"name": "Delay Typing",
"type": "n8n-nodes-base.wait",
"position": [
1104,
240
],
"parameters": {
"amount": "={{ Math.random()*5+3 }}"
},
"typeVersion": 1.1
},
{
"id": "e0c4a033-5b6a-4679-a57f-8db6e60e79b4",
"name": "Start Typing",
"type": "@aldinokemal2104/n8n-nodes-gowa.gowa",
"position": [
880,
240
],
"parameters": {
"operation": "sendChatPresence",
"phoneNumber": "={{ $('Calculate Price').item.json.formattedWhatsapp }}"
},
"credentials": {
"goWhatsappApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "5c5d6484-368f-4fd5-b26b-41f70c2a1203",
"name": "Stop Typing",
"type": "@aldinokemal2104/n8n-nodes-gowa.gowa",
"position": [
1328,
240
],
"parameters": {
"operation": "sendChatPresence",
"phoneNumber": "={{ $('Calculate Price').item.json.formattedWhatsapp }}",
"chatPresenceAction": "stop"
},
"credentials": {
"goWhatsappApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "bb23ee2d-1656-49ff-a003-060e739e3efe",
"name": "Send Message",
"type": "@aldinokemal2104/n8n-nodes-gowa.gowa",
"position": [
1552,
240
],
"parameters": {
"message": "=Hai, {{ $('Calculate Price').item.json.customerName }}\n\nBerikut Detail Booking Kamu:\nBooking Id: {{ $('Process Booking').item.json.bookingId }}\nTipe Makeup: {{ $('Process Booking').item.json.makeupType }}\nTanggal: {{ $('Process Booking').item.json.eventDate }} / {{ $('Process Booking').item.json.eventTime }}\nLokasi: {{ $('Process Booking').item.json.location }}\nTipe Pembayaran: {{ $('Process Booking').item.json.paymentType }}\n\nJika Belum melakukan pembayaran di halaman form, kamu bisa melakukan pembayaran melalui link berikut ya\n{{ $('Generate Invoice').item.json.invoice_url }}",
"phoneNumber": "={{ $('Calculate Price').item.json.formattedWhatsapp }}"
},
"credentials": {
"goWhatsappApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "4c12d09a-6f4f-4c04-a4ae-e31c490e34dd",
"name": "Generate Invoice",
"type": "n8n-nodes-base.httpRequest",
"position": [
640,
96
],
"parameters": {
"url": "https://api.xendit.co/v2/invoices",
"method": "POST",
"options": {},
"jsonBody": "={\n \"external_id\": \"{{ $json.invoiceExpiry }}\",\n \"amount\": {{ $json.priceForXendit }},\n \"description\": \"Pembayaran untuk {{ $json.invoiceDescription }}\",\n \"invoice_duration\": 86400,\n \"customer\": {\n \"given_names\": \"{{ $json.customerName }}\",\n \"surname\": \"{{ $json.customerName }}\",\n \"email\": \"email@email.com\",\n \"mobile_number\": \"{{ $json.whatsappNumber }}\"\n },\n \"success_redirect_url\": \"https://bykhaisa.my.id/payment-success\",\n \"failure_redirect_url\": \"https://bykhaisa.my.id/payment-failed\",\n \"currency\": \"IDR\",\n \"items\": [\n {\n \"name\": \"Make Up {{ $json.makeupType }}\",\n \"quantity\": 1,\n \"price\": {{ $json.priceForXendit }},\n \"category\": \"Makeup - {{ $json.makeupType }}\",\n \"url\": \"testo\"\n }\n ],\n \"metadata\": {\n \"store_branch\": \"Jakarta\"\n }\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth"
},
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "63c2e449-9dc5-488a-958a-7c8d6e2db713",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
448
],
"parameters": {
"color": 6,
"width": 448,
"height": 608,
"content": ""
},
"typeVersion": 1
},
{
"id": "0e3d106d-287a-4fba-8232-5242044ba274",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
448,
448
],
"parameters": {
"color": 5,
"width": 512,
"height": 608,
"content": "## 1. Xendit API Key\n\n### How to Get API Key:\n1. **Register/Login** to [Xendit Dashboard](https://dashboard.xendit.co/)\n2. **Choose Environment**:\n - Test mode for development\n - Live mode for production\n3. **Generate API Key**:\n - Go to **Settings** \u2192 **API Keys**\n - Click **Generate new key**\n - Copy **Secret Key** (format: `xnd_test_xxx` or `xnd_production_xxx`)\n\n### Setup in n8n:\n- **Node**: HTTP Request\n- **Authentication**: Basic Auth\n- **Username**: Xendit API Key\n- **Password**: (leave empty)\n\n### Documentation:\n- [Xendit API Documentation](https://developers.xendit.co/)\n- [Invoice API Guide](https://developers.xendit.co/api-reference/#create-invoice)\n"
},
"typeVersion": 1
},
{
"id": "c3d61119-cbc7-4ca7-b183-97f0444d6944",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
992,
448
],
"parameters": {
"color": 5,
"width": 656,
"height": 608,
"content": "## 2. GoWhatsApp API\n\n### Setup Process:\n1. **Install GoWhatsApp** on your server\n2. **Setup Container**:\n ```bash\n docker run -d -p 3000:3000 aldinokemal2104/go-whatsapp-web-multidevice\n ```\n3. **Scan QR Code**:\n - Open `http://localhost:3000`\n - Scan QR with WhatsApp\n4. **Get API Endpoint**: `http://localhost:3000`\n\n### Setup in n8n:\n- **Node**: [GoWA](https://www.npmjs.com/package/@aldinokemal2104/n8n-nodes-gowa) (Community Node)\n- **API URL**: `http://localhost:3000`\n- **Phone Number**: Format 62xxx (without +)\n\n### Documentation:\n- [GoWhatsApp GitHub](https://github.com/aldinokemal/go-whatsapp-web-multidevice)\n- [API Endpoints](https://github.com/aldinokemal/go-whatsapp-web-multidevice#api-docs)"
},
"typeVersion": 1
}
],
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "6e219bda-3118-48d7-b509-42d81a17ad64",
"connections": {
"Webhook": {
"main": [
[
{
"node": "Process Booking",
"type": "main",
"index": 0
}
]
]
},
"Stop Typing": {
"main": [
[
{
"node": "Send Message",
"type": "main",
"index": 0
}
]
]
},
"Delay Typing": {
"main": [
[
{
"node": "Stop Typing",
"type": "main",
"index": 0
}
]
]
},
"Start Typing": {
"main": [
[
{
"node": "Delay Typing",
"type": "main",
"index": 0
}
]
]
},
"Calculate Price": {
"main": [
[
{
"node": "Generate Invoice",
"type": "main",
"index": 0
}
]
]
},
"Process Booking": {
"main": [
[
{
"node": "Calculate Price",
"type": "main",
"index": 0
}
]
]
},
"Generate Invoice": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
},
{
"node": "Start Typing",
"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.
goWhatsappApihttpBasicAuth
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
⚠️ Disclaimer: This workflow utilizes community nodes that needs self hosted version
Source: https://n8n.io/workflows/6474/ — 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.
HR teams, IT Operations, and System Administrators managing employee onboarding at scale. It’s perfect if you use Odoo 18 to trigger account requests and need Redmine + GitLab accounts created instant
This workflow is a complete, production-ready solution for recovering abandoned carts in Shopify stores using a multi-channel, multi-touch approach. It automates personalized follow-ups via Email, SMS
qualiopi. Uses airtable, telegram, emailSend, httpRequest. Webhook trigger; 51 nodes.
This workflow automates end-to-end research analysis by coordinating multiple AI models—including NVIDIA NIM (Llama), OpenAI GPT-4, and Claude to analyze uploaded documents, extract insights, and gene
PsyCardv2. Uses executeCommand, telegram, readBinaryFile, googleDrive. Webhook trigger; 41 nodes.