Payload
We POST this when an API order's status changes to 1, 2, 11, 23 or 24. A 24 is always followed by one more callback once we have confirmed the outcome. Reply 2xx within 10 seconds; otherwise we retry after 1 minute and after 5. Console orders get no webhook.
Fields
From order_id down, the fields are inside data: the same object
Check a status returns, plus
voucher.
event | Always order.updated here. Product
changes are product.updated and product.removed. |
meta.unix_timestamp | When the order reached this status. Keep the
newest per order_id and ignore anything older. |
order_id | Your reference. |
trx_id | Our reference. Always present. |
status | What to do next: 0, 1, 2, 11, 23 or 24. See Order status. |
failure_code | Why it failed. Null unless it failed. |
message | One sentence you can show a person. |
sku | The product ordered. |
target | The player account. Empty string on a gift card, which is delivered to nobody. |
nickname | The player name the supplier returned, when it returned one. |
sn | Supplier serial. Null unless delivered. Proof an order happened — not something to redeem. |
fee | Charged for this order, NPR. |
balance | Karauti balance after the fee, NPR. |
created_at | When the order was placed, ISO 8601. |
voucher | A gift card's redeemable code, when the order produced one. Null on every other order. Webhook only. This is money — see Gift cards. |
Test payloads carry "test": true. Reject those before delivering goods.
Callbacks come from 103.235.196.125. Allowlist it if you like, but verify the
signature regardless.
This is the order callback. The catalogue has its own stream — product updates — signed the same way, and pointable at a different URL.
Verifying
v1 is HMAC-SHA256 of timestamp . "." . raw body, keyed with the
whsec_ signing secret from Settings → Webhook. Not the API secret key.
Hash the raw body as received. Decoding and re-encoding the JSON changes the bytes and valid callbacks will fail the check.
- Reject a
tmore than 5 minutes old, so a captured callback cannot be replayed later. - The same order can arrive twice (a retry, or a manual Resend). Act once per
order_idandstatus.
Every callback failing the check usually means the two copies of the secret have drifted apart. An owner can read the current one back under Show secret on the Webhooks page — compare it with what your own config holds before changing anything else. Rotating issues a new one and signs with it immediately, so your site rejects every callback until the new value is deployed.
API documentation