【已解决】.NET 微信支付API V3中JSAPI支付发起wx.chooseWXPay时,提示 支付验证签名失败
时间:2021-07-13
环境:.NET5 MVC
工具:Visual Studio 2019
状态:已解决,巨坑
问题描述:微信支付
对接,使用 JSAPI
发起支付 wx.chooseWXPay
的时候,总是提示 支付验证签名失败
解决日志
先在后台打印日志,签名字符串和签名结果
/// <summary> /// 计算JSSDK WXPay的签名,wx.chooseWXPay方法使用 /// </summary> /// <param name="APPID"></param> /// <param name="noncestr"></param> /// <param name="timestamp"></param> /// <param name="prepay_id"></param> /// <returns></returns> string GetJSSDKWXPaySignature(string APPID, string noncestr, long timestamp, string prepay_id) { string message = $"{APPID}\n{timestamp}\n{noncestr}\nprepay_id={prepay_id}\n"; string sign = GZ.OnlinePay.WXPay.HttpUtils.Sign(message, ConfigData.Intance.WXPaySetting.wx_private_key); Logs.Log.Info(message + "sign=" + sign); return sign; }
日志内容
【时间】:2021/7/13 13:11:26
【信息】:wxc55ee041e1ff840f
1626153086
0vhssrhbz45
prepay_id=wx131311267455271ab3f192295a5fd10000
sign=kW5pIOVl0sxnKRS5l2A19TuHnMij8E5PskpjKqCn6cHUeiRYPxl+u+dnE50NWsPdDCxRlxap+/KOL5dEGMKsyG1mYX08+qo6u6bEq2OUG3FseHAwjzJwgUyXRAAKBY11XJm/+6bqlG1hheK7Oy/T7CpVIFWh+7vmrs5UXvyLFWc+NiC7muFSiE7pWPcN3QXHyCnxMyyO0VDpjhi0t9Fs94bkeAZFRXbqO9pgMRZFc7NDoTIzZVItOFBAeUn8ollDXv9tvirx3zurq/p0IxLTSzMoHv6SuvY3PBS79CLAYQcw2FKP1hpVuYBMjCMC0bIxhkARJU1E0JcfQx65h2oLqw==
使用微信签名验证工具: 签名/验签/加密/解密工具
工具官方介绍地址: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay6_0.shtml
签名结果如下:
签名计算时一致的,所以问题不是出在签名计算的地方
但是实际情况是不管怎么测试,调用 wx.chooseWXPay
的时候,微信总是始终坚挺的给你返回 支付验证签名失败
证书 pem 文件 获取方式参考:
参考1:https://kf.qq.com/faq/161222NneAJf161222U7fARv.html
参考2:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter2_1.shtml#part-5
如果证书已经生成,并且向我这样存在了配置文件中,并且没有了原始文件,不必重新生成证书
参考 RSA PrivateKey私钥字符串转PEM格式证书:https://www.yesdotnet.com/archive/post/1626183289.html
经过痛苦折磨的排查,过程惨不忍睹
day1 无收获
day2 无收获
day3 无收获
day4 无收获
day5 无收获
发现原因
可能是全网唯一踩坑的,签名计算最后会得到 Base64 字符串,然后我这里 Base64 字符串从后台到前台,特殊符号 / 和 + 被转换了,换了,了
怎么发现的?
由于微信支付要发起,只能真机测试 ( 微信真操蛋 ),真机测试的话又不方便调试,
参考:https://www.yesdotnet.com/archive/post/1626169030.html 中 的方法,( 由于我手头上没有安卓手机,所以我用的是第三种方法 浏览器调试 )
然后在 JS 中把后台获取的值都打印出来
日志如下
经过分析 ( 实际是经过了漫长的苦恼和探索 ) 发现了 paySign 好像有异常,有一些 + 这种字符,而后台的日志记录中是这样的
【信息】:wxc55ee041e1ff840f
1626155118
34qv33nxi03
prepay_id=wx131345178422881ab3f192298a070b0000
sign=XYceloktlmQDV+KgCDHs4QQXnt+47Ob6oL/6FOs50S1JO8BeMPXB4UTJbEJwFlyoSAkl0IBhH2q+/SdoKWO/zCGcwlXFUVr9HU0Hwle6SohsuedrfGYlAKeiI3PSWZFOwUzpRsLxujbysvNjtSTtgwc6qu4l336znDIrxHahogqKL8sqhhJlFBt9azyTduG3vDS65LCVeUKc8vNi68kqAI6RCzC0ZW35dsREszs57MPM4Rzr7qKXgGE8GsvyyP7cs812EoVxNV4k22Tg9RDy4ZkRAGgdLFMer9tr8Yq14uEAFuORBIoyOPkDWiIbxn9WupujFpk9c4hEEoVThfzbFQ==
【阿西吧】 base64 字符串中是包含 /
和 +
这两个字符的,现在这两个字符前台取值的时候被转换了,这样转后的签名字符串肯定就不对咯,
安卓手机上的 Base64
总算是定位到问题了
既然是取值造成的,我们修改下代码,把 Base64 字符串取值的地方改为
@Html.Raw(***)
发布后,看到久违的支付界面了
至此问题解决,中午吃饭加 ??????
总结
查问题还是得一步一步排查,不能跳,我就是一直没有想到前端会出问题,排查问题不能想象着哪里有问题,哪里没问题,一定要一层一层的打印日志,跟踪排查,确保数据流都是正确的,如果我开始从给微信传值那里查起,就可能不会这么多天解决不了该问题,谨记! 谨记! 谨记!