2018.05.08 微信小程序添加卡券遇到的坑

准备工作:

  • 一个可以开通卡券功能的服务公众号
  • 一个小程序账号

注意两者是独立的,分别有着不同的appid和appsercet

开发框架:jfinal-weixin

需求:

  • 创建会议门票卡券
  • 每人限领一张
  • 不可转赠给好友
  • 自己定义二维码内容

第一步:创建卡券

        Map base_info = new HashMap<>();
        //卡券的商户logo,建议像素为300*300
        base_info.put("logo_url", "");//logo
        base_info.put("brand_name", ""); //商户名字,字数上限为12个汉字
        base_info.put("code_type", "CODE_TYPE_QRCODE");//Code展示类型 "CODE_TYPE_TEXT",文本; "CODE_TYPE_BARCODE",一维码 ; "CODE_TYPE_QRCODE",二维码; "CODE_TYPE_ONLY_QRCODE",二维码无code显示; "CODE_TYPE_ONLY_BARCODE",一维码无code显示;
        base_info.put("title", "");//卡券名,字数上限为9个汉字。(建议涵盖卡券属性、服务及金额)
        base_info.put("color", "Color100");//券颜色。按色彩规范标注填写Color010-Color100。
        base_info.put("notice", "使用时向检票员出示此券");//卡券使用提醒,字数上限为16个汉字
        base_info.put("service_phone", "");//客服电话
        base_info.put("description", "请务必准时入场");//卡券使用说明,字数上限为1024个汉字
        Map date_info = new HashMap<>();
        date_info.put("type", 1);//使用时间的类型,仅支持填写1或2。1为固定日期区间,2为固定时长(自领取后按天算)。
        date_info.put("begin_timestamp", "时间戳(秒级)");//  type为1时专用,表示起用时间。从1970年1月1日00:00:00至起用时间的秒数,最终需转换为字符串形态传入。(东八区时间(UTC+8),单位为秒)
        date_info.put("end_timestamp", "时间戳(秒级)");//type为1时专用,表示结束时间,建议设置为截止日期的23:59:59过期。(东八区时间 (UTC+8) ,单位为秒)
        base_info.put("date_info", date_info);//使用日期,有效期的信息
        Map sku = new HashMap<>();
        sku.put("quantity", "100000000");//卡券库存的数量,不支持填写0,上限为100000000。
        base_info.put("sku", sku);
        base_info.put("get_limit", 1);//每人可领券的数量限制
        base_info.put("use_custom_code", true);//是否自定义Code码。填写true或false,默认为false。通常自有优惠码系统的开发者选择自定义Code码,在卡券投放时带入
        base_info.put("bind_openid", false);//是否指定用户领取,填写true或false。默认为false。
        base_info.put("can_share", false);//卡券领取页面是否可分享
        base_info.put("can_give_friend", false);//卡券是否可转赠。
        meeting_ticket.put("base_info", base_info);
        card.put("meeting_ticket", meeting_ticket);
        Map data = new HashMap<>();
        data.put("card", card);

        ApiResult apiResult = CardApi.create(JSON.toJSONString(data));
自己定义二维码内容的好处
  • 小程序和公众号是两套独立的appid和appsercet,因此在小程序获取到用户的openid和查询用户领取卡券后返回的openid是不一致的,所以如果自己定义二维码,就可以事先知道并决定二维码的内容,并且可以将其作为桥梁,在用户领取卡券后做领取事件回调。
  • 对应的参数是("use_custom_code", true)

生成卡券后,即可获得cardId,后面用户领取时会用到

第二步:小程序中添加卡券

官方文档地址:
https://developers.weixin.qq.com/miniprogram/dev/api/card.html#wxaddcardobject

单个卡券添加需要提供的参数:


所需参数

其中cardExt需要以下参数:


cardExt

比较麻烦的一点就是签名的生成,在官方文档中如此描述:

卡券签名和JSSDK的签名完全独立,两者的算法和意义完全不同,请不要混淆。JSSDK的签名是使用所有JS接口都需要走的一层鉴权,用以标识调用者的身份,和卡券本身并无关系。其次,卡券的签名考虑到协议的扩展性和简单的防数据擅改,设计了一套独立的签名协议。另外由于历史原因,卡券的JS接口先于JSSDK出现,当时的JSAPI并没有鉴权体系,所以在卡券的签名里也加上了appsecret/api_ticket这些身份信息,希望开发者理解。

  • 首先获取卡券 api_ticket
    注意是:JsApiType.wx_card
        JsTicket jsApiTicket = JsTicketApi.getTicket(JsTicketApi.JsApiType.wx_card);
        String api_ticket = jsApiTicket.getTicket();
  • 然后是timestamp和nonce_str
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
  • 卡券id即cardId在生成卡券成功时有返回
  • 然后根据参数的顺序,按照 key 值 ASCII 码升序排序
        ArrayList list = new ArrayList();
        list.add(timestamp);
        list.add(CardCode);//自己定义,可以使用12位随机数
        list.add(nonce_str);
        list.add(api_ticket);
        list.add(cardId);
        Collections.sort(list);
  • 最后进行sha1加密,得到signature
        String signature = HashKit.sha1(str);
注意的事情
  • 卡券的签名算法与JSSDK签名算法不一致,卡券的签名是按照值来排序的,而JSSDK签名是按照键值对固定排序的,这个地方需要着重注意一下。

第三步:卡券事件回调

卡券事件分别是领取事件,核销事件,删除事件...
这里只描述领取事件和核销事件
首先要在公众号中设置开发者模式,这样才会接收到微信发过来的信息

如果不知道如何设置开发者模式,可以参考这篇文章:
https://blog.csdn.net/zyw_java/article/details/61415205

  • 领取事件
    因为CardCode在派发时已经知道了,可以事先保存到数据库,用户领取后,根据下面的userCardCode 从而得知是哪个用户领取的,从而做自己想要的处理
 /**
     * 卡券领取事件推送
     *
     * @param msg 卡券领取事件推送
     */
    @Override
    protected void processInUserGetCardEvent(InUserGetCardEvent msg) {
        String userCardCode = msg.getUserCardCode();//code序列号
        //To-Do
        renderNull();
    }
  • 核销事件
/**
     * 卡券核销事件推送
     *
     * @param msg 卡券核销事件推送
     */
    @Override
    protected void processInUserConsumeCardEvent(InUserConsumeCardEvent msg) {
        String userCardCode = msg.getUserCardCode();//code序列号
         //To-Do
        renderNull();
    }

第四步:在小程序中获取卡券列表

官方文档:
https://developers.weixin.qq.com/miniprogram/dev/api/card.html#wxopencardobject

简单来说就需要两样东西,一个是cardId,一个是cardCode

  • cardId就是需要打开的卡券 Id
  • cardCode就是自己定义的二维码内容

你可能感兴趣的:(2018.05.08 微信小程序添加卡券遇到的坑)