微信JSAPI支付 支付签名验证失败

无敌的宇宙
无敌的宇宙
擅长邻域:Java,HTML,JavaScript,MySQL,支付,退款,图片上传

分类: Java 微信小程序 专栏: 支付 标签: 微信内支付签名失败

2022-10-29 22:05:58 1098浏览

最近再接微信内支付,也就是微信JSAPI支付,总提示签名失败,各种检查参数检查大小写,统一下单搞成md5加密,前端的也是md5加密,已排除所有可能出错的情况,结果还是签名错误,原因是加密不一致,而不一致的原因是微信给的支付方法有问题,哈哈,想不到吧

代码:

image.png


调用签名方法确实是用了md5的加密,但是统一下单的wxpay.unifiedOrder接口里居然又一次调用签名方法,而是他用的一直都是HMACSHA256加密,这就导致支付时一直提示签名失败。

解决方法,我是参考别人的,直接贴出来吧

-----------------------------------------------------------------------------------------------------------------------------------

官方的SDK中WXPay类的构造函数定义是这样的:

public WXPay(final WXPayConfig config) throws Exception {
        this(config, null, true, false);  //useSandbox值为false,即默认为非沙箱环境
}
...//此处省略
public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox) throws Exception {
        this.config = config;
        this.notifyUrl = notifyUrl;
        this.autoReport = autoReport;
        this.useSandbox = useSandbox;
        if (useSandbox) {
            this.signType = SignType.MD5; // 沙箱环境
        }
        else {
            this.signType = SignType.HMACSHA256; //非沙箱环境signtype默认为HMACSHA256
        }
        this.wxPayRequest = new WXPayRequest(config);
}

所以在使用官方的示例时:

MyConfig config = new MyConfig();
WXPay wxpay = new WXPay(config);

默认signtype值为SignType.HMACSHA256而不是SignType.MD5。

        那么如果直接给定sign_type值为MD5是不是就可以了呢?通过研究后续代码发现:在WXPay.fillRequestData方法中压根儿就没有判断用户是否传入了默认的sign_type,所以给了默认值也没用。

public Map fillRequestData(Map reqData) throws Exception {
        reqData.put("appid", config.getAppID());
        reqData.put("mch_id", config.getMchID());
        reqData.put("nonce_str", WXPayUtil.generateNonceStr());
 
        if (SignType.MD5.equals(this.signType)) {
            reqData.put("sign_type", WXPayConstants.MD5);
        }
        else if (SignType.HMACSHA256.equals(this.signType)) {
            reqData.put("sign_type", WXPayConstants.HMACSHA256);
        }
        reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), this.signType));
        return reqData;
    }

这里可以将上面这个方法更改一下,判断一下初始给定的默认值就OK了。

(PS:也可以根据需求按照指定的构造方法初始化WXPay实例。)

public Map fillRequestData(Map reqData) throws Exception {
        reqData.put("appid", config.getAppID());
        reqData.put("mch_id", config.getMchID());
        reqData.put("nonce_str", WXPayUtil.generateNonceStr());
        String userSignType = ""+reqData.get("sign_type"); //如果定义了signtype,则使用定义的signtype
        if(userSignType.equals(WXPayConstants.MD5)){
        	this.signType = SignType.MD5;
        }else if(userSignType.equals(WXPayConstants.HMACSHA256)){
        	this.signType = SignType.HMACSHA256;
        }else{
        	if (SignType.MD5.equals(this.signType)) {
                reqData.put("sign_type", WXPayConstants.MD5);
            }
            else if (SignType.HMACSHA256.equals(this.signType)) {
                reqData.put("sign_type", WXPayConstants.HMACSHA256);
            }
        }
        reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), this.signType));
        return reqData;
    }

把这个fillrequestData方法替换一下,他下单的时候就是你需要的签名方式了,解决 

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695