{
  "name": "Mercanta \u2014 WA Bot",
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "nodes": [
    {
      "id": "b0000001-0000-0000-0000-000000000001",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        240,
        600
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "wa-bot",
        "responseMode": "onReceived",
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000003",
      "name": "Parse & Intent",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        600
      ],
      "parameters": {
        "jsCode": "// \u2500\u2500 Extract message from Evolution API payload \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst body = $input.item.json.body || $input.item.json;\nconst data = body?.data || body;\nconst jid = data?.key?.remoteJid || '';\nconst sender = jid.replace('@s.whatsapp.net','').replace('@g.us','');\nconst isFromMe = data?.key?.fromMe === true;\nconst isGroup = jid.includes('@g.us');\nconst msgObj = data?.message || {};\nconst firstKey = Object.keys(msgObj)[0] || '';\n\nlet text = '';\nif (firstKey === 'conversation') text = msgObj.conversation || '';\nelse if (firstKey === 'extendedTextMessage') text = msgObj.extendedTextMessage?.text || '';\ntext = text.trim();\n\n// \u2500\u2500 Config \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst BUSINESS_ACCOUNT_ID = 'd72e900f-a09e-4b8c-bf77-aff843ef754a';\n\n// \u2500\u2500 Ignore non-text, own messages, groups \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nif (!text || isFromMe || isGroup) {\n  return [{ json: { intent: 'ignore', sender, text, itemName: '', qty: 1, BUSINESS_ACCOUNT_ID } }];\n}\n\n// \u2500\u2500 Classify intent \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Best routing: single classification here keeps Switch node simple and testable.\nconst lower = text.toLowerCase();\nlet intent = 'buy'; // default: treat unrecognized text as item name\nlet itemName = text;\nlet qty = 1;\n\nif (/^(hi|hello|hey|start|menu|food|list|what|show|namaste|hola|help)\\b/i.test(lower)) {\n  intent = 'menu'; itemName = '';\n\n} else if (/^(status|token|my order|track|where|when will|order status)\\b/i.test(lower)) {\n  intent = 'status'; itemName = '';\n\n} else if (/^(receipt|bill|invoice)\\b/i.test(lower)) {\n  intent = 'receipt'; itemName = '';\n\n} else if (/^(buy|order|get|give me|i want)\\s/i.test(lower)) {\n  // Parse 'buy Butter Chicken 2' \u2192 itemName='Butter Chicken', qty=2\n  const m = text.match(/^(?:buy|order|get|give me|i want)\\s+(.+)/i);\n  if (m) {\n    const parts = m[1].trim().split(/\\s+/);\n    const last = parseInt(parts[parts.length - 1]);\n    if (!isNaN(last) && last > 0 && parts.length > 1) {\n      qty = last;\n      itemName = parts.slice(0, -1).join(' ');\n    } else {\n      itemName = m[1].trim();\n    }\n  }\n  // else: itemName stays as full text (default)\n}\n\nreturn [{ json: { intent, sender, text, itemName, qty, BUSINESS_ACCOUNT_ID } }];"
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000004",
      "name": "Intent Router",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 1,
      "position": [
        720,
        600
      ],
      "parameters": {
        "dataType": "string",
        "value1": "={{ $json.intent }}",
        "rules": {
          "rules": [
            {
              "value2": "ignore"
            },
            {
              "value2": "menu"
            },
            {
              "value2": "buy"
            },
            {
              "value2": "status"
            },
            {
              "value2": "receipt"
            }
          ]
        },
        "fallbackOutput": 5
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000005",
      "name": "Fetch Menu",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        960,
        400
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT id, category, item_name, price, is_vegetarian, is_spicy FROM restaurant_menu WHERE business_account_id = '{{ $('Parse & Intent').item.json.BUSINESS_ACCOUNT_ID }}' AND is_available = true ORDER BY category, sort_order, item_name;",
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000006",
      "name": "Format Menu",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        400
      ],
      "parameters": {
        "jsCode": "const rows = $input.all();\nif (!rows.length) return [{ json: { reply: 'Sorry, no items available right now. Check back soon!' } }];\n\nlet out = '*Mercanta Menu*\\n\\n';\nlet cat = '';\nfor (const r of rows) {\n  const i = r.json;\n  if (i.category !== cat) { cat = i.category; out += `*${cat}*\\n`; }\n  const tags = [];\n  if (i.is_vegetarian) tags.push('\ud83c\udf3f');\n  if (i.is_spicy) tags.push('\ud83c\udf36');\n  out += `  \u2022 ${i.item_name}${tags.length ? ' '+tags.join('') : ''} \u2014 \u20b9${parseFloat(i.price).toFixed(0)}\\n`;\n}\nout += '\\n_Just type an item name to order, e.g._ *Paneer Tikka*\\n_Type *status* to track your order_';\nreturn [{ json: { reply: out } }];"
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000007",
      "name": "Send WA: Menu",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 3,
      "position": [
        1440,
        400
      ],
      "parameters": {
        "method": "POST",
        "url": "http://evolution-api:8080/message/sendText/musaib_bot",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "Musaib_2026_Secure"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "number",
              "value": "={{ $('Parse & Intent').item.json.sender }}"
            },
            {
              "name": "text",
              "value": "={{ $json.reply }}"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000008",
      "name": "Lookup Item",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        960,
        600
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT id, item_name, category, price FROM restaurant_menu WHERE business_account_id = '{{ $json.BUSINESS_ACCOUNT_ID }}' AND is_available = true AND LOWER(item_name) LIKE LOWER('%{{ $json.itemName.replace(/'/g, \"''\") }}%') ORDER BY CASE WHEN LOWER(item_name) = LOWER('{{ $json.itemName.replace(/'/g, \"''\") }}') THEN 0 ELSE 1 END, item_name LIMIT 1;",
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000009",
      "name": "Build Order",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        600
      ],
      "parameters": {
        "jsCode": "const rows = $input.all();\nconst ctx = $('Parse & Intent').item.json;\n\nif (!rows.length || !rows[0].json.id) {\n  return [{ json: {\n    found: false,\n    reply: `Sorry, *${ctx.itemName}* isn't available. Type *menu* to see what we have.`,\n    sender: ctx.sender\n  } }];\n}\n\nconst item = rows[0].json;\nconst qty = ctx.qty || 1;\nconst total = parseFloat(item.price) * qty;\n\nreturn [{ json: {\n  found: true,\n  itemId: item.id,\n  itemName: item.item_name,\n  price: parseFloat(item.price),\n  qty,\n  total,\n  totalPaise: Math.round(total * 100),\n  sender: ctx.sender,\n  BUSINESS_ACCOUNT_ID: ctx.BUSINESS_ACCOUNT_ID\n} }];"
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000010",
      "name": "Item Found?",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 1,
      "position": [
        1440,
        600
      ],
      "parameters": {
        "dataType": "boolean",
        "value1": "={{ $json.found }}",
        "rules": {
          "rules": [
            {
              "value2": true
            }
          ]
        },
        "fallbackOutput": 1
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000011",
      "name": "Create Payment Link",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 3,
      "position": [
        1680,
        500
      ],
      "credentials": {
        "httpBasicAuth": {
          "name": "<your credential>"
        }
      },
      "parameters": {
        "method": "POST",
        "url": "https://api.razorpay.com/v1/payment_links",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "sendBody": true,
        "contentType": "json",
        "body": "={{ JSON.stringify({ amount: $json.totalPaise, currency: 'INR', accept_partial: false, description: `Order: ${$json.qty}x ${$json.itemName}`, customer: { contact: `+${$json.sender}` }, notify: { whatsapp: false, sms: false }, reminder_enable: false, notes: { item_name: $json.itemName, qty: $json.qty, sender: $json.sender, business_account_id: $json.BUSINESS_ACCOUNT_ID, item_id: $json.itemId, price: $json.price } }) }}",
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000012",
      "name": "Save Pending Sale",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        1920,
        500
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO sales (customer_name, total, subtotal, payment_method, payment_details, business_account_id, is_restaurant_order) VALUES ('WhatsApp Customer', {{ $('Build Order').item.json.total }}, {{ $('Build Order').item.json.total }}, 'upi', jsonb_build_object('razorpay_payment_link_id', '{{ $('Create Payment Link').item.json.id }}', 'status', 'pending', 'sender', '{{ $('Build Order').item.json.sender }}'), '{{ $('Build Order').item.json.BUSINESS_ACCOUNT_ID }}', true) RETURNING id;",
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000013",
      "name": "Save Sale Item",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        2160,
        500
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO sale_items (sale_id, sku, item_name, quantity, price) VALUES ('{{ $('Save Pending Sale').item.json.id }}', '{{ $('Build Order').item.json.itemId }}', '{{ $('Build Order').item.json.itemName.replace(/'/g, \"''\") }}', {{ $('Build Order').item.json.qty }}, {{ $('Build Order').item.json.price }});",
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000014",
      "name": "Format Pay Reply",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2400,
        500
      ],
      "parameters": {
        "jsCode": "const order = $('Build Order').item.json;\nconst link = $('Create Payment Link').item.json;\nconst reply = `*Order Summary*\\n\\n\ud83d\udce6 ${order.qty}\u00d7 ${order.itemName}\\n\ud83d\udcb0 Total: \u20b9${order.total.toFixed(0)}\\n\\n\ud83d\udcb3 *Pay to confirm your order:*\\n${link.short_url}\\n\\n_Your token number will be sent once payment is received._\\n_Type *status* to track anytime._`;\nreturn [{ json: { reply } }];"
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000015",
      "name": "Send WA: Pay",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 3,
      "position": [
        2640,
        500
      ],
      "parameters": {
        "method": "POST",
        "url": "http://evolution-api:8080/message/sendText/musaib_bot",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "Musaib_2026_Secure"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "number",
              "value": "={{ $('Parse & Intent').item.json.sender }}"
            },
            {
              "name": "text",
              "value": "={{ $json.reply }}"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000016",
      "name": "Format Not Found",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1680,
        700
      ],
      "parameters": {
        "jsCode": "return [{ json: { reply: $json.reply } }];"
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000017",
      "name": "Send WA: Not Found",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 3,
      "position": [
        1920,
        700
      ],
      "parameters": {
        "method": "POST",
        "url": "http://evolution-api:8080/message/sendText/musaib_bot",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "Musaib_2026_Secure"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "number",
              "value": "={{ $('Parse & Intent').item.json.sender }}"
            },
            {
              "name": "text",
              "value": "={{ $json.reply }}"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000018",
      "name": "Lookup Status",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        960,
        800
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT ot.token_number, ot.status, ot.created_at, ot.ready_at, tqs.estimated_minutes, si.item_name, si.quantity FROM order_tokens ot JOIN sales s ON s.id = ot.sale_id JOIN sale_items si ON si.sale_id = s.id LEFT JOIN token_queue_status tqs ON tqs.token_id = ot.id LEFT JOIN customers c ON c.id = s.customer_id WHERE (c.phone = '{{ $json.sender }}' OR s.payment_details->>'sender' = '{{ $json.sender }}') AND ot.is_active = true AND ot.business_account_id = '{{ $json.BUSINESS_ACCOUNT_ID }}' ORDER BY ot.created_at DESC LIMIT 1;",
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000019",
      "name": "Format Status",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        800
      ],
      "parameters": {
        "jsCode": "const rows = $input.all();\nif (!rows.length || !rows[0].json.token_number) {\n  return [{ json: { reply: 'No active orders found. Type *menu* to browse our items.' } }];\n}\nconst t = rows[0].json;\nconst statusEmoji = { ordered:'\ud83d\udd50', confirmed:'\u2705', preparing:'\ud83d\udc68\u200d\ud83c\udf73', prepared:'\ud83c\udf7d', ready:'\ud83d\udd14', served:'\u2705', cancelled:'\u274c' };\nconst emoji = statusEmoji[t.status] || '\ud83d\udd50';\nlet reply = `${emoji} *Token #${t.token_number}*\\n\\nStatus: *${t.status.toUpperCase()}*\\n\ud83d\udce6 ${t.item_name} \u00d7${t.quantity}`;\nif (t.estimated_minutes) reply += `\\n\u23f1 Est. wait: ~${t.estimated_minutes} min`;\nif (t.status === 'ready') reply += '\\n\\n*Your order is ready for pickup!*\\nPlease collect at the counter.';\nreturn [{ json: { reply } }];"
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000020",
      "name": "Send WA: Status",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 3,
      "position": [
        1440,
        800
      ],
      "parameters": {
        "method": "POST",
        "url": "http://evolution-api:8080/message/sendText/musaib_bot",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "Musaib_2026_Secure"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "number",
              "value": "={{ $('Parse & Intent').item.json.sender }}"
            },
            {
              "name": "text",
              "value": "={{ $json.reply }}"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000021",
      "name": "Lookup Receipt",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        960,
        1000
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT s.date, s.total, s.token_number, si.item_name, si.quantity, si.price, ot.status as order_status FROM sales s JOIN sale_items si ON si.sale_id = s.id LEFT JOIN order_tokens ot ON ot.sale_id = s.id LEFT JOIN customers c ON c.id = s.customer_id WHERE (c.phone = '{{ $json.sender }}' OR s.payment_details->>'sender' = '{{ $json.sender }}') AND s.business_account_id = '{{ $json.BUSINESS_ACCOUNT_ID }}' AND s.is_restaurant_order = true ORDER BY s.date DESC LIMIT 5;",
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000022",
      "name": "Format Receipt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        1000
      ],
      "parameters": {
        "jsCode": "const rows = $input.all();\nif (!rows.length || !rows[0].json.date) {\n  return [{ json: { reply: 'No orders found yet. Type *menu* to browse.' } }];\n}\nconst latest = rows[0].json;\nconst date = new Date(latest.date).toLocaleString('en-IN', { timeZone: 'Asia/Kolkata', day:'2-digit', month:'short', hour:'2-digit', minute:'2-digit', hour12:true });\nlet reply = `\ud83e\uddfe *Last Order*\\n\ud83d\udcc5 ${date}\\n\\n`;\nfor (const r of rows) {\n  reply += `  \u2022 ${r.json.item_name} \u00d7${r.json.quantity} @ \u20b9${parseFloat(r.json.price).toFixed(0)}\\n`;\n}\nreply += `\\n\ud83d\udcb0 *Total: \u20b9${parseFloat(latest.total).toFixed(0)}*`;\nif (latest.token_number) reply += `\\n\ud83c\udfab Token: *#${latest.token_number}*`;\nif (latest.order_status) reply += `\\n\ud83d\udccb Status: ${latest.order_status}`;\nreturn [{ json: { reply } }];"
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000023",
      "name": "Send WA: Receipt",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 3,
      "position": [
        1440,
        1000
      ],
      "parameters": {
        "method": "POST",
        "url": "http://evolution-api:8080/message/sendText/musaib_bot",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "Musaib_2026_Secure"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "number",
              "value": "={{ $('Parse & Intent').item.json.sender }}"
            },
            {
              "name": "text",
              "value": "={{ $json.reply }}"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000024",
      "name": "Format Help",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        960,
        1200
      ],
      "parameters": {
        "jsCode": "return [{ json: { reply: '*Welcome to Mercanta!*\\n\\nHere is what you can do:\\n  *menu* \u2014 browse our menu\\n  *<item name>* \u2014 type any item to order\\n  *buy <item> <qty>* \u2014 order with quantity\\n  *status* \u2014 track your current order\\n  *receipt* \u2014 view your last order\\n\\n_Example: type_ *Paneer Tikka* _or_ *buy Butter Chicken 2*' } }];"
      }
    },
    {
      "id": "b0000001-0000-0000-0000-000000000025",
      "name": "Send WA: Help",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 3,
      "position": [
        1200,
        1200
      ],
      "parameters": {
        "method": "POST",
        "url": "http://evolution-api:8080/message/sendText/musaib_bot",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "Musaib_2026_Secure"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "number",
              "value": "={{ $('Parse & Intent').item.json.sender }}"
            },
            {
              "name": "text",
              "value": "={{ $json.reply }}"
            }
          ]
        },
        "options": {}
      }
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Parse & Intent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse & Intent": {
      "main": [
        [
          {
            "node": "Intent Router",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Intent Router": {
      "main": [
        [],
        [
          {
            "node": "Fetch Menu",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Lookup Item",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Lookup Status",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Lookup Receipt",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Help",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Menu": {
      "main": [
        [
          {
            "node": "Format Menu",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Menu": {
      "main": [
        [
          {
            "node": "Send WA: Menu",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup Item": {
      "main": [
        [
          {
            "node": "Build Order",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Order": {
      "main": [
        [
          {
            "node": "Item Found?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Item Found?": {
      "main": [
        [
          {
            "node": "Create Payment Link",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Not Found",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Payment Link": {
      "main": [
        [
          {
            "node": "Save Pending Sale",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Pending Sale": {
      "main": [
        [
          {
            "node": "Save Sale Item",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Sale Item": {
      "main": [
        [
          {
            "node": "Format Pay Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Pay Reply": {
      "main": [
        [
          {
            "node": "Send WA: Pay",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Not Found": {
      "main": [
        [
          {
            "node": "Send WA: Not Found",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup Status": {
      "main": [
        [
          {
            "node": "Format Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Status": {
      "main": [
        [
          {
            "node": "Send WA: Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup Receipt": {
      "main": [
        [
          {
            "node": "Format Receipt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Receipt": {
      "main": [
        [
          {
            "node": "Send WA: Receipt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Help": {
      "main": [
        [
          {
            "node": "Send WA: Help",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}