빠른 시작

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일 만에 운영 시작