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

        最近研究微信支付,尝试用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: 微信JSAPI支付是一种使用微信内置浏览器或微信客户端内的网页进行支付的方式。流程如下: 1. 用户在商户的网站或应用内点击支付按钮,触发支付请求。 2. 商户服务器收到支付请求后,向微信支付服务器发起下单请求,并将支付信息传递给微信支付服务器。 3. 微信支付服务器收到下单请求后,会根据商户提交的信息生成支付二维码或支付链接。 4. 商户服务器收到微信支付服务器的响应后,将支付二维码或支付链接发送给用户浏览器。 5. 用户浏览器打开支付二维码或支付链接,跳转到微信内置浏览器或微信客户端进行支付。 6. 用户在微信内置浏览器或微信客户端内输入支付密码或通过其他认证方式进行支付。 7. 微信支付服务器收到用户的支付信息后,会向商户服务器发送支付通知。 8. 商户服务器收到支付通知后,会对订单进行处理,并向用户 ### 回答2: 微信JSAPI支付是一种在微信公众号内进行支付的流程。具体流程如下: 1. 用户在微信公众号内选择商品并点击支付按钮。 2. 公众号服务器向微信服务器发送统一下单接口的请求,包含商品信息、支付金额等。 3. 微信服务器返回预支付交易会话标识prepay_id给公众号服务器。 4. 公众号服务器将prepay_id和其他必要参数进行签名,生成支付配置。 5. 公众号将签名后的支付配置返回给前端页面。 6. 前端使用微信JS-SDK调起支付窗口,调用微信支付接口,并传入签名后的支付配置。 7. 微信客户端收到支付请求后,弹出支付窗口,展示商品信息和支付金额。 8. 用户确认支付金额,并输入支付密码进行支付。 9. 微信客户端支付成功后,会返回支付结果给公众号服务器。 10. 公众号服务器接收到支付结果后进行校验,若校验通过,表示支付成功。 11. 公众号服务器更新订单状态,并向用户展示支付成功页面。 以上就是微信JSAPI支付的整个流程。通过将用户在微信公众号内的支付请求发送给微信服务器,再由微信客户端完成支付,最后由公众号服务器校验支付结果,实现了在微信公众号内进行支付的功能。 ### 回答3: 微信JSAPI支付流程是指用户在微信公众号内进行支付的一种支付方式。其流程如下: 1. 用户在微信公众号内选择商品或服务,并点击支付按钮。 2. 公众号向微信后台发起支付请求,并返回一个预支付交易会话标识(prepay_id)。 3. 公众号将prepay_id传递给前端页面,前端页面使用prepay_id生成签名,例如通过微信的SDK引入的js文件。 4. 前端页面将生成的签名和其他必要的支付参数传递给微信支付接口,发起支付请求。 5. 微信支付接口验证签名和参数合法性后,返回支付结果给前端页面。 6. 前端页面接收到支付结果后,可以根据结果进行相应的处理,例如弹出支付成功提示或跳转到支付成功页面。 7. 微信支付接口向商户服务器发送支付通知。 8. 商户服务器收到支付通知后,校验通知的合法性,并进行相应的处理,例如更新订单状态或给用户发放购买的商品或服务。 9. 商户服务器向微信支付接口返回处理结果,以确认已经接收到支付通知。 10. 微信支付接口收到商户服务器的确认后,停止向商户服务器发送支付通知。 总结起来,微信JSAPI支付流程主要包括用户在公众号内选择支付、公众号发起支付请求、前端页面生成签名并发起支付请求、微信支付接口返回支付结果、商户服务器处理支付通知等环节。通过这个流程,用户可以方便地在微信公众号内进行支付
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

nwsxdxqs

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

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

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

打赏作者

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

抵扣说明:

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

余额充值