{
  "name": "Nodbot - 1C HTTP order exchange with idempotency",
  "nodes": [
    {
      "parameters": {
        "path": "1c-http-order-exchange",
        "responseMode": "responseNode",
        "httpMethod": "POST"
      },
      "id": "1",
      "name": "Webhook input",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "const src = $json.body ?? $json;\nconst externalOrderId = String(src.external_order_id ?? '').trim();\nif (!externalOrderId) throw new Error('No external_order_id for 1C exchange');\nconst items = Array.isArray(src.items) ? src.items : [];\nif (!items.length) throw new Error(`Order ${externalOrderId} has no items`);\nconst payloadFor1c = {\n  НомерВнешний: externalOrderId,\n  Идемпотентность: src.idempotency_key ?? `shop:order:${externalOrderId}:create`,\n  Клиент: {\n    Наименование: String(src.customer?.name ?? '').trim(),\n    Телефон: String(src.customer?.phone ?? '').replace(/[^0-9+]/g, ''),\n    ИНН: String(src.customer?.inn ?? '').replace(/\\D/g, '')\n  },\n  Товары: items.map(i => ({ Артикул: String(i.sku).trim(), Количество: Number(i.qty), Цена: Number(i.price) })),\n  Оплата: src.payment_status ?? 'unknown',\n  Доставка: src.delivery ?? {},\n  ДатаПолучения: new Date().toISOString()\n};\nreturn [{ json: { idempotency_key: payloadFor1c.Идемпотентность, endpoint: '/hs/n8n/orders', payload_for_1c: payloadFor1c } }];"
      },
      "id": "2",
      "name": "Normalize and validate",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        240,
        0
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO integration_events (idempotency_key, payload, created_at) VALUES ($1, $2, now()) ON CONFLICT (idempotency_key) DO NOTHING RETURNING id;"
      },
      "id": "3",
      "name": "Check idempotency",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        480,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{$env.TARGET_API_URL}}",
        "sendBody": true,
        "contentType": "json",
        "jsonBody": "={{$json}}"
      },
      "id": "4",
      "name": "Call target API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        720,
        0
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { ok: true, idempotency_key: $json.idempotency_key } }}"
      },
      "id": "5",
      "name": "Respond 200",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        960,
        0
      ]
    }
  ],
  "connections": {
    "Webhook input": {
      "main": [
        [
          {
            "node": "Normalize and validate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize and validate": {
      "main": [
        [
          {
            "node": "Check idempotency",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check idempotency": {
      "main": [
        [
          {
            "node": "Call target API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call target API": {
      "main": [
        [
          {
            "node": "Respond 200",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  }
}