最近在做微信公众平台开发时用到了微信卡券功能,应用场景为用户抽奖,并将抽到的优惠券添加到微信卡包中。此外,有个特殊需求是优惠券的code需要指定(客户有自己的商城,此code可以在另外一个商城中直接使用;如不自定义code,微信生成的code不能直接在其商城中使用)。

然而在实现过程中发现,自定义code模式下,添加卡券(addCard)时领券页面上的按钮为灰色不可用状态,显示“参数错误”。如图所示:

遇到这个问题,首先跟微信官方文档进行了核查,接口调用均按接口中要求没有出入。然后开始在网上搜索,搜索的结果大同小异,且大都是从微信官方文档里copy的,没有什么实际价值。

此情况下,百思不得其解。在不自定义code的情况下,addCard工作正常,为何自定义code就出错了呢?偶然间,考虑去掉自定义code试一下。这一试不要紧,竟然成功了!这才恍然大悟,被微信开发文档坑了!

批量添加卡券接口

  1. wx.addCard({
  2. cardList: [{
  3. cardId: '',
  4. cardExt: ''
  5. }], // 需要添加的卡券列表
  6. success: function (res) {
  7. var cardList = res.cardList; // 添加的卡券列表信息
  8. }
  9. });
  10. cardExt详见附录4,值得注意的是,这里的card_ext参数必须与参与签名的参数一致,格式为字符串而不是Object,否则会报签名错误。

这里将附录4中关于cardExt的相关内容复制过来:

字段是否必填说明
code指定的卡券code码,只能被领一次。use_custom_code字段为true的卡券必须填写,非自定义code不必填写。
openid指定领取者的openid,只有该用户能领取。bind_openid字段为true的卡券必须填写,bind_openid字段为false不必填写。
timestamp时间戳,商户生成从1970年1月1日00:00:00至今的秒数,即当前的时间,且最终需要转换为字符串形式;由商户生成后传入,不同添加请求的时间戳须动态生成,若重复将会导致领取失败!
nonce_str随机字符串,由开发者设置传入,加强签名的安全性。随机字符串,不长于32位。推荐使用大小写字母和数字,不同添加请求的nonce须动态生成,若重复将会导致领取失败!
signature签名,商户将接口列表中的参数按照指定方式进行签名,签名方式使用SHA1,具体签名方案参见下文;由商户按照规范签名后传入。
outer_id领取场景值,用于领取渠道的数据统计,默认值为0,字段类型为整型,长度限制为60位数字。用户领取卡券后触发的事件推送中会带上此自定义场景值,不参与签名。

签名说明

  1. 将 api_ticket、timestamp、card_id、code、openid、nonce_str的value值进行字符串的字典序排序。
  2. 将所有参数字符串拼接成一个字符串进行sha1加密,得到signature。
  3. signature中的timestamp,nonce字段和card_ext中的timestamp,nonce_str字段必须保持一致。

注意
受文档的误导,在签名过程中把code进行了排序及加密,实际上这是不需要的。

微信卡券自定义code时,卡券的生成和领取逻辑,猜测如下,仅供参考

  1. 将自定义的code上传到微信服务器
  2. 向服务器申请领取卡券(不需要告诉服务器你要哪一个code),服务器按一定机制返回一个未领取过的code。

总结
不管是否自定义code,在领取卡券时(包括服务端签名&前端调用js接口addCard),无需包含code字段。