微信公众号支付从开始到结束遇到的问题--------特别是前端调起支付时提示“支付签名验证失败”

时间:2024-05-22 13:10:30

1、公众号支付与其他类型的支付在调用统一下单接口时的区别是多个openid参数,而这个参数是需要通过授权后获得的(可以参考官方文档的授权功能)

2、有两个地方需要提前设置好

2.1、设置支付目录

在微信商户平台(pay.weixin.qq.com)设置您的JSAPI支付支付目录,设置路径:商户平台-->产品中心-->开发配置。JSAPI支付在请求支付的时候会校验请求来源是否有在商户平台做了配置,所以必须确保支付目录已经正确的被配置,否则将验证失败,请求支付不成功

一开始很迷茫支付目录如何设置,官方的设置界面如下:

微信公众号支付从开始到结束遇到的问题--------特别是前端调起支付时提示“支付签名验证失败”

此处我只设置了一个(可以设置多个),具体格式要求上面写的都很详细只要按照要求填写不会出现问题,容易出现问题的是这个支付授权目录设置到哪一级(这是我们项目中用到设置的:支付授权目录 http://域名/static/,因为我们项目中发起支付的页面是在项目中的static文件夹下,我这样设置后 在后续的支付过程没有提示关于支付授权目录设置不正确的类似信息);我所理解的支付授权目录 是具有发起支付功能的操作所在的位置,如果是页面中具有发起支付操作功能,此处的地址就应该写到页面所在的位置。

2.2、设置授权域名

官方原话:开发JSAPI支付时,在统一下单接口中要求必传用户openid,而获取openid则需要您在公众平台设置获取openid的域名,只有被设置过的域名才是一个有效的获取openid的域名,否则将获取失败。具体界面如图下图所示:

微信公众号支付从开始到结束遇到的问题--------特别是前端调起支付时提示“支付签名验证失败”

我在此处的配置是一个直接的域名,也就是公众号项目布署的域名(xxxx.com),不带www、http等;记得一定要把上图中提到的XXX.txt文件放到指定的位置,我就是在此处停了好久(各种试,我们布署的服务器是linux系统服务器,我一开始把文件放在root下(不行),又把它放在项目的static文件下也不行,最后又把文件放在了resources文件夹下,我们是Maven项目,也就是把它放在了和配置文件同级下),最后可以了,在后续的支付过程中也没有遇到关于授权域名不正确的问题。

2.3、最后还有一个地方要设置,就是设置IP白名单,要把布署的公众号的服务器地址放入白名单里,不然前端在作操作时会有此相关提示(这个一定不要忘记设置)。

3、以上准备工作都准备完成后就可以执行【统一下单接口】,这个接口的执行和其他类型(比如APP,扫码支付)的区别就是在执行之前,传入的参数一定要加上openid,不然就会有提示的哦!到此都是顺利进行的,就是在执行后要返参数给前端页面, 以供前端小伙伴【调起支付接口】,因为签名都是在后台执行的,后台在执行签名参数的时候一直遇到的提示“支付签名验证失败”(在此之前已经做过了App支付、扫码支付基本上都是顺利进行的),一定要重点阅读微信的文档(虽然写的不是特别好)

微信公众号支付从开始到结束遇到的问题--------特别是前端调起支付时提示“支付签名验证失败”

上图中圈出的部分就是我之前一直遇到的忽略的,参与签名参数是区分大小写的,公众号里变量名这一列里的变量名都是大写,在签名的时候一定要和文档里的名称一模一样(参与签名的参数),签名方式一定要与统一下单的签名类型一致。

// 此段是错误的写法,反正写的是啥样的都有,参数名都是小写的,而且里面也有不需要参与签名的参数之类的
responseMap.put("prepayid", prepayid);// 随机字符串
responseMap.put("noncestr", WXPayUtil.generateNonceStr());// 随机字符串
responseMap.put("appid", gzhconfig.getAppID());// 应用ID
responseMap.put("timestamp", GzhWxPayConfig.getTimeStamp());// 时间戳
responseMap.put("package", "prepay_id="+prepay_id);// 统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=***
responseMap.put("signtype", WXPayConstants.MD5);//签名类型,默认为MD5,支持HMAC-SHA256和MD5。注意此处需与统一下单的签名类型一致
System.out.println(responseMap);
sign = WXPayUtil.generateSignature(responseMap,gzhconfig.getKey(),SignType.MD5);//
System.out.println(sign);
responseMap.put("paySign", sign);//签名



// 以下是正确的写法
responseMap.put("nonceStr", WXPayUtil.generateNonceStr());// 随机字符串
responseMap.put("appId", gzhconfig.getAppID());// 应用ID
responseMap.put("timeStamp", GzhWxPayConfig.getTimeStamp());// 时间戳
responseMap.put("package", "prepay_id="+prepay_id);// 统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=***
responseMap.put("signType", WXPayConstants.MD5);//签名类型,默认为MD5,支持HMAC-SHA256和MD5。注意此处需与统一下单的签名类型一致
System.out.println(responseMap);
sign = WXPayUtil.generateSignature(responseMap,gzhconfig.getKey(),SignType.MD5);//
System.out.println(sign);
responseMap.put("paySign", sign);//签名

特别说明此处用到的jdk是

#Generated by Maven
#Thu Mar 16 14:16:28 CST 2017
version=0.0.3
groupId=com.github.wxpay
artifactId=wxpay-sdk

最新版的 java_sdk_v3.0.9,里面的某些写法可以不一样,比如默认的签名方式是HMAC-SHA256而不是MD5,我用的默认还是MD5,在解决此问题的时候我看到好多网友说,重置一下key或检查并让前后两个签名方式调成一致,同时用MD5或同时用HMAC-SHA256,不妨试试。