官方解决方案:
可参考以下指引:
https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay7_1.shtml#part-2
当使用V3接口报签名类错误,还有在对返回的信息做验签,如:回调通知验签,验签失败的错误,都可以使用验签工具验签,本文主要介绍如何正确使用签名工具,以及签名工具能排查出的几种原因。
工具下载、使用:
1.首先先下载官方提供的验签工具:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml#part-1
2.下载解压后打开文件夹,里面有我们的验签工具、错误码对照表和使用说明书,TenpayCertUtil.exe就是验签工具了,双击打开
3.工具界面:
一共三个部分:
1、选择文件:
校验自己请求接口生成的签名,使用在商户平台下载的商户证书文件,建议使用其中具体的商户私钥文件,apiclient_key.pem文件(这个是默认的文件名,如果有下载后自己改过,就按自己改的选,只要是正确的商户私钥文件就行),因为使用这个文件,既可以用工具验签自己的签名,又可以用工具直接生成签名值。商户证书获取:https://kf.qq.com/faq/161222NneAJf161222U7fARv.html
校验接口应答的签名值,如:回调通知的验签,就要使用平台证书验签,所以要先获取平台证书:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay5_1.shtml
2、明文:
这里要填放的是生成签名或验签时构造的签名串/验签串,注意不是已经生成好的签名值
签名串:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml#part-1
验签串:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml#part-2
3、签名
这里要填放的就是要校验的签名值,如果是要直接对签名串进行签名,而不是要校验签名,可以不填写此处,然后点击下方的签名按钮,工具会将生成的签名值显示在此处,可以用工具生成的签名值和自己代码中生成的签名值进行对比,看是否一致。
验签排查思路:
了解了验签工具要填写的三个部分后,就可以开始验签了,下面我会举例几种工具可以排查出来的情况,或配合工具可以排查出来的情况,为了不泄露信息,我会用官网示例这样的中文代替实际数值
先放三个正确验签的明文示例,点击验签,后面的示例图主要放的是对自己生成的签名值校验的示例图:
此处注意应答签名的验签使用的是平台证书验签,而不是使用商户证书,所以第一步选择的文件要选择平台证书文件
平台证书的获取:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay5_1.shtml
情景一:如果按正确验签示例填写的方式:验签不通过,说明这个签名值与这个签名串是不匹配的,建议按文章开头提供的官方解决方案检查下,也可以尝试下面情景二、三的明文方式,看看是否碰巧:验签通过
情景二:
如上方式填写明文:验签通过,说明程序中,在构造签名串时,最后一行没有加上换行
情景三:
如上方式填写明文:验签通过,说明程序中,在构造签名串时,将换行符 \n 作为字符串"\n"去构造签名串/验签串的,而不是作为转义字符 \n 去构造签名串/验签串的
情景四:如果按正确验签示例填写的方式:验签通过,就需要更加仔细的检查下自己的代码:
1.可能使用错了一个商户私钥/平台证书
这个不是指代码里用的和工具用的不是同一个,而是指比如本来要使用A商户的商户私钥/平台证书,但实际使用的是B商户的
2.可能代码中实际编码存在问题
将所有中文部分换成英文,如果这时请求通过,说明是编码问题
3.可能签名串中的参数,和实际请求的参数不一致,不能增加或缺少参数,参数大小写要与文档一致(可通过打印签名原串进行排查)
如请求头中的时间戳、随机字符串和签名串的不一致,具体请参考文章开头提供的官方解决方案
4.可能签名串/验签串、签名值在数值传递过程中,发生了改变
在代码实际填写签名值时,可能在各种方法传递中去除了'=',或将一些符号做了其他转换,如'+'被替换成' '(空格),然后被添加到请求头,或用来应答验签,所以工具通过,代码报错。'+'替换成' '在网络上有相应的解决方案,可自行查找下。
注:如果不确定签名值是否在传值过程中被处理修改,可以在工具中不填写签名值,点击签名按钮,将生成好的签名值直接放进请求头,时间戳、随机字符串也是,都写成固定值,如果通过请求,则说明在之前传值过程中,数据有被修改,须仔细排查
情景五:如果是下单成功,调起支付时报错,按正确验签示例填写的方式:验签通过,则需要前后端同学一起配合检查
1.传给前端接收到的调起时所用的数据,是否和后端生成的签名值所使用的签名串中数据一致
例如:时间戳、随机字符串等,可以由前端打印出调起支付时实际使用数据,组成签名串,进行验签,看看验签是否通过,如果后端验签通过,而前端使用调起支付的数据做签名串验签不通过,则说明前端调起使用的数据与后端生成签名值使用的数据不一致
2.前端调起支付时填写的参数是否有一一对应
例如:timeStamp的值错填了随机字符串,nonceStr的值错填了时间戳
3.前端调起支付时填写的参数名、参数值是否正确,要注意参数名的大小写,参数值一定要正确填写
例如:signType的值为'RSA',不要错填'RAS',package的值不要忘记加上'prepay_id='
4.调起支付时生成签名使用的商户私钥和下单时生成签名使用的不是同一个商户私钥
这个可以用下单时的签名串、签名值和这个调起支付签名使用的私钥文件验签一下,如果通过则说明下单和调起的签名用的是同一个私钥文件,没有使用错误,如果不通过,说明调起支付时使用的商户私钥是错误的,需要检查
情景六:校验应答签名时,校验总是报错,比如回调通知验签,建议检查下应答报文主体中,各个参数的顺序,一定要原样按照通知的顺序去构造验签串
如微信通知的是{C,B,A},就要按{C,B,A}原样填写,注意不要在转JSON格式时,或其他传值过程中进行排序,变成了{A,B,C},这样构造的验签串是肯定验签不通过的
明文中{C,B,A}要写成一行的形式,不要按JSON去换行写成:
正确示例:
以上是我个人总结的一些V3校验签名工具的使用,和排除查思路,如果有需要补充或修改的地方,欢迎留言反馈
另补充下:判断商户私钥、商户号、商户证书序列号是否匹配,可以用官方提供的postman脚本去校验下的,如果postman脚本也是报签名错误,说明这三个是不匹配的,要检查,还有就是官方的postman脚本是V3的签名规则来的,V3的签名规则和V2的签名规则是不一样的
postman脚本:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml#part-1
{{item.user_info.nickname ? item.user_info.nickname : item.user_name}}
作者 管理员 企业
{{itemf.name}}
{{itemc.user_info.nickname}}
{{itemc.user_name}}
回复 {{itemc.comment_user_info.nickname}}
{{itemf.name}}