Webhooks
We POST JSON when an order or payout changes. Acknowledge with the exact body success.
Events
| Event | When |
|---|---|
order.paid | Received amount covers the quote (within underpay tolerance) |
order.paid_partial | Partial funds |
order.paid_over | Over the quote plus overpay tolerance |
order.expired | Timer elapsed while still open |
order.cancelled | Payer cancelled checkout |
payout.submitted | Withdrawal accepted and sent on-chain |
payout.completed | On-chain payout confirmed |
payout.failed | Payout failed; available USD is credited back |
Destination is callback_url on the order or payout, or the URL saved under Notifications. Headers: X-Bytix-Event, X-Bytix-Signature. Content type is application/json. We POST once per status change — not once per on-chain transfer.
Ack
HTTP/1.1 200 OK
Content-Type: text/plain
successHTTP must be 2xx and the body must be exactly success (trimmed, case-insensitive). JSON such as { "ok": true } is a failure. We store the first 2,000 characters of the response as the error.
Signature
HMAC-SHA256 of the using your webhook secret. Compare the hex digest in constant time. Prefer the raw request bytes; re-serializing a parsed object can change key order and fail verification.
const crypto = require("node:crypto");
function verify(rawBody, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
const a = Buffer.from(signature, "utf8");
const b = Buffer.from(expected, "utf8");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Body
| Field | When |
|---|---|
event | Always. order.paid | paid_partial | paid_over | expired | cancelled |
event_type | Always. Suffix after order. |
cid | Always. Public payment id from create. |
order_id | Always. Your order id. |
payer_id | If sent on create. |
order_amount | Always. Decimal string. |
order_currency | Always. |
status | Always. Current order status. |
crypto_amount | After a quote is locked. |
asset_symbol | After a quote is locked. |
network_name | After a quote is locked. |
payment_address | After a quote is locked. |
txid | When a transfer matched. |
received_amount | When a transfer matched. |
payout_id | Payout events. Your payout id from create. |
id | Payout events. Bytix payout id. |
amount | Payout events. USD decimal string. |
asset | Payout events. Ticker sent on-chain. |
network | Payout events. Network display name. |
address | Payout events. Destination address. |
Retry
Failed rows appear under Settings → Notifications. Retry sends the same payload again with a fresh signature. Fix your ack first or the retry will fail too. We do not auto-replay on a schedule — use Retry in the portal after you fix the endpoint.