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 →
{
"name": "01_order_processing_tilda",
"nodes": [
{
"parameters": {
"content": "## Earning",
"height": 256,
"width": 1056,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
448
],
"typeVersion": 1,
"id": "06cd60f6-0ff3-4e19-934f-66289c818596",
"name": "Sticky Note"
},
{
"parameters": {
"content": "## Spending",
"height": 240,
"width": 1056,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
0
],
"typeVersion": 1,
"id": "118a2be3-28eb-4a19-b4d2-f9f306808366",
"name": "Sticky Note1"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "6da41e92-2b4b-44f7-8b1c-cd533e774999",
"leftValue": "={{ $json.order_id }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
-496,
176
],
"id": "912fa65d-a2c6-42cc-8bee-8af33a5759ea",
"name": "Check Duplicate"
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "1IH1j7tDItMlfPUjawuXSywX83fMQ_6m9ToIN6exWiMk",
"mode": "list",
"cachedResultName": "n8n_execution_logs",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IH1j7tDItMlfPUjawuXSywX83fMQ_6m9ToIN6exWiMk/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "logs",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IH1j7tDItMlfPUjawuXSywX83fMQ_6m9ToIN6exWiMk/edit#gid=0"
},
"filtersUI": {
"values": [
{
"lookupColumn": "order_id",
"lookupValue": "={{ $json.body.payment.orderid }}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
-704,
176
],
"id": "c24315a0-4372-48bb-b388-be99539c52b8",
"name": "Search Existing Order",
"alwaysOutputData": true,
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"httpMethod": "POST",
"path": "tilda-order",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-912,
176
],
"id": "43ee4582-bfd5-4682-acf3-ccc15cd863a3",
"name": "Receive Tilda Order"
},
{
"parameters": {
"method": "POST",
"url": "https://api-ru.iiko.services/api/1/access_token",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "apiLogin",
"value": "my_api"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
-256,
192
],
"id": "c9137c48-1663-461d-a637-1dec5bca776c",
"name": "iiko Auth (Get Token)",
"retryOnFail": true,
"waitBetweenTries": 3000
},
{
"parameters": {
"method": "POST",
"url": "https://api-ru.iiko.services/api/1/loyalty/iiko/customer/create_or_update",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $('iiko Auth (Get Token)').item.json.token }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"organizationId\": \"org_id\",\n \"phone\": \"+7{{ ($('Receive Tilda Order').item.json.body.phone || $('Receive Tilda Order').item.json.body.Phone).toString().replace(/\\D/g, '').slice(-10) }}\",\n \"name\": \"{{ $('Receive Tilda Order').item.json.body.name }}\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
-16,
192
],
"id": "fd2fe9f3-cbc3-482a-9a6a-d0befff6e7e9",
"name": "Sync Customer Profile",
"retryOnFail": true,
"waitBetweenTries": 3000
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "df188b1e-3ae0-4c35-b089-012da4709064",
"leftValue": "={{ $('Receive Tilda Order').item.json.body.spend_bonus }}",
"rightValue": "yes",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
192,
192
],
"id": "85732a3d-7d82-42bf-a0cd-7dadf2830e20",
"name": "Router: Spend or Earn"
},
{
"parameters": {
"method": "POST",
"url": "https://api-ru.iiko.services/api/1/loyalty/iiko/customer/info",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $('iiko Auth (Get Token)').item.json.token }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"organizationId\": \"org_id\",\n \"phone\": \"+7{{ ($('Receive Tilda Order').item.json.body.phone || $('Receive Tilda Order').item.json.body.Phone).toString().replace(/\\D/g, '').slice(-10) }}\",\n \"type\": \"phone\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
464,
64
],
"id": "aac6cc25-4657-4a5c-9107-6c24e0dd84e1",
"name": "Get Current Balance",
"retryOnFail": true,
"waitBetweenTries": 3000
},
{
"parameters": {
"method": "POST",
"url": "https://api-ru.iiko.services/api/1/loyalty/iiko/customer/wallet/chargeoff",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $('iiko Auth (Get Token)').item.json.token }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"organizationId\": \"org_id\",\n \"customerId\": \"{{ $json.id }}\",\n \"walletId\": \"my_wallet_id\",\n \"sum\": {{ Math.min($json.walletBalances[0].balance, $('Receive Tilda Order').item.json.body.payment.products.reduce((sum, p) => sum + p.amount, 0)) }},\n \"comment\": \"Bonus write-off\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
672,
64
],
"id": "224bfde1-900f-46f2-88df-b1b084c465d3",
"name": "Withdraw Bonuses",
"retryOnFail": true,
"waitBetweenTries": 3000
},
{
"parameters": {
"method": "POST",
"url": "https://api-ru.iiko.services/api/1/loyalty/iiko/customer/wallet/topup",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $('iiko Auth (Get Token)').item.json.token }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"organizationId\": \"org_id\",\n \"customerId\": \"{{ $('Get Current Balance').item.json.id }}\",\n \"walletId\": \"my_id\",\n \"sum\": {{ \nMath.round(($('Receive Tilda Order').item.json.body.payment.amount - Math.min($('Get Current Balance').item.json.walletBalances[0].balance, $('Receive Tilda Order').item.json.body.payment.products.reduce((sum, p) => sum + p.amount, 0))) * 0.05 ) }},\n \"comment\": \"Bonuses for orders in the online store\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
880,
64
],
"id": "2ebbc37a-cce0-418a-8daa-195ee11499e2",
"name": "Update Local Balance",
"retryOnFail": true,
"waitBetweenTries": 3000
},
{
"parameters": {
"jsCode": "// 1. Extract initial data\nconst walletBalance = $('Get Current Balance').item.json.walletBalances[0].balance;\nconst products = $('Receive Tilda Order').item.json.body.payment.products;\n// Parse order total to number (ensure type safety)\nconst orderTotal = parseInt($('Receive Tilda Order').item.json.body.payment.amount);\n\n// 2. Calculate total product sum (to check write-off limits)\nconst productsSum = products.reduce((sum, p) => sum + parseInt(p.amount), 0);\n\n// 3. Calculate redeemed amount (min of wallet balance vs product total)\nconst spentBonus = Math.min(walletBalance, productsSum);\n\n// 4. Calculate remaining amount to pay (Cash/Card)\nconst finalPay = orderTotal - spentBonus;\n\n// 5. Calculate new accrual on the remaining amount (5%)\nconst addedBonus = Math.round(finalPay * 0.05);\n\n// Return calculated figures for next steps\nreturn {\n json: {\n added: addedBonus, // How much was accrued?\n spent: spentBonus, // How much was written off?\n pay: finalPay // Total to be paid\n }\n}"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1088,
64
],
"id": "1b144579-9a32-42c6-b9e9-286dcf449cb3",
"name": "Format Admin Message"
},
{
"parameters": {
"jsCode": "// 1. We get the order amount from Tilda\nconst orderTotal = parseInt($('Receive Tilda Order').item.json.body.payment.amount);\n\n// 2. We calculate 5% (round up to the nearest whole number)\nconst bonusToAdd = Math.round(orderTotal * 0.05);\n\n// 3. Return calculated bonus object\nreturn {\n json: {\n bonus: bonusToAdd\n }\n}"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
464,
512
],
"id": "af45c33e-af74-4932-9de1-fc18eeea59c7",
"name": "Calc Bonus Amount"
},
{
"parameters": {
"method": "POST",
"url": "https://api-ru.iiko.services/api/1/loyalty/iiko/customer/wallet/topup",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $('iiko Auth (Get Token)').item.json.token }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"organizationId\": \"org_id\",\n \"customerId\": \"{{ $('Router: Spend or Earn').item.json.id }}\",\n \"walletId\": \"my_id\",\n \"sum\": {{ $json.bonus }},\n \"comment\": \"Bonuses for ordering on the website\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
672,
512
],
"id": "b54b6a26-5a0d-4390-bb0d-09f2b08cce8c",
"name": "Accrue Bonuses",
"retryOnFail": true,
"waitBetweenTries": 3000
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "1IH1j7tDItMlfPUjawuXSywX83fMQ_6m9ToIN6exWiMk",
"mode": "list",
"cachedResultName": "n8n_execution_logs",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IH1j7tDItMlfPUjawuXSywX83fMQ_6m9ToIN6exWiMk/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "logs",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1IH1j7tDItMlfPUjawuXSywX83fMQ_6m9ToIN6exWiMk/edit#gid=0"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"date": "={{ $now }}",
"order_id": "={{ $('Receive Tilda Order').item.json.body.payment.orderid }}",
"status": "Success"
},
"matchingColumns": [],
"schema": [
{
"id": "date",
"displayName": "date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "order_id",
"displayName": "order_id",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "status",
"displayName": "status",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.7,
"position": [
1296,
512
],
"id": "303c9cc1-3b96-4bc0-a5d3-d2715b171a91",
"name": "Log Transaction to DB",
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "admin_id",
"text": "=<b>\u041d\u041e\u0412\u042b\u0419 \u0417\u0410\u041a\u0410\u0417 \u0421 \u0418\u041d\u0422\u0415\u0420\u041d\u0415\u0422-\u041c\u0410\u0413\u0410\u0417\u0418\u041d\u0410 \n\u0421\u041e \u0421\u041f\u0418\u0421\u0410\u041d\u0418\u0415\u041c \u0411\u041e\u041d\u0423\u0421\u041e\u0412\n#{{ $('Receive Tilda Order').item.json.body.payment.orderid }}</b>\n\n<b>\u0421\u043f\u043e\u0441\u043e\u0431 \u043e\u043f\u043b\u0430\u0442\u044b:</b> {{ $('Receive Tilda Order').item.json.body.paymentsystem == 'banktransfer' ? '\u041f\u043e Kaspi' : '\u041d\u0430\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438' }}\n\n<b>\u0418\u043c\u044f:</b> {{ $('Receive Tilda Order').item.json.body.name }}\n<b>\u0422\u0435\u043b\u0435\u0444\u043e\u043d:</b> +{{ ($('Receive Tilda Order').item.json.body.phone || $('Receive Tilda Order').item.json.body.Phone).replace(/\\D/g, '') }}\n<b>\u0410\u0434\u0440\u0435\u0441:</b> {{ $('Receive Tilda Order').item.json.body.address }}\n<b>\u0414\u0435\u043d\u044c \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438:</b> {{ $('Receive Tilda Order').item.json.body.den_dostavki }} ({{ $('Receive Tilda Order').item.json.body.vremya_dostavki_c }} - {{ $('Receive Tilda Order').item.json.body.vremya_dostavki_do }})\n\n<b>\u0417\u0410\u041a\u0410\u0417:</b>\n{{ $('Receive Tilda Order').item.json.body.payment.products.map(p => `${p.name} ${p.options ? `\n${p.options[0].option}: ${p.options[0].variant}` : ''}\n${p.quantity} \u0448\u0442 \u0445 ${p.price.toLocaleString('ru-RU')} = ${p.amount.toLocaleString('ru-RU')} \u20b8`).join('\\n\\n') }}\n{{ $('Receive Tilda Order').item.json.body.commentary ? `\n<b>\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439:</b> ${$('Receive Tilda Order').item.json.body.commentary}` : '' }}\n{{ $('Receive Tilda Order').item.json.body.podpiska ? `\n<b>\u041a\u043b\u0438\u0435\u043d\u0442 \u0445\u043e\u0447\u0435\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 \u043d\u0430 \u043a\u043e\u0444\u0435!</b>` : '' }}\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n<b>\u0421\u0423\u041c\u041c\u0410 \u0417\u0410\u041a\u0410\u0417\u0410:</b> {{ parseInt($('Receive Tilda Order').item.json.body.payment.amount).toLocaleString('ru-RU') }} \u20b8\n\n<b>\u0411\u041e\u041d\u0423\u0421\u042b:</b>\n\u0421\u043f\u0438\u0441\u0430\u043d\u043e: -{{ $json.spent.toLocaleString('ru-RU') }}\n\u041d\u0430\u0447\u0438\u0441\u043b\u0435\u043d\u043e \u0437\u0430 \u043d\u043e\u0432\u044b\u0439 \u0437\u0430\u043a\u0430\u0437: +{{ $json.added.toLocaleString('ru-RU') }}\n\n<b>\u0418\u0422\u041e\u0413\u041e \u041a \u041e\u041f\u041b\u0410\u0422\u0415: {{ $json.pay.toLocaleString('ru-RU') }} \u20b8</b>",
"replyMarkup": "inlineKeyboard",
"inlineKeyboard": {
"rows": [
{
"row": {
"buttons": [
{
"text": "\u274c Order cancellation",
"additionalFields": {
"callback_data": "=undo_mix|{{ $('Receive Tilda Order').item.json.body.phone.replace(/\\D/g, '') }}|{{ $('Format Admin Message').item.json.spent }}|{{ $('Format Admin Message').item.json.added }}"
}
}
]
}
}
]
},
"additionalFields": {
"appendAttribution": false,
"parse_mode": "HTML"
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1280,
64
],
"id": "38efb35a-926b-4a3f-a05e-f20979fd499e",
"name": "Notify Admin (Spending) RU",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "admin_id",
"text": "=<b>\u041d\u041e\u0412\u042b\u0419 \u0417\u0410\u041a\u0410\u0417 \u0421 \u0418\u041d\u0422\u0415\u0420\u041d\u0415\u0422-\u041c\u0410\u0413\u0410\u0417\u0418\u041d\u0410 \n#{{ $('Receive Tilda Order').item.json.body.payment.orderid }}</b>\n\n<b>\u0421\u043f\u043e\u0441\u043e\u0431 \u043e\u043f\u043b\u0430\u0442\u044b:</b> {{ $('Receive Tilda Order').item.json.body.paymentsystem == 'banktransfer' ? '\u041f\u043e Kaspi' : '\u041d\u0430\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438' }}\n\n<b>\u0418\u043c\u044f:</b> {{ $('Receive Tilda Order').item.json.body.name }}\n<b>\u0422\u0435\u043b\u0435\u0444\u043e\u043d:</b> +{{ ($('Receive Tilda Order').item.json.body.phone || $('Receive Tilda Order').item.json.body.Phone).replace(/\\D/g, '') }}\n<b>\u0410\u0434\u0440\u0435\u0441:</b> {{ $('Receive Tilda Order').item.json.body.address }}\n<b>\u0414\u0435\u043d\u044c \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438:</b> {{ $('Receive Tilda Order').item.json.body.den_dostavki }} ({{ $('Receive Tilda Order').item.json.body.vremya_dostavki_c }} - {{ $('Receive Tilda Order').item.json.body.vremya_dostavki_do }})\n\n<b>\u0417\u0410\u041a\u0410\u0417:</b>\n{{ $('Receive Tilda Order').item.json.body.payment.products.map(p => `${p.name} ${p.options ? `\n${p.options[0].option}: ${p.options[0].variant}` : ''}\n${p.quantity} \u0448\u0442 \u0445 ${p.price.toLocaleString('ru-RU')} = ${p.amount.toLocaleString('ru-RU')} \u20b8`).join('\\n\\n') }}\n{{ $('Receive Tilda Order').item.json.body.commentary ? `\n<b>\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439:</b> ${$('Receive Tilda Order').item.json.body.commentary}` : '' }}\n{{ $('Receive Tilda Order').item.json.body.podpiska ? `\n<b>\u041a\u043b\u0438\u0435\u043d\u0442 \u0445\u043e\u0447\u0435\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 \u043d\u0430 \u043a\u043e\u0444\u0435!</b>` : '' }}\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n<b>\u0421\u0423\u041c\u041c\u0410: {{ parseInt($('Receive Tilda Order').item.json.body.payment.amount).toLocaleString('ru-RU') }} \u20b8</b>\n\n<b>\u0411\u041e\u041d\u0423\u0421\u042b:</b>\n\u041d\u0430\u0447\u0438\u0441\u043b\u0435\u043d\u043e: +{{ $('Calc Bonus Amount').item.json.bonus.toLocaleString('ru-RU') }} \u0431\u043e\u043d\u0443\u0441\u043e\u0432",
"replyMarkup": "inlineKeyboard",
"inlineKeyboard": {
"rows": [
{
"row": {
"buttons": [
{
"text": "=\u274c Order cancellation",
"additionalFields": {
"callback_data": "=undo_add|{{ ($('Receive Tilda Order').item.json.body.phone || $('Receive Tilda Order').item.json.body.Phone).toString().replace(/\\D/g, '').slice(-10) }}|{{ $('Calc Bonus Amount').item.json.bonus }}"
}
}
]
}
}
]
},
"additionalFields": {
"appendAttribution": false,
"parse_mode": "HTML"
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
880,
512
],
"id": "ac142b41-f69a-440d-a106-d4af5bda3e50",
"name": "Notify Admin (Earning) RU",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "https://7105.api.greenapi.com/waInstance****/SendMessage/******",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"chatId\": \"{{ $('Receive Tilda Order').item.json.body.phone.replace(/\\D/g, '') }}@c.us\",\n \"message\": \"\u2615\ufe0f *\u0412\u0430\u0448 \u0437\u0430\u043a\u0430\u0437 \u2116{{ $('Receive Tilda Order').item.json.body.payment.orderid }} \u043f\u0440\u0438\u043d\u044f\u0442!*\\n\\n\n\ud83d\udcc5 \u0414\u043e\u0441\u0442\u0430\u0432\u043a\u0430: {{ $('Receive Tilda Order').item.json.body.den_dostavki }} ({{ $('Receive Tilda Order').item.json.body.vremya_dostavki_c }} - {{ $('Receive Tilda Order').item.json.body.vremya_dostavki_do }})\\n\ud83d\udccd \u0410\u0434\u0440\u0435\u0441: {{ $('Receive Tilda Order').item.json.body.address }}\\n\\n\n\ud83d\uded2 *\u0421\u043e\u0441\u0442\u0430\u0432 \u0437\u0430\u043a\u0430\u0437\u0430:*\\n{{ $('Receive Tilda Order').item.json.body.payment.products.map(p => `- *${p.name}* (${p.quantity} \u0448\u0442)${p.options ? '\\n ' + p.options.map(o => o.variant).join(', ') : ''}`).join('\\n\\n') }}\\n\\n{{ $('Receive Tilda Order').item.json.body.podpiska ? \n'\ud83d\udd04 *\u0412\u044b \u043e\u0444\u043e\u0440\u043c\u0438\u043b\u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 \u043d\u0430 \u043a\u043e\u0444\u0435!*' : '' }}\\n\\n\ud83d\udcb0 *\u0421\u0443\u043c\u043c\u0430: {{ parseInt($('Receive Tilda Order').item.json.body.payment.amount).toLocaleString('ru-RU') }} \u20b8*\\n\n\ud83d\udcb3 \u041e\u043f\u043b\u0430\u0442\u0430: {{ $('Receive Tilda Order').item.json.body.paymentsystem == 'banktransfer' ? 'Kaspi' : '\u041d\u0430\u043b\u0438\u0447\u043d\u044b\u0435' }}\\n\\n\n\ud83c\udf81 *\u0411\u041e\u041d\u0423\u0421\u042b:*\\n{{ $('Calc Bonus Amount').item.json.bonus > 0 ? \n`\u2705 \u041d\u0430\u0447\u0438\u0441\u043b\u0435\u043d\u043e: ${$('Calc Bonus Amount').item.json.bonus} BONUS` : '\u0411\u043e\u043d\u0443\u0441\u044b \u043d\u0435 \u043d\u0430\u0447\u0438\u0441\u043b\u0435\u043d\u044b' }}\\n\\n\u041c\u044b \u0443\u0436\u0435 \u043d\u0430\u0447\u0430\u043b\u0438 \u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0432\u0430\u0448 \u043a\u043e\u0444\u0435! \u0416\u0434\u0438\u0442\u0435 \u0437\u0432\u043e\u043d\u043a\u0430 \u043a\u0443\u0440\u044c\u0435\u0440\u0430.\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
1088,
512
],
"id": "6afc47ed-b637-4797-b273-17c88f4fe0d6",
"name": "Notify Customer (WhatsApp) RU",
"retryOnFail": true,
"waitBetweenTries": 3000
},
{
"parameters": {
"content": "Formats admin notification with order details and payment method.",
"height": 80,
"width": 320
},
"type": "n8n-nodes-base.stickyNote",
"position": [
864,
736
],
"typeVersion": 1,
"id": "94d152a9-b7a3-4111-bb8e-cadba56a78f9",
"name": "Sticky Note2"
},
{
"parameters": {
"content": "**Workflow Overview**\n1. **Goal:** Processes Tilda orders, manages loyalty points (earn/burn) via iikoCard API.\n2. **Input:** Webhook from Tilda (JSON payload with order details).\n3. **Idempotency:** Prevents duplicate processing via Google Sheets lookup (`order_id`).\n4. **Logic:** Routes execution based on `spend_bonus` flag (True = Withdraw, False = Accrue).\n5. **Notifications:** Admin (Telegram), Customer (WhatsApp).\n6. **Error Handling:** Global workflow catches 4xx/5xx errors.",
"height": 336,
"width": 352
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-1360,
80
],
"typeVersion": 1,
"id": "ef0ab0aa-7823-4c04-bc03-a37087cf6682",
"name": "Sticky Note3"
},
{
"parameters": {
"content": "**Spending Logic (Complex)**\n1. **Redeem:** Deduced bonuses based on wallet balance (covers full or partial order).\n2. **Calc Remainder:** Calculates how much the customer must pay by card.\n3. **Accrue on Remainder:** Calculates new points (5%) based on the actual cash payment amount.\n4. **Sync:** Updates iikoCard and notifies Admin.",
"height": 144,
"width": 672
},
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
-176
],
"typeVersion": 1,
"id": "24406ca1-b7cc-4faa-8b57-c494449fe4e9",
"name": "Sticky Note4"
},
{
"parameters": {
"content": "**Earning Logic**\n1. Calculates loyalty points (5% of order total).\n2. Accrues points via iikoCard API (POST request).\n3. Sends WhatsApp notification to customer.\n4. Logs successful transaction to DB.",
"height": 144,
"width": 480
},
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
272
],
"typeVersion": 1,
"id": "fc8a467a-90c3-48e9-ad80-b1bf3dee1a55",
"name": "Sticky Note5"
},
{
"parameters": {
"content": "**Idempotency Check**\n* **Logic:** Checks if `order_id` exists in Google Sheets.\n* **True:** Order exists -> Stop execution (prevent double-charging).\n* **False:** New order -> Proceed.",
"height": 176
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-544,
-32
],
"typeVersion": 1,
"id": "28b104bd-0241-48fc-a3e2-b41d93a43a92",
"name": "Sticky Note6"
},
{
"parameters": {
"content": "**Business Logic Router**\nChecks the `spend_bonus` field from Tilda:\n* **True:** Customer wants to pay with points.\n* **False:** Standard accrual."
},
"type": "n8n-nodes-base.stickyNote",
"position": [
128,
0
],
"typeVersion": 1,
"id": "ad18ce62-2899-4792-8dac-6aeb8a8b0eab",
"name": "Sticky Note7"
},
{
"parameters": {
"content": "**Bonus Calculation**\n* **Input:** `payment.amount` from Webhook.\n* **Logic:** 5% of order total (rounded).\n* **Output:** Integer value for API."
},
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
736
],
"typeVersion": 1,
"id": "ac2d8c50-50ad-4ba4-8947-3c5bfd58310e",
"name": "Sticky Note8"
}
],
"connections": {
"Check Duplicate": {
"main": [
[],
[
{
"node": "iiko Auth (Get Token)",
"type": "main",
"index": 0
}
]
]
},
"Search Existing Order": {
"main": [
[
{
"node": "Check Duplicate",
"type": "main",
"index": 0
}
]
]
},
"Receive Tilda Order": {
"main": [
[
{
"node": "Search Existing Order",
"type": "main",
"index": 0
}
]
]
},
"iiko Auth (Get Token)": {
"main": [
[
{
"node": "Sync Customer Profile",
"type": "main",
"index": 0
}
]
]
},
"Sync Customer Profile": {
"main": [
[
{
"node": "Router: Spend or Earn",
"type": "main",
"index": 0
}
]
]
},
"Router: Spend or Earn": {
"main": [
[
{
"node": "Get Current Balance",
"type": "main",
"index": 0
}
],
[
{
"node": "Calc Bonus Amount",
"type": "main",
"index": 0
}
]
]
},
"Get Current Balance": {
"main": [
[
{
"node": "Withdraw Bonuses",
"type": "main",
"index": 0
}
]
]
},
"Withdraw Bonuses": {
"main": [
[
{
"node": "Update Local Balance",
"type": "main",
"index": 0
}
]
]
},
"Update Local Balance": {
"main": [
[
{
"node": "Format Admin Message",
"type": "main",
"index": 0
}
]
]
},
"Format Admin Message": {
"main": [
[
{
"node": "Notify Admin (Spending) RU",
"type": "main",
"index": 0
}
]
]
},
"Calc Bonus Amount": {
"main": [
[
{
"node": "Accrue Bonuses",
"type": "main",
"index": 0
}
]
]
},
"Accrue Bonuses": {
"main": [
[
{
"node": "Notify Admin (Earning) RU",
"type": "main",
"index": 0
}
]
]
},
"Notify Admin (Spending) RU": {
"main": [
[
{
"node": "Log Transaction to DB",
"type": "main",
"index": 0
}
]
]
},
"Notify Admin (Earning) RU": {
"main": [
[
{
"node": "Notify Customer (WhatsApp) RU",
"type": "main",
"index": 0
}
]
]
},
"Notify Customer (WhatsApp) RU": {
"main": [
[
{
"node": "Log Transaction to DB",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"availableInMCP": false,
"timeSavedMode": "fixed",
"timezone": "Asia/Almaty",
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "hqRcKQkYO4KNl7CpVzjbg"
},
"versionId": "5dacf37f-572c-40a2-903a-753b9ffcd072",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "s9Ah877ioKzNigtUAcxiU",
"tags": []
}
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.
googleSheetsOAuth2ApitelegramApi
About this workflow
01_order_processing_tilda. Uses stickyNote, googleSheets, httpRequest, telegram. Webhook trigger; 25 nodes.
Source: https://github.com/gulnaz-bakinova/n8n-automation-integrations-showcase/blob/main/01_order_processing_tilda.json — original creator credit. Request a take-down →