POST · /api/v1/payment/orders
创建支付订单
创建一笔支付订单:系统分配专属收款地址、按需锁价,返回托管付款页地址 checkoutUrl。按 appOrderNo 幂等。
/api/v1/payment/orders HMAC 幂等 金额二选一:传 payAmount 直接指定币数;或传 fiatCurrency + fiatAmount 由系统报价锁价。两者都不传返回 1007004021;两者都传时以 payAmount 为准、不报价。
幂等:重复请求返回原订单,不会改单
同一应用 + 同一appOrderNo 第二次请求,直接返回首次创建的订单(若已到期会先按规则转为 EXPIRED 再返回)。 要换金额 / 币种请换一个新的 appOrderNo。 Header 参数
X-Api-Keystring required | 应用 apiKey。沙箱前缀 pk_test_,正式 pk_live_。 例: pk_test_4f9d8ab1c0e74... |
X-Timestampinteger (UNIX 毫秒) required | 请求发起时刻的 UNIX 毫秒时间戳(13 位整数)。与服务端时差不能超过 ±300000ms(5 分钟)。 例: 1746450000000 |
X-Noncestring required | 本次请求的随机串,建议 UUID v4 或 16 字节 hex。同一 (apiKey, nonce) 在 10 分钟窗口内不可重复。 例: 8e3a1c2f7b6d4a90 |
X-Signaturestring required | HMAC-SHA256 签名(小写 hex,64 字符)。算法: HMAC(secret, METHOD + "\n" + PATH + "\n" + ts + "\n" + nonce + "\n" + SHA256(body))。详见 鉴权章节。 例: 6e4a8c1f...(64 字符) |
Body 参数
application/jsonappOrderNostring required | 商户业务单号,幂等键,最多 64 个字符。同一应用下同一 appOrderNo 重复请求直接返回原订单(不会按新参数改单)。 例: ORDER_20261023_0001 |
fiatCurrencystring optional | 法币币种,最多 16 个字符。未传 payAmount 时必填,用于自动锁价。 例: USD |
fiatAmountnumber optional | 法币金额,必须大于 0。未传 payAmount 时必填,系统据此换算 payAmount。 例: 100.00 |
payCurrencystring optional | 收款币种符号,最多 32 个字符。不传时按应用已启用的第一个代币兜底;传了则在已启用代币里按符号(不区分大小写)匹配。 例: USDT |
payAmountnumber optional | 应付币种金额,必须大于 0。传入时跳过自动报价,订单不带汇率快照。 例: 100 |
chainCodestring optional | 公链 code,可选,用于限定收款链。 例: TRON |
chainIdinteger optional | 公链内部 id,可选;与 chainCode 同时传时必须一致。 |
chainTokenIdinteger optional | 链上代币 id,可选;传了则直接用该代币(必须属于请求的链、且应用已启用)。不传时按 chain / payCurrency 选择。 |
callbackUrlstring optional | 本订单的回调地址,最多 500 个字符,必须 http(s)。传了则覆盖应用后台配置的 PAYMENT_ORDER 回调地址。 |
expireMinutesinteger optional | 推荐使用。多少分钟后过期,≥ 1。expireTime 不传时生效,默认 30。 例: 30 |
expireTimeinteger optional | 过期时间,UNIX 毫秒时间戳,必须晚于当前时间。服务端按服务器时区(东八区,Asia/Shanghai)换算成本地时间存储,跨时区对时容易出错,建议改用 expireMinutes。 |
payerSelectsCurrencyboolean optional | 传 true 时由付款人在付款页自选币种:此时必须传 fiatCurrency + fiatAmount、不能传 payAmount,订单先处于 AWAITING_CURRENCY,响应里没有收款地址和币数。(新增参数,随后端版本上线) |
allowedChainTokenIdsinteger[] optional | 配合 payerSelectsCurrency 使用:限定付款人可选的代币 id 列表;不传 = 应用所有已启用代币。(新增参数,随后端版本上线) 例: [50, 61] |
extrasstring optional | 商户扩展字段(JSON 字符串),原样存储并在查询、回调中返回。 例: {"userId":"u_1024"} |
示例
{
"appOrderNo": "ORDER_20261023_0001",
"fiatCurrency": "USD",
"fiatAmount": 100.00,
"payCurrency": "USDT",
"chainCode": "TRON",
"expireMinutes": 30,
"extras": "{\"userId\":\"u_1024\"}"
}请求示例
# 签名算法(stringToSign / 4 个 header)见 /docs/api/auth
API_KEY=pk_test_xxx
SECRET=sk_test_xxx
METHOD=POST
REQ_PATH='/api/v1/payment/orders'
BODY='{"appOrderNo":"ORDER_20261023_0001","fiatCurrency":"USD","fiatAmount":100.00,"payCurrency":"USDT","chainCode":"TRON","expireMinutes":30}'
TS=$(( $(date +%s) * 1000 ))
NONCE=$(uuidgen | tr -d '-' | tr '[:upper:]' '[:lower:]')
BODY_SHA=$(printf "%s" "$BODY" | openssl dgst -sha256 -hex | awk '{print $2}')
SIG=$(printf "%s\n%s\n%s\n%s\n%s" "$METHOD" "$REQ_PATH" "$TS" "$NONCE" "$BODY_SHA" \
| openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $2}')
curl -X POST "https://api.pqpa.com$REQ_PATH" \
-H "Content-Type: application/json" \
-H "X-Api-Key: $API_KEY" \
-H "X-Timestamp: $TS" \
-H "X-Nonce: $NONCE" \
-H "X-Signature: $SIG" \
-d "$BODY"响应
200OK
{
"code": 0,
"data": {
"appOrderNo": "ORDER_20261023_0001",
"checkoutUrl": "https://pay.example.com/checkout/3f9c...e1",
"payAddress": "TXyz...abc",
"memo": null,
"fiatCurrency": "USD",
"fiatAmount": 100.00,
"payAmount": 100.010001,
"payCurrency": "USDT",
"chainCode": "TRON",
"chainTokenId": 50,
"rateSnapshotId": 7001,
"rate": 0.99990000,
"rateSource": "THIRD_PARTY",
"rateExpireTime": 1792732800000,
"rateExpireTimeMillis": 1792732800000,
"ratePrecision": 8,
"payPrecision": 6,
"slippageBps": 0,
"expireTime": 1792732800000,
"expireTimeMillis": 1792732800000,
"status": "PENDING"
},
"msg": ""
}data 字段说明
appOrderNostring required | 商户业务单号。 |
checkoutUrlstring required | 托管付款页地址 {checkoutBaseUrl}/checkout/{checkoutToken},直接重定向付款人即可。服务端未配置 checkoutBaseUrl 时只返回相对路径 /checkout/{checkoutToken}。 |
payAddressstring required | 本订单专属收款地址。 |
memostring? optional | Memo 链的 memo/tag,付款时必须填写;非 memo 链为 null。 |
fiatCurrencystring? optional | 法币币种;按法币下单时返回。 |
fiatAmountnumber? optional | 法币金额;按法币下单时返回。 |
payAmountnumber required | 应付币种金额。 |
payCurrencystring required | 收款币种。 |
chainCodestring required | 公链 code。 |
chainTokenIdinteger required | 链上代币 id。 |
rateSnapshotIdinteger? optional | 汇率快照 id;直接传 payAmount 时为 null。以下汇率字段同理。 |
ratenumber? optional | 汇率:1 个 payCurrency 对应的 fiatCurrency 价格。 |
rateSourcestring? optional | 报价来源: THIRD_PARTY / LOCAL_TABLE / MOCK。 |
rateExpireTimeinteger? optional | 锁价过期时间(毫秒时间戳)。 |
rateExpireTimeMillisinteger? optional | 锁价过期时间戳(毫秒),与上一字段同值。 |
ratePrecisioninteger? optional | 报价精度(小数位),默认 8。 |
payPrecisioninteger? optional | 支付币种精度,取代币小数位。 |
slippageBpsinteger? optional | 滑点保护,单位 bps。 |
expireTimeinteger required | 订单过期时间(毫秒时间戳)。按法币下单时可能被截短到 rateExpireTime,见锁价与过期。 |
expireTimeMillisinteger required | 订单过期时间戳(毫秒),与上一字段同值。 |
statusstring required | 订单状态,新订单为 PENDING;幂等命中时返回原订单当前状态。 |
时间字段都是毫秒时间戳
请求里的expireTime 与响应里所有时间字段都是 UNIX 毫秒数字(与全站约定一致)。 错误码
| code | 名称 | 说明 |
|---|---|---|
1007004021 | PAYMENT_ORDER_PAY_AMOUNT_REQUIRED | 请传 payAmount,或传 fiatAmount + fiatCurrency 由系统报价。 |
1007004022 | PAYMENT_ORDER_RATE_NOT_SUPPORTED | 该法币 / 收款币种组合没有可用报价(未配置汇率且实时报价不可用)。 |
1007004023 | PAYMENT_ORDER_TOKEN_NOT_ENABLED | 应用未启用该支付代币(或应用没有任何已启用代币、payCurrency 匹配不到)。 |
1007004024 | PAYMENT_ORDER_TOKEN_CHAIN_MISMATCH | 支付代币不属于请求公链:chainCode / chainId / chainTokenId 三者互相矛盾。 |
1007004025 | PAYMENT_ORDER_EXPIRE_TIME_INVALID | 支付订单过期时间必须晚于当前时间。 |
1007004026 | PAYMENT_ORDER_CALLBACK_URL_INVALID | callbackUrl 非法:必须是 http:// 或 https:// 开头,且不超过 500 个字符。 |
1007004027 | PAYMENT_ORDER_PAY_AMOUNT_INVALID | 支付金额必须大于 0。 |
1007004028 | PAYMENT_ORDER_FIAT_AMOUNT_INVALID | 法币金额必须大于 0。 |
1007004029 | PAYMENT_ORDER_RATE_INVALID | 支付订单汇率配置无效(汇率为空或不大于 0)。 |
1007004035 | PAYMENT_ORDER_SELF_SELECT_FIAT_REQUIRED | 付款人自选币种的订单必须按法币金额开具(fiatCurrency + fiatAmount),且不能传 payAmount。 |
参数校验失败(如 appOrderNo 为空、超长、金额 ≤ 0)走全站通用的参数错误码,见 API 总览 · 错误码。