Skip to content

创建订单 ​

创建一个新的支付订单。此接口使用请求头 HMAC 签名。

接口 ​

POST /v4.0.0/api/orders/create

请求体 ​

字段类型必填说明
accessKeyIdstring是您的商户 Access Key ID
merchantOrderIdstring是您的订单标识符,在(链 + 商户 + 渠道)范围内唯一
merchantChannelstring否商户渠道,默认为 default
blockChainstring是区块链名称(如 ETH、TRON、BSC、POLYGON),大小写不敏感
tokenSymbolstring是代币符号(如 usdt、usdc)
amountstring是支付金额,十进制字符串(如 "10.50"),最多精确到小数点后 2 位
splitterAddressstring是您的分账合约地址,必须处于已激活状态且属于该商户
subjectstring否订单主题 / 描述
expireDurationinteger否过期时长(秒),默认 172800(48 小时),上限 259200(72 小时)
callbackUrlstring否前端自定义跳转链接,不传则以 api key 配置的 callbackUrl 为准
remarkstring否订单备注
extrastring否订单额外信息
param1string否订单额外参数 1
param2string否订单额外参数 2

WARNING

请求体里没有 notifyUrl。后端通知地址是 api key 上的配置,创建订单时无法逐笔覆盖; 只有 callbackUrl(前端跳转)可以逐笔指定。两者方向相反,详见 Notify URL 与 Callback URL 的区别。

NOTE

merchantOrderId 的唯一性是按 (链 + 商户地址 + 商户渠道) 判定的, 所以同一个 merchantOrderId 可以在不同链上各存在一笔订单。

请求示例 ​

json
{
  "accessKeyId" : "01K...BB",
  "merchantOrderId" : "aaf..-8",
  "merchantChannel" : null,
  "blockChain" : "ETH",
  "tokenSymbol" : "usdt",
  "amount" : "0.05",
  "splitterAddress" : "0xfd5...f8b",
  "subject" : "Test Order - API Doc",
  "remark" : null,
  "param1" : null,
  "param2" : null,
  "callbackUrl" : null,
  "extra" : null,
  "expireDuration" : 60000,
  "payWebType" : null
}

响应示例 ​

json
{
  "code" : 0,
  "msg" : "success",
  "ui" : null,
  "version" : null,
  "count" : 0,
  "data" : {
    "merchantAddress" : "0x17a...42",
    "merchantChannel" : "default",
    "blockChain" : "ETH",
    "tokenSymbol" : "usdt",
    "createChannel" : 1,
    "merchantOrderId" : "aaf..-8",
    "payOrderId" : "01K...H8",
    "tokenAddress" : "0xdac17f958d2ee523a2206206994597c13d831ec7",
    "receiptAddress" : "0x5...c4",
    "amount" : 0.05,
    "state" : 0,
    "accessSign" : "AA377....F5",
    "rate" : 80,
    "obtainAmount" : 0.0496,
    "platformFee" : 4.0E-4,
    "expireDuration" : "60000",
    "underPaid" : false,
    "paidAmount" : 0.0,
    "createTime" : 1785753243948,
  }
}

NOTE

data 里未赋值的字段会以 null 返回(如 payTxId、param1、errorMsg),上面的示例为可读性省略了它们。 另外 expireDuration、confirmCount、chainId、eip712ChainId 是 JSON 字符串而不是数字—— 服务端把 Java 的 long / Long 统一序列化成字符串,避免 JavaScript 超过 2^53 丢精度。

响应字段 ​

字段类型说明
codeinteger0 表示成功,非零表示错误
msgstring可读的消息文本
data.merchantAddressstring部署分账合约的商户地址
data.merchantChannelstring商户下单渠道,如果入参为空,则返回默认的default
data.blockChainstring区块链名称(如 ETH、TRON、BSC、POLYGON)
data.tokenSymbolstring代币符号(如 usdt、usdc)
data.createChannelinteger下单渠道,0 = 通过商户系统下单,1 = 通过 api key 下单
data.merchantOrderIdstring商户下单时填入的商户订单号
data.payOrderIdstringHashNut 生成的唯一订单ID(26 位 ULID)
data.tokenAddressstring支付订单的 token 合约地址,比方说: USDT的合约地址
data.receiptAddressstring订单收款地址,客户支付订单时需要发送 token 到该地址
data.amountnumber订单应付金额
data.stateinteger订单状态(0 = INIT)。参见订单状态
data.accessSignstring后续查询 / 确认订单必须回传的凭证,请落库保存
data.rateinteger手续费率,除以 rateBase 得到实际比率
data.obtainAmountnumber扣除平台手续费后商户实收金额
data.platformFeenumber平台手续费,商户提现时才会收取
data.expireDurationstring过期时长(秒)
data.underPaidbool订单是否被短款支付,如果用户未支付该状态为false,如果用户支付金额不足,则该字段为true,用户补款足额支付后该字段为true
data.paidAmountnumber用户已经支付的金额
data.createTimedate订单创建时间

TIP

请在您的系统中同时保存 payOrderId、merchantOrderId 和 accessSign。 accessSign 是服务端用 secretKey 对 payOrderId + merchantOrderId 做的 HMAC, 客户端无法自行重算,而查询订单和确认支付都要求带上它。

跳转支付页URL ​

订单创建后,跳转到支付页面的URL格式如下:

https://defi.hashnut.io/pay?accessSign=${accessSign}&merchantOrderId=${merchantOrderId}&payOrderId=${payOrderId}&blockChain=${blockChain}&payApiVersion=v4

返回码 ​

业务错误不使用独立的错误码段,统一通过 code + msg 返回,具体原因看 msg:

code说明
0成功
-1失败
-2异常(参数校验失败、业务规则不满足等,msg 为具体原因)
-3未授权
-4未认证

创建订单时常见的 msg:

msg含义
can not find api key by accessKeyId[...]accessKeyId 不存在,或不是 api key 类型
invalid request sign签名不匹配,见认证签名
request timestamp out of allowed window, ...时间戳超出 ±5 分钟窗口,通常是机器时钟不准
duplicate request uuid, replay rejectedhashnut-request-uuid 复用了
client ip [...] not allowed出口 IP 不在 api key 的 bindIp 白名单里
coin not support / chain not support该链或该币种未开通
merchant order id already exist同链 + 同商户 + 同渠道下 merchantOrderId 重复
eoa splitter address not active分账合约未激活,或不属于该商户
the minimum unit of the amount is 0.01amount 小数位超过 2 位
max expire duration is 259200expireDuration 超过 72 小时