法幣代付 (出金 / 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 | 代付已取消 | 訂單取消,商戶凍結資產原路退回可用餘額,終態 | 是 |
