{
  "name": "HivePay → credit the user",
  "nodes": [
    {
      "parameters": {
        "content": "## HivePay → credit the user\n\n1. Open **Look up the payment** and replace `https://www.hivepay.asia` with your HivePay URL, then pick your *HivePay API key* credential (Header Auth: name `Authorization`, value `Bearer hp_live_…`).\n2. Replace **Credit the user (replace me)** with what actually gives the credit — Google Sheets append, Postgres insert, or an HTTP Request to your own site.\n3. Activate the workflow, copy the **Production URL** of the *HivePay webhook* node and give it to the HivePay operator as your project's webhook URL.\n\nTest events from the portal (`test: true`, reference `HP-TEST-…`) are recognised first and ignored, so pressing *Send test event* never credits anyone and never turns an execution red.\n\nWhy it looks up the payment instead of trusting the body: no crypto needed — the unguessable reference + your API key make the lookup the source of truth.",
        "height": 400,
        "width": 480
      },
      "name": "Read me",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -40,
        -420
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "hivepay",
        "responseMode": "onReceived",
        "options": {}
      },
      "name": "HivePay webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        0
      ],
      "webhookId": "hivepay-payment-events"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "is-test",
              "leftValue": "={{ $json.body.test === true || String($json.body.data.reference).startsWith('HP-TEST-') }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Is it a test event?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        260,
        0
      ]
    },
    {
      "parameters": {},
      "name": "Test event — nothing to do",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        520,
        -160
      ]
    },
    {
      "parameters": {
        "url": "=https://www.hivepay.asia/api/v1/payments/{{ $json.body.data.reference }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {}
      },
      "name": "Look up the payment",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        520,
        40
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "status-is-paid",
              "leftValue": "={{ $json.data.status }}",
              "rightValue": "PAID",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "Is it PAID?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        780,
        40
      ]
    },
    {
      "parameters": {
        "operation": "removeItemsSeenInPreviousExecutions",
        "dedupeValue": "={{ $json.data.reference }}",
        "options": {}
      },
      "name": "Skip if already credited",
      "type": "n8n-nodes-base.removeDuplicates",
      "typeVersion": 2,
      "position": [
        1040,
        -60
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "user",
              "name": "userId",
              "value": "={{ $json.data.externalUserId }}",
              "type": "string"
            },
            {
              "id": "credits",
              "name": "credits",
              "value": "={{ $json.data.creditAmount }}",
              "type": "number"
            },
            {
              "id": "unit",
              "name": "creditName",
              "value": "={{ $json.data.creditName }}",
              "type": "string"
            },
            {
              "id": "ref",
              "name": "reference",
              "value": "={{ $json.data.reference }}",
              "type": "string"
            },
            {
              "id": "amount",
              "name": "amountMMK",
              "value": "={{ $json.data.amountMMK }}",
              "type": "number"
            },
            {
              "id": "order",
              "name": "orderId",
              "value": "={{ $json.data.metadata && $json.data.metadata.orderId }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "name": "Credit the user (replace me)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1300,
        -60
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "ref2",
              "name": "reference",
              "value": "={{ $json.data.reference }}",
              "type": "string"
            },
            {
              "id": "st",
              "name": "status",
              "value": "={{ $json.data.status }}",
              "type": "string"
            },
            {
              "id": "why",
              "name": "failureReason",
              "value": "={{ $json.data.failureReason }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "name": "Not paid (mark the order)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1040,
        180
      ]
    },
    {
      "parameters": {
        "content": "**Dedupe:** *Skip if already credited* remembers every reference it has passed (n8n ≥ 1.64). If your n8n is older, delete it and instead check your own sheet/table for the reference before crediting. HivePay retries and redeliveries reuse the same reference, so this step is what stops double credits.",
        "height": 160,
        "width": 380
      },
      "name": "About dedupe",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1020,
        -280
      ]
    }
  ],
  "connections": {
    "HivePay webhook": {
      "main": [
        [
          {
            "node": "Is it a test event?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Look up the payment": {
      "main": [
        [
          {
            "node": "Is it PAID?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is it PAID?": {
      "main": [
        [
          {
            "node": "Skip if already credited",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Not paid (mark the order)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Skip if already credited": {
      "main": [
        [
          {
            "node": "Credit the user (replace me)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is it a test event?": {
      "main": [
        [
          {
            "node": "Test event — nothing to do",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Look up the payment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {}
}
