信息流
这一页讲订单状态怎么流转:订单从创建到完成经过哪些状态、每次状态变化由什么触发、 商户在哪一步会收到通知。
与之相对的资金流讲的是钱怎么走。两者的分工是:
| 资金流 | 信息流 | |
|---|---|---|
| 关心什么 | 钱现在在哪、下一步去哪 | 这笔钱算哪个订单的、订单到哪一步了 |
| 谁驱动 | 商户主动发起归集、提现 | HashNut 检测链上到账、推进状态、发通知 |
| 载体 | 链上交易 | 订单状态 + Webhook 通知 |
TIP
订单状态到 SUCCESS 只表示款已收到、可以发货,不表示钱已经进了你的提现地址 —— 那还需要你主动归集和提现,见资金流。
本页出现的名词都在名词解释里有定义。
时序图
分步说明
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 创建订单 | 商户调用 POST /v4.0.0/api/orders/create。HashNut 返回 receiptAddress 和 payOrderId。 |
| 2 | 展示支付信息 | 将客户重定向至 payUrl,或使用 receiptAddress 和 amount 构建自定义支付页面。 |
| 3 | 客户付款 | 客户在指定链上将代币金额发送至 receiptAddress。 |
| 4 | 到账检测 | HashNut 检测到转账。订单状态变为 PAID (1)。 |
| 5 | 区块确认 | HashNut 等待所需的区块确认数。状态变为 CONFIRMING (2),然后变为 SUCCESS (3)。 |
| 6 | Webhook 通知 | HashNut 向商户的 Notify URL 发送 POST 请求,包含支付结果。 |
| 7 | 反查订单 | 商户先验签,再用通知里的 payOrderId + accessSign 调用查询订单,以查询结果为准更新本地订单。 |
| 8 | 确认收到 | 商户返回 HTTP 200 + 响应体 success。 |
WARNING
第 7 步不能省。通知报文只带 payOrderId / merchantOrderId / accessSign / state 四个字段, 不要仅凭报文里的 state 就发货 —— 金额、交易哈希、补款情况都要靠查询接口拿到权威值。 反查通过之后再回 success,这样万一你的处理逻辑出错,HashNut 还会按重试策略再送一次。
状态流转
金额不符的处理
用户实付金额与订单金额不一致时,订单状态怎么走由 api key 上的长款策略 / 短款策略决定。
短款(少付)
如果客户支付的金额少于所需金额,订单停留在 PAID(1),HashNut 会为差额部分创建一个补单。
| 场景 | 处理方式 |
|---|---|
| 部分支付 | 为差额创建补单 |
| 多次部分支付 | 每次部分支付都会生成新的补单,直到覆盖全部金额 |
| 查询补单 | 使用查询补款记录 API |
是否就此通知商户由短款策略决定:NOTIFY(默认)通知,SILENT 静默等待补款。
WARNING
补单与原订单共享相同的 payOrderId。当订单状态未进入 SUCCESS 时,请务必检查补单列表。
长款(多付)
如果客户支付的金额超过订单金额,处理方式由长款策略决定:
| 策略 | 订单状态 |
|---|---|
AUTO_CONFIRM(默认) | 直接进入 CONFIRMING(2),按支付成功处理 |
MANUAL | 订单保持原状态,等待人工介入 |
WARNING
多付的部分会随资金一起归集进分账合约并参与分账,HashNut 不会自动退还差额。 如需退款请自行与用户结算。
订单过期
- 默认过期时间:可通过
expireDuration配置(最长 259,200 秒 = 3 天) - 过期订单会将其收款地址释放回地址池
- 过期订单不可恢复 —— 需创建新订单
DANGER
不要复用过期订单的收款地址。请始终创建新订单以获取新的地址。
TIP
地址释放不影响已到账的资金 —— 钱仍留在链上那个收款地址里,照样可以归集。 过期订单的资金归属问题见资金流 · 特殊情况下资金去哪了。