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

准备工作:

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

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

开发框架:jfinal-weixin

需求:

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

第一步:创建卡券

        Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String> list = new ArrayList<String>();
        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就是自己定义的二维码内容
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容