关于微信jsapi 支付签名验证失败

本文探讨了微信支付中签名验证失败的问题,原因在于统一下单签名方式与前端签名不一致。作者揭示了如何在官方SDK中正确设置签名类型,并提供了修改`fillRequestData`方法的建议,以确保签名一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        最近研究微信支付,尝试用jsapi前端发起支付时,弹出“支付签名验证失败”,多方查找后发现是由于统一下单时的加密方式与前端再次签名时的签名方式不同导致。

官方的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<String, String> fillRequestData(Map<String, String> 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<String, String> fillRequestData(Map<String, String> 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;
    }

另外,还需注意官方文档中的描述:参数区分大小写以及签名方式与统一下单时的签名类型一致!

开发云 - 一站式云服务平台

更多优惠,尽在--开发云 - 一站式云服务平台

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nwsxdxqs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值