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

# API文档

## 2026年05月08日

| 发布时间        | 升级说明                                     | 版本编号   |
| ----------- | ---------------------------------------- | ------ |
| 2026年03月17日 | 发布了V1.0版本，支持自动归集，二维码显示收款地址，动态收款地址的自动化策略。 | V1.0.0 |
| 2026年05月08日 | 发布了V1.1版本，新增结算功能，支持商户资金结算到RD Convert钱包。  | V1.1.0 |

## 接入流程

### 开通环境

1. **开通商户与获取密钥**
   1. 在运营/管理后台完成商户开户与配置。
   2. 在后台生成以下认证信息：
      * `AppId`：商户应用标识
      * `AppSecret`：商户应用密钥（仅服务端保存，不可泄露）
      * `ApiKey`：用于基础认证和权限控制
   3. 配置 IP 白名单（推荐仅开放商户服务器出口 IP）。
2. **选择环境并完成连通性测试**
   1. 使用开发环境进行联调验证。
   2. 测试通过后，切换到生产环境。
3. **对接核心接口**
   1. 订单管理：创建订单、查询订单、查询对账单。
   2. 退款管理：创建退款、查询退款。
   3. Payout管理：创建Payout、查询Payout。
4. **接入回调通知（Webhook）**
   1. 在商户后台配置订单/退款/Payout状态通知 URL。
   2. 实现通知处理接口，支持：
      * 校验签名（必须）
      * 幂等处理（必须）
      * 重试接收
5. **联调与上线**
   1. 按业务场景联调（下单、支付成功、超时取消、退款成功/失败等）。
   2. 在生产环境小流量验证后逐步放量。

### **环境基础**

* **基础 URL**
  * 开发环境：[https://gw.uat.rdezlink.tech](https://gw.uat.rdezlink.tech)
  * 生产环境：[https://gw.rd.group](https://gw.rd.group)
* **协议与格式**
  * 协议：HTTPS
  * 数据格式：JSON
  * 字符编码：UTF-8
  * API 版本：`v1`（通过 URL `/api/v1/...` 体现）
* **金额字段统一规范（重要）**
  * 所有涉及金额、手续费、余额等字段在 **JSON 中一律采用字符串类型** 传输，避免精度丢失。
  * 例如：`"amount": "100.00"`
  * 不能使用 `"amount": 100.00`

### 认证安全

认证方式与签名机制（强制）：

所有 API 请求必须通过 HTTPS，并在 Header 中携带如下字段进行认证与防篡改校验：

请求头字段：

| 字段名           | 类型     | 必填 | 说明                 |
| :------------ | :----- | :- | :----------------- |
| `X-Api-Key`   | String | 是  | 商户 API Key（平台分配）   |
| `X-App-Id`    | String | 是  | 商户应用标识             |
| `X-Timestamp` | String | 是  | 时间戳（毫秒, 13位），用于防重放 |
| `X-Nonce`     | String | 是  | 随机字符串，建议长度 ≥ 16    |
| `X-Signature` | String | 是  | 请求签名（HMAC-SHA256）  |

**签名算法说明（推荐实现方式）**：

1. 将以下内容按顺序拼接为一个字符串 `signPayload`：
   1. HTTP 方法（大写，如 `POST`）
   2. 请求路径（不含域名，如 `/api/v1/order/create`）
   3. `X-App-Id`
   4. `X-Timestamp`
   5. `X-Nonce`
   6. 请求 Body 原始 JSON 字符串（去除多余空格，保持与实际发送一致）
2. 使用 `AppSecret` 作为密钥，对 `signPayload` 执行 HMAC-SHA256，结果按十六进制或 Base64 输出，即为 `X-Signature`。
3. 平台服务端会按照相同规则验证签名：
   1. 校验 `X-Timestamp` 是否在允许时间窗口内（例如 ±5 分钟）。
   2. 校验 `X-Nonce` 未被重复使用（平台内部去重存储，防止重放）。
   3. 校验 `X-Signature` 是否正确。

**示例伪代码（仅示意）：**

```javascript theme={null}
// Header
X-Api-Key: your-api-key
X-App-Id: your-app-id
X-Timestamp: "1710576000"
X-Nonce: "random-string-123456"
X-Signature: "计算后的签名字符串"
```

平台可提供 Java/Go/Node/PHP 等语言的签名示例或 SDK。

### IP 白名单

支持以下格式的 IP 白名单配置（在商户管理后台设置）：

* 单个 IP：`192.168.1.100`
* 多个 IP：`192.168.1.100,192.168.1.110,192.168.1.120`

**安全建议:**

* 仅允许商户服务器出口 IP 访问，避免 API Key 暴露给前端或非受控环境。
* 避免在浏览器、移动端等环境直接调用接口。

**通用响应格式:**

所有接口返回统一的响应结构：

```json theme={null}
{
  "code": "0000",
  "msg": "success",
  "data": {},
  "traceId": "xxx"
}
```

* `code`：响应码，`0000` 表示成功，非 `0000` 表示失败。
* `msg`：响应消息，包含简要错误原因。
* `data`：业务数据内容。
* `traceId`：请求追踪 ID，便于问题排查（请在与平台排障时提供）。

**响应码示例**

以下为当前文档中涉及到的主要响应码，完整错误码列表可由平台后续扩展。

| code | 说明              |
| :--- | :-------------- |
| 0000 | 成功              |
| 1000 | 用户不存在           |
| 1010 | 认证失败            |
| 1015 | 订单不存在           |
| 1020 | 风控拒绝            |
| 3001 | 无效的钱包地址格式       |
| 3002 | 暂不支持该区块链网络      |
| 3003 | 余额不足以支付链上 Gas 费 |
| 3004 | 重复创建订单          |
| 3005 | 退款金额超出订单可退金额    |
| 3006 | 订单已过期，无法支付      |

## 订单管理

### 创建订单

创建新的收单订单，生成收款地址及收银台 URL。

* URL：`POST /api/v1/order/create`
* Content-Type：`application/json`

**请求参数**

| 字段名             | 类型      | 最大长度 | 必填 | 说明                            |
| :-------------- | :------ | :--- | :- | :---------------------------- |
| `bizNo`         | String  | 128  | 是  | 商户业务单号，用于幂等控制，同一商户下唯一         |
| `amount`        | String  | 64   | 是  | 订单金额，必须大于 0，最小值 `"0.01"`      |
| `currency`      | String  | 8    | 是  | 下单币种，当前请使用 `USD`              |
| `expireSeconds` | Integer | 4    | 否  | 订单过期时间（秒），不传则使用系统默认值（如 600 秒） |
| `userInfo`      | Object  | -    | 条件 | 用户信息；订单金额 ≥ 1000美元 时必填        |
| `productInfo`   | Object  | -    | 是  | 商品信息                          |
| `successUrl`    | String  | 256  | 否  | 订单成功状态前端通知 URL（如需前端感知状态变更时使用） |
| `failureUrl`    | String  | 256  | 否  | 订单失败状态前端通知 URL（如需前端感知状态变更时使用） |

`userInfo` 字段说明：

| 字段名        | 类型     | 最大长度 | 必填 | 说明      |
| :--------- | :----- | :--- | :- | :------ |
| `clientId` | String | 64   | 是  | 商户侧用户标识 |
| `name`     | String | 128  | 是  | 用户姓名    |
| `address`  | String | 512  | 是  | 用户住址信息  |
| `certType` | String | 32   | 否  | 证件类型    |
| `certNo`   | String | 32   | 否  | 证件号     |
| `email`    | String | 128  | 否  | 用户邮箱    |
| `phone`    | String | 32   | 否  | 用户手机号   |

`productInfo` 字段说明：

| 字段名           | 类型      | 最大长度 | 必填 | 说明   |
| :------------ | :------ | :--- | :- | :--- |
| `productName` | String  | 128  | 是  | 商品名称 |
| `productLink` | String  | 512  | 否  | 商品链接 |
| `quantity`    | Integer | 11   | 否  | 购买数量 |
| `description` | String  | 1024 | 是  | 商品描述 |

**请求示例**

```json theme={null}
{
  "bizNo": "BIZ202401010001",
  "amount": "100.00",
  "currency": "USD",
  "expireSeconds": 3600,
  "userInfo": {
    "clientId": "USER001",
    "name": "zhangsan",
    "address": "中国深圳南山xxxx",
    "email": "user@example.com"
  },
  "productInfo": {
    "productName": "Premium Membership",
    "productLink": "https://example.com/product/123",
    "quantity": 1,
    "description": "1 month premium membership"
  },
  "successUrl": "https://merchant.example.com/callback/success",
  "failureUrl": "https://merchant.example.com/callback/failure"
}
```

**响应参数**

| 字段名              | 类型     | 最大长度 | 说明                     |
| :--------------- | :----- | :--- | :--------------------- |
| `orderId`        | String | 64   | 系统订单 ID                |
| `bizNo`          | String | 128  | 商户业务单号                 |
| `amount`         | String | 64   | 订单金额（字符串格式）            |
| `status`         | String | 16   | 订单状态，见「订单状态说明」         |
| `expireTime`     | Date   | -    | 过期时间（ISO8601 格式）       |
| `receiveAddress` | List   | -    | 收款地址列表（多链、多币种时会返回多条记录） |
| `cashierUrl`     | String | 256  | 收银台 URL（可重定向到该页面完成支付）  |

`receiveAddress` 字段说明：

| 字段名             | 类型            | 最大长度 | 说明                                     |
| :-------------- | :------------ | :--- | :------------------------------------- |
| `address`       | String        | 64   | 钱包地址                                   |
| `chain`         | String        | 16   | 链类型（如 `ETH` / `TRX` / `SOL`/`POLYGON`） |
| `tokenCurrency` | List\<String> | -    | 支持的代币币种（如 `["USDT"]`）                  |

> **多链支付说明**：
>
> * 系统支持返回多条收款地址（不同链/币种）。
> * 推荐商户前端在收银台展示时，引导用户只选择 **一条链** 完成支付，避免拆分多笔。
> * 默认情况下，系统会按照订单维度累计到账金额，当同一订单下多笔有效入账累计达到或超过期望金额时，可视为支付成功；如需其他策略，请与平台确认。

**响应示例**

```json theme={null}
{
  "code": "0000",
  "msg": "success",
  "data": {
    "orderId": "O202401010001",
    "bizNo": "BIZ202401010001",
    "amount": "100.00",
    "status": "PENDING",
    "expireTime": "2024-01-01T12:00:00Z",
    "receiveAddress": [
      {
        "address": "0x1234...5678",
        "chain": "ETH",
        "tokenCurrency": ["USDT","USDC"]
      },
      {
        "address": "TK1234...5678",
        "chain": "TRX",
        "tokenCurrency": ["USDT","USDC"]
      }
    ],
    "cashierUrl": "https://cashier.example.com/pay?order=xxx"
  },
  "traceId": "trace123"
}
```

### 查询订单

根据系统订单 ID 查询订单详情。

* URL：`POST /api/v1/order/query`
* Content-Type：`application/json`

**请求参数**

| 字段名       | 类型     | 最大长度 | 必填 | 说明      |
| :-------- | :----- | :--- | :- | :------ |
| `orderId` | String | 64   | 是  | 系统订单 ID |

**请求示例**

```json theme={null}
{
  "orderId": "O202401010001"
}
```

**响应参数**

| 字段名               | 类型     | 最大长度 | 说明          |
| :---------------- | :----- | :--- | :---------- |
| `orderId`         | String | 64   | 系统订单 ID     |
| `bizNo`           | String | 128  | 商户业务单号      |
| `orderAmount`     | String | 64   | 下单金额（字符串）   |
| `actualAmount`    | String | 64   | 实际到账金额（字符串） |
| `currency`        | String | 8    | 下单币种        |
| `chain`           | String | 16   | 链类型         |
| `receiveCurrency` | String | 16   | 收款币种        |
| `receiveAddress`  | String | 64   | 收款地址        |
| `txHash`          | String | 64   | 区块链交易哈希     |
| `status`          | String | 16   | 订单状态        |
| `orderTime`       | Date   | -    | 下单时间        |
| `finishTime`      | Date   | -    | 完成时间        |

**订单状态说明**

| 状态                | 说明    |
| :---------------- | :---- |
| `PENDING`         | 待支付   |
| `AMOUNT_MISMATCH` | 金额不匹配 |
| `PAY_SUCCESS`     | 支付成功  |
| `PAY_FAIL`        | 支付失败  |
| `TIMEOUT`         | 超时    |
| `COMPLETED`       | 已结算   |
| `REFUNDED`        | 已退款   |

**响应示例**

```json theme={null}
{
  "code": "0000",
  "msg": "success",
  "data": {
    "orderId": "O202401010001",
    "bizNo": "BIZ202401010001",
    "orderAmount": "100.00",
    "actualAmount": "100.00",
    "currency": "USD",
    "chain": "ETH",
    "receiveCurrency": "USDT",
    "receiveAddress": "0x1234...5678",
    "txHash": "0xabc123...def456",
    "status": "PAY_SUCCESS",
    "orderTime": "2024-01-01T10:00:00Z",
    "finishTime": "2024-01-01T10:30:00Z"
  },
  "traceId": "trace123"
}
```

### 查询对账单

根据下单时间范围分页查询订单对账信息。

* URL：`POST /api/v1/order/queryRecon`
* Content-Type：`application/json`

**请求参数**

| 字段名         | 类型   | 最大长度 | 必填 | 说明                  |
| :---------- | :--- | :--- | :- | :------------------ |
| `startTime` | Date | -    | 是  | 查询开始时间（包括），以下单时间为准  |
| `endTime`   | Date | -    | 是  | 查询结束时间（不包括），以下单时间为准 |
| `pageId`    | Int  | 11   | 是  | 页数，从 1 开始           |
| `pageSize`  | Int  | 11   | 是  | 每页大小，最大 1000 条      |

**请求示例**

```json theme={null}
{
  "startTime": "2024-01-01T10:00:00Z",
  "endTime": "2024-01-03T10:30:00Z",
  "pageId": 1,
  "pageSize": 1000
}
```

**响应参数**

| 字段名         | 类型              | 最大长度 | 说明    |
| :---------- | :-------------- | :--- | :---- |
| `total`     | Int             | 11   | 订单总数  |
| `orderList` | List\\\<Object> | -    | 对账单列表 |

**对账单明细字段**

| 字段名               | 类型     | 最大长度 | 说明      |
| :---------------- | :----- | :--- | :------ |
| `orderId`         | String | 64   | 系统订单 ID |
| `bizNo`           | String | 128  | 商户业务单号  |
| `orderAmount`     | String | 64   | 订单金额    |
| `actualAmount`    | String | 64   | 实际到账金额  |
| `currency`        | String | 8    | 下单币种    |
| `chain`           | String | 16   | 链类型     |
| `receiveCurrency` | String | 16   | 收款币种    |
| `receiveAddress`  | String | 64   | 收款地址    |
| `txHash`          | String | 64   | 区块链交易哈希 |
| `status`          | String | 16   | 订单状态    |
| `orderTime`       | Date   | -    | 下单时间    |
| `finishTime`      | Date   | -    | 支付完成时间  |
| `settleTime`      | Date   | -    | 结算时间    |
| `settleAmount`    | String | 64   | 结算金额    |
| `feeList`         | List   | -    | 费用明细列表  |

**费用明细字段**

| 字段名           | 类型     | 最大长度 | 说明                  |
| :------------ | :----- | :--- | :------------------ |
| `feeAmount`   | String | 64   | 收费金额                |
| `feeCurrency` | String | 16   | 收费币种                |
| `feeType`     | String | 16   | 费用类型： WITHDRAW\_FEE |

**响应示例**

```json theme={null}
{
  "code": "0000",
  "msg": "success",
  "data": {
    "total": 100,
    "orderList": [
      {
        "orderId": "O202401010001",
        "bizNo": "BIZ202401010001",
        "userId": "U001",
        "orderAmount": "100.00",
        "actualAmount": "100.00",
        "currency": "USD",
        "chain": "ETH",
        "receiveCurrency": "USDT",
        "receiveAddress": "0x1234...5678",
        "txHash": "0xabc123...def456",
        "status": "PAY_SUCCESS",
        "orderTime": "2024-01-01T10:00:00Z",
        "finishTime": "2024-01-01T10:30:00Z",
        "settleTime": "2024-01-02T10:30:00Z",
        "settleAmount": "90.00",
        "feeList": [
          {
            "feeAmount": "10.00",
            "feeCurrency": "USDT",
            "feeType": "WITHDRAW_FEE"
          }
        ]
      }
    ]
  },
  "traceId": "trace123"
}
```

## 退款管理

### 创建退款

为指定订单创建退款申请，支持全额或部分退款（实际能力以平台配置为准）。

为避免资金被盗，退款地址 **原路退回**

* URL：`POST /api/v1/refund/create`
* Content-Type：`application/json`

**请求参数**

| 字段名       | 类型     | 最大长度 | 必填 | 说明     |
| :-------- | :----- | :--- | :- | :----- |
| `orderId` | String | 64   | 是  | 原订单 ID |
| `reason`  | String | 512  | 是  | 退款原因   |

**请求示例**

```json theme={null}
{
  "orderId": "O202401010001",
  "reason": "用户申请退款"
}
```

**响应参数**

| 字段名            | 类型     | 最大长度 | 说明          |
| :------------- | :----- | :--- | :---------- |
| `refundId`     | String | 64   | 退款 ID       |
| `orderId`      | String | 64   | 原订单 ID      |
| `refundAmount` | String | 64   | 退款金额        |
| `feeAmount`    | String | 64   | 退款手续费金额     |
| `currency`     | String | 8    | 币种          |
| `status`       | String | 16   | 退款状态，见6.2.4 |

**响应示例**

```json theme={null}
{
  "code": "0000",
  "msg": "success",
  "data": {
    "refundId": "R202401010001",
    "orderId": "O202401010001",
    "refundAmount": "100.00",
    "feeAmount": "10.00",
    "currency": "USDT",
    "status": "PROCESSING"
  },
  "traceId": "trace123"
}
```

### 查询退款

根据退款 ID 或订单 ID 查询退款信息。

* URL：`POST /api/v1/refund/query`
* Content-Type：`application/json`

**请求参数**

参数二选一：`refundId` 或 `orderId` 必须且只能提供其中一个。

| 字段名        | 类型     | 最大长度 | 必填    | 说明                       |
| :--------- | :----- | :--- | :---- | :----------------------- |
| `refundId` | String | 64   | 否\\\* | 退款 ID（与 `orderId` 二选一）   |
| `orderId`  | String | 64   | 否\\\* | 原订单 ID（与 `refundId` 二选一） |

**请求示例**

```json theme={null}
{
  "refundId": "R202401010001"
}
```

**响应参数**

| 字段名            | 类型     | 最大长度 | 说明      |
| :------------- | :----- | :--- | :------ |
| `refundId`     | String | 64   | 退款 ID   |
| `orderId`      | String | 64   | 原订单 ID  |
| `refundAmount` | String | 64   | 退款金额    |
| `feeAmount`    | String | 64   | 退款手续费金额 |
| `currency`     | String | 8    | 币种      |
| `chain`        | String | 16   | 链类型     |
| `toAddress`    | String | 64   | 退款目标地址  |
| `txHash`       | String | 64   | 区块链交易哈希 |
| `status`       | String | 16   | 退款状态    |
| `reason`       | String | 512  | 退款原因    |

**退款状态说明**

| 状态           | 说明  |
| :----------- | :-- |
| `PROCESSING` | 处理中 |
| `SUCCESS`    | 成功  |
| `FAILED`     | 失败  |

**响应示例**

```json theme={null}
{
  "code": "0000",
  "msg": "success",
  "data": {
    "refundId": "R202401010001",
    "orderId": "O202401010001",
    "refundAmount": "100.00",
    "feeAmount": "10.00",
    "currency": "USDT",
    "chain": "ETH",
    "toAddress": "0x9876...5432",
    "txHash": "0xdef456...abc123",
    "status": "SUCCESS",
    "reason": "用户申请退款"
  },
  "traceId": "trace123"
}
```

## Payout管理

### 创建Payout

发起商户资金结算到RD Convert钱包（Payout）。

* URL：`POST /api/v1/payout/create`
* Content-Type：`application/json`

**请求参数**

| 字段名               | 类型     | 最大长度 | 必填 | 说明                                       |
| :---------------- | :----- | :--- | :- | :--------------------------------------- |
| `merchantOrderNo` | String | 128  | 是  | 商户业务单号，用于幂等控制，同一商户下唯一                    |
| `chain`           | String | 16   | 是  | 链类型（如 `ETH` / `TRX` / `SOL` / `POLYGON`） |
| `currency`        | String | 8    | 是  | Payout币种（如 `USDT`）                       |
| `amount`          | String | 64   | 是  | Payout金额，必须大于最小值（默认 `10`）                |

**请求示例**

```json theme={null}
{
  "merchantOrderNo": "PO202401010001",
  "chain": "ETH",
  "currency": "USDT",
  "amount": "1000.00"
}
```

**响应参数**

| 字段名               | 类型     | 最大长度 | 说明                     |
| :---------------- | :----- | :--- | :--------------------- |
| `payoutId`        | String | 64   | 系统Payout ID            |
| `merchantOrderNo` | String | 128  | 商户业务单号                 |
| `amount`          | String | 64   | Payout金额（字符串格式）        |
| `currency`        | String | 8    | Payout币种               |
| `chain`           | String | 16   | 链类型                    |
| `status`          | String | 16   | Payout状态，见「Payout状态说明」 |

**响应示例**

```json theme={null}
{
  "code": "0000",
  "msg": "success",
  "data": {
    "payoutId": "PO202401010001",
    "merchantOrderNo": "PO202401010001",
    "amount": "1000.00",
    "currency": "USDT",
    "chain": "ETH",
    "status": "INIT"
  },
  "traceId": "trace123"
}
```

### 查询Payout

根据Payout ID或商户业务单号查询Payout信息。

* URL：`POST /api/v1/payout/query`
* Content-Type：`application/json`

**请求参数**

参数二选一：`payoutId` 或 `merchantOrderNo` 必须提供其中一个。

| 字段名               | 类型     | 最大长度 | 必填  | 说明                                 |
| :---------------- | :----- | :--- | :-- | :--------------------------------- |
| `payoutId`        | String | 64   | 否\* | Payout ID（与 `merchantOrderNo` 二选一） |
| `merchantOrderNo` | String | 128  | 否\* | 商户业务单号（与 `payoutId` 二选一）           |

**请求示例**

```json theme={null}
{
  "payoutId": "PO202401010001"
}
```

**响应参数**

| 字段名               | 类型     | 最大长度 | 说明              |
| :---------------- | :----- | :--- | :-------------- |
| `payoutId`        | String | 64   | 系统Payout ID     |
| `merchantOrderNo` | String | 128  | 商户业务单号          |
| `amount`          | String | 64   | Payout金额（字符串格式） |
| `currency`        | String | 8    | Payout币种        |
| `chain`           | String | 16   | 链类型             |
| `toAddress`       | String | 64   | Payout目标地址      |
| `txHash`          | String | 64   | 区块链交易哈希         |
| `convertOrderNo`  | String | 64   | RD Convert 订单号  |
| `status`          | String | 16   | Payout状态        |

**Payout状态说明**

| 状态           | 说明  |
| :----------- | :-- |
| `INIT`       | 初始化 |
| `PROCESSING` | 处理中 |
| `SUCCESS`    | 成功  |
| `FAILED`     | 失败  |

**响应示例**

```json theme={null}
{
  "code": "0000",
  "msg": "success",
  "data": {
    "payoutId": "PO202401010001",
    "merchantOrderNo": "PO202401010001",
    "amount": "1000.00",
    "currency": "USDT",
    "chain": "ETH",
    "toAddress": "0x9876...5432",
    "txHash": "0xdef456...abc123",
    "convertOrderNo": "CO202401010001",
    "status": "SUCCESS"
  },
  "traceId": "trace123"
}
```

## 状态通知（Webhook，含签名）

**概述**

当订单、退款或Payout状态发生变更时，系统会通过 HTTPS `POST` 请求向商户配置的通知 URL 发送状态通知 ，回调请求的签名生成、基础合法性校验由网关统一处理。

商户需在管理后台配置用于接收通知的 URL，仅支持 HTTPS 协议，并在服务端实现处理逻辑。

所有通知请求均会携带签名头，商户必须完成签名校验后再进行业务处理。

**通知请求头**

与业务请求类似，回调通知也会携带以下 Header：

| 字段名           | 类型     | 必填 | 说明                |
| :------------ | :----- | :- | :---------------- |
| `X-Api-Key`   | String | 是  | 商户 API Key（平台分配）  |
| `X-App-Id`    | String | 是  | 商户应用标识            |
| `X-Timestamp` | String | 是  | 时间戳，用于防重放         |
| `X-Nonce`     | String | 是  | 随机字符串             |
| `X-Signature` | String | 是  | 回调签名（HMAC-SHA256） |

回调请求的签名由网关统一生成，签名算法与 3.1 节业务请求签名算法完全一致，签名 Payload 固定拼接规则为：

POST + 回调URL完整路径 + X-App-Id + X-Timestamp + X-Nonce + 回调Body原始JSON字符串

签名算法与第 3.1 节一致，Body 为通知的 JSON 内容。商户侧必须使用自身保存的 `AppSecret` 对通知进行验签，拒绝未通过验签的请求，返回 401 状态码。

> 注意：与上面不同的地方是，这里使用回调URL完整路径，即 **用于接收通知的完整URL**

**触发场景**

| 触发场景     | 说明                           |
| :------- | :--------------------------- |
| 订单支付成功   | 用户完成支付，订单状态变更为 `PAY_SUCCESS` |
| 订单支付失败   | 订单被主动取消，状态变更为 `PAY_FAILED`   |
| 订单过期     | 订单超时未支付，系统自动取消，状态为 `TIMEOUT` |
| 退款成功     | 退款处理完成，状态变更为 `SUCCESS`       |
| 退款失败     | 退款处理失败，状态变更为 `FAILED`        |
| Payout成功 | Payout处理完成，状态变更为 `SUCCESS`   |
| Payout失败 | Payout处理失败，状态变更为 `FAILED`    |

### 订单状态通知

* 请求方式：
  * URL：商户配置的通知 URL
  * Method：`POST`
  * Content-Type：`application/json`

**请求参数（订单通知）**

| 字段名               | 类型     | 最大长度 | 说明               |
| :---------------- | :----- | :--- | :--------------- |
| `orderId`         | String | 64   | 系统订单 ID          |
| `bizNo`           | String | 128  | 商户业务单号           |
| `orderAmount`     | String | 64   | 订单金额             |
| `actualAmount`    | String | 64   | 实际到账金额           |
| `currency`        | String | 8    | 币种               |
| `receiveCurrency` | String | 16   | 链上收到的币种          |
| `receiveAddress`  | String | 64   | 链上收到钱的地址         |
| `chain`           | String | 16   | 链类型              |
| `status`          | String | 16   | 订单状态（与 5.2.4 一致） |
| `blockHeight`     | Long   | -    | 区块高度，便于链上查证      |

**请求示例**

```json theme={null}
{
  "orderId": "O202401010001",
  "bizNo": "BIZ202401010001",
  "orderAmount": "100.00",
  "actualAmount": "100.00",
  "currency": "USD",
  "receiveCurrency": "USDT",
  "receiveAddress": "0x123...xyz",
  "chain": "ETH",
  "status": "PAY_SUCCESS",
  "blockHeight": 19384738
}
```

### 退款状态通知

请求参数（退款通知）：

| 字段名            | 类型     | 最大长度 | 说明               |
| :------------- | :----- | :--- | :--------------- |
| `refundId`     | String | 64   | 退款 ID            |
| `orderId`      | String | 64   | 原订单 ID           |
| `refundAmount` | String | 64   | 退款金额             |
| `currency`     | String | 16   | 币种               |
| `txHash`       | String | 64   | 区块链交易哈希（使用驼峰命名）  |
| `status`       | String | 16   | 退款状态（与 6.2.4 一致） |
| `blockHeight`  | Long   | -    | 区块高度             |

**请求示例**

```json theme={null}
{
  "refundId": "R202401010001",
  "orderId": "O202401010001",
  "refundAmount": "100.00",
  "currency": "USDT",
  "txHash": "0xabc123...def456",
  "status": "SUCCESS",
  "blockHeight": 19384800
}
```

### Payout状态通知

请求参数（Payout通知）：

| 字段名               | 类型     | 最大长度 | 说明                   |
| :---------------- | :----- | :--- | :------------------- |
| `payoutId`        | String | 64   | 系统Payout ID          |
| `merchantOrderNo` | String | 128  | 商户业务单号               |
| `amount`          | String | 64   | Payout金额             |
| `currency`        | String | 8    | Payout币种             |
| `chain`           | String | 16   | 链类型                  |
| `txHash`          | String | 64   | 区块链交易哈希              |
| `status`          | String | 16   | Payout状态（与 7.2.4 一致） |

**请求示例**

```json theme={null}
{
  "payoutId": "PO202401010001",
  "merchantOrderNo": "PO202401010001",
  "amount": "1000.00",
  "currency": "USDT",
  "chain": "ETH",
  "txHash": "0xdef456...abc123",
  "status": "SUCCESS"
}
```

**商户响应要求与重试**

* 商户服务需返回 HTTP `200` 状态码表示成功接收并处理通知。
* 非 `200` 状态码或超时会被视为失败，系统会进行一定次数的重试（具体策略以平台实际配置为准）。
* 建议返回统一响应格式：

```json theme={null}
{
  "code": "SUCCESS"
}
```

> **重要要求：**
>
> * 商户侧通知处理逻辑必须实现幂等性（例如通过 `orderId` / `refundId` + 状态进行去重），避免重复通知导致业务重复处理。
> * 在业务处理前，必须先进行签名校验与参数校验，拒绝所有未通过验签的请求。

## 最佳实践建议

1. **幂等性控制**
   1. 使用 `bizNo` 保证订单创建幂等性：相同 `bizNo` 的请求会返回同一订单信息。
   2. 建议使用 UUID 或业务唯一标识作为 `bizNo`。
2. **订单状态轮询**
   1. 可在前端或商户系统中根据业务需要轮询「查询订单」接口，合理设置轮询间隔和最长轮询时间，避免过于频繁请求。
3. **回调通知处理**
   1. 收到订单/退款状态通知后，先进行签名校验、参数校验，再进行业务处理。
   2. 实现幂等逻辑，确保多次通知不会导致重复扣款或重复发货。
4. **错误处理与排查**
   1. 根据 `code` 字段判断请求是否成功，失败时根据 `msg` 提示及业务日志进行排查。
   2. 与平台对接排查时，请提供对应的 `traceId`、请求时间范围及业务关键信息（如 `orderId` / `bizNo`）。
5. **安全建议**
   1. `ApiKey`/`AppSecret` 仅在服务端使用，不要在前端、移动端或浏览器环境中暴露。
   2. 配置 IP 白名单，限制仅可信服务器访问。
   3. 全程使用 HTTPS，避免明文传输。
   4. 定期轮换密钥并及时更新到服务端配置。

## 常见问题（FAQ）示例

**Q：创建订单时提示** `1010 认证失败`**，如何处理？**

请检查：

* 请求是否在 Header 中携带了正确的 `X-Api-Key`、`X-App-Id`；
* `X-Timestamp` 是否在允许时间窗口内（未过期）；
* `X-Nonce` 是否每次请求都不同；
* 签名 `X-Signature` 是否按照文档要求生成；
* API Key 是否已在后台启用且未过期；
* 当前请求 IP 是否在配置的白名单范围内。

**Q：收不到回调通知怎么办？**

请检查：

* 确认在商户后台已正确配置通知 URL；
* 检查商户服务是否能被公网访问，且未被防火墙拦截；
* 查看服务端日志，确认是否有请求到达但返回非 200 或超时；
* 确认是否正确处理了签名校验（未通过验签的平台会记录失败日志，可与平台侧核对 `traceId`）；
* 可通过订单/退款查询接口对比状态是否已更新。

**Q：如何避免回调通知重复处理？**

请检查：

* 在业务处理前，先根据 `orderId` / `refundId` + 状态检查是否已处理过该状态；如已处理则直接返回成功，保持幂等。

**Q：多链支付场景下，用户往 ETH 和 TRX 地址分别转了一部分金额，订单怎么算成功？**

请检查：

* 推荐前端只展示并引导用户选择一条链完成支付。若确需支持多笔累加。
* 与平台确认：是否允许按订单维度对多条链/多笔交易进行金额累计；
* 若允许，应在业务上约定累计达到期望金额后视为成功，并在对账单中体现各笔交易明细。
