跳转到内容

Webhooks

After status=PAID and the configured confirmation threshold, we POST to the notifyUrl from payment creation.

Use Webhook Secret (not API Secret):

expected = HMAC-SHA256(webhookSecret, t + "." + rawBody).hex()

Compare v1 from X-Influx-Signature with a constant-time equality check.

HeaderDescription
X-Influx-EventAlways payment.paid
X-Influx-Signaturet=<unix>,v1=<hex>
X-Influx-DeliveryUnique delivery ID for idempotency
POST https://merchant.example.com/webhook
Content-Type: application/json
X-Influx-Event: payment.paid
X-Influx-Signature: t=1714291800,v1=abc123...
X-Influx-Delivery: dl_01HYYY...
{
"event": "payment.paid",
"paymentId": "p_01HXXX...",
"orderNo": "ORDER-20260428-0001",
"txId": "abc123def456...",
"tokenSymbol": "USDT",
"paymentNetwork": "TRC20",
"amount": "10.50",
"amountRaw": "10500000",
"blockNum": "62000000",
"confirmations": 8,
"paidAt": "2026-04-28T16:32:10.000Z"
}

blockNum / confirmations may be null when no on-chain record exists.

Return HTTP 2xx within 5 seconds (body optional). Other statuses or timeouts trigger retries (up to 8 attempts, exponential backoff).

HTTP/1.1 200 OK
Content-Type: application/json
{ "ok": true }

Any 2xx status counts as success.

Deduplicate using X-Influx-Delivery or paymentId.

rawBody = raw HTTP body bytes
parse X-Influx-Signature -> t, v1
expected = HMAC-SHA256(webhookSecret, t + "." + rawBody).hex()
assert timing-safe-equal(v1, expected)