收藏
回答

调用wx.config 报 Unable to verify signature

wechatH5Pay(transactionId, totalPrice, ip, openid) {
    var self = this;
    let data;
    var url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    var appid = settings.appid;//应用微信中的id
    var mch_id = settings.mch_id;//商户号
    var notify_url = 'http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php';//回调通知地址
    var out_trade_no = transactionId;//订单号
    var total_fee = totalPrice * 100;//商品价格
    var attach = 'Butchart布查德';
    var body = "花束产品"; //客户端商品描述
    var nonce_str = self.randomWord(false, 32);//随机32位之内字符串
    var formData = "<xml>";
    formData += "<appid>" + appid + "</appid>"; //appid
    formData += "<attach>" + attach + "</attach>"; //附加数据
    formData += "<body>" + body + "</body>"; //商品或支付单简要描述
    formData += "<mch_id>" + mch_id + "</mch_id>"; //商户号
    formData += "<nonce_str>" + nonce_str + "</nonce_str>"; //随机字符串,不长于32位
    formData += "<notify_url>" + notify_url + "</notify_url>"; //支付成功后微信服务器通过POST请求通知这个地址
    formData += "<openid>" + openid + "</openid>"; //openid
    formData += "<out_trade_no>" + out_trade_no + "</out_trade_no>"; //订单号
    formData += "<spbill_create_ip>" + ip + "</spbill_create_ip>"; //服务端ip
    formData += "<total_fee>" + total_fee + "</total_fee>"; //金额
    formData += "<trade_type>" + settings.trade_type + "</trade_type>"; //类型APP
    formData += "<sign>" + self.generatePaySignment(attach, body, nonce_str, notify_url, out_trade_no, ip, total_fee, settings.trade_type, openid) + "</sign>";
    formData += "</xml>";
    console.log(formData);
    let option = {
      method: 'POST',
      url: url,
      body: formData
    }
    return rp(option).then(result => {
      let resp;
      console.log(result);
      var parser = new xml2js.Parser({ trim: true, explicitArray: false, explicitRoot: false });//解析签名结果xml转json
      parser.parseString(result, function (err, data) {
        resp = data;
        return;
      });
      data = {
        "appId": settings.appid,     //公众号名称,由商户传入
        "timeStamp": moment().unix().toString(),         //时间戳,自1970年以来的秒数
        "nonceStr": nonce_str, //随机串 // 通过统一下单接口获取
        "package": "prepay_id=" + resp.prepay_id,
        "signType": "MD5",         //微信签名方式:
      }
      console.log("二次加密data: " + JSON.stringify(data));
      data.paySign = self.sign(data);
      return self.getSignature(data.timeStamp, data.nonceStr)
    }).then(result => {
      data.jsapi_ticket = global.settings.wxConfig.jsapi_ticket;
      data.access_token = global.settings.wxConfig.jsapi_ticket;
      data.signature = result;
      console.log("signature: " + result + ", paySign: " + data.paySign);
      return data;
    }).catch(err => {
      throw err;
    })
 
  }
generatePaySignment(attach, body, nonce_str, notify_url, out_trade_no, spbill_create_ip, total_fee, trade_type, openid) {
    var data = {
      appid: settings.appid,
      attach: attach,
      body: body,
      mch_id: settings.mch_id,
      nonce_str: nonce_str,
      notify_url: notify_url,
      openid: openid,
      out_trade_no: out_trade_no,
      spbill_create_ip: spbill_create_ip,
      total_fee: total_fee,
      trade_type: trade_type
    };
    return this.sign(data);
  }
 
  sign(data) {
    var string = this.raw(data);
    string = string + '&key=' + settings.key; //key为在微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
    var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex');
    return sign.toUpperCase();
  }
 
randomWord(randomFlag, min, max) {
    var str = "",
      range = min,
      arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
 
    // 随机产生
    if (randomFlag) {
      let range = Math.round(Math.random() * (max - min)) + min;
    }
    for (var i = 0; i < range; i++) {
      let pos = Math.round(Math.random() * (arr.length - 1));
      str += arr[pos];
    }
    return str;
  }
 
 getSignature(timestamp, noncestr) {
 
    let data = {
      url: "https://www.thebutchart.cn/pay/",
      timestamp: timestamp,
      noncestr: noncestr,
      jsapi_ticket: global.settings.wxConfig.jsapi_ticket
    }
    let str = "jsapi_ticket=" + data.jsapi_ticket + "&noncestr=" + data.noncestr + "&timestamp=" + data.timestamp + "&url=" + data.url;
    return crypto.createHash('sha1').update(str, 'utf8').digest('hex');
  }

前端代码:

export default {
  name: "pay",
  data () {
    return {
      appId: this.$store.state.payParam.appId, // 必填,公众号的唯一标识
      timestamp: this.$store.state.payParam.timestamp, // 必填,生成签名的时间戳
      nonceStr: this.$store.state.payParam.nonceStr, // 支付签名随机串,不长于 32 位
      signature: this.$store.state.payParam.signature, // 必填,签名
      timeStamp: this.$store.state.payParam.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
      package: this.$store.state.payParam.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*
      signType: this.$store.state.payParam.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
      paySign: this.$store.state.payParam.paySign // 支付签名
    }
  },
  methods: {
    pay () {
      wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: this.appId, // 必填,公众号的唯一标识
        timestamp: this.timestamp, // 必填,生成签名的时间戳
        nonceStr: this.nonceStr, // 必填,生成签名的随机串
        signature: this.signature,// 必填,签名
        jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表
      })
      wx.chooseWXPay({
        timestamp: this.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
        nonceStr: this.nonceStr, // 支付签名随机串,不长于 32 位
        package: this.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
        signType: this.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
        paySign: this.paySign, // 支付签名
        success: function (res) {
          // 支付成功后的回调函数
          console.log(res)
        }
      })
    }
  },
  mounted () {
    console.log('6:',this.appId,this.$store.state.payParam.appId)
    this.pay()
  }
}

生成signature的参数总共只有4个,timestamp和noncestr是调用生成统一下单API时候生成的,jsapi_ticket在系统缓存中,url是https://www.thebutchart.cn/pay试了在最后加上'/'但是依然报错,有没有大神帮忙看看问题出在哪里?小弟跪谢了

回答关注问题邀请回答
收藏

1 个回答

登录 后发表内容