> ## 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.

# Reward Distribution Notification

> When a batch transfer order status changes, GatePay sends a webhook with `bizType` `PAY_BATCH`.

Verify the signature and return `{"returnCode":"SUCCESS","returnMessage":""}` after successful processing. On delivery failure, GatePay retries at the intervals documented in [Notifications Overview](/global/api-reference/version/100/en/common/asyncNotification).

## Overview

This page documents asynchronous order-status notifications for reward distribution, corresponding to `webhook batchTransferWebhook`.

Based on the current implementation, this notification is sent by the batch processing task **after all sub-orders succeed**:

* Call site: `BatchTransferProcessTask` (line 187)
* Send method: `BatchNotifyService.batchNotify(...)`

The notification uses the standard notification envelope:

* `bizType` is always `PAY_BATCH`
* `bizId` is the batch order ID (`batchTransferModel.getBatchId()`)
* `bizStatus` is the batch order status (on this send path it is `PAID`)
* `data` is a **JSON string** from `JSON.toJSONString(batchOrderNotify)`

## Notes

* Signature verification, retries, and success response: [Notifications Overview](https://docs.gate.com/eu/api-reference/version/100/en/common/asyncNotification.md).
* Signing rules: [Security and Signature](https://docs.gate.com/eu/api-reference/version/100/en/common/securityAndSignature.md).
* Prefer idempotency on `merchant_batch_no` + `reward_id`.
* If a notification is delayed, call [Merchant batch transfer order query](https://docs.gate.com/eu/api-reference/version/100/en/endpoint/withdraw/reward-distribution/query.md) for reconciliation.

## Trigger scenarios

In the current code, reward-distribution notifications are sent only when **the entire batch succeeds**:

* `BatchTransferProcessTask` first checks batch processing status
* When the status is `BatchTransferProcessStatusEnum.AllPaid`
* It calls `batchNotifyService.batchNotify(batchTransferModel.getMerchantBatchNo(), batchTransferModel, batchTransferProcessStatus.getTransferOrderModels())`

Therefore, `bizStatus` and each sub-order `status` in examples on this path should match the success scenario.

## Message structure

| Field | Type | Description |
| - | - | - |
| `bizType` | string | Always `PAY_BATCH` |
| `bizId` | string | Batch order ID |
| `bizStatus` | string | Batch order status; on the current send path the example is `PAID` |
| `client_id` | string | Merchant `client_id` that created the order |
| `data` | string | Business payload as a JSON string; parse with `JSON.parse` first |

### Example message

```json theme={null}
{
  "bizType": "PAY_BATCH",
  "bizId": "79553020665790540",
  "bizStatus": "PAID",
  "client_id": "mZ96D37oKk-HrWJc",
  "data": "{\"currency\":\"USDC\",\"merchant_batch_no\":\"K4t1ijqX1LYRYmlp\",\"batchItemList\":[{\"receiver_id\":22112573,\"amount\":\"0.12300000\",\"currency\":\"USDC\",\"status\":\"PAID\",\"reward_id\":\"50888456789213330\",\"create_time\":1780017207390,\"channel_id\":\"\"}]}"
}
```

## `data` fields

After parsing `data`, the object fields are:

| Field | Type | Description |
| - | - | - |
| `currency` | string | Batch currency (`BatchOrderNotify.currency`) |
| `merchant_batch_no` | string | Merchant batch number (`batchTransferModel.getMerchantBatchNo()`) |
| `batchItemList` | array | Reward-distribution sub-order list |

### `batchItemList` item fields

| Field | Type | Description |
| - | - | - |
| `receiver_id` | int64 | Receiver UID (`transferOrderModel.getReceive()`) |
| `amount` | string | Reward amount (`transferOrderModel.getAmount().toPlainString()`) |
| `currency` | string | Currency (`transferOrderModel.getCurrency()`) |
| `status` | string | Sub-order status (`transferOrderModel.getStatus()`); success callback example is `PAID` |
| `reward_id` | string | Reward / business sub-order ID (`transferOrderModel.getRewardId()`) |
| `create_time` | int64 | Create time in milliseconds (`transferOrderModel.getCreateTime()`) |
| `channel_id` | string | Customer name / channel ID (`transferOrderModel.getChannelId()`) |

## Code mapping

The payload is built by `BatchNotifyService.batchNotify(...)`:

* Top-level notification fields:
  * `bizType = BizTypeEnum.PAY_BATCH.getType()`
  * `bizId = batchTransferModel.getBatchId()`
  * `bizStatus = batchTransferModel.getStatus()`
  * `data = JSON.toJSONString(batchOrderNotify)`
* Inner `batchOrderNotify` fields in `data`:
  * `currency`
  * `merchant_batch_no`
  * `batchItemList`
* `batchItemList` item fields:
  * `receiver_id`
  * `amount`
  * `currency`
  * `status`
  * `reward_id`
  * `create_time`
  * `channel_id`

## Callback example

### Reward distribution batch success

```json theme={null}
{
  "bizType": "PAY_BATCH",
  "bizId": "79553020665790540",
  "bizStatus": "PAID",
  "client_id": "mZ96D37oKk-HrWJc",
  "data": "{\"currency\":\"USDC\",\"merchant_batch_no\":\"K4t1ijqX1LYRYmlp\",\"batchItemList\":[{\"receiver_id\":22112573,\"amount\":\"0.12300000\",\"currency\":\"USDC\",\"status\":\"PAID\",\"reward_id\":\"50888456789213330\",\"create_time\":1780017207390,\"channel_id\":\"\"}]}"
}
```

## Integration tips

1. Verify the signature before parsing the body.
2. Deserialize `data` as JSON, then read `merchant_batch_no` and `batchItemList`.
3. Identify the batch with `merchant_batch_no` and each reward with `reward_id`.
4. Treat each item's `status` as the actual payout result.
5. After successful handling, return HTTP 200 with the standard success body:

```json theme={null}
{
  "returnCode": "SUCCESS",
  "returnMessage": ""
}
```


## OpenAPI

````yaml eu/api-reference/version/100/en/openapi/batch-transfer-callback-openapi.json webhook batchTransferWebhook
openapi: 3.1.0
info:
  title: GatePay Batch Transfer Callback API
  version: 1.0.0
  description: >-
    Asynchronous notifications for batch transfer (batch reward) order status
    changes. When a batch transfer order status changes, GatePay sends a
    notification to the merchant callback URL; `data` is a JSON string.
servers:
  - url: https://openplatform-eu.gateapi.io
    description: Production
security: []
paths: {}

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.