Demarrage rapide

Integrez les paiements en 5 etapes

1

Inscrivez-vous et obtenez votre API Key

Creez un compte commercant, configurez un projet dans le tableau de bord et obtenez votre Access Key et votre Secret Key.

2

Configurez l'URL de notification

Definissez l'URL de notification Webhook dans les parametres du projet. Le systeme enverra des notifications lors des changements de statut des commandes.

3

Appelez l'API de creation de commande

Utilisez HMAC-SHA256 pour signer votre requete et appelez POST /payments pour obtenir une adresse de reception et un lien de paiement.

4

Traitez les notifications Webhook

Recevez les notifications Webhook, verifiez la signature X-BS-Signature et mettez a jour le statut de la commande locale.

5

Testez et passez en production

Effectuez des tests de bout en bout dans l'environnement sandbox, puis basculez en production une fois la verification terminee.

🔑

Authentification par signature HMAC-SHA256

Chaque requete doit inclure un Access Key, un horodatage, un Nonce aleatoire et une signature HMAC pour garantir l'infalsifiabilite des requetes.

🔔

Notifications asynchrones (Webhook)

Prise en charge de 8 types d'evenements dont payment.completed, order.expired et payment.underpaid, couvrant l'integralite du cycle de vie du paiement.

🔄

Machine a etats de commande a 12 etats

PENDING → PAID_UNCONFIRMED → CONFIRMED → COMPLETED, avec branches d'exception (sous-paiement/surpaiement/expiration/controle des risques). Transitions d'etat claires et controlables.

🔒

Idempotence et protection anti-rejeu

Le Nonce empeche les attaques par rejeu, merchant_order_no empeche les creations en double et event_id empeche le traitement en double : triple protection d'idempotence.

Authentification API

Toutes les requetes API du commercant necessitent une authentification par signature HMAC-SHA256

En-tetes requis (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

Algorithme de signature

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,所有签名计算应在服务端完成。

Documentation de reference 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 }

Notifications asynchrones (Webhook)

Lorsque le statut d'une commande change, BlockSettler envoie une requete HTTP POST a l'URL de rappel configuree par le commercant

Types d'evenements pris en charge

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

Format du message de notification

系统向商户 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"
  }
}

Verification de signature

商户收到通知后,必须验证 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)

Mecanisme de tentatives

成功标准

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

重试策略

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

幂等处理

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

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

Exemples de code

Exemples complets pour creer des commandes (avec signature) et recevoir des notifications Webhook

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}"

Transitions de statut des commandes

BlockSettler utilise une machine a 12 etats pour gerer le cycle de vie des commandes

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

Pret a commencer l'integration ?

Inscrivez-vous pour obtenir une API Key, testez dans l'environnement sandbox et passez en production en 1 jour en moyenne