法币代付 (出金 / Pay-out)
法币代付(Withdrawal)服务支持商户向终端用户指定的中国大陆银行卡进行法币资金下发打款。网关在收到请求后,先从商户资金账户预扣(冻结)等值数字资产,随后撮合承兑商通过手机银行/网银向收款人转账。承兑商打款后上传真实银行凭证,商户可复核到账情况并调用决策接口确认放行或发起争议。
1. 业务交互时序
mermaid
sequenceDiagram
autonumber
participant Merchant as 商户系统
participant Gateway as SureLink 网关
actor Trader as 场外承兑商
actor User as 收款人 (银行卡)
Merchant->>Gateway: 1. POST /api/v1/withdrawals (提交代付请求)
Gateway->>Gateway: 2. 预扣/冻结商户可用资金账本
Gateway->>Trader: 3. 撮合派单给承兑商
Trader->>User: 4. 承兑商向指定银行卡转账汇款 (CNY)
Trader->>Gateway: 5. 上传转账回单电子凭证 (1~3 张图片)
Gateway->>Merchant: 6. Webhook 推送 payout.proof_submitted
alt 商户确认打款属实
Merchant->>Gateway: 7a. POST /api/v1/withdrawals/:orderNo/decision (CONFIRM)
Gateway->>Gateway: 8a. 扣除商户冻结资产,代币正式释放给承兑商
Gateway->>Merchant: 9a. Webhook 推送 payout.completed (订单终态)
else 金额不符或未到账
Merchant->>Gateway: 7b. POST /api/v1/withdrawals/:orderNo/decision (DISPUTE)
Gateway->>Gateway: 8b. 订单进入争议状态,人工客服介入仲裁
end2. 创建代付订单
POST /api/v1/withdrawals
请求头 (Headers)
携带标准 HMAC 签名头及 Idempotency-Key。
请求体 (Body)
| 字段 | 类型 | 是否必填 | 约束说明 |
|---|---|---|---|
merchantOrderNo | string | 必填 | 商户唯一代付订单号,长度 1 ~ 64 字符。 |
direction | string | 否 | 固定 'WITHDRAW',默认为 'WITHDRAW'。 |
fiatAmount | string | 选填* | 欲下发给收款人的法币金额(CNY,严格保留 2 位小数,如 "1500.00")。 |
usdAmount | string | 选填* | 欲扣除的数字资产结算金额(严格保留 2 位小数,如 "206.89")。 |
fiatCurrency | string | 否 | 目前固定为 'CNY'。 |
recipient | object | 必填 | 收款人银行账户敏感信息(结构见下表)。 |
recipient 收款人对象字段
| 字段 | 类型 | 是否必填 | 约束说明 |
|---|---|---|---|
holderName | string | 必填 | 收款人姓名,长度 1 ~ 64 位字符。 |
bankAccount | string | 必填 | 收款银行卡卡号,纯数字,长度 8 ~ 32 位字符。 |
bankName | string | 必填 | 收款银行开户行名称(如 "招商银行"、"中国工商银行")。 |
金额要求与隐私安全
fiatAmount与usdAmount二者必填其一。- 收款人银行卡信息直接入库 AES-256-GCM 高度密文存储。为保障用户 PII 隐私合规,任何明文卡号均绝不在后续的列表响应、日志或 Webhook 中明文透出。
请求示例
bash
curl -X POST "https://api-sandbox.surelink.io/api/v1/withdrawals" \
-H "Content-Type: application/json" \
-H "X-Api-Key: mch_key_your_api_key" \
-H "X-Timestamp: 1715000000000" \
-H "X-Nonce: 9f8e7d6c5b4a392817263544a1b2c3d4" \
-H "X-Signature: c8b9...f01" \
-H "Idempotency-Key: MCH_PAYOUT_20261011_888" \
-d '{
"merchantOrderNo": "MCH_PAYOUT_20261011_888",
"direction": "WITHDRAW",
"fiatAmount": "1000.00",
"fiatCurrency": "CNY",
"recipient": {
"holderName": "张三",
"bankAccount": "6222021234567890123",
"bankName": "中国工商银行"
}
}'typescript
import { sendSignedRequest } from './signer';
const result = await sendSignedRequest({
apiKey: 'mch_key_...',
apiSecret: 'sec_...',
method: 'POST',
url: 'https://api-sandbox.surelink.io/api/v1/withdrawals',
body: {
merchantOrderNo: 'MCH_PAYOUT_20261011_888',
direction: 'WITHDRAW',
fiatAmount: '1000.00',
recipient: {
holderName: '张三',
bankAccount: '6222021234567890123',
bankName: '中国工商银行'
}
}
});响应说明 (Response)
- HTTP 状态码:
201 Created
json
{
"orderId": "3b2e5a7d-8f90-4c12-9e34-5a6b7c8d9e0f",
"orderNo": "WD20261011000088",
"status": "PENDING_MATCH",
"direction": "WITHDRAW",
"fiatAmount": "1000.00",
"fiatCurrency": "CNY",
"usdAmount": "138.50",
"usdFeeAmount": "1.00",
"createdAt": "2026-10-11T09:00:00.000Z"
}3. 分页查询代付订单列表
GET /api/v1/withdrawals
商户可通过本接口分页批量拉取自身创建的代付订单记录,支持按平台单号、商户单号、订单状态以及时间范围多维度组合检索。
请求头 (Headers)
携带标准 HMAC 鉴权请求头(X-Api-Key、X-Timestamp、X-Nonce、X-Signature)。
Query 参数
| 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
page | number | 否 | 1 | 当前页码,从 1 开始 |
pageSize | number | 否 | 20 | 每页数量,最大 100 |
orderNo | string | 否 | - | 按平台业务代付订单号精准筛选(如 WD20261011000088) |
merchantOrderNo | string | 否 | - | 按商户外部订单号精准筛选(如 MCH_PAYOUT_20261011_888) |
status | string | 否 | - | 订单状态筛选,多个状态可用逗号分隔(如 COMPLETED 或 PENDING_MATCH,PENDING_PAYMENT) |
from | string | 否 | - | 创建时间起始范围 (ISO 8601,如 2026-10-01T00:00:00.000Z) |
to | string | 否 | - | 创建时间截止范围 (ISO 8601,如 2026-10-11T23:59:59.000Z) |
请求示例
bash
curl -X GET "https://api-sandbox.surelink.io/api/v1/withdrawals?page=1&pageSize=20&status=PAYMENT_SUBMITTED" \
-H "X-Api-Key: mch_key_your_api_key" \
-H "X-Timestamp: 1715000000000" \
-H "X-Nonce: 9f8e7d6c5b4a392817263544a1b2c3d4" \
-H "X-Signature: c8b9...f01"typescript
import { sendSignedRequest } from './signer';
const result = await sendSignedRequest({
apiKey: 'mch_key_...',
apiSecret: 'sec_...',
method: 'GET',
url: 'https://api-sandbox.surelink.io/api/v1/withdrawals?page=1&pageSize=20&status=PAYMENT_SUBMITTED'
});
console.log('代付订单总数:', result.total);
console.log('订单列表:', result.items);响应说明 (Response)
- HTTP 状态码:
200 OK
json
{
"items": [
{
"orderId": "3b2e5a7d-8f90-4c12-9e34-5a6b7c8d9e0f",
"orderNo": "WD20261011000088",
"merchantOrderNo": "MCH_PAYOUT_20261011_888",
"status": "PAYMENT_SUBMITTED",
"direction": "WITHDRAW",
"usdAmount": "138.50",
"usdFeeAmount": "1.00",
"feeBps": 50,
"fiatCurrency": "CNY",
"referenceFiatAmount": "1000.00",
"slippage": "0.005",
"lockedFiatAmount": "1000.00",
"traderId": "tra_67890",
"paymentDueAt": "2026-10-11T09:30:00.000Z",
"merchantActionDueAt": "2026-10-11T11:00:00.000Z",
"firstProofSubmittedAt": "2026-10-11T09:15:30.000Z",
"createdAt": "2026-10-11T09:00:00.000Z",
"updatedAt": "2026-10-11T09:15:30.000Z"
}
],
"page": 1,
"pageSize": 20,
"total": 1
}4. 查询单笔代付订单详情
GET /api/v1/withdrawals/:orderNo
支持按 平台代付订单号(orderNo) 或 商户外部订单号(merchantOrderNo) 查询单笔代付订单的状态与详情。
路由参数
orderNo(string): 平台的代付订单号(如WD20261011000088)或商户自定义单号(如MCH_PAYOUT_20261011_888)。
响应说明 (Response)
- HTTP 状态码:
200 OK
json
{
"orderId": "3b2e5a7d-8f90-4c12-9e34-5a6b7c8d9e0f",
"orderNo": "WD20261011000088",
"merchantOrderNo": "MCH_PAYOUT_20261011_888",
"status": "PAYMENT_SUBMITTED",
"direction": "WITHDRAW",
"usdAmount": "138.50",
"usdFeeAmount": "1.00",
"feeBps": 50,
"fiatCurrency": "CNY",
"referenceFiatAmount": "1000.00",
"slippage": "0.005",
"lockedFiatAmount": "1000.00",
"traderId": "tra_67890",
"paymentDueAt": "2026-10-11T09:30:00.000Z",
"merchantActionDueAt": "2026-10-11T11:00:00.000Z",
"firstProofSubmittedAt": "2026-10-11T09:15:30.000Z",
"createdAt": "2026-10-11T09:00:00.000Z",
"updatedAt": "2026-10-11T09:15:30.000Z"
}银行卡信息安全与租户隔离
- 为保障持卡人金融信息安全,查询接口不会明文返回收款银行卡全量卡号(卡密信息仅在系统内部加密存储)。
- 若尝试查询属于其他商户的代付订单,系统统一返回
404 Not Found(ORDER_NOT_FOUND),杜绝订单号撞单枚举探测。
5. 商户放行确认与争议决策
POST /api/v1/withdrawals/:orderNo/decision
在承兑商打款并提交凭证后(订单进入 PAYMENT_SUBMITTED 状态),商户系统在核实持卡人账户确实到账后,需调用本接口进行正式确认;如查账未到账或凭证虚假,可发起争议。
请求体 (Body)
| 字段 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
decision | string | 必填 | 裁决动作:"CONFIRM" (确认到账放行) 或 "DISPUTE" (发起争议申诉)。 |
reason | string | 条件必填 | 争议原因(当 decision === "DISPUTE" 时必须提供,长度 1 ~ 500 字符;CONFIRM 时无需填写)。 |
请求示例
bash
curl -X POST "https://api-sandbox.surelink.io/api/v1/withdrawals/WD20261011000088/decision" \
-H "Content-Type: application/json" \
-H "X-Api-Key: mch_key_your_api_key" \
-H "X-Timestamp: 1715000000000" \
-H "X-Nonce: 9f8e7d6c5b4a392817263544a1b2c3d4" \
-H "X-Signature: c8b9...f01" \
-d '{"decision": "CONFIRM"}'bash
curl -X POST "https://api-sandbox.surelink.io/api/v1/withdrawals/WD20261011000088/decision" \
-H "Content-Type: application/json" \
-H "X-Api-Key: mch_key_your_api_key" \
-H "X-Timestamp: 1715000000000" \
-H "X-Nonce: 9f8e7d6c5b4a392817263544a1b2c3d4" \
-H "X-Signature: c8b9...f01" \
-d '{
"decision": "DISPUTE",
"reason": "银行对账单核查至 10:00,未收到该笔转账"
}'响应说明
- HTTP 状态码:
200 OK - 返回格式:
{ "status": "COMPLETED" }或{ "status": "DISPUTED" }。
6. 代付订单状态机
| 状态代码 | 状态名称 | 说明 | 是否终态 |
|---|---|---|---|
PENDING_MATCH | 待匹配承兑商 | 商户已下单,已冻结资金,正在撮合承兑商接单 | 否 |
PENDING_PAYMENT | 承兑商打款中 | 承兑商已接单,正在执行银行卡打款操作 | 否 |
PAYMENT_OVERDUE | 打款超时 | 承兑商未在规定时效内提交凭证,系统告警调度 | 否 |
PAYMENT_SUBMITTED | 凭证已上传 | 承兑商已上传付款凭证,等待商户核查到账并放行 | 否 |
COMPLETED | 代付完成 | 商户确认放行,冻结代币划转给承兑商,终态 | 是 |
DISPUTED | 争议中 | 商户未收到款或凭证异常发起申诉,人工客服介入处理 | 否 |
CANCELLED | 代付已取消 | 订单取消,商户冻结资产原路退回可用余额,终态 | 是 |
