This workflow follows the HTTP Request → Telegram 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 →
{
"name": "03_admin_refund_handler",
"nodes": [
{
"parameters": {
"content": "## Spending",
"height": 208,
"width": 288,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"typeVersion": 1,
"id": "05ae9c8e-bd93-4d58-83ff-8c7af8c90073",
"name": "Sticky Note"
},
{
"parameters": {
"content": "## Earning",
"height": 240,
"width": 448,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
272
],
"typeVersion": 1,
"id": "cfb0d8c2-77ea-4862-b091-8cfd2043c14e",
"name": "Sticky Note3"
},
{
"parameters": {
"updates": [
"callback_query"
],
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [
-1248,
320
],
"id": "7938bf69-c089-4d51-87c1-8565a3681cec",
"name": "Admin Button Click (Trigger)",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Get data from the clicked button\nconst item = items[0].json;\nconst buttonData = item.data || (item.callback_query && item.callback_query.data);\n\nif (!buttonData) throw new Error(\"No callback data found in button\");\n\n// Data format: action|phone|amount1|amount2\nconst parts = buttonData.split('|');\n\nreturn {\n json: {\n action: parts[0], // 'undo_add' or 'undo_mix'\n phone: parts[1],\n amount1: parseInt(parts[2]), // Primary amount\n amount2: parseInt(parts[3]) || 0 // Secondary amount (for mixed payments)\n }\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1040,
320
],
"id": "ab6a0406-1fbf-491d-8be4-6af90e464cfc",
"name": "Parse Button Data"
},
{
"parameters": {
"method": "POST",
"url": "https://api-ru.iiko.services/api/1/access_token",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "apiLogin",
"value": "REPLACE_WITH_SECRET"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
-800,
320
],
"id": "05edfcf3-1db1-4d7b-a063-7dd5ea196a09",
"name": "iiko Auth (Get Token)",
"retryOnFail": true,
"waitBetweenTries": 3000
},
{
"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{{ $('Parse Button Data').item.json.phone.toString().replace(/\\D/g, '').slice(-10) }}\",\n \"type\": \"phone\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
-560,
320
],
"id": "af43df8f-7fff-4a2b-9860-9446c1e9881c",
"name": "Fetch Customer Wallet",
"retryOnFail": true,
"waitBetweenTries": 3000
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"leftValue": "={{ $('Parse Button Data').item.json.action }}",
"rightValue": "undo_add",
"operator": {
"type": "string",
"operation": "equals"
},
"id": "0c3ffd14-d854-4681-8527-951873a1055a"
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "undo_add"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "f42ca719-44de-4cb8-993b-e412fa97b0c1",
"leftValue": "={{ $('Parse Button Data').item.json.action }}",
"rightValue": "undo_mix",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "undo_mix"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.3,
"position": [
-320,
320
],
"id": "c948fc1f-a45c-49fd-a4f1-ede6c46a3070",
"name": "Router: Refund Type"
},
{
"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_id\",\n \"sum\": {{ $('Parse Button Data').item.json.amount1 }},\n \"comment\": \"Order Cancelled (Revert Accrual)\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
80,
48
],
"id": "2060c689-e30d-4379-aac2-9aca6a95a0ea",
"name": "Revoke Accrued Points",
"alwaysOutputData": true,
"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\": \"{{ $json.id }}\",\n \"walletId\": \"my_id\",\n \"sum\": {{ $('Parse Button Data').item.json.amount1 }},\n \"comment\": \"Refund Spent Points (Order Cancelled)\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
-32,
336
],
"id": "b868ff11-ae7d-4aba-897e-95f232664b53",
"name": "Refund: Return Spent Points",
"retryOnFail": true,
"waitBetweenTries": 3000
},
{
"parameters": {
"resource": "callback",
"queryId": "={{ $('Admin Button Click (Trigger)').item.json.callback_query.id }}",
"additionalFields": {
"text": "\u2705 The bonuses reverted to the opposite state"
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
480,
336
],
"id": "d770c5e6-a42d-4f3c-a779-ac154220929a",
"name": "Stop Button Loading",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "editMessageText",
"chatId": "={{ $('Admin Button Click (Trigger)').item.json.callback_query.message.chat.id }}",
"messageId": "={{ $('Admin Button Click (Trigger)').item.json.callback_query.message.message_id }}",
"text": "=\u274c <b>\u0414\u0430\u043d\u043d\u044b\u0439 \u0437\u0430\u043a\u0430\u0437 \u043e\u0442\u043c\u0435\u043d\u0435\u043d</b> \n(\u041d\u0430\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u0431\u043e\u043d\u0443\u0441\u044b \u0431\u044b\u043b\u0438 \u0441\u043f\u0438\u0441\u0430\u043d\u044b/\u043d\u0430\u0447\u0438\u0441\u043b\u0435\u043d\u044b \u043e\u0431\u0440\u0430\u0442\u043d\u043e)\n\n<b>\u0418\u0421\u0422\u041e\u0420\u0418\u042f \u0417\u0410\u041a\u0410\u0417\u0410:</b>\n{{ $('Admin Button Click (Trigger)').item.json.callback_query.message.text }}",
"additionalFields": {
"parse_mode": "HTML"
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
688,
336
],
"id": "6dbd2fe5-1897-4ac2-9b87-b514c14b7afe",
"name": "Update Admin Message (RU)",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "**Admin Refund Handler**\nTriggered when Admin clicks \"Cancel Order\" in Telegram.\n1. **Parse:** Decodes hidden data in the button (Phone, Amounts, Action type).\n2. **Auth:** Connects to iikoCard.\n3. **Route:** Determines refund type:\n * **Simple:** Just revoke points earned.\n * **Mixed:** Return spent points AND revoke points earned on cash part.\n4. **Update:** Changes message status to \"Cancelled\".",
"height": 288,
"width": 320
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-1664,
240
],
"typeVersion": 1,
"id": "873a0b51-a5c6-4609-8f74-75c49aab31b7",
"name": "Sticky Note1"
},
{
"parameters": {
"content": "**Refund Logic Router**\n* `undo_add`: Cancel accrual only (Customer didn't spend points).\n* `undo_mix`: Full reversal (Customer spent points + paid remaining cash).",
"height": 176
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-384,
112
],
"typeVersion": 1,
"id": "0b8126fa-5d63-4161-8449-02cbcc907342",
"name": "Sticky Note2"
},
{
"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\": \"{{ $('Router: Refund Type').item.json.id }}\",\n \"walletId\": \"my_id\",\n \"sum\": {{ $('Parse Button Data').item.json.amount2 }},\n \"comment\": \"Revoke Accrual (Order Cancelled)\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
192,
336
],
"id": "8309dee9-5664-4d80-bbc5-7922dacc02fe",
"name": "Revoke Cash-Part Points",
"retryOnFail": true,
"waitBetweenTries": 3000
}
],
"connections": {
"Admin Button Click (Trigger)": {
"main": [
[
{
"node": "Parse Button Data",
"type": "main",
"index": 0
}
]
]
},
"Parse Button Data": {
"main": [
[
{
"node": "iiko Auth (Get Token)",
"type": "main",
"index": 0
}
]
]
},
"iiko Auth (Get Token)": {
"main": [
[
{
"node": "Fetch Customer Wallet",
"type": "main",
"index": 0
}
]
]
},
"Fetch Customer Wallet": {
"main": [
[
{
"node": "Router: Refund Type",
"type": "main",
"index": 0
}
]
]
},
"Router: Refund Type": {
"main": [
[
{
"node": "Revoke Accrued Points",
"type": "main",
"index": 0
}
],
[
{
"node": "Refund: Return Spent Points",
"type": "main",
"index": 0
}
]
]
},
"Revoke Accrued Points": {
"main": [
[
{
"node": "Stop Button Loading",
"type": "main",
"index": 0
}
]
]
},
"Refund: Return Spent Points": {
"main": [
[
{
"node": "Revoke Cash-Part Points",
"type": "main",
"index": 0
}
]
]
},
"Stop Button Loading": {
"main": [
[
{
"node": "Update Admin Message (RU)",
"type": "main",
"index": 0
}
]
]
},
"Revoke Cash-Part Points": {
"main": [
[
{
"node": "Stop Button Loading",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"availableInMCP": false,
"timeSavedMode": "fixed",
"timezone": "Asia/Almaty",
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "hqRcKQkYO4KNl7CpVzjbg"
},
"versionId": "7e4467d2-02ab-4356-91f6-c4f751339fec",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "2G2CemAcy0HxpbjE_CMQo",
"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.
telegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
Effortlessly manage customer refunds in your hospitality business by automating the process from a simple Telegram message, saving hours of manual admin work and reducing errors in handling points and payments. This workflow suits small business owners or admins dealing with loyalty programmes integrated with iiko, allowing you to process refunds securely without switching apps. The key step involves a Telegram trigger that captures button clicks, routes the request based on refund type, and uses HTTP requests to authenticate with iiko, fetch wallet details, and revoke accrued points seamlessly.
Use this workflow when you need quick, event-driven refunds triggered via Telegram for iiko-based operations, such as revoking loyalty points after a customer cancellation. Avoid it for non-iiko systems or high-volume enterprises requiring advanced compliance logging. Common variations include adding email notifications post-refund or integrating with accounting tools like Xero for full financial reconciliation.
About this workflow
03_admin_refund_handler. Uses stickyNote, telegramTrigger, httpRequest, telegram. Event-driven trigger; 14 nodes.
Source: https://github.com/gulnaz-bakinova/n8n-automation-integrations-showcase/blob/main/03_admin_refund_handler.json — 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.
N8N Complete Final. Uses telegramTrigger, dataTable, telegram, mqtt. Event-driven trigger; 58 nodes.
TextMain. Uses telegramTrigger, stopAndError, telegram, httpRequest. Event-driven trigger; 56 nodes.
Pede Ai. Uses httpRequest, telegram, postgres, telegramTrigger. Event-driven trigger; 53 nodes.
📄 Documentation: Notion Guide
Telegram Wait. Uses stickyNote, httpRequest, redis, noOp. Event-driven trigger; 36 nodes.