微信支付后“返回页面”可能遇到两种相反现象:刷新导致再次调起支付,不刷新又显示旧购买状态。解决办法要围绕支付入口和状态读取,而不能简单规定全部刷新或全部不刷新。
支付完成后反复弹错:先查入口重入
2018 年的一个项目中,iPhone 已经扣款成功,页面却反复弹错误,Android 当时没有同样表现。我逐步排除,最后移除了支付回调里的 window.location.reload,现象随之消失。
旧代码在 WeixinJSBridge.invoke 的结果分支中同时使用 history.back 和 reload。下面只展示其中与问题有关的部分,不包含真实支付参数:
function handlePayResult(result) {
if (result.err_msg === "get_brand_wcpay_request:ok") {
history.back();
} else if (result.err_msg === "get_brand_wcpay_request:cancel") {
history.back();
} else {
window.alert("支付操作未完成,请查看订单状态");
}
}
这只是旧 JSAPI 回调的页面处理形状,不是完整支付接入模板。旧结果支持“刷新使支付入口再次执行”的方向,但没有保存完整初始化代码,不能将它泛化为 iOS 通用缺陷。
商品页不刷新:实际需要更新的是购买状态
同年另一次,商品视频需要购买后观看。支付完成通过 history.back 返回时,页面仍显示未购买;退出后再进才更新。
当时尝试 pageshow 的 event.persisted,测试中一直为 false;后来结合旧 performance.navigation.type 判断并强刷,得到了预期展示。这属于当年的处理,不适合作为今天统一的后退识别方案。
pageshow 可发生于初次加载、前进后退和缓存恢复等情形;persisted 表示是否来自页面缓存,并不是所有“按了后退”的同义词。pageshow 事件说明
把支付动作与状态查询分开
更清晰的页面结构是:用户明确点击支付才发起支付;商品页初次展示或恢复时,重新读取服务端订单和内容权限。刷新页面不应无条件再次调用支付接口。
重新查询可以重复,更新权限必须按服务端确认结果处理。客户端显示成功、取消或网络错误,都不能单独决定是否已付款;统一下单成功也仅是取得预支付会话的前提。微信支付 V2 统一下单
验证时分别检查首次进入、支付成功返回、取消、网络中断和快速重复点击,记录支付调起次数与状态查询次数。把两类请求分开后,就不会再用“刷新越多越可靠”来解决状态问题。