评论

JSAPI支付踩坑“支付验证签名失败”

微信网页开发js-sdk调用JSAPI支付“支付验证签名失败”

大佬请绕道!

最开始图方便,使用了PHP的http_build_query来将数组转为字符串,此处会将prepay_id=123456789的等号进行转换成%3D导致签名验证失败。

此处建议使用官方的例子,使用字符串将参数拼接,避免出错。

特别注意timestamps后端在签名的时候是大写S,而微信的js-sdk里面wx.chooseWXPay接口调用时是小写。

微信js-sdk文档里面还有一个坑。

wx.chooseWXPay({
  timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
  nonceStr: '', // 支付签名随机串,不长于 32 位
  package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
  signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
  paySign: '', // 支付签名
  success: function (res) {
    // 支付成功后的回调函数
  }
});


调用这个接口居然没有用appId这个参数,不管你怎么调,最后都报支付验证签名失败。

最终在微信支付官方的文档里面看到调用接口有appId,果断加上试了一下。成功了。

最后一次编辑于  2020-02-12  
点赞 7
收藏
评论

11 个评论

  • 小马
    小马
    2022-05-13

    你们这都不算什么,你们知道我被什么卡住了两天吗?

    我之前对结果native支付,好像没有这么多事,挺顺利的,结果jsapi 卡住了,我是V2版的

    //JS端
    alert("payparams:" + JSON.stringify(payparams));
    		WeixinJSBridge.invoke("getBrandWCPayRequest", {
    				"appId": payparams.appId,
    				"nonceStr": payparams.nonceStr,
    				"package": payparams.package,
    				"paySign": payparams.paySign,
    				"signType": payparams.signType,
    				"timeStamp": payparams.timeStamp
    			},
    			function(res) {
    				if (res.err_msg == "get_brand_wcpay_request:ok") {
    					alert("微信支付成功");
    				} else if (res.err_msg == 'get_brand_wcpay_request:cancel') {
    					alert('用户取消支付');
    				} else {
    					alert('支付失败');
    				}
    
    			}
    
    //java 端
    /**
     * 统一下单 jsapi 方式
     * @param orderId  自身订单号
     * @param amount  金额:分
     * @param description  描述
     * @return
     */
    public ResponseMessage unifiedOrderByJsapi(String orderId,int amount,String description,String openid){
        try{
            Map<String,String> requestData = new HashMap<>();
            //商品描述
            requestData.put("body",description);
            requestData.put("openid",openid);
            requestData.put("appid",config.getAppID());
            requestData.put("mch_id",config.getMchID());
            requestData.put("nonce_str",WXPayUtil.generateNonceStr());
            requestData.put("out_trade_no",orderId);
            requestData.put("total_fee",String.valueOf(amount));
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = requestAttributes.getRequest();
            String ip = StringUtil.getIp(request);
            requestData.put("spbill_create_ip",ip);
            requestData.put("notify_url",notify_url);
            requestData.put("trade_type","JSAPI");
            requestData.put("sign_type", WXPayConstants.MD5);
            String oneSing = WXPayUtil.generateSignature(requestData,config.getKey(),WXPayConstants.SignType.MD5);
            requestData.put("sign", oneSing);
            Map<String,String> responseData = wxPay.unifiedOrder(requestData);
            if(responseData == null){
                return ResponseMessage.error("调用jsapi统一下单失败");
            }
            log.info("调用jsapi统一下单结果:return_code:"+responseData.get("return_code"));
            log.info("return_msg:"+responseData.get("return_msg"));
            log.info("result_code:"+responseData.get("result_code"));
            log.info("err_code:"+responseData.get("err_code"));
            log.info("err_code_des:"+responseData.get("err_code_des"));
            if(!"SUCCESS".equals(responseData.get("return_code"))){
                return ResponseMessage.error(responseData.get("return_msg"));
            }else if(!"SUCCESS".equals(responseData.get("result_code"))) {
                return ResponseMessage.error("请求支付失败:" + responseData.get("err_code") + "-" + responseData.get("err_code_des"));
            }else{
                String prepayId = responseData.get("prepay_id");
                Map<String,String> payMap = new HashMap<String, String>();
                payMap.put("appId",config.getAppID());
                payMap.put("timeStamp", System.currentTimeMillis()/1000 + "");
                payMap.put("nonceStr",WXPayUtil.generateNonceStr());
                payMap.put("signType", WXPayConstants.MD5);
                payMap.put("package","prepay_id="+prepayId);
                String paySign = WXPayUtil.generateSignature(payMap,config.getKey(),WXPayConstants.SignType.MD5);
                payMap.put("paySign",paySign);
                return ResponseMessage.success(payMap);
            }
        }catch(Exception e){
            return ResponseMessage.error("调用微信支付统一下单异常");
        }
    }
    
    
    

    参数什么的都没问题,包括签名我也用工具校验过了,最后实在想不明白,我就把签名方式从HMAC-SHA256 改为MD5(包括统一下单的也改了),他竟然成功了

    我啥都不想说了(文档里说的清清楚楚,两种都支持)

    2022-05-13
    赞同 1
    回复
  • 枫叶
    枫叶
    2020-05-22

    微信这个jsapi就是个垃圾,,调了几天了,还是签名错误

    2020-05-22
    赞同 1
    回复 4
    • Yan tao
      Yan tao
      2020-09-13
      遇到类似问题,求解决方案
      2020-09-13
      回复
    • 孤木๛
      孤木๛
      2020-12-15
      请问解决了吗,同问题,求解
      2020-12-15
      回复
    • Mr.H
      Mr.H
      2022-09-30
      一样没解决,都特么两年过去了,垃圾垃圾文档,要不是用微信的人多,吗的我才不接。现在给人做程序我都首推支付宝。
      2022-09-30
      回复
    • m
      m
      2024-05-24
      我使用v3版本也是提示签名错误,好恶心
      2024-05-24
      回复
  • W
    W
    2020-02-29

    我按照你说的加了后不行啊


    2020-02-29
    赞同 1
    回复 3
    • App小程序软件开发
      App小程序软件开发
      2020-02-29
      检查参数少了没有,前端js-sdk接口要加appId这个参数,注意大小写,后端加密是用的大写
      2020-02-29
      回复
    • W
      W
      2020-02-29回复App小程序软件开发
      正常啊。查了半天资料,还是提示支付验证签名失败
      2020-02-29
      回复
    • W
      W
      2020-02-29回复App小程序软件开发
      莫名其妙能用了。。。我TM
      2020-02-29
      回复
  • peng鹏
    peng鹏
    01-25

    前端timestamp,s一定要小写,文档里面的示例是大写,调了一晚上,感谢题主,微信的文档搞死人

    01-25
    赞同
    回复
  • ☆鼠♥
    ☆鼠♥
    2024-07-23

    遇到同样的问题,有两种可能,一种就是参数大小写的问题,另一种就是版本问题

    2024-07-23
    赞同
    回复
  • Bill Hsieh
    Bill Hsieh
    2024-03-08
    遇到了同样的问题,解决过程是 前后端1个1个对比统一参数。小程序后端的加密字段和App的不一致特别注意这几个 appid和appId的区别
                payMap.put("appId",);
                payMap.put("timeStamp",);    
                payMap.put("nonceStr",);
                payMap.put("signType",);
                payMap.put("package","prepay_id="+prepayId);
    


    2024-03-08
    赞同
    回复
  • A习水豆腐皮火锅
    A习水豆腐皮火锅
    发表于移动端
    2023-08-05
    ..
    2023-08-05
    赞同
    回复
  • 稀饭
    稀饭
    2023-03-28

    牛啊牛啊,狗样的大小写

    2023-03-28
    赞同
    回复
  • 张伟
    张伟
    2022-03-09

    就是大小写s问题卡了一天

    2022-03-09
    赞同
    回复
  • 夜辰
    夜辰
    2021-03-25

    统一下单完成后,需要返回给前端的参数中的签名paySign ,一定要再次生成!!!!

    网页端接口请求参数列表参数需要重新进行签名计算,参与签名的参数为:appId、timeStamp、nonceStr、package、signType,参数区分大小写。)

    详情参考手册

    https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6


    2021-03-25
    赞同
    回复

正在加载...

登录 后发表内容