支付成功回调后如何确保订单状态可靠更新?
我在做微信支付集成时遇到个问题:用户支付成功后,前端通过回调函数调用后端接口更新订单状态,但偶尔遇到网络波动导致订单状态没更新,或者重复触发请求导致订单被标记两次。我试过在支付回调里这样写:
wx.requestPayment({
...payParams,
success: (res) => {
// 这里直接发请求更新订单状态
fetch('/update-order', { method: 'POST', body: { orderId } })
}
})
但测试时发现,当支付成功弹窗出现到真正扣款完成之间有短暂延迟,用户可能重复点击导致重复请求。有没有更稳妥的前后端配合方案?
正确做法是:前端不要直接负责更新订单状态,支付成功后只跳转页面或者展示结果,真正更新订单得靠微信的服务器异步通知。
具体流程是这样:你调用微信统一下单接口的时候,会传一个 notify_url,微信那边支付成功后会主动往这个地址发一次甚至多次 POST 请求,告诉你支付结果。你的后端收到这个通知后,校验签名,确认是真的微信发来的,然后再去改订单状态。这个叫「服务端回调」,比前端可靠一万倍。
至于重复请求的问题,可以在数据库订单表加个状态字段,比如 status = paid 的时候就不再处理。再配合唯一索引防重复,比如用 out_trade_no 做唯一键,避免插入重复记录。
还有个小技巧,前端那个 success 回调里别急着发请求,可以加个本地锁,比如 loading = true,防止用户连点。但记住这只是体验优化,不能依赖它来保证数据一致。
总之核心就是一句话:订单状态以微信服务端回调为准,前端只是展示层,别让它承担关键逻辑。