前端提示“调用支付 JSAPI 缺少参数 total_fee”,不一定表示补上这个参数就能解决。2018 年两次排障连起来看,真正需要先处理的是统一下单失败:后端没有取得有效 prepay_id,却继续向前端提供了不完整的调起信息。

从前端提示追到后端响应

第一次记录出现“201 商户订单号重复”,手机上却只看到缺少 total_fee。后来另一篇记录补充了服务端日志,关键诊断信息如下:

return_code = SUCCESS
result_code = FAIL
err_code = INVALID_REQUEST
err_code_des = 包含“201 商户订单号重复”的描述
prepay_id = null

这是脱敏诊断摘要,不是可提交的协议报文。201 是当时日志中的提示,不能当成所有 V2 接口都使用的标准错误码;也不能凭此证明前端那条文字由哪个 SDK 分支生成。

成功至少要分三层

层次应检查什么
通信返回请求和响应是否按协议完成
统一下单业务结果result_code、错误码与必要预支付字段
最终付款支付通知、查询及服务端订单状态

V2 统一下单分别定义了 return_code 和 result_code;两者成功时才返回相应预支付信息。官方错误表还把 INVALID_REQUEST 与参数格式、订单重入参数一致性关联。统一下单返回与错误码

因此,不能只判断 return_code,然后无论业务结果如何都把字段发给前端。下单失败应返回业务可理解的失败状态,停止继续调起支付。

不通过删除本地订单修复重试

旧稿曾建议删掉数据库订单记录再跑,这个建议不应采用。本地记录删除不会消除支付侧已有交易,还可能破坏通知、对账和幂等关系。

先查询并核对原订单、首次请求和重试参数。已支付、未支付、已关闭等状态需要按对应协议分别处理;业务信息变化也不能随意复用同一交易关系。

怎样验证这条链已经理顺

在受控环境中,对同一业务请求保留脱敏关联标识,检查统一下单失败时前端不会继续收到可调起支付的伪成功结果。再覆盖取消后重试、重复点击和通知重入等情形。

这篇处理的是错误传播与订单关系;金额自身的精确转换见整数分与 BigDecimal。不要把相似的前端报错直接合并成一个根因。