快速開始

5 步完成支付整合

1

註冊並取得 API Key

註冊商戶帳號,在控制台建立專案,取得 Access Key 和 Secret Key。

2

設定非同步通知位址

在專案設定中配置接收非同步通知的 URL,系統將在訂單狀態變更時推送通知。

3

呼叫建立訂單 API

使用 HMAC-SHA256 簽章呼叫 POST /payments,取得收款位址和收銀台連結。

4

處理非同步通知

接收非同步通知,驗證 X-BS-Signature 簽章後更新本地訂單狀態。

5

測試與上線

在沙箱環境完成全流程測試,確認無誤後切換到生產環境。

🔑

HMAC-SHA256 簽章認證

每個請求需攜帶 Access Key、時間戳記、隨機 Nonce 和 HMAC 簽章,確保請求不可偽造。

🔔

非同步通知 (Webhook)

支援 payment.completed、order.expired、payment.underpaid 等 8 種事件類型,涵蓋完整支付生命週期。

🔄

12 態訂單狀態機

PENDING → PAID_UNCONFIRMED → CONFIRMED → COMPLETED,含異常分支(少付/多付/過期/風控),狀態流轉清晰可控。

🔒

冪等與防重放

Nonce 防重放,merchant_order_no 防重複建立,event_id 防重複處理,三重冪等保障。

API 認證方式

所有商戶 API 請求均需使用 HMAC-SHA256 簽章認證

請求標頭 (Required Headers)

Header说明示例
X-BS-Access-Key商户 Access Key(公钥),标识商户身份ak_live_xxxxxxxxxxxx
X-BS-Timestamp请求时间戳(秒级 Unix 时间),与服务器时间偏差不超过 5 分钟1704067200
X-BS-Nonce随机字符串(UUID),防止重放攻击,每次请求唯一550e8400-e29b-41d4-a716-446655440000
X-BS-SignatureHMAC-SHA256 签名(Hex 编码)a1b2c3d4e5f6...
Content-Type固定为 JSON 格式application/json

簽章演算法

signature.txt
// 1. Construct signature body
signature_body = "{timestamp}" + "." + "{nonce}" + "." + "{request_body}"

// 2. Compute HMAC-SHA256 with Secret Key
signature = HMAC-SHA256(signature_body, secret_key)

// 3. Convert signature to Hex string, set as X-BS-Signature header
X-BS-Signature = hex(signature)

// Example:
// timestamp  = "1704067200"
// nonce      = "550e8400-e29b-41d4-a716-446655440000"
// body       = '{"merchant_order_no":"ORD-001","fiat_amount":"100.00",...}'
// secret_key = "sk_live_your_secret_key"
// signature_body = "1704067200.550e8400-e29b-41d4-a716-446655440000.{...json...}"
安全提示:Secret Key 仅在创建时展示一次,请妥善保存。请勿在前端代码中暴露 Secret Key,所有签名计算应在服务端完成。

API 介面文件

Base URL: https://api.blocksettler.com/api/v1/merchant

POST/payments创建支付订单

请求参数 (Request Body)

字段类型必填说明
merchant_order_nostring商户订单号,同一应用下唯一(最长 64 字符)
titlestring订单标题,展示给付款方(最长 128 字符)
descriptionstring订单描述(最长 512 字符)
fiat_amountstring法币金额,如 "100.00"
fiat_currencystring法币币种,如 "USD", "CNY"
pay_chainstring支付链:POLYGON / TRON / ETH / BSC / SOLANA,不传则使用项目默认值
pay_tokenstring支付代币:USDT / USDC,不传则使用项目默认值
notify_urlstring异步通知地址,不传则使用项目配置的默认地址
return_urlstring支付完成后前端跳转地址
expires_inint订单有效期(秒),范围 300~86400,默认 1800(30分钟)
metadataobject商户自定义数据,原样返回在异步通知中

响应参数 (Response Body)

字段类型说明
platform_order_nostring平台订单号(BlockSettler 生成的唯一标识)
merchant_order_nostring商户订单号(请求时传入)
statusstring订单状态,创建时为 "PENDING"
fiat_amountstring法币金额
fiat_currencystring法币币种
pay_amountstring应付加密货币金额(系统按实时汇率计算)
paid_amountstring已付加密货币金额(创建时为 0)
pay_chainstring支付链名称
pay_tokenstring支付代币
pay_addressstring收款地址(付款方需向此地址转账)
expired_atstring订单过期时间(ISO 8601 格式)
created_atstring创建时间

请求示例

POST /api/v1/merchant/payments
// Request Body
{
  "merchant_order_no": "ORD-20250415-0001",
  "title": "Premium Plan - 1 Month",
  "description": "Premium membership subscription",
  "fiat_amount": "99.00",
  "fiat_currency": "USD",
  "pay_chain": "TRON",
  "pay_token": "USDT",
  "notify_url": "https://your-site.com/api/payment/notify",
  "return_url": "https://your-site.com/payment/success",
  "expires_in": 1800,
  "metadata": {
    "user_id": "U-10086",
    "plan": "premium"
  }
}

响应示例

Response 200 OK
{
  "code": 200,
  "message": "success",
  "data": {
    "platform_order_no": "BS2025041500000001",
    "merchant_order_no": "ORD-20250415-0001",
    "status": "PENDING",
    "fiat_amount": "99.00",
    "fiat_currency": "USD",
    "pay_amount": "99.000000000000000000",
    "paid_amount": "0.000000000000000000",
    "pay_chain": "TRON",
    "pay_token": "USDT",
    "pay_address": "TN7gK3Wfxy4RDXG5DPGnXmkJJPqozvMBkR",
    "return_url": "https://your-site.com/payment/success",
    "expired_at": "2025-04-15T11:30:00Z",
    "created_at": "2025-04-15T11:00:00Z"
  }
}
GET/payments/:order_no查询订单详情

通过平台订单号查询订单最新状态。 :order_no = platform_order_no

响应示例(支付完成后)

Response 200 OK
{
  "code": 200,
  "message": "success",
  "data": {
    "platform_order_no": "BS2025041500000001",
    "merchant_order_no": "ORD-20250415-0001",
    "status": "COMPLETED",
    "fiat_amount": "99.00",
    "fiat_currency": "USD",
    "pay_amount": "99.000000000000000000",
    "paid_amount": "99.000000000000000000",
    "pay_chain": "TRON",
    "pay_token": "USDT",
    "pay_address": "TN7gK3Wfxy4RDXG5DPGnXmkJJPqozvMBkR",
    "expired_at": "2025-04-15T11:30:00Z",
    "paid_at": "2025-04-15T11:05:32Z",
    "confirmed_at": "2025-04-15T11:06:45Z",
    "completed_at": "2025-04-15T11:06:45Z",
    "created_at": "2025-04-15T11:00:00Z"
  }
}
POST/payments/:order_no/close关闭订单

关闭一个待支付的订单。仅 PENDING、UNDERPAID、OVERPAID、LATE_PAID 状态的订单可关闭。

请求参数

字段类型必填说明
reasonstring关闭原因(最长 128 字符)
INFO统一响应格式与错误码

所有接口返回统一 JSON 结构:

response_format.json
// Success response
{ "code": 200, "message": "success", "data": { ... } }

// Invalid parameters
{ "code": 400, "message": "invalid fiat_amount", "data": null }

// Authentication failed (invalid signature / Access Key / expired timestamp)
{ "code": 401, "message": "invalid signature", "data": null }

// Resource not found
{ "code": 404, "message": "order not found", "data": null }

// Internal server error
{ "code": 500, "message": "internal error", "data": null }

非同步通知 (Webhook)

當訂單狀態發生變化時,BlockSettler 會向商戶設定的回呼位址傳送 HTTP POST 請求

支援的事件類型

event_type触发时机说明
payment.confirmed链上确认数达标交易已确认,可发货或交付服务
payment.completed订单完成结算订单流程正常完结
order.expired订单超时未支付超过有效期仍未收到足额支付
order.closed订单被关闭商户主动关闭或系统关闭
payment.underpaid实付金额不足收到的金额少于应付金额
payment.overpaid实付金额超额收到的金额超过应付金额
payment.late_paid过期后到账订单已过期,但仍收到了链上支付
payment.failed支付失败风控审核拒绝等异常

通知報文格式

系统向商户 notify_url 发送 POST 请求,Content-Type 为 application/json。

通知请求头

Header说明
Content-Typeapplication/json
X-BS-Event-ID事件唯一 ID,用于幂等去重
X-BS-Event-Type事件类型,如 payment.completed
X-BS-Timestamp通知发送的时间戳(秒级 Unix 时间)
X-BS-SignatureHMAC-SHA256 签名(用于验证通知来源)

通知 Body 示例(payment.completed)

webhook_payload.json
{
  "event_id": "evt_8f14e45f-ceea-4a4d-a8e0-3c2b5d4e9f01",
  "event_type": "payment.completed",
  "timestamp": "2025-04-15T11:06:45Z",
  "platform_order_no": "BS2025041500000001",
  "status": "COMPLETED",
  "payment": {
    "fiat_amount": "99.00",
    "fiat_currency": "USD",
    "pay_amount": "99.000000",
    "paid_amount": "99.000000",
    "pay_chain": "TRON",
    "pay_token": "USDT",
    "pay_address": "TN7gK3Wfxy4RDXG5DPGnXmkJJPqozvMBkR",
    "tx_hash": "6a1b2c3d4e5f...abc123def456"
  }
}

簽章驗證

商户收到通知后,必须验证 X-BS-Signature 以确认通知来源可信。验证方式:

verify_signature.txt
// 1. Get timestamp and signature from request headers
timestamp  = request.headers["X-BS-Timestamp"]
signature  = request.headers["X-BS-Signature"]

// 2. Read the raw request body (JSON string)
raw_body   = request.body

// 3. Construct signature body and compute HMAC-SHA256
expected   = HMAC-SHA256(timestamp + "." + raw_body, your_webhook_secret)

// 4. Use constant-time comparison to verify signature (prevent timing attacks)
is_valid   = constant_time_equal(hex(expected), signature)

重試機制

成功标准

商户接口返回 HTTP 2xx 状态码视为成功

重试策略

指数退避:1s → 5s → 30s → 5m → 30m → 2h,最多 6 次

幂等处理

请根据 event_id 做幂等判断,同一事件可能被投递多次

最佳实践:收到通知后应先返回 200 OK,再异步处理业务逻辑。若处理耗时过长(>5s),可能导致超时触发重试。

程式碼範例

包含建立訂單(含簽章)和接收非同步通知的完整範例

create_order.sh
# ====== Create Payment Order ======

TIMESTAMP=$(date +%s)
NONCE=$(uuidgen)
BODY='{"merchant_order_no":"ORD-20250415-0001","title":"Premium Plan","fiat_amount":"99.00","fiat_currency":"USD","pay_chain":"TRON","pay_token":"USDT","notify_url":"https://your-site.com/api/notify"}'

# Compute signature: HMAC-SHA256(timestamp.nonce.body, secret_key)
SIGN_BODY="${TIMESTAMP}.${NONCE}.${BODY}"
SIGNATURE=$(echo -n "${SIGN_BODY}" | openssl dgst -sha256 -hmac "sk_live_xxxx" | awk '{print $2}')

curl -X POST https://api.blocksettler.com/api/v1/merchant/payments \
  -H "Content-Type: application/json" \
  -H "X-BS-Access-Key: ak_live_xxxxxxxxxxxx" \
  -H "X-BS-Timestamp: ${TIMESTAMP}" \
  -H "X-BS-Nonce: ${NONCE}" \
  -H "X-BS-Signature: ${SIGNATURE}" \
  -d "${BODY}"

# ====== Query Order ======
curl -X GET https://api.blocksettler.com/api/v1/merchant/payments/BS2025041500000001 \
  -H "X-BS-Access-Key: ak_live_xxxxxxxxxxxx" \
  -H "X-BS-Timestamp: ${TIMESTAMP}" \
  -H "X-BS-Nonce: $(uuidgen)" \
  -H "X-BS-Signature: {computed_signature}"

訂單狀態流轉

BlockSettler 使用 12 態狀態機管理訂單生命週期

CREATED已创建
PENDING待支付
PAID_UNCONFIRMED已支付待确认
CONFIRMED已确认
COMPLETED已完成
EXPIRED已过期
CLOSED已关闭
UNDERPAID少付
OVERPAID多付
LATE_PAID过期到账
RISK_REVIEW风控审核
FAILED失败
order_status_flow.txt
                         Normal Payment Flow
CREATED ──> PENDING ──> PAID_UNCONFIRMED ──> CONFIRMED ──> COMPLETED
                │
                │          Exception Branches
                ├──> EXPIRED          Timed out without payment
                ├──> CLOSED           Closed by merchant
                ├──> UNDERPAID        Paid < Required
                ├──> OVERPAID         Paid > Required
                └──> LATE_PAID        Payment after expiry

EXPIRED ──> LATE_PAID                Payment received after expiry
PAID_UNCONFIRMED ──> RISK_REVIEW   Risk control triggered
RISK_REVIEW ──> CONFIRMED / FAILED  Approved / Rejected

準備好開始整合了嗎?

註冊帳戶取得 API Key,在沙箱環境中測試,平均 1 天完成上線