描述:
需求是根据订单来源切换商家收银
1、微信支付,公众号方式正常拉起支付,小程序正常拉起支付
2、在支付了几次后,小程序拉起支付后提示,支付验证签名失败
3、服务端返回数据
[<xml><return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<result_code><![CDATA[SUCCESS]]></result_code>
<mch_id><![CDATA[脱敏了]]></mch_id>
<appid><![CDATA[脱敏了]]></appid>
<nonce_str><![CDATA[npLzixF4HKdniIHT]]></nonce_str>
<sign><![CDATA[38A4DE6015B221789544195E3C0CC04E]]></sign>
<prepay_id><![CDATA[wx06165802093038697ae0f38a7f3a120001]]></prepay_id>
<trade_type><![CDATA[JSAPI]]></trade_type>
</xml>]
4、前端拉起支付关键参数
timeStamp: obj.timeStamp,
nonceStr: obj.nonceStr,
package: obj.packageMp,
signType: obj.signType,
paySign: obj.paySign
5、小程序支付是正常使用的,只是切换新的商户收款的时候就出现这 "支付验证签名失败" 类提示。使用其他商户收银的时候,小程序支付又是正常的。
三个问题求解答
请问这类问题是哪里出现了错误呢?
如果是前端拉起支付的参数问题,那为什么同样的代码下,切换其他商户收银就可以?
如果是签名问题,那为什么服务端拉起微信下单后能正常返回SUCCESS,以及prepay_id等参数呢?

如果能获取prepayid说明下单时使用的密钥是正确的,调起报签名错误可以从以下方向排查:
1、调起时的参数签名(非下单返回sign 调起需要重新计算sign的)是否是正确对应的密钥计算的,而不是切换前的商户秘钥
2、检查后端计算拼接的调起参数和调起时传给前端的参数是否一致
V2 接口下单成功,调起支付出现签名错误是因为你计算签名参数与调起支付参数不一致导致的
V2接口版本
总结一下:
v2的小程序支付流程
1、服务端调用微信的下单接口/pay/unifiedorder
2、根据/pay/unifiedorder返回的信息进行处理得到,timeStamp,nonceStr,packageMp,signType,paySign。这五个参数
3、传给前端进行调用requestPayment()拉起支付
而本次问题出现在第一步。
调用/pay/unifiedorder下单接口时的appId。和第二步加密签名时的appId不一致导致的。
已解决。
备注:
在查问题的时,有些说前端需要传appId,但实际上小程序环境下不需要传,前端重点只要关注timeStamp,nonceStr,packageMp,signType,paySign这五个参数即可。后端则关注参数的正确性