Skip to content

创建订单 ​

在你的服务端调用,为一次业务创建一张平台支付单。

http
POST {API_BASE}/api/pay/open/createOrder
X-Pay-Api-Key: <你的 API KEY>
Content-Type: application/json

这个接口的调用方是持 API KEY 的商家系统,不是浏览器。商户身份只来自 KEY。

请求字段 ​

字段类型必填说明
merchantOrderNostring是你的订单号。幂等键,重试必须用同一个号。长度上限 64
amountstring是代币单位的小数字符串,如 "100" / "100.5"。见下方"金额约定"
chainIdnumber是用哪条链收款(来自你的可用链清单)
tokenIdnumber是这条链上的哪个代币
subjectstring否标题,展示在收银页与订单列表里
notifyUrlstring否本单专属回调地址,覆盖商户档案上的默认值
returnUrlstring否支付完成后把买家浏览器跳回你的哪个地址

关于 notifyUrl 与 returnUrl 的区别:前者是服务器到服务器(你的后端据此发货), 后者是买家浏览器里的那一跳(你的"支付完成"页)。很多商家两个都要。

bash
curl -X POST "$API_BASE/api/pay/open/createOrder" \
  -H "X-Pay-Api-Key: $PAY_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "merchantOrderNo": "SHOP-2026-0001",
    "chainId": 2,
    "tokenId": 1,
    "amount": "100.5",
    "subject": "订单 SHOP-2026-0001",
    "notifyUrl": "https://your-shop.com/pay/notify",
    "returnUrl": "https://your-shop.com/pay/done"
  }'

金额约定 ​

这是整套接口里最容易出错的地方,请务必看清。

接口amount 的形态示例
开放接口下单(本页)代币单位的小数字符串"100" / "100.5"
收银页线下下单 createCashierOrder最小单位整数字符串6 位小数的币,100 就是 "100000000"

两者刻意相反:商家的服务端本来就知道人可读的金额,而收银页前端是 parseUnits 之后的结果。 传错形态会被拒绝或被误解 —— 金额差 10 的 decimals 次方,而对方很可能不会立刻发现。

decimals 由代币决定(USDT 常见为 6),可以在链与代币清单里读到。

幂等:merchantOrderNo 是幂等键 ​

同一个 merchantOrderNo 重复调用不会新建订单,而是返回同一张支付单,响应里的 idempotentReplay 为 true。

  • 网络抖动、超时重试,用同一个 merchantOrderNo 再发一次是安全的。
  • 想确实再开一单,就必须换一个新的 merchantOrderNo。
  • 为什么不这么做会出事:没有幂等键,重试会生成两张单、可能收到两笔钱, 而平台没有私钥,多收的那一笔退不回去。

响应 ​

json
{
  "code": 0,
  "data": {
    "order": {
      "orderNo": "PO20261011XXXXXXXXXXXX",
      "merchantOrderNo": "SHOP-2026-0001",
      "merchantNo": "M00000XXXX",
      "status": 1,
      "statusText": "待支付",
      "orderType": 1,
      "amountMinimal": "100500000",
      "payAmountMinimal": "100500123",
      "payAmountDisplay": "100.500123",
      "receivedAmountMinimal": "0",
      "chainId": 2,
      "chainKey": "tron",
      "chainType": 2,
      "tokenId": 1,
      "tokenSymbol": "USDT",
      "tokenContract": "TXxx...合约地址",
      "tokenDecimals": 6,
      "payAddress": "TXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      "subject": "订单 SHOP-2026-0001",
      "txHash": "",
      "confirmations": 0,
      "requiredConfirmations": 19,
      "expiresAt": "2026-10-11T10:30:00Z",
      "identify": {
        "mode": 1,
        "orderNo": "PO20261011XXXXXXXXXXXX",
        "calldataSuffix": "0x...订单识别码..."
      },
      "notifyUrl": "https://your-shop.com/pay/notify"
    },
    "idempotentReplay": false
  },
  "msg": "下单成功"
}

关键字段 ​

字段说明
orderNo平台订单号。查询接口与收银页都用它定位这一单
idempotentReplaytrue = 复用了已有支付单,不是新建。重试时必须读它,否则你会以为又开了一张新单
amountMinimal你下单时给的金额(最小单位)
payAmountMinimal实际应该转的金额(最小单位)。识别方式为"金额尾数"时会比 amountMinimal 多一段尾数 —— 以它为准
payAmountDisplay上面那个给人看的形式,省得你按 decimals 自己除一遍
receivedAmountMinimal链上实际收到的金额。对账用,可能大于应付(买家多转),也可能是 0(还没扫到)
payAddress这一单该转给谁(下单时锁定的快照)
tokenContract代币合约地址。拼接交易要用它(交易的 to 是合约,不是收款地址,写反了代币一个都不会动)
identify订单识别信息,必须原样透传,改了大小写或加前缀,扫块时就认不出这一单
notifyUrl这一单实际生效的回调地址。回给你,是为了让你当场发现"我传的地址没生效"
expiresAt订单的付款有效期

用 payAmountMinimal,不要用 amountMinimal

买家实际该转的金额是 payAmountMinimal。当你看到它和 amountMinimal 不一样时, 那是识别用的尾数,不是错误。

常见拒绝原因 ​

下单被拒时,错误信息是给人看的,会原样转达(例如"金额低于最小限额")。 这些不消耗幂等额度,可以修正后重试。完整的排查表见错误码。

相关 ​

面向全球中小商家的 Web3 支付基础设施