> For the complete documentation index, see [llms.txt](https://docs.banxa.com/llms.txt). Append `.md` to any page URL for its markdown version.


You may receive webhooks when certain order statuses are reached. This is an optional configuration that can reduce the number of API requests you need to send to Banxa.

## Before you begin

* Log into [Banxa Dashboard](https://dashboard.banxa.com/) and configure your webhook URL's which Banxa will use to send your webhooks. You will be able to configure separate webhook URLs for both Sandbox and Production environments.
* Otherwise feel free to contact your Account Manager with your Webhook URLs.


## Using Webhooks

After we have configured your webhook URLs, webhooks will be sent to this URL when an order has changed status. A webhook notification will be sent via **HTTP POST** in the below format.

> **Transition to Webhooks v2 from March 1st:** From March 1st, we will be transitioning from a Legacy Webhook System to it's newer version 2.


### Webhook v2

```json
{
  "order_id": "d9efc5d228cb7edfc4b6bb82f7b39f94",
  "status": "complete",
  "status_date": "2026-01-1604:04:21",
  "created_at": "2026-01-1604:04:20",
  "updated_at": "2026-01-1604:04:20",
  "external_id": null,
  "order_type": "BUY",
  "crypto_coin": "USDT",
  "crypto_blockchain": "ETH",
  "crypto_amount": "67.1000000000000000",
  "fiat_currency": "AUD",
  "fiat_amount": "100",
  "asset_price": "1.490312965722801",
  "payment_method": "payid-bank-transfer",
  "processing_fee": "0",
  "network_fee": "0",
  "usd_exchange_rate": "1.4923330",
  "transaction_hash": "0",
  "metadata": []
}
```

### Legacy System

```json
{
  "order_id": "3526ccb0e20f31de92hec732c37bb683"
}
```

When you receive a webhook, you can call the Get Order endpoint in the [API Reference](/products/legacy-api/openapi) to retrieve detailed order information. This ensures that you do not act on calls from bad actors with incorrect information.

## Securing Webhooks

Banxa signs every webhook it sends using HMAC-SHA256. You verify this signature to confirm the request genuinely came from Banxa.

> **Webhook verification is the reverse of request signing.** When you sign outbound API requests to Banxa, you use a Banxa API path in the canonical string. When you verify an incoming webhook, you use the URI path of **your own webhook endpoint** — for example `/webhooks/banxa` — not a Banxa API path. Everything else follows the same algorithm described in [Step 3: Authentication](/products/legacy-api/docs/on-ramp-off-ramp/on-ramp-api-tutorial/step-3-authentication).


Each webhook arrives with an `Authorization` header:

```
Authorization: Bearer {API Key}:{Signature}:{Nonce}
```

The nonce Banxa sends is 16 digits
Banxa generates the webhook nonce as a Unix timestamp in **microseconds — 16 digits**, not the 13 digits of a millisecond timestamp:

|  | Value | Digits |
|  --- | --- | --- |
| What Banxa sends | `1785804345837761` | 16 |
| A millisecond timestamp | `1785804345837` | 13 |


A real header looks like this:

```
Authorization: Bearer pk_2f8c91ab4d7e:4a7f2c9e81b3d6058f1e2a7c4b9d3e6f8a1c5b2d7e4f9a3c6b8d1e5f2a7c4b9d:1785804345837761
```

Treat the nonce as an **opaque string**: read it from the `Authorization` header and pass it into the canonical string exactly as received. Do not parse it as a date, truncate it, convert it, or regenerate it — and do not validate it against a fixed digit length. Doing any of these produces a signature mismatch.

To verify:

1. Extract and parse the `Authorization` header — split on `:` to get the key, signature, and nonce
2. Construct the canonical string using `POST`, **your webhook endpoint path**, the nonce, and the JSON payload
3. Compute HMAC-SHA256 of that string using your API secret
4. Compare the result to the received signature using a **timing-safe comparison**


**Note:** Use a timing-safe comparison function (not `==`) to prevent timing-based attacks.

## Webhook Events

A webhook will be triggered and sent to your URL on all Order status transitions. The full list of order statuses can be found [here](/products/legacy-api/docs/resources/order-status)

> Please note that if you are testing Webhooks in sandbox, you will only receive them when an order has transitioned to `EXPIRED`, as orders in our sandbox environment are not live orders where the cryptocurrency can be transferred to the user.