加密货币结账会发出哪些事件?

InfraIO Pay 每次状态转换都会触发一个 webhook。这个状态机被有意设计得很简洁,因此你可以将履约逻辑精确绑定到某一个事件,忽略其余事件。

  • payment.pending,买家已广播交易;确认数仍在累积。
  • payment.confirmed,交易已达到该网络的确认阈值。
  • payment.settled,资金已归集到你的结算钱包。在此履约。
  • session.expired,结账窗口未付款即关闭。永远不会计费。

应该在哪个事件上履约?

payment.settled 上履约。处于 pending 状态的交易仍可能确认失败,且确认阈值因网络而异,因此将更早的状态当作最终结果,就会有对一笔永远不会到账的支付发货的风险。结算(settlement)才是这笔资金不可逆地归你所有的那一刻。

如果你需要向买家展示进度,可以在 UI 中显示 pending 和 confirmed 状态,但要将不可逆的操作(发货、授予访问权限、铸造)始终绑定到 settled。

如何验证 webhook 是真实的?

每个 webhook 都使用你的端点密钥签名。对原始请求体重新计算 HMAC,并以恒定时间(constant-time)与签名头进行比较;任何不匹配的请求都应拒绝。如果你刚接触 HMAC,MDN 的 SubtleCrypto.sign 参考文档是很好的入门材料,Stripe 的 webhook 最佳实践指南则很好地覆盖了运维层面。

先验证,再解析或处理。未签名或签名错误的请求绝不应到达你的业务逻辑层。

如何让投递可以安全地重试?

Webhook 采用至少一次(at-least-once)投递,因此在一次网络抖动之后,同一个事件可能不止一次到达。每个事件都带有一个 idempotency key;记录你已处理过的 key,对重复事件不做任何操作(no-op)。快速响应 2xx,并将耗时的工作异步处理,以避免发送方超时并进行不必要的重试。InfraIO 保留一份投递日志,支持一键 replay,供你需要主动重新处理时使用。