当前后台的“关闭订单”只会把目标订单本身设为 expired,不会处理该父订单下仍然处于待支付状态的子订单。
相关代码:
src/controller/admin/order_controller.go:100-131
src/model/data/order_admin_data.go:108-115
src/model/service/order_service.go:167-239
当前行为:
- 后台关闭订单时,只调用
CloseOrderManually(tradeID),把这一条订单设为 StatusExpired
- 父订单下已有的子订单不会一起关闭
- 如果之后用户实际支付到了某个子订单地址,
OrderProcessing 会先把子订单写成支付成功
- 接着它会尝试把父订单也结算成功,但这一步要求父订单仍然是
StatusWaitPay
- 由于父订单已经被后台手动关闭,这一步会失败,最后形成“子单已支付、父单已过期”的不一致状态
影响:
- 会出现孤儿支付:链上钱到了,但父订单无法正常完成。
- 商户侧可能拿不到预期回调。
- 后台排查时会看到一组父子订单状态互相打架,处理起来很麻烦。
建议:
- 如果关闭的是父订单,应同步关闭并释放所有仍在
WaitPay 的子订单。
- 或者后台直接禁止关闭仍然存在活动子订单的父订单。
- 更稳妥的做法是,在子订单到账的结算路径里,也要在第一笔事务提交前确认父订单仍处于可结算状态,避免先把子订单写成成功再失败返回。
复现路径很简单:
- 创建父订单
- 在支付页切网,生成子订单
- 后台手动关闭父订单
- 再向子订单地址付款
- 可以看到子单、父单状态无法正常收口
当前后台的“关闭订单”只会把目标订单本身设为
expired,不会处理该父订单下仍然处于待支付状态的子订单。相关代码:
src/controller/admin/order_controller.go:100-131src/model/data/order_admin_data.go:108-115src/model/service/order_service.go:167-239当前行为:
CloseOrderManually(tradeID),把这一条订单设为StatusExpiredOrderProcessing会先把子订单写成支付成功StatusWaitPay影响:
建议:
WaitPay的子订单。复现路径很简单: