- 调用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 + [代码][代码]"×tamp="[代码] [代码]+ 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试了在最后加上'/'但是依然报错,有没有大神帮忙看看问题出在哪里?小弟跪谢了
2019-08-29 - JSAPI支付报 invalid signature 错误
jsapi_ticket: sM4AOVdWfPE4DxkXGEs8VF-blQ4mWprx4zI1SZN_Hbo_8xnvvdDAWNJJRJdAmATSlu14hqUYEVAnqayfpyiSLQ noncestr: fsnugmmh1xu timestamp: 1566833975 url: https://www.thebutchart.cn/pay [图片] 跟后台生成的signature一样,jsapi_ticket用过access_token获得,noncestr通过统一下单API的结果拿到,一直卡在这里不知道问题在哪,诸位有遇到类似的情况吗?求助 signature: 11db042834fa0215ed27b283ebdb4298166b0fd
2019-08-27