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

# 出金

> 本文档介绍 GatePay 的出金能力，适用于批量资金分发、佣金发放、商户结算等批量转账场景。

## 概述

本文中的“出金”“出款”“提现”描述的是同一类商户侧资金转出能力。为便于阅读，下文以“出金”为主进行表述。

GatePay 出款能力支持商户在单个批次中向多个收款方分发资金，常见使用场景包括：

* 向合作伙伴或代理商发放佣金
* 商户结算及分润发放
* 向用户钱包批量转账
* 版税支付
* 退款及拒付资金处理

***

## 前置条件

在接入出款能力之前，需先完成以下准备工作：

1. **创建应用**：在商户后台创建 GatePay 应用
2. **获取 ClientId**：获取用于 API 认证的 `ClientId`
3. **配置签名密钥**：配置请求签名所需的密钥
4. **配置回调地址**：设置用于接收异步通知的回调接口地址

详细配置说明请参见 [接入总览](/essentials/version/100/cn/common/overview) 和 [认证与安全](/essentials/version/100/cn/common/authentication)。

***

## 出款接入步骤

### 第一步：查询手续费与限额

在创建任何出款批次之前，需先查询当前手续费规则及金额限制。这些值可能会动态变化，不应在本地缓存长期使用。

**请求接口：**

```http theme={null}
POST /v1/pay/withdraw/query
```

该接口可获取以下信息：

* 当前提现手续费
* 最小和最大出款金额
* 单笔交易限额
* 每日出款限额

从读者视角看，这一步不只是“查费用”，更是在确认当前链路是否允许本次出金。因此更稳妥的做法是把它视为正式下单前的必经校验步骤。

### 第二步：创建批量出款

创建一个包含一个或多个子订单（即收款人提现请求）的批次。每个批次由唯一的 `batch_id` 标识。

#### 最小接入链路

从实现顺序看，最小出金链路通常如下：

1. 调用 `POST /v1/pay/withdraw/query` 获取当前手续费与限额
2. 调用 `POST /v1/pay/withdraw` 创建批次
3. 处理提现回调通知
4. 在需要时调用查询接口做兜底确认

对首次接入的商户，建议先用单个子订单跑通整条链路，再扩展到批量分发。

### 第三步：接收回调并跟踪状态

GatePay 会向你配置的回调地址发送异步通知。回调中会同时包含：

* 批次级状态
* 每个子订单的处理状态

**回调顺序通常如下：**

1. 批次创建后的初始回调（`INIT` 状态）
2. 批次进入处理中后的回调（`PROCESSING` 状态）
3. 最终完成状态回调（`SUCCESS`、`PARTIAL` 或 `FAIL`）

### 第四步：对账与兜底查询

查询接口可作为兜底机制，用于：

* 校验回调是否成功送达
* 进行账户对账
* 排查失败交易
* 确认最终状态

如果系统对到账时效要求较高，建议在内部流程中把“回调已收到”和“查询已确认”作为两个独立检查点，而不是只依赖其中一种。

***

## 以回调为主，查询为辅

GatePay 的出款系统优先采用 **异步回调** 作为主通知机制，以提高可靠性和处理效率。

| 阶段        | 主方式                   | 兜底方式                                    |
| --------- | --------------------- | --------------------------------------- |
| **批次状态**  | 通过 `callbackUrl` 接收回调 | 使用 `POST /v1/pay/withdraw/query` 查询批次状态 |
| **子订单状态** | 回调中直接返回子订单详情          | 通过查询接口获取单个子订单详情                         |
| **对账**    | 回调中返回完整金额和手续费信息       | 通过查询接口获取审计和确认信息                         |

**最佳实践：**
应将回调处理作为主要状态更新机制，查询接口仅用于兜底校验或定期对账。

关于回调、签名和验签的详细说明，请参见 [通知与回调](/essentials/version/100/cn/common/notification)。

如果你更希望先理解回调状态组合，请继续阅读 [通知](/essentials/version/100/cn/common/notification)。

***

## 幂等性与对账标识

GatePay 使用以下两个核心标识实现幂等控制和对账：

| 字段                     | 范围   | 作用                | 用法                  |
| ---------------------- | ---- | ----------------- | ------------------- |
| `merchant_withdraw_id` | 子订单级 | 商户为每个收款对象分配的唯一标识  | 用于幂等控制，防止向同一收款人重复出款 |
| `suborder_id`          | 子订单级 | GatePay 生成的唯一子订单号 | 用于平台侧跟踪、回调和查询       |

**幂等保障：**
如果你重复提交了相同 `merchant_withdraw_id` 的出款请求，GatePay 会识别为重复请求，避免重复支付。

对商户侧系统而言，`merchant_withdraw_id` 更适合被视为“业务事实主键”，而不仅仅是一个技术幂等字段。这样在对账、客服排查和人工补单时都会更清晰。

***

## 批次与子订单状态

### 批次状态流转

批次会经历以下状态：

| 状态           | 说明               |
| ------------ | ---------------- |
| `INIT`       | 批次已创建，正在进行初始校验   |
| `PROCESSING` | 批次处理中，资金正在链上转移   |
| `PARTIAL`    | 部分子订单成功，部分失败     |
| `FAIL`       | 整个批次失败，未完成资金分发   |
| `SUCCESS`    | 整个批次成功，所有子订单均已完成 |

### 子订单状态

批次中的每一笔提现都会有独立状态：

| 状态     | 说明                |
| ------ | ----------------- |
| `DONE` | 子订单处理成功，资金已转出并确认  |
| `FAIL` | 子订单处理失败，资金未转出或已回退 |

***

## 回调负载结构

### 批次主单回调字段

当批次状态发生变化时，GatePay 会发送包含以下主单字段的回调：

| 字段                | 必填 | 说明                                                    |
| ----------------- | -- | ----------------------------------------------------- |
| `batch_id`        | 是  | GatePay 分配的批次唯一标识                                     |
| `merchant_id`     | 是  | 你的 GatePay 商户 ID                                      |
| `status`          | 是  | 当前批次状态：`INIT`、`PROCESSING`、`PARTIAL`、`FAIL`、`SUCCESS` |
| `client_id`       | 是  | 创建该批次时使用的 `client_id`                                 |
| `pay_back_status` | 是  | 该批次的回退 / 退款状态                                         |
| `channel_id`      | 是  | 本次出款所使用的渠道标识                                          |

### 子订单数组回调字段

每个回调中都会包含 `suborders` 数组，返回每笔子订单的详细信息：

| 字段                     | 必填 | 说明                        |
| ---------------------- | -- | ------------------------- |
| `suborder_id`          | 是  | GatePay 分配的子订单 ID         |
| `chain`                | 是  | 区块链网络，例如 Ethereum、Polygon |
| `address`              | 是  | 收款钱包地址                    |
| `currency`             | 是  | 出款币种，例如 USDT、ETH          |
| `amount`               | 是  | 请求出款金额，单位为对应币种            |
| `fee`                  | 是  | 该子订单实际扣除的手续费              |
| `txHash`               | 是  | 链上交易哈希，用于确认链上转账           |
| `status`               | 是  | 子订单状态：`DONE` 或 `FAIL`     |
| `merchant_withdraw_id` | 是  | 商户侧分配的对账标识                |
| `fee_type`             | 是  | 手续费扣费类型：`0`（内扣）或 `1`（外扣）  |
| `finish_time`          | 是  | 完成时间，Unix 时间戳（秒）          |
| `sub_amount`           | 是  | 该子订单总金额（如适用，可能含手续费）       |
| `done_amount`          | 是  | 实际到账到收款地址的金额              |

### 手续费类型说明

* **`fee_type = 0`（内扣）**：手续费由商户账户承担，收款方收到完整 `amount`
* **`fee_type = 1`（外扣）**：手续费从提现金额中扣除，收款方实际收到 `amount - fee`

***

## 错误处理

### 常见错误码

在创建或处理出款时，可能会遇到以下错误码：

| 错误码      | 说明                                       | 适用接口   | 建议处理方式                         |
| -------- | ---------------------------------------- | ------ | ------------------------------ |
| `550233` | 商户账户余额不足                                 | 批量出款创建 | 先通过余额查询接口确认可用余额，并补充资金          |
| `550234` | 备注 / 描述字段超出最大长度                          | 批量出款创建 | 检查备注长度限制，必要时进行截断               |
| `550235` | 金额精度超过允许的小数位数                            | 批量出款创建 | 按币种精度要求调整金额，例如 USDT 通常支持 6 位小数 |
| `550238` | 批次中包含的子订单过多                              | 批量出款创建 | 拆分为多个较小批次提交                    |
| `550239` | `amount` 字段缺失或为空                         | 批量出款创建 | 确保每个子订单都传入 `amount`            |
| `550240` | `currency` 字段缺失或为空                       | 批量出款创建 | 确保每个子订单都传入 `currency`          |
| `550241` | `address` 字段缺失或为空                        | 批量出款创建 | 确保每个子订单都传入收款地址                 |
| `550242` | `chain` 字段缺失或为空                          | 批量出款创建 | 确保每个子订单都传入区块链网络                |
| `550245` | `batch_id` 已存在（重复批次）                     | 批量出款创建 | 使用新的 `batch_id`，或在重试时正确利用幂等机制  |
| `550249` | `batch_id` 或 `merchant_withdraw_id` 格式非法 | 批量出款创建 | 确保 ID 为合法字符串，且不包含非法特殊字符        |

### 错误响应处理

当发生错误时，GatePay 会返回错误响应，通常包括：

* **错误码**：用于标识具体错误类型
* **错误信息**：可读的错误描述
* **说明信息**：如有，会返回更多上下文

建议：

* 对于临时性错误（如网络问题、超时），采用 **指数退避重试**
* 对于永久性错误（如余额不足、参数非法），需先修复问题后再发起重试

***

## 对账与审计

### 账户余额对账

建议定期将 GatePay 商户账户余额与内部系统记录进行核对：

1. **每次出款前先查询手续费**：获取当前费率
2. **跟踪批次状态**：通过回调监控批次和子订单状态
3. **核对金额字段**：确认 `amount`、`fee` 和 `done_amount` 与预期一致
4. **每日对账**：在日终通过查询接口完成对账

详细对账流程请参见 [账户余额与对账](/essentials/version/100/cn/common/balance)。

### 失败出款排查

如果某个子订单失败，建议按以下步骤排查：

1. **检查子订单状态**：查询批次，确认每个子订单的 `status`
2. **查看错误原因**：从回调或查询响应中获取失败原因
3. **校验收款地址**：确认钱包地址与指定链匹配且格式正确
4. **确认链支持情况**：确保收款方钱包支持该区块链网络
5. **临时失败可重试**：若属于临时失败，可使用新的 `batch_id` 和原 `merchant_withdraw_id` 重新提交

***

## 查询出款结果

**请求接口：**

```http theme={null}
POST /v1/pay/withdraw/query
```

该接口可查询指定出款批次的详细结果，返回内容包括：

* 批次状态及元数据
* 子订单数组及逐笔处理结果
* 手续费信息
* 链上交易哈希（用于确认链上转账）

该接口适用于：

* 回调延迟时的兜底确认
* 定期对账
* 审计追踪
* 客服支持与问题排查

***

## 请求签名与校验

所有出金请求都必须使用 GatePay 统一签名机制完成签名。关于请求签名、签名生成方式，以及回调签名验签规则，请参见 [认证与安全](/essentials/version/100/cn/common/authentication)。

签名要求如下：

* 使用 Payment API Secret 对请求体按 `timestamp\nnonce\nbody\n` 规则计算 HMAC-SHA512
* 将签名结果放入请求头 `X-GatePay-Signature`
* 回调验签同样使用 Payment API Secret 按相同规则进行校验

***

## 最佳实践

1. **动态查询手续费**：每次创建批次前都应查询当前手续费，不要缓存费率
2. **使用唯一标识**：为 `merchant_withdraw_id` 和 `batch_id` 分配唯一值，避免重复并支持幂等
3. **完善回调处理**：建立稳定的回调处理机制，实时更新状态
4. **监控批次状态**：重点关注 `PARTIAL` 和 `FAIL` 状态，并设置告警
5. **核验链上交易**：对于关键出款，可通过区块链浏览器校验 `txHash`
6. **每日对账**：每日将内部账户记录与 GatePay 数据进行核对
7. **妥善处理错误**：对重试、失败和人工介入场景建立清晰的处理机制
8. **保护签名密钥**：签名密钥不得出现在日志或暴露给未授权人员
9. **校验收款地址**：提交前对地址进行基础校验，例如格式和校验和检查
10. **考虑限流机制**：关注 API 频率限制，大批量提交时应做好请求排队

***

## 相关文档

* [接入总览](/essentials/version/100/cn/common/overview)
* [认证与安全](/essentials/version/100/cn/common/authentication)
* [通知与回调](/essentials/version/100/cn/common/notification)
* [账户余额与对账](/essentials/version/100/cn/common/balance)
* [通知](/essentials/version/100/cn/common/notification)
