微信小程序卡劵 开发(踩坑)指南

最近做了小程序卡劵的功能,算是各种报错都碰到了。个人觉得为什么有这么多"报错"。可能真是官网的文档着实有点让人懵逼。今天总结一下。希望能帮助到有需要的人;

一、卡劵功能开发前的准备工作

1.申请微信公众号 、小程序公众号、 微信开放平台

2.微信公众号里面卡劵的所有接口权限全部开通。需要微信认证! 查看这些接口权限的位置在:开发-->接口权限 就可以看到啦! 切记是在微信公众号里面!!审核需要3个工作日这样。提前申请好。

image
image

3.在微信公众号平台里面绑定好对应的小程序。位置在:左侧菜单小程序-->小程序管理-->添加即可~ 这个就有点傻瓜式了

4.需要在微信开放平台将小程序和公众号绑定在开放平台下。将微信小程序和公众号 进行打通。一些小伙伴会遇到微信小程序获取的unionid 和微信公众号获取的unionid 不一致。 则需要在这边进行绑定。即可解决


image.png

二、各种报错~该怎么解决

1、{"errcode": 40164, "errmsg": "invalid ip 11.11.11.11, not in whitelist"} 当前IP不在白名单列表里面。解决办法如下:

左侧菜单 公众号----> 设置---->安全中心---->IP白名单 添加好对应服务器的IP地址即可(其实后台报错中已经告诉你哪个IP不在了)

2、{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest hint: [2m6eSa0531e292]"} 无效的access_token。解决办法如下:

首页要确保你生成access_token接口用到的appid和secret是正确的。且是对应功能需要的、分清楚是公众号的功能还是小程序的功能。 获取access_token接口是有次数限制的。建议放入缓存处理。但即使没有超过7200秒也会失效。这是微信的BUG。如果出现这样问题代码中再去获取下即可。

3、领取卡劵 签名错误

image

这个问题解决起来很懵逼吧。官方文档如下

image

当你点击卡签名时候跳转到没有任何你觉得关于签名的地方~ 哈哈哈 我是这样感觉得。下面贴出正确的卡卷签名地址吧!卡卷签名 找到卡卷拓展字段及签名算法。文章就在这里啦;

加密因为需要放在后台做。做个简单的介绍

1.加密的参数 只要 api_ticket、timestamp、nonce_str、card_id(卡卷的ticket、时间戳、不超过32位的随机字符串、卡卷ID)

敲黑板!!划重点了!!api_ticket 这个卡卷的ticket 需要通过微信公众号的appid+appsecret生成的access_token 去获取!不是小程序的appid+appsecre生成的!这是很重要的!!很重要的!!不要搞错!!

3.小程序端领劵代码(小白写的代码 勿喷)

//添加卡卷
addCard: function () {
  wx.login({
    success: res => {
      const code = res.code;
      let params = {
        code: code,//登录的code
        cardId: cardId,//卡卷的ID
      }
      //这边是调用后台生成signature的接口
      //res.timestamp  res.nonce_str res.signature 
      // (这几个参数都是后台生成签名的参数。全部返回到前台。时间戳、随机字符串、签名)
      webApi.xxxxxx(params).then(res => {
          wx.addCard({
            cardList: [
              {
                cardId: cardId,
                cardExt: '{"code":"","openid":"","timestamp":' + res.timestamp +',"nonce_str":"' + res.nonce_str + '","signature":"' + res.signature + '"}'
              }
            ],
            success(data) {
              //恭喜你已经成功了!
            }
          })
      })
    }
  })
},

4.后台java生成签名代码(是java的看一眼。其他语言顺序也是一样)

 /**
     * 微信小程序领取卡券生成签名方法
     * @param request
     * @return
     */
    public Response getSignature(WechatAuthUserInfoRequest request) {
        String newString = new String();
        Response response = new Response();
        try {
            String nonce_str = create_nonce_str();//创建随机字符串
            String timestamp = create_timestamp();//创建随机时间戳
            String cardId = request.getCardId();//前端传来的卡卷ID
            String ticket = ApiUtil.getTicket();//通过微信公众平台的appid和secret获取的卡卷ticket
            response.setTimestamp(timestamp);//给响应赋值时间戳
            response.setNonce_str(nonce_str);//给响应赋值时间戳
            response.setTicket(ticket);//给响应赋值ticket
            String[] strArr = {ticket,timestamp,nonce_str,cardId};
            Arrays.sort(strArr);//对参数的value值进行字符串的字典序排序
            for(int i=0; i<4; i++){
                newString += strArr[i];
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //加密结果
        String signature = getSha1(newString);  //Sha1加密
        response.setSignature(signature);
        return response;
    }
    /**
     * 生成签名随机字符串
     * @return
     */
    private static String create_nonce_str() {
        String nonce = new String();
        for(int i=0; i<10; i++){
            int rannum = (int)(Math.random()*1000) % (chars.length);
            nonce += chars[rannum];
        }
        return nonce;
    }
    /**
     * 签名加密生成时间戳
     * @return
     */
    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

    /**
     * 生成签名sha1加密
     * @param str
     * @return
     */
    public static String getSha1(String str){
        if(str==null||str.length()==0){
            return null;
        }
        char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9',
                'a','b','c','d','e','f'};
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
            mdTemp.update(str.getBytes("UTF-8"));

            byte[] md = mdTemp.digest();
            int j = md.length;
            char buf[] = new char[j*2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
                buf[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(buf);
        } catch (Exception e) {
            return null;
        }
    }

上面贴出了开发时候领取卡劵踩坑花费时间比较多的地方。代码上没什么。主要是领劵的一套逻辑理清楚。 代码希望能帮助有需要的朋友。代码写的不好 勿喷。解决问题第一位。(再次提醒下 凡是和卡劵生成access_token的一些接口。需要用到appid和secret都是用微信公众号的而不是小程序的)
第一次发布简书~~溜了溜了

自己无聊写的小程序 欢迎使用~


gh_af88ca3ac9c4_430.jpg

推荐阅读更多精彩内容