管理员在线Capture时页面报错,支付平台后台却显示成功,订单里发票仍是Pending。此时最危险的操作是再点一次Capture。先用交易号确认钱的状态,再修复Magento本地状态。
现象
我保留了一个失败样本,并用同样输入在无缓存或单节点条件下再跑一遍。这样可以把前端假象、缓存和真正的数据问题分开。
排除法
- 在支付平台查gateway transaction id,不要只看increment_id。
- 核对sales_payment_transaction是否已有capture记录,invoice的transaction_id是否为空。
mysql -e "SELECT transaction_id,txn_id,txn_type,is_closed,parent_id FROM sales_payment_transaction WHERE order_id=(SELECT entity_id FROM sales_order WHERE increment_id='000000123');" mysql -e "SELECT entity_id,increment_id,state,grand_total,transaction_id FROM sales_invoice WHERE order_id=(SELECT entity_id FROM sales_order WHERE increment_id='000000123');" grep -R "000000123" var/log var/report
这里的重点不是把报错暂时消掉,而是让同一操作再执行一次仍保持幂等;因此修复后一定要做第二次重复执行测试。
最终处理
先关闭该订单的人工再次扣款入口。若网关webhook可安全重放,优先按原event id重放,让模块幂等补齐invoice与transaction。不能重放时写一次性修复脚本:在事务内加载订单和发票,核对金额后设置transaction id、pay并保存,同时记录订单history。脚本先在副本演练。
修改范围
- 先在单个SKU、单个订单或单个Store验证。
- 保留可回退的旧配置,不覆盖原始证据。
- 需要批量处理时分批提交并输出成功/失败清单。
检查收尾
- 网关只有一次capture
- Magento只有一张对应金额发票
- payment total_paid与order total_paid一致
- 退款入口引用正确的capture transaction
验收不只看后台提示“成功”。我还会从前台/API再走一次真实链路,并在下一轮cron、索引或缓存命中后重复检查,确认不是短暂正常。
经验
禁止用SQL直接把state改成paid;这会跳过库存、总额和事件逻辑。
如果线上数据已经不一致,先停掉会继续扩大差异的入口,再修历史数据;否则一边补一边写,最后很难判断哪些记录已经处理。

