问题解决了,原来是排序问题 正确的字符串排序应该是 [代码]var[代码] [代码]perpare = [代码][代码]string[代码][代码].Format([代码][代码]"{0}{1}{2}{3}"[代码][代码], timestamp, nonce_str,api_ticket, cardid );[代码]另外小程序端 字符串 拼接应该是: [代码]cardExt: [代码][代码]'{"timestamp":'[代码] [代码]+ res.data.timestamp + [代码][代码]',"signature":"'[代码] [代码]+ res.data.signature + [代码][代码]'", "nonce_str":"'[代码] [代码]+ res.data.nonceStr + [代码][代码]'"}'[代码]注意 timestamp不能 有引号。
wx.addCard一直报签名错误这个问题折腾了两天了,搜了很多网友的解决方法,以及按照签名排错文档中的提示逐一排查,然而并没有什么用,下面将我的环境和遇到的签名问题描述一下。 我的公众号和小程序均已认证,同时使用工作号的appid 获取token 和api_ticket 并且做了缓存。 https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1} https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=wx_card 前目排序如下: [代码]var[代码] [代码]perpare = [代码][代码]string[代码][代码].Format([代码][代码]"{0}{1}{2}{3}"[代码][代码], api_ticket, timestamp.ToString(), nonce_str,cardid );[代码]这个是参照调试工具的排序方法,官方文档说的字典排序,可是我用字典排序,排序的结果跟调试工具完全不一样。 签名后的结果与调试工具一直。 cardExt 字符串拼装如下: [代码]var[代码] [代码]cards =[{[代码][代码] [代码][代码]cardId: me.data.cardId,[代码][代码] [代码][代码]cardExt: [代码][代码]'{"timestamp":'[代码] [代码]+ res.data.timestamp + [代码][代码]',"signature":"'[代码] [代码]+ res.data.signature + [代码][代码]'", "nonce_str":"'[代码] [代码]+ res.data.nonceStr + [代码][代码]'"}'[代码][代码] [代码][代码]}];[代码]输出结果 输出结果如下: [代码]{[代码][代码]cardExt[代码]:[代码]"{"[代码][代码]timestamp[代码][代码]":1547435004,"[代码][代码]signature[代码][代码]":"[代码][代码]bf50d6cef45d43137e0494b9a299b59d569a84b0[代码][代码]", "[代码][代码]nonce_str[代码][代码]":"[代码][代码]313d0cc5af004275845f15f1c7b40e9d[代码][代码]"}",[代码][代码]cardId[代码]:"p18KQ55QuuWfC9NxcM2yKBGAKUbk"[代码]}[代码]我实在是没辙了,所以发帖求助,如能解决万分感谢。
2019-01-14微信支付栏目无法发帖。。。。
你是否也遇到小程序卡卷签名错误,求解决~微信小程序卡卷签名错误无法找到原因,希望这方面的大佬能正解!万分感谢~ 最近开发微信小程序的时候遇到卡卷签名错误的问题,因为我是前端人员,不太懂后台,在网上各种找结果还是签名错误,让我很头痛,希望小程序这方面的大佬能正解一下,在下感激不尽! 后台已经成功获得签名并校验(这里有个小问题就是签名校验排序问题,我在我电脑测试的时候api_ticket与timestamp没有进行交换位置所以签名校验(地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=cardsign)不一样,但是他们电脑出现位置交换(timestamp在第一个)),我们没有自定义code没有指定openid,所以这两个参数都没有用到! 后台代码: [代码]<?php[代码][代码]define([代码][代码]"appID"[代码][代码], [代码][代码]$_POST[代码][代码][[代码][代码]"appid"[代码][代码]]);[代码][代码]define([代码][代码]"appsecret"[代码][代码], [代码][代码]$_POST[代码][代码][[代码][代码]"secret"[代码][代码]]);[代码] [代码]class[代码] [代码]JSSDK {[代码][代码]private[代码] [代码]$appId[代码][代码];[代码][代码]private[代码] [代码]$appSecret[代码][代码];[代码][代码]public[代码] [代码]function[代码] [代码]__construct([代码][代码]$appId[代码][代码], [代码][代码]$appSecret[代码][代码]) {[代码][代码] [代码][代码]$this[代码][代码]->appId = [代码][代码]$appId[代码][代码];[代码][代码] [代码][代码]$this[代码][代码]->appSecret = [代码][代码]$appSecret[代码][代码];[代码][代码]}[代码][代码]public[代码] [代码]function[代码] [代码]getSignPackage() {[代码][代码] [代码][代码]//获取access_token[代码][代码] [代码][代码]$TOKEN_URL[代码][代码]=[代码][代码]"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="[代码][代码].[代码][代码]$this[代码][代码]->appId.[代码][代码]"&secret="[代码][代码].[代码][代码]$this[代码][代码]->appSecret;[代码][代码] [代码][代码]$json[代码][代码]=[代码][代码]file_get_contents[代码][代码]([代码][代码]$TOKEN_URL[代码][代码]);[代码][代码] [代码][代码]$result[代码][代码]=json_decode([代码][代码]$json[代码][代码],true);[代码][代码] [代码][代码]$ACCESS_TOKEN[代码][代码]=[代码][代码]$result[代码][代码][[代码][代码]'access_token'[代码][代码]];[代码][代码] [代码][代码]//echo $ACCESS_TOKEN.'<br /><br />';[代码][代码] [代码][代码]//jsapiTicket[代码][代码] [代码][代码]$TOKEN_URL[代码][代码]=[代码][代码]"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$ACCESS_TOKEN&type=wx_card"[代码][代码];[代码][代码] [代码][代码]$json[代码][代码]=[代码][代码]file_get_contents[代码][代码]([代码][代码]$TOKEN_URL[代码][代码]);[代码][代码] [代码][代码]$result[代码][代码]=json_decode([代码][代码]$json[代码][代码],true);[代码][代码] [代码][代码]$api_ticket[代码][代码]=[代码][代码]$result[代码][代码][[代码][代码]'ticket'[代码][代码]];[代码][代码] [代码][代码]//echo $jsapi_ticket.'<br /><br />';[代码][代码] [代码][代码]//$jsapi_ticket = $this->getJsApiTicket();[代码][代码] [代码][代码]//$url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]" ;[代码][代码] [代码][代码]$card_id[代码] [代码]= [代码][代码]$_POST[代码][代码][[代码][代码]"card_id"[代码][代码]] ;[代码][代码] [代码][代码]$timestamp[代码] [代码]= time();[代码][代码] [代码][代码]$nonceStr[代码] [代码]= [代码][代码]$this[代码][代码]->createNonceStr();[代码][代码] [代码][代码]//$string = "api_ticket=$api_ticket×tamp=$timestamp&nonce_str=$nonceStr&card_id=$card_id" ;[代码][代码] [代码][代码]//$string = $timestamp.$nonceStr.$api_ticket.$card_id ;[代码][代码] [代码][代码]//echo '<br /><br />';[代码][代码] [代码][代码]$arr[代码] [代码]= [代码][代码]array[代码][代码]( [代码][代码]$card_id[代码][代码],[代码][代码]$api_ticket[代码][代码],[代码][代码]$nonceStr[代码][代码],[代码][代码]$timestamp[代码][代码]);[代码][代码] [代码][代码]asort([代码][代码]$arr[代码][代码], SORT_STRING);[代码][代码] [代码][代码]$string[代码] [代码]= [代码][代码]""[代码][代码];[代码][代码] [代码][代码]foreach[代码][代码]([代码][代码]$arr[代码] [代码]as[代码] [代码]$temp[代码][代码]){[代码][代码] [代码][代码]$string[代码] [代码]= [代码][代码]$string[代码][代码].[代码][代码]$temp[代码][代码];[代码][代码] [代码][代码]}[代码][代码]$signature[代码] [代码]= sha1([代码][代码]$string[代码][代码]);[代码][代码]//$signature = sha1($sortString );[代码][代码] [代码][代码]//$signature = sha1($string );[代码][代码] [代码][代码]$signPackage[代码] [代码]= [代码][代码]array[代码][代码]([代码][代码] [代码][代码]"appId"[代码] [代码]=> [代码][代码]$this[代码][代码]->appId,[代码][代码] [代码][代码]"nonceStr"[代码] [代码]=> [代码][代码]$nonceStr[代码][代码],[代码][代码] [代码][代码]"timestamp"[代码] [代码]=> [代码][代码]$timestamp[代码][代码],[代码][代码] [代码][代码]"card_id"[代码] [代码]=> [代码][代码]$card_id[代码][代码],[代码][代码] [代码][代码]"signature"[代码] [代码]=> [代码][代码]$signature[代码][代码],[代码][代码] [代码][代码]"rawString"[代码] [代码]=> [代码][代码]$string[代码][代码],[代码][代码] [代码][代码]"api_ticket"[代码] [代码]=> [代码][代码]$api_ticket[代码][代码] [代码][代码]);[代码][代码] [代码][代码]return[代码] [代码]$signPackage[代码][代码]; [代码][代码]}[代码][代码]private[代码] [代码]function[代码] [代码]createNonceStr([代码][代码]$length[代码] [代码]= 16) {[代码][代码] [代码][代码]$chars[代码] [代码]= [代码][代码]"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[代码][代码];[代码][代码] [代码][代码]$str[代码] [代码]= [代码][代码]""[代码][代码];[代码][代码] [代码][代码]for[代码] [代码]([代码][代码]$i[代码] [代码]= 0; [代码][代码]$i[代码] [代码]< [代码][代码]$length[代码][代码]; [代码][代码]$i[代码][代码]++) {[代码][代码] [代码][代码]$str[代码] [代码].= [代码][代码]substr[代码][代码]([代码][代码]$chars[代码][代码], mt_rand(0, [代码][代码]strlen[代码][代码]([代码][代码]$chars[代码][代码]) - 1), 1);[代码][代码] [代码][代码]}[代码][代码] [代码][代码]return[代码] [代码]$str[代码][代码];[代码][代码]}[代码][代码]/*public function httpGet($url) {[代码][代码] [代码][代码]$curl = curl_init();[代码][代码] [代码][代码]curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);[代码][代码] [代码][代码]curl_setopt($curl, CURLOPT_TIMEOUT, 500);[代码][代码] [代码][代码]curl_setopt($curl, CURLOPT_URL, $url);[代码][代码] [代码][代码]$res = curl_exec($curl);[代码][代码] [代码][代码]curl_close($curl);[代码][代码] [代码][代码]return $res;[代码][代码]}*/[代码][代码] [代码][代码]}[代码][代码]$jssdk[代码][代码]=[代码][代码]new[代码] [代码]JSSDK(appID,appsecret);[代码][代码]$signPackage[代码] [代码]= [代码][代码]$jssdk[代码][代码]->GetSignPackage();[代码][代码] [代码][代码]//echo $signPackage["signature"];[代码][代码] [代码][代码]$res[代码] [代码]= [代码][代码]"<signPackage><card_id>"[代码][代码].[代码][代码]$signPackage[代码][代码][[代码][代码]"card_id"[代码][代码]].[代码][代码]"</card_id><timestamp>"[代码][代码].[代码][代码]$signPackage[代码][代码][[代码][代码]"timestamp"[代码][代码]].[代码][代码]"</timestamp><nonceStr>"[代码][代码].[代码][代码]$signPackage[代码][代码][[代码][代码]"nonceStr"[代码][代码]].[代码][代码]"</nonceStr><signature>"[代码][代码].[代码][代码]$signPackage[代码][代码][[代码][代码]"signature"[代码][代码]].[代码][代码]"</signature><api_ticket>"[代码][代码].[代码][代码]$signPackage[代码][代码][[代码][代码]"api_ticket"[代码][代码]].[代码][代码]"</api_ticket></signPackage>"[代码][代码];[代码][代码] [代码][代码]/*function arrayToXml( $data, $wrap= 'xml' ){[代码][代码] [代码][代码]$str = "<{$wrap}>";[代码][代码] [代码][代码]if( is_array( $data ) ){[代码][代码] [代码][代码]if( hasIndex( $data ) ){ [代码][代码] [代码][代码]foreach( $data as $k=>$v ){[代码][代码] [代码][代码]$str .= arrayToXml( $v, $k );[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}else{[代码][代码] [代码][代码]foreach( $data as $v ){[代码][代码] [代码][代码]foreach( $v as $k1=>$v1 ) [代码][代码] [代码][代码]$str .= arrayToXml( $v1, $k1 );[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}else[代码][代码] [代码][代码]$str .= $data;[代码][代码] [代码][代码]$str .= "</{$wrap}>";[代码][代码] [代码][代码]return $str;[代码][代码] [代码][代码]}[代码][代码] [代码][代码]$res = $this->arrayToXml($signPackage);[代码][代码] [代码][代码]header("Content-type: text/xml");*/[代码][代码] [代码][代码]echo[代码] [代码]$res[代码][代码];[代码][代码]?>[代码]前端代码: [代码]onLoad:function(options){[代码][代码] [代码][代码]wx.login({[代码][代码] [代码][代码]success: res =>{[代码][代码] [代码][代码]var code = res.code;[代码][代码] [代码][代码]console.log(code);[代码][代码] [代码][代码]if (res.code) {[代码][代码] [代码][代码]//发起网络请求[代码][代码] [代码][代码]wx.request({[代码][代码] [代码][代码]url: 'https://api.weixin.qq.com/sns/jscode2session?appid=小程序appid&secret=小程序密钥&js_code=' + code + '&grant_type=authorization_code',[代码][代码] [代码][代码]method: 'GET',[代码][代码] [代码][代码]data:{[代码][代码] [代码][代码]'appid': "小程序appid",[代码][代码] [代码][代码]'secret': "小程序密钥",[代码][代码] [代码][代码]"code": res.code[代码][代码] [代码][代码]},[代码][代码] [代码][代码]header:{[代码][代码] [代码][代码]'content-type': 'application/json'[代码][代码] [代码][代码]},//以上获取的code与openid只是为了后面的,其实现在并不用到[代码][代码] [代码][代码]success:function(res){[代码][代码] [代码][代码]console.log(res);[代码][代码] [代码][代码]var openid = res.data.openid //返回openid[代码][代码] [代码][代码]console.log(openid);[代码][代码] [代码][代码] [代码][代码]wx.request({[代码][代码] [代码][代码]url: 'https://www.dgsy888888.com/DGKJNEW/sc/sign3.php?appid="公众号appid"&secret="公众号密钥"',[代码][代码] [代码][代码]method:'POST',[代码][代码] [代码][代码]data:{ [代码][代码] [代码][代码]"appid":"公众号appid", //获取access_token时,使用的appid是公众号的而非小程序的[代码][代码] [代码][代码]"secret":"公众号密钥"[代码][代码] [代码][代码]},[代码][代码] [代码][代码]header:{[代码][代码] [代码][代码]//'Content-type': 'application/json'[代码][代码] [代码][代码]'Content-Type': 'application/x-www-form-urlencoded' [代码][代码] [代码][代码]},[代码][代码] [代码][代码]success:function(res){[代码][代码] [代码][代码]var strmobile = res.data;[代码][代码] [代码][代码]console.log(strmobile);[代码][代码] [代码][代码]var XMLParser = new Parser.DOMParser() //后台传来的是XML格式,这里就是解析[代码][代码] [代码][代码]var doc = XMLParser.parseFromString(strmobile)[代码][代码] [代码][代码]var timestamp = doc.getElementsByTagName('timestamp')['0']; [代码][代码] [代码][代码] [代码][代码]var nonceStr = doc.getElementsByTagName('nonceStr')['0'];[代码][代码] [代码][代码] [代码][代码]var signature = doc.getElementsByTagName('signature')['0'];[代码][代码] [代码][代码] [代码][代码]var api_ticket = doc.getElementsByTagName('api_ticket')['0'];[代码][代码] [代码][代码]//strmobile = [timestamp.firstChild.data, nonceStr.firstChild.data, signature.firstChild.data,api_ticket.firstChild.data][代码][代码] [代码][代码]//console.log(strmobile)[代码][代码] [代码][代码] [代码][代码]//添加卡卷[代码][代码] [代码][代码]wx.addCard({[代码][代码] [代码][代码]cardList:[{[代码][代码] [代码][代码]cardId: '我们现在用的是固定cardid,这里我写死了',[代码][代码] [代码][代码]cardExt:'{"timestamp":"'+timestamp.firstChild.data+'","api_ticket":"'+api_ticket.firstChild.data+'","nonceStr":"'+nonceStr.firstChild.data+'","signature":"'+signature.firstChild.data+'"}'[代码][代码] [代码][代码]}],[代码][代码] [代码][代码]success:function(res){[代码][代码] [代码][代码]console.log(cardList)//卡券添加结果[代码][代码] [代码][代码]console.log("你成功领取会员卡")[代码][代码] [代码][代码]},[代码][代码] [代码][代码]fail: function (res){[代码][代码] [代码][代码]console.log("失败");[代码][代码] [代码][代码]},[代码][代码] [代码][代码]complete: function (res){[代码][代码] [代码][代码]console.log("成功失败我都会执行");[代码][代码] [代码][代码]}[代码][代码] [代码][代码]})[代码][代码] [代码][代码]}[代码][代码] [代码][代码]})[代码][代码] [代码][代码]}[代码][代码] [代码][代码]})[代码][代码] [代码][代码]}else{[代码][代码] [代码][代码]console.log('获取用户登录态失败!'+res.errMsg);[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}[代码][代码]})[代码][代码]}[代码]希望大佬们出出主意帮帮我这个还没有入道的小辈,在下一鞠躬! 我的联系方式 WX:wj2578025916 邮箱:2578025916@qq.com
2019-01-13