实务专题 · 网站交接

支付回调交接:重启后还能防止重复处理吗

这是给网站交付需求使用的合成教学例,不是客户成果、真实账号测试或认证。

回调返回成功,不等于订单处理已经完成

采购支付集成时,请供应商演示“事件已经接收,但后续处理失败”的情况。仅存在内存中的事件编号,服务重启就可能消失;如果先标记已处理,再执行一个失败的操作,任务可能丢失。只按事件编号去重,也无法处理两个不同事件对应同一项履约的情况。

已填写的失败与恢复过程

步骤输入应看到的证据
1evt-A → fulfil-order-DEMO-1事件接收记录写入磁盘
2在本地处理事务中模拟失败业务操作与完成标记一起回滚
3关闭并重新打开SQLiteevt-A仍待处理
4处理evt-A,再重放同一事件本地业务操作只有一笔
5evt-B指向同一业务操作两条接收记录,业务操作仍只有一笔

示例分别为传输编号与业务操作建立唯一约束。同一个事件编号如果换了业务操作,会保留冲突并报错,不会悄悄忽略。下载独立运行的示例,用Node 24+执行node durable-inbox.mjs。所测Node版本的SQLite仍标为实验功能;程序只创建并清理自己的临时目录。

预期输出为inboxRows 2、completedRows 2、localOperations 1,以及rollbackAndReopenVerified true。交接时同时保存结果与业务操作编号规则。不能让不同订单或订阅续期错误共用一个履约编号。

不要把本地演示当成生产保证

这里的“业务操作”只是同一个SQLite事务内的一行记录,不是调用仓库、邮件服务或支付接口。外部副作用还需要独立的幂等、发件箱与恢复设计。本工具不是“恰好一次”保证,不是生产消息队列,也不验签、不接收Stripe回调。正式验收仍需验证持久接收后再应答、并发、重试、失败队列与对账。

官方依据与边界

Stripe回调指南:说明重复投递以及同一对象可能对应不同事件;事件编号不等于所有业务的唯一键。

来源于2026年10月15日核验。输入与验收规则为原创教学设计;正式实施前还要核对当前平台版本及实际交付合同。

处理事件前,先认证原始字节