> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coinvoyage.io/llms.txt
> Use this file to discover all available pages before exploring further.

# CoinVoyage webhook event types and payload reference

> Every CoinVoyage order webhook event with its subscription identifier and v3 payload structure.

CoinVoyage emits webhook events at each stage of the order lifecycle. For every event you subscribe to, CoinVoyage delivers a `POST` request containing an event envelope and the current order snapshot.

## Event types

Subscription identifiers and delivered payload values are the same uppercase `ORDER_*` strings.

| Event                    | Description                                                                                                                        |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `ORDER_CREATED`          | A new order was created.                                                                                                           |
| `ORDER_AWAITING_PAYMENT` | The order is ready and awaiting payment from the user.                                                                             |
| `ORDER_CONFIRMING`       | Payment has been detected and is being confirmed on-chain.                                                                         |
| `ORDER_EXECUTING`        | CoinVoyage is executing the destination transfer or contract call.                                                                 |
| `ORDER_COMPLETED`        | The order completed successfully.                                                                                                  |
| `ORDER_ERROR`            | An error occurred during processing.                                                                                               |
| `ORDER_REFUNDED`         | Funds were refunded to the user.                                                                                                   |
| `ORDER_EXPIRED`          | The order expired before payment was received.                                                                                     |
| `ORDER_PARTIAL_PAYMENT`  | The user sent less than the required amount. Pay to Address can accept additional deposits; other payment methods need resolution. |

## Base payload

Every webhook delivery uses this envelope:

```json theme={null}
{
  "event": "ORDER_COMPLETED",
  "delivered_at": "2026-06-23T12:34:56Z",
  "order": {
    "id": "cabc1234567890abcdef12",
    "created_at": "2026-06-23T12:30:00Z",
    "updated_at": "2026-06-23T12:34:55Z",
    "organization_id": "org_123",
    "mode": "SALE",
    "status": "COMPLETED",
    "fulfillment": {
      "amount": {
        "ui": "49.99",
        "raw": "49990000",
        "value_usd": 49.99
      },
      "fiat_unit": "USD"
    },
    "payment": {
      "payment_rail": "CRYPTO",
      "recipient": "0xMerchantWallet",
      "source_tx_hash": "0xabc123",
      "destination_tx_hash": "0xdef456",
      "steps": [],
      "expires_at": "2026-06-23T13:00:00Z"
    },
    "metadata": {
      "order_id": "order_123"
    },
    "hosted_url": "https://pay.coinvoyage.io/pay/cabc1234567890abcdef12"
  }
}
```

| Field            | Description                                                                                             |
| ---------------- | ------------------------------------------------------------------------------------------------------- |
| `event`          | Uppercase `ORDER_*` identifier for the lifecycle event.                                                 |
| `delivered_at`   | Event publish time. The value is stable across webhook retries and WebSocket pushes for the same event. |
| `order`          | Current order snapshot in the v3 `OrderResponse` shape.                                                 |
| `order.id`       | CoinVoyage order ID. Store this for reconciliation and idempotency.                                     |
| `order.status`   | Current lifecycle status.                                                                               |
| `order.metadata` | Optional metadata attached when the order was created. Use this to map back to your internal records.   |
| `order.payment`  | Payment details. Present after payment instructions have been created.                                  |

## Payment object

When present, `order.payment` contains the funding input, resolved output, rail-specific instructions, transaction hashes, and expiry.

```json theme={null}
{
  "payment_rail": "CRYPTO",
  "input": {
    "currency": {
      "chain_id": 1,
      "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "symbol": "USDC",
      "decimals": 6
    },
    "amount": {
      "ui": "49.99",
      "raw": "49990000",
      "value_usd": 49.99
    }
  },
  "output": {
    "currency": {
      "chain_id": 30000000000002,
      "address": null,
      "symbol": "SUI",
      "decimals": 9
    },
    "amount": {
      "ui": "22.4",
      "raw": "22400000000",
      "value_usd": 49.99
    }
  },
  "funding": {
    "required_amount": {
      "ui": "49.99",
      "raw": "49990000",
      "value_usd": 49.99
    },
    "received_amount": {
      "ui": "20.00",
      "raw": "20000000",
      "value_usd": 20
    },
    "remaining_amount": {
      "ui": "29.99",
      "raw": "29990000",
      "value_usd": 29.99
    },
    "transactions": [
      {
        "tx_hash": "0xabc123",
        "amount": {
          "ui": "20.00",
          "raw": "20000000",
          "value_usd": 20
        }
      }
    ]
  },
  "recipient": "0xMerchantWallet",
  "refund": {
    "address": "0xRefundAddress",
    "tx_hash": null,
    "reason": null
  },
  "source_tx_hash": "0xabc123",
  "destination_tx_hash": "0xdef456",
  "fee_tx_hash": null,
  "steps": [
    {
      "rail": "CRYPTO",
      "kind": "deposit",
      "deposit_address": "0xDepositAddress",
      "data": {
        "deposit_address": "0xDepositAddress",
        "currency": {
          "chain_id": 1,
          "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
        },
        "amount": "49990000"
      }
    }
  ],
  "expires_at": "2026-06-23T13:00:00Z"
}
```

## Payload examples

The examples below highlight event-specific fields. Production deliveries include the full `order` snapshot described above.

<AccordionGroup>
  <Accordion title="ORDER_CREATED">
    ```json theme={null}
    {
      "event": "ORDER_CREATED",
      "delivered_at": "2026-06-23T12:30:00Z",
      "order": {
        "id": "cabc1234567890abcdef12",
        "mode": "SALE",
        "status": "PENDING",
        "metadata": {
          "order_id": "order_123"
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="ORDER_AWAITING_PAYMENT">
    ```json theme={null}
    {
      "event": "ORDER_AWAITING_PAYMENT",
      "delivered_at": "2026-06-23T12:31:00Z",
      "order": {
        "id": "cabc1234567890abcdef12",
        "mode": "SALE",
        "status": "AWAITING_PAYMENT",
        "payment": {
          "payment_rail": "CRYPTO",
          "recipient": "0xMerchantWallet",
          "steps": [],
          "expires_at": "2026-06-23T13:00:00Z"
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="ORDER_CONFIRMING">
    ```json theme={null}
    {
      "event": "ORDER_CONFIRMING",
      "delivered_at": "2026-06-23T12:32:00Z",
      "order": {
        "id": "cabc1234567890abcdef12",
        "mode": "SALE",
        "status": "AWAITING_CONFIRMATION",
        "payment": {
          "source_tx_hash": "0xabc123",
          "destination_tx_hash": null
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="ORDER_EXECUTING">
    ```json theme={null}
    {
      "event": "ORDER_EXECUTING",
      "delivered_at": "2026-06-23T12:33:00Z",
      "order": {
        "id": "cabc1234567890abcdef12",
        "mode": "SALE",
        "status": "EXECUTING_ORDER",
        "payment": {
          "source_tx_hash": "0xabc123",
          "destination_tx_hash": null
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="ORDER_COMPLETED">
    ```json theme={null}
    {
      "event": "ORDER_COMPLETED",
      "delivered_at": "2026-06-23T12:34:00Z",
      "order": {
        "id": "cabc1234567890abcdef12",
        "mode": "SALE",
        "status": "COMPLETED",
        "payment": {
          "source_tx_hash": "0xabc123",
          "destination_tx_hash": "0xdef456"
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="ORDER_ERROR">
    ```json theme={null}
    {
      "event": "ORDER_ERROR",
      "delivered_at": "2026-06-23T12:34:00Z",
      "order": {
        "id": "cabc1234567890abcdef12",
        "mode": "SALE",
        "status": "FAILED"
      }
    }
    ```
  </Accordion>

  <Accordion title="ORDER_REFUNDED">
    ```json theme={null}
    {
      "event": "ORDER_REFUNDED",
      "delivered_at": "2026-06-23T12:34:00Z",
      "order": {
        "id": "cabc1234567890abcdef12",
        "mode": "SALE",
        "status": "REFUNDED",
        "payment": {
          "refund": {
            "address": "0xRefundAddress",
            "tx_hash": "0xrefund123",
            "reason": "execution failed"
          }
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="ORDER_EXPIRED">
    ```json theme={null}
    {
      "event": "ORDER_EXPIRED",
      "delivered_at": "2026-06-23T13:00:00Z",
      "order": {
        "id": "cabc1234567890abcdef12",
        "mode": "SALE",
        "status": "EXPIRED"
      }
    }
    ```
  </Accordion>

  <Accordion title="ORDER_PARTIAL_PAYMENT">
    For Pay to Address, use `payment.funding.remaining_amount` to tell the payer what is still due. Each additional deposit is appended to `payment.funding.transactions`. Keep fulfillment paused until a later event reports `ORDER_COMPLETED`.

    ```json theme={null}
    {
      "event": "ORDER_PARTIAL_PAYMENT",
      "delivered_at": "2026-06-23T12:34:00Z",
      "order": {
        "id": "cabc1234567890abcdef12",
        "mode": "SALE",
        "status": "PARTIAL_PAYMENT",
        "payment": {
          "source_tx_hash": "0xabc123",
          "funding": {
            "required_amount": { "ui": "49.99", "raw": "49990000" },
            "received_amount": { "ui": "20.00", "raw": "20000000" },
            "remaining_amount": { "ui": "29.99", "raw": "29990000" },
            "transactions": [
              {
                "tx_hash": "0xabc123",
                "amount": { "ui": "20.00", "raw": "20000000" }
              }
            ]
          }
        }
      }
    }
    ```

    <Warning>
      Additional-deposit recovery is available only for Pay to Address. Do not treat this webhook as resumable for other payment methods.
    </Warning>
  </Accordion>
</AccordionGroup>
