8
n8n 中文网amn8n.com

bykhaisa

中级

这是一个CRM领域的自动化工作流,包含 12 个节点。主要使用 Set, Code, Wait, Webhook, HttpRequest 等节点。 自动化服务预约与支付:WhatsApp和Xendit

前置要求
  • HTTP Webhook 端点(n8n 会自动生成)
  • 可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "HRSrLncWtsjpThtX",
  "meta": {
    "instanceId": "c2650793f644091dc80fb900fe63448ad1f4b774008de9608064d67294f8307c",
    "templateCredsSetupCompleted": true
  },
  "name": "bykhaisa",
  "tags": [],
  "nodes": [
    {
      "id": "4db560b9-9410-402e-a2dc-8d23f7a25139",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -32,
        96
      ],
      "webhookId": "1339c533-da44-428b-ae38-f0429adb6534",
      "parameters": {
        "path": "makeup-booking",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "77858380-3f0b-43eb-b8cd-d1c6ce4ac6c7",
      "name": "处理预订",
      "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": "计算价格",
      "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": "响应 Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        880,
        16
      ],
      "parameters": {
        "options": {},
        "respondWith": "allIncomingItems"
      },
      "typeVersion": 1.4
    },
    {
      "id": "37b3137c-a724-465c-b6c3-a157f4e32b56",
      "name": "延迟输入",
      "type": "n8n-nodes-base.wait",
      "position": [
        1104,
        240
      ],
      "webhookId": "2ad403e6-4377-4e0f-b0d1-76182bcef108",
      "parameters": {
        "amount": "={{ Math.random()*5+3 }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "e0c4a033-5b6a-4679-a57f-8db6e60e79b4",
      "name": "开始输入",
      "type": "@aldinokemal2104/n8n-nodes-gowa.gowa",
      "position": [
        880,
        240
      ],
      "parameters": {
        "operation": "sendChatPresence",
        "phoneNumber": "={{ $('Calculate Price').item.json.formattedWhatsapp }}"
      },
      "credentials": {
        "goWhatsappApi": {
          "id": "WJo4Yn0Xouu1FkD3",
          "name": "anisa"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5c5d6484-368f-4fd5-b26b-41f70c2a1203",
      "name": "停止输入",
      "type": "@aldinokemal2104/n8n-nodes-gowa.gowa",
      "position": [
        1328,
        240
      ],
      "parameters": {
        "operation": "sendChatPresence",
        "phoneNumber": "={{ $('Calculate Price').item.json.formattedWhatsapp }}",
        "chatPresenceAction": "stop"
      },
      "credentials": {
        "goWhatsappApi": {
          "id": "WJo4Yn0Xouu1FkD3",
          "name": "anisa"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "bb23ee2d-1656-49ff-a003-060e739e3efe",
      "name": "发送消息",
      "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": {
          "id": "WJo4Yn0Xouu1FkD3",
          "name": "anisa"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4c12d09a-6f4f-4c04-a4ae-e31c490e34dd",
      "name": "生成发票",
      "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": {
          "id": "QTs9FpNdOTvm3C5A",
          "name": "Xendit test Khaisa Studio"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "63c2e449-9dc5-488a-958a-7c8d6e2db713",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -16,
        448
      ],
      "parameters": {
        "color": 6,
        "width": 448,
        "height": 608,
        "content": "![表单](https://raw.githubusercontent.com/khmuhtadin/n8n-template/main/Additional%20FE/Automate%20Booking%20with%20Xendit%20/Images/Screenshot%202025-07-25%20at%2021.09.06.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "0e3d106d-287a-4fba-8232-5242044ba274",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        448
      ],
      "parameters": {
        "color": 5,
        "width": 512,
        "height": 608,
        "content": "## 1. Xendit API 密钥"
      },
      "typeVersion": 1
    },
    {
      "id": "c3d61119-cbc7-4ca7-b183-97f0444d6944",
      "name": "便签 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        992,
        448
      ],
      "parameters": {
        "color": 5,
        "width": 656,
        "height": 608,
        "content": "## 2. GoWhatsApp API"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "pinData": {},
  "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
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

中级 - 客户关系管理

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量12
分类1
节点类型8
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

外部链接
在 n8n.io 查看

分享此工作流