支付平台后台显示扣款成功,Magento 订单却一直是 Pending Payment。最危险的处理是直接把订单状态改成 Processing,因为这会让页面看起来正常,却可能没有 transaction、invoice,也没有完成后续库存和邮件动作。
按时间把四段日志拼起来
我会用 increment_id、支付平台 transaction ID 和 quote/order ID,把“创建支付请求、用户返回页、异步 webhook、Magento 状态更新”放在同一条时间线上。用户关闭返回页不应该影响异步回调,所以不要只查 success URL。
如果网关能看到 webhook 已发送,记录它的 HTTP 状态和响应体。404 是路由不对,401/403 多半是签名或 WAF,500 才进入 Magento 代码异常。返回 200 也不代表业务成功,有些插件捕获异常后仍然响应 200。
Webhook进来了,就查它为什么没认出这张订单
对照 merchant account、store scope、订单号字段、金额、币种和签名使用的原始 body。反向代理修改 body、读取流后没有重置、测试与正式密钥混用,都会导致验签失败。
再看 sales_payment_transaction 和 order payment additional information。支付成功事件如果没有保存外部 transaction ID,后续重复回调无法幂等判断,也无法正确 capture 或开票。
有些网关先发 authorized,再发 captured;两个事件可能乱序到达。处理 captured 时如果代码要求订单仍处于某个固定状态,早到或晚到的事件就会被丢弃。应该按外部交易的状态与唯一 ID 判断是否可以推进,而不是只依赖当前 Magento status 文本。
别把Pending Payment只当成status文本
检查订单内部 state/status、payment action 是 Authorize 还是 Authorize and Capture,以及插件成功分支实际调用了什么。Authorize 只授权时不一定立即生成发票;Capture 成功却仍 pending,才说明状态机或回调处理断了。
SELECT entity_id, increment_id, state, status, updated_at
FROM sales_order
WHERE increment_id = '000000123';
修复后重放同一个Webhook
第一次回放应把订单推进到正确状态并写入交易;第二次回放必须安全返回,不能重复开票、扣库存或发邮件。再测金额不一致、签名错误和回调延迟。旧订单的数据修复要根据支付平台真实交易逐单处理,不能批量把 Pending Payment 全改成 Processing。

