# Order Notifications

To receive order notifications, you can either provide a <mark style="color:red;">`responseUrl`</mark> per order or define a merchant-level webhook on the “Developers” page within the [**Swapped.com Dashboard**](https://dashboard.swapped.com/developers). You will receive the notification via the provided URL. In the header of the HTTP request, there’s a signature to validate that the data comes from Swapped.com.

The callback destination is locked at order creation and cannot be changed.

### Callback Config Priority

The system follows a clear priority structure for determining where to send callbacks.

* If a responseURL is provided in the iframe initialization URL, this will be used as a priority.
* If a responseURL is not provided, but a callback URL is configured via the [Swapped.com dashboard](https://dashboard.swapped.com/developers), this will be used.
* If neither responseURL nor callback URL is set, callbacks will be disabled for this order.

This configuration is locked in when the order is created and cannot be changed, even if you later update your merchant-level webhook settings.

### Best Practices

Order notifications can be resent to account for network errors. As such, <mark style="color:red;">you</mark> <mark style="color:red;"></mark><mark style="color:red;">**must**</mark> <mark style="color:red;"></mark><mark style="color:red;">validate that a transaction has not been credited</mark> before crediting it.

For more information on notification resending, see the [Order Notification Retry Policy](https://docs.swapped.com/#order-notification-retry-policy).

### Callback examples:

#### Payment Pending:

The transaction was created, but the payment is still incomplete.

```json
{
  "order_id": "16a285c1-b04e-4b9f-b35d-a68fc292229e",
  "external_transaction_id": null,
  "external_customer_id": null,
  "order_status": "payment_pending",
  "order_crypto": "LTC",
  "order_type": "sell",
  "order_crypto_amount": "1.1880399307349",
  "order_crypto_address": "ltc1qgydf26ffh3zen6k75ye568rpqmes7fx4daqvrg",
  "order_crypto_tag": null,
  "order_amount_usd": 109.38,
  "order_amount_usd_plus_fees": 116.01,
  "order_amount_eur": 94.29,
  "order_amount_eur_plus_fees": 100,
  "network": "litecoin"
}
```

#### Payout pending:

Indicates that the cryptocurrency transaction has been confirmed on the chain and the payout to the user is pending.

```json
{
  "order_id": "81f2fcff-a81c-4e5a-8377-14bbe23fb1ef",
  "external_transaction_id": null,
  "external_customer_id": null,
  "order_status": "payout_pending",
  "order_crypto": "SOL",
  "order_type": "sell",
  "order_crypto_amount": 0.060096622,
  "order_crypto_address": "7frXvz2EutQmsmX6mgFMTE9MPuLsSPT2mgEro2EzPoNz",
  "order_crypto_tag": null,
  "order_amount_usd": 10.21,
  "order_amount_usd_plus_fees": 10.45,
  "order_amount_eur": 8.8,
  "order_amount_eur_plus_fees": 9.01,
  "network": "solana",
  "transaction_id": "C2237DF9D3268F715A80E48BF20D860C495B9726F28097A9AA18399F49BB7342"
}
```

#### Order Completed:

Indicates that the order has been processed, and the sale of cryptocurrency was successful.

```json
{
  "order_id": "81f2fcff-a81c-4e5a-8377-14bbe23fb1ef",
  "external_transaction_id": null,
  "external_customer_id": null,
  "order_status": "order_completed",
  "order_crypto": "SOL",
  "order_type": "sell",
  "order_crypto_amount": "0.060096622",
  "order_crypto_address": "7frXvz2EutQmsmX6mgFMTE9MPuLsSPT2mgEro2EzPoNz",
  "order_crypto_tag": null,
  "order_amount_usd": 10.21,
  "order_amount_usd_plus_fees": 10.45,
  "order_amount_eur": 8.8,
  "order_amount_eur_plus_fees": 9.01,
  "network": "solana",
  "transaction_id": "C2237DF9D3268F715A80E48BF20D860C495B9726F28097A9AA18399F49BB7342"
}
```

#### Order Cancelled:

Indicates that the order is cancelled for any reason, such as payment failure or user cancellation.

```json
{
  "order_id": "16a285c1-b04e-4b9f-b35d-a68fc292229e",
  "external_transaction_id": null,
  "external_customer_id": null,
  "order_status": "order_cancelled",
  "order_crypto": "LTC",
  "order_type": "sell"
}
```

### Response Definition:

* <mark style="color:red;">`order_id`</mark>: The order ID on Swapped.com.
* <mark style="color:red;">`order_crypto_amount`</mark>: The exact cryptocurrency amount you will receive.
* <mark style="color:red;">`order_crypto`</mark>: The cryptocurrency you receive.
* <mark style="color:red;">`order_status`</mark>: The current status of the order.
* <mark style="color:red;">`order_crypto_address`</mark>: The cryptocurrency address where you receive the cryptocurrency.
* <mark style="color:red;">`external_customer_id`</mark>: Your customer's ID (If provided in the URL).
* <mark style="color:red;">`order_amount_usd`</mark>: The <mark style="color:orange;">`order_crypto_amount`</mark> converted to USD (Mid-market rates without spread). This does not include the platform fee.
* <mark style="color:red;">`order_crypto_tag`</mark>: The destination tag/memo of the order (often used with e.g. XRP or TON)
* <mark style="color:red;">`order_amount_usd_plus_fees`</mark>: The <mark style="color:red;">`order_amount_usd`</mark> plus the platform fee.
* <mark style="color:red;">`network`</mark>: The network used to send transactions.
* <mark style="color:red;">`order_type`</mark>: Indicator if the order is a buy or sell order.
* <mark style="color:red;">`transaction_id`</mark>: The crypto transaction hash.

### Order State Flows

An order can follow one of two possible state flows:

Flow 1: This is applied when an order gets completed successfully and the user receives crypto:

<mark style="color:red;">`payment_pending`</mark> →<mark style="color:red;">`order_processing`</mark>→<mark style="color:red;">`payout_pending`</mark>→ <mark style="color:red;">`order_completed`</mark>

Flow 2: This occurs when an order gets cancelled for any reason, and the user does not receive crypto:

<mark style="color:red;">`payment_pending`</mark> → <mark style="color:red;">`order_cancelled`</mark>

Both <mark style="color:red;">`order_completed`</mark> and <mark style="color:red;">`order_cancelled`</mark> are final states that correspond to a finalized swapped.com order ID. This means that an order will **never** go from a <mark style="color:red;">completed</mark> to a <mark style="color:red;">cancelled</mark> state.

### The signature:

Compute an HMAC with a SHA-256 hash function. Use your secret API key as the key and use the request body as the message. Compare this to the signature sent in the request header.

#### Example with NodeJS:

```javascript
import crypto from 'crypto';

const secretKey = 'sk_test_key'; // Replace with your secret key
const requestBody = '{ "order_id": "9fcc45a5-4def-4953-9bd8-9ff75d9aaa9c"}'

const signature =
  crypto
    .createHmac('sha256', secretKey)
    .update(requestBody)
    .digest('base64'); 
```
