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

# Withdrawal Callback

> When a batch withdrawal order status changes (e.g., all successful, all failed, or partially successful), GatePay will send an asynchronous POST notification to the callback URL configured by the merchant.

The callback message contains the `main_order` object and `suborders` array. After receiving the callback, signature verification must be performed before processing business logic. Use `batch_id` + `merchant_withdraw_id` as the idempotency key to avoid duplicate updates. If no callback is received for an extended period, polling compensation can be done through the withdrawal query API.

## Overview

This page documents `webhook callbackWebhook`. The full schema, parameters, and examples are rendered from the linked OpenAPI or webhook definition above.

When batch withdrawal/payout status changes, GatePay notifies your callback URL using the dedicated **`WITHDRAW`** payload (**no** `data` field).

## Notes

* Use `batch_id` + `merchant_withdraw_id` for idempotency.
* Signature verification, retries, and the success response: [Notifications Overview](/api-reference/version/100/en/common/asyncNotification); signing: [Security and Signature](/api-reference/version/100/en/common/securityAndSignature).
* Use [Withdrawal query](/api-reference/version/100/en/endpoint/withdraw/withdrawQuery) if callbacks are delayed.

## Trigger Scenarios

* When a batch withdrawal/payout order status changes (all succeeded, all failed, or partially succeeded), GatePay sends a notification to the **callback URL** configured at merchant registration
* If delivery fails, see retry rules in [Notifications Overview](/api-reference/version/100/en/common/asyncNotification).

**Scope**: Batch and sub-order withdrawal/payout status changes, corresponding to **`bizType=WITHDRAW`** in the general callback taxonomy. For integration guidance, see [Payout](/essentials/version/100/en/outflow/payout).

## bizType Reference

In the [Notifications Overview](/api-reference/version/100/en/common/asyncNotification) `bizType` enumeration, withdrawal notifications use **`WITHDRAW`** to indicate withdrawal/payout status changes.

Unlike payment or refund callbacks that use the standard envelope (`bizType`, `bizId`, `bizStatus`, `client_id`, `data`), **`WITHDRAW` callbacks use a dedicated payload**: the request body contains `main_order` (batch header) and `suborders` (line items) directly, with batch status in `main_order.status`.

## bizStatus Values

Terminal notification semantics align with the `bizStatus` values below. Batch progress is also reflected in `main_order.status` (including intermediate values such as `INIT` and `PROCESSING`).

| Value              | Description                                                                                                |
| ------------------ | ---------------------------------------------------------------------------------------------------------- |
| `WITHDRAW_SUCCESS` | Entire batch succeeded; all sub-orders reached a terminal state (maps to `main_order.status=SUCCESS`)      |
| `WITHDRAW_PARTIAL` | Batch partially succeeded; some sub-orders succeeded and some failed (maps to `main_order.status=PARTIAL`) |
| `WITHDRAW_FAIL`    | Entire batch failed (maps to `main_order.status=FAIL`)                                                     |

## Message Structure

| Field        | Type   | Description                     |
| ------------ | ------ | ------------------------------- |
| `main_order` | object | Batch header; see table below   |
| `suborders`  | array  | Sub-order list; see table below |

### Example Message

```json theme={null}
{
  "main_order": {
    "batch_id": "831618381568",
    "merchant_id": 17329983,
    "status": "SUCCESS",
    "client_id": "igasgasdbub",
    "pay_back_status": "NO",
    "channel_id": ""
  },
  "suborders": [
    {
      "suborder_id": "30969031299072",
      "status": "DONE",
      "merchant_withdraw_id": "1839295815",
      "currency": "USDT",
      "amount": 2362.1
    }
  ]
}
```

## Batch Status (`main_order.status`)

| Value        | Terminal | Description                                      |
| ------------ | -------- | ------------------------------------------------ |
| `INIT`       | No       | Batch created; initial validation in progress    |
| `PROCESSING` | No       | Batch processing; funds in transit               |
| `PARTIAL`    | Yes      | Some sub-orders succeeded, some failed           |
| `FAIL`       | Yes      | Entire batch failed                              |
| `SUCCESS`    | Yes      | Entire batch succeeded; all sub-orders completed |

**Typical callback sequence**: `INIT` → `PROCESSING` → terminal state (`SUCCESS` / `PARTIAL` / `FAIL`).

## main\_order Field Reference

| Field             | Type   | Description                              |
| ----------------- | ------ | ---------------------------------------- |
| `batch_id`        | string | Batch ID                                 |
| `merchant_id`     | int64  | Merchant ID                              |
| `status`          | string | Batch status; see table above            |
| `client_id`       | string | `client_id` used when creating the batch |
| `pay_back_status` | string | Rollback status                          |
| `channel_id`      | string | Customer name / channel identifier       |

## suborders Item Fields

| Field                   | Type   | Description                                              |
| ----------------------- | ------ | -------------------------------------------------------- |
| `suborder_id`           | string | Sub-order ID                                             |
| `merchant_id`           | int64  | Merchant ID                                              |
| `channel_id`            | string | Customer name / channel identifier                       |
| `chain`                 | string | Blockchain network                                       |
| `from_address`          | string | Sender on-chain address                                  |
| `address`               | string | Recipient address                                        |
| `currency`              | string | Currency                                                 |
| `amount`                | number | Transfer amount                                          |
| `fee`                   | number | Fee                                                      |
| `tx_id`                 | string | Transaction hash                                         |
| `memo`                  | string | Memo                                                     |
| `status`                | string | Sub-order status: `DONE` (success) or `FAIL` (failure)   |
| `merchant_withdraw_id`  | string | Merchant withdrawal ID; recommended idempotency key      |
| `fee_type`              | int    | Fee type: `0` internal deduction, `1` external deduction |
| `batch_withdraw_id`     | string | Batch withdrawal ID                                      |
| `desc`                  | string | Description                                              |
| `reconciliation_status` | int    | Reconciliation status                                    |
| `is_placed`             | int    | Submission flag: `0` not submitted, `1` submitted        |
| `finish_time`           | int64  | Completion time (milliseconds)                           |
| `sub_amount`            | number | Total sub-order amount                                   |
| `done_amount`           | number | Actually completed amount                                |

Use `batch_id` + `merchant_withdraw_id` as the idempotency key to avoid duplicate updates. If no callback is received for an extended period, poll via [Withdrawal query](/api-reference/version/100/en/endpoint/withdraw/withdrawQuery).

## Callback Example

### Batch withdrawal fully succeeded (`main_order.status=SUCCESS`)

```json theme={null}
{
  "main_order": {
    "batch_id": "1526052914503263472",
    "merchant_id": 48177363,
    "status": "SUCCESS",
    "client_id": "DlaHYwkeGDjSGRVr",
    "pay_back_status": "NO",
    "channel_id": ""
  },
  "suborders": [
    {
      "fee": "0.0499",
      "desc": "",
      "chain": "BASEEVM",
      "tx_id": "0x2546829d95b7614acebde9dcc92d5b880ae82fa9791c2f80faa7ca668fc5cd3b",
      "amount": "0.1",
      "status": "DONE",
      "address": "0x524287c1e5a312a12c76380a3227611d3cb20ddf",
      "currency": "USDC",
      "fee_type": 0,
      "channel_id": "",
      "sub_amount": "0.1",
      "done_amount": "0.0501",
      "finish_time": 1780037579000,
      "merchant_id": 48177363,
      "suborder_id": "79553574716833917",
      "from_address": "0x0D0707963952f2fBA59dD06f2b425ace40b492Fe",
      "batch_withdraw_id": "1526052914503263472",
      "merchant_withdraw_id": "1526052914503263472",
      "reconciliation_status": 0
    }
  ]
}
```

### Partial success (`main_order.status=PARTIAL`)

```json theme={null}
{
  "main_order": {
    "batch_id": "1526052914503263472",
    "merchant_id": 48177363,
    "status": "PARTIAL",
    "client_id": "DlaHYwkeGDjSGRVr",
    "pay_back_status": "NO",
    "channel_id": ""
  },
  "suborders": [
    {
      "fee": "0.0499",
      "desc": "",
      "chain": "BASEEVM",
      "tx_id": "0x2546829d95b7614acebde9dcc92d5b880ae82fa9791c2f80faa7ca668fc5cd3b",
      "amount": "0.1",
      "status": "DONE",
      "address": "0x524287c1e5a312a12c76380a3227611d3cb20ddf",
      "currency": "USDC",
      "fee_type": 0,
      "channel_id": "",
      "sub_amount": "0.1",
      "done_amount": "0.0501",
      "finish_time": 1780037579000,
      "merchant_id": 48177363,
      "suborder_id": "79553574716833917",
      "from_address": "0x0D0707963952f2fBA59dD06f2b425ace40b492Fe",
      "batch_withdraw_id": "1526052914503263472",
      "merchant_withdraw_id": "1526052914503263472",
      "reconciliation_status": 0
    },
    {
      "fee": "0.0499",
      "desc": "",
      "chain": "BASEEVM",
      "tx_id": "",
      "amount": "0.1",
      "status": "FAIL",
      "address": "0x524287c1e5a312a12c76380a3227611d3cb20ddf",
      "currency": "USDC",
      "fee_type": 0,
      "channel_id": "",
      "sub_amount": "0.1",
      "done_amount": "0.0501",
      "finish_time": 1780037579000,
      "merchant_id": 48177363,
      "suborder_id": "79553574716833918",
      "from_address": "0x0D0707963952f2fBA59dD06f2b425ace40b492Fe",
      "batch_withdraw_id": "1526052914503263472",
      "merchant_withdraw_id": "1526052914503263473",
      "reconciliation_status": 0
    }
  ]
}
```

### All failed (`main_order.status=FAIL`)

```json theme={null}
{
  "main_order": {
    "batch_id": "1526052914503263472",
    "merchant_id": 48177363,
    "status": "FAIL",
    "client_id": "DlaHYwkeGDjSGRVr",
    "pay_back_status": "NO",
    "channel_id": ""
  },
  "suborders": [
    {
      "fee": "0.0499",
      "desc": "",
      "chain": "BASEEVM",
      "tx_id": "",
      "amount": "0.1",
      "status": "FAIL",
      "address": "0x524287c1e5a312a12c76380a3227611d3cb20ddf",
      "currency": "USDC",
      "fee_type": 0,
      "channel_id": "",
      "sub_amount": "0.1",
      "done_amount": "0.0501",
      "finish_time": 1780037579000,
      "merchant_id": 48177363,
      "suborder_id": "79553574716833917",
      "from_address": "0x0D0707963952f2fBA59dD06f2b425ace40b492Fe",
      "batch_withdraw_id": "1526052914503263472",
      "merchant_withdraw_id": "1526052914503263472",
      "reconciliation_status": 0
    }
  ]
}
```


## OpenAPI

````yaml /api-reference/version/100/en/openapi/withdraw-callback-openapi.json webhook callbackWebhook
openapi: 3.1.0
info:
  title: GatePay Withdrawal & Wallet API
  version: 1.0.0
  description: >-
    OpenAPI 3.1 specification for GatePay withdrawal and wallet APIs, based on
    the English withdrawal documentation. It covers batch withdrawals,
    withdrawal status query, supported chains by currency, total balance query,
    and withdrawal fee query.
servers:
  - url: https://openplatform.gateapi.io
    description: Production
security: []
paths: {}

````