收款单生命周期
收款单从创建走到关闭或过期。本节介绍它可能处于的状态、状态之间的流转,以及商户在每一步可以做什么。
收款单状态
| 状态 | API 值 | 说明 | 是否参与付款检索 |
|---|---|---|---|
| 待支付 (Unpaid) | unpaid | 收款单已开出,支付期限未过,未收到付款 | 是 |
| 已支付 (Paid) | paid | 已找到付款并关联到收款单 | 否 |
| 已过期 (Expired) | expired | 支付期限已过,未收到付款 | 是,过期后再持续 1 小时 |
| 已取消 (Canceled) | canceled | 商户手动或通过 API 取消了收款单 | 否 |
状态流转
- 创建收款单。收款单立即获得待支付状态。
- 待支付 → 已支付。收到与收款单金额完全一致的付款,或商户手动关联了付款。
- 待支付 → 已过期。支付期限已过,未收到付款。
- 待支付 → 已取消。商户取消了收款单。
- 已过期 → 已支付。付款在过期后 1 小时内到达并被自动找到,或由商户手动关联。
- 已取消。终态,无法回退。
处于已支付状态的收款单同样不再变化——不能再次支付,也不能取消。
支付期限
支付期限在创建收款单时设定,范围从 30 分钟到 12 小时。可选值:30 分钟、1 小时、3 小时、6 小时、12 小时。
期限之内,买家能看到支付表单并支付收款单。过期后,收款单转为已过期状态,支付表单不再提供支付。
两个极端都有代价。期限太短在慢速网络上有风险——买家可能来不及;太长则拉大创建收款单时与付款时汇率之间的差距。
付款检索窗口
付款检索在支付期限过后再持续 1 小时——照顾慢速网络:交易可能在收款单形式上过期之后才确认。这段时间里买家看到的收款单是已过期的,但只要金额正确的付款到达,收款单就自动转为已支付,并发送全部通知。
由此得出集成方的规则:不要因为期限已过就拒绝付款通知——这种检查会砍掉一部分真实付款。
取消收款单
收款单有误时可以取消。取消需要满足两个条件:
- 收款单未支付——即处于待支付状态
- 没有人打开过收款单的支付页面,浏览计数为零
第二个条件防止取消买家已经看到、且可能已开始支付的收款单。
取消不可逆。已取消的收款单被排除在付款检索之外,连手动也无法把付款关联上去。如果付款仍有可能到来,与其取消,不如等期限过去——已过期的收款单仍可以由付款关闭。
创建时锁定与付款时重算的内容
创建收款单时,服务按当前汇率把法币金额换算成加密货币,并为收款单锁定这些金额。买家看到的是这些金额,服务在链上找的也是这些金额。汇率不再影响它们:无论过去多久,买家支付的都是锁定的金额。
付款时会重算记账金额:
| 字段 | 变化 |
|---|---|
amountFiat | 收款单的法币原始金额,永不改变 |
amountFiatUSD | 被实际收到的金额覆盖,按付款时的汇率折算成 USD |
commissionFiatUSD | 按项目费率由新的 amountFiatUSD 值重新计算 |
由于汇率波动,即使付款金额分毫不差,这些值也可能与最初的不同。与店铺订单对账时使用 amountFiat——唯一保持不变的金额。
收款单生命周期中的通知
通知按项目配置。与收款单相关的有两种:
- 入账付款 (Incoming payment)。钱包上检测到任何入账交易时发送到邮箱和 Telegram,无论是否关联到了收款单。
- 收款单已支付 (Invoice paid)。收款单转为已支付的那一刻发送到邮箱、Telegram 和 Webhook URL——自动关联和手动关联都会发送。
由此得到一条简单的诊断规则:收到了入账付款通知,却没有随后的收款单已支付通知,说明付款因金额不一致而未关联,需要人工处理。
将买家带回店铺站点
在项目设置中可以设定两个地址,买家会从支付页面返回到那里:
- 成功跳转地址 (Successful URL)——收款单支付后自动跳转
- 失败跳转地址 (Unsuccessful URL)——打开已过期或已取消的收款单时自动跳转
两个地址分别启用。未设定时,买家停留在支付页面并看到收款单状态。
地址后会附加 uid 参数——面向买家的收款单标识:https://example.com/order/success?uid=AFhygKX21ecd。店铺靠它找到订单,并向买家展示自己的页面。