借助小程序云开发创建微信卡券
2020年腾讯数字文创节(以下简称TGC)在海南举行,为了能让玩家提前了解TGC的文化和线下活动,在活动开始前的一个月时间,我们就上线了「线上提前预约门票」的功能。为了提升门票预约的体验,以及更好的在活动开始之前提前触达到预约门票的用户,团队今年在小程序预约门票的基础上增加了「添加门票到微信卡券」的功能。
您需要提前准备以下账号信息:
- 微信开放平台账号
- 微信小程序账号
- 微信公众号
一、将微信小程序账号和微信公众号绑定在同一个微信开放平台账号下
二、开通微信公众号的卡券功能
在 mp.weixin.qq.com 中,登录微信公众号后台,点击左侧菜单栏 -> 功能 -> 卡券功能(如果没有该功能,请点击添加功能插件进行添加)。
访问 open.weixin.qq.com,登录微信开放平台后,将小程序账号和微信公众号绑定在该开放平台账号下。
三、生成卡券模板
在微信公众号后台,可以对优惠券和会员卡类型进行手动创建,但是针对一些特殊的票券则需要使用 API(会议门票、电影票和景区门票等等)的方式进行生成,TGC的活动是在海南线下举行,所以我们则使用了微信卡券的景区门票类型,无法直接在后台直接创建,所以这里介绍下如果使用 API 的方式进行生成。
1、获取access_token
创建卡券API需要用到微信的 access_token,而公众号生成 access_token 的方式需要特别注意一下,需要在公众号后台绑定生成 access_token 的服务器IP白名单,由于生成卡券我们只需要创建一次,所以这里我们直接添加本地的IP作为白名单IP即可。
2、创建卡券
这一步就是利用创建卡券的API,传入卡券的配置即可。相关的请求参数说明直接查看文档:
https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Special_ticket.html
这里特别需要注意的是,小程序添加微信卡券功能允许我们将卡券使用界面添加跳转回小程序的入口,所以在创建卡券的时候,我们可以通过设置一些参数,让卡券服务入口能跳转回小程序内,具体参数说明,请前往相关文档查看,这里简单贴下使用效果,供大家参考。
文档链接:
四、服务端生成卡券下发(小程序云开发)
创建完卡券之后,接下就是用户在小程序内通过某些操作领取卡券了。小程序内领取卡券需要服务端提供卡券的校验参数,所以这一步,我们介绍下如何在服务端生成卡券的校验参数。
1、生成access_token
这步我们在生成卡券模板中有提到过,只不过因为这里客户端频繁调用的,我们需要在代码层面去实现 access_token 的获取。这里由于我们使用的是小程序云,云函数的运行机制,导致其默认的是非固定IP,我们需要在腾讯云的 cloudbase 控制台,将获取 access_token 的云函数设置成固定IP。
设置固定IP成功后,将得到的 IP 配置到 公众号管理后台的 开发 -> 基本配置 -> IP白名单 中:
配置好IP白名单后,利用基本配置中的 AppID 和 AppSecret 请求access_token:
let requestApiTicketResult = await request({
uri: 'https://api.weixin.qq.com/cgi-bin/ticket/getticket',
qs: {
access_token: accessToken,
type: 'wx_card'
}
})
2、生成api_ticket
生成 api_ticket 和获取 access_token 类似,直接利用 access_token请求微信的接口获取即可,这里需要注意的是,access_token和api_ticket 每天都有请求次数的限制以及都有过期时间,所以我们需要将这两个值缓存起来使用(注:这个问题好像不少新人同学都犯过错)。
let requestApiTicketResult = await request({
uri: 'https://api.weixin.qq.com/cgi-bin/ticket/getticket',
qs: {
access_token: accessToken,
type: 'wx_card'
}
})
3、生成卡券参数
卡券参数主要分为这几部分:随机字符串 nonce_str、时间戳 timestamp、用户 openid、卡券号码 code、卡券签名 signature。
卡券签名 signature 的生成依赖其他的参数。
后端代码实现:
const cardExt = {
cardId: 'cardId', // 卡券id
code: code,
api_ticket: apiTicket,
nonce_str: generate(),
timestamp: parseInt((Date.now() / 1000), 10) + ''
}
// 按照字典升序排列
return {
cardId: 'CardId',
cardExt: JSON.stringify({
openid: '', // 不指定openid领取
code: cardExt.code,
nonce_str: cardExt.nonce_str,
timestamp: cardExt.timestamp,
signature: sha1(valueToString(cardExt))
})
}
// 生成随机字符串
const generate = (length = 16) => {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
let noceStr = '',
maxPos = chars.length
while (length--) noceStr += chars[Math.random() * maxPos | 0]
return noceStr
}
// 排序
const valueToString = (obj) => Object.values(obj).sort().join('')
// 加密
const sha1 = (str, encoding = 'utf8') => crypto.createHash('sha1').update(str, encoding).digest('hex')
五、小程序端添加卡券
小程序端添加卡券的就直接将服务端生成的卡券参数传入小程序添加卡券 API 即可:
wx.addCard({
cardList: [
{
cardId: 'cardId',
cardExt: 'cardExt' // 拿到后端生成好的cardExt
}],
success (res) {
console.log(res.cardList) // 卡券添加结果
}
})
六、实现效果
调用 wx.addCard 的效果:
调用 wx.openCard 的效果:
七、门票卡券核销
由于业务的特殊性(用户可以多次通过门票卡券二维码进入活动现场),我们并未对卡券做核销的操作。但是卡券本身的核销也是直接可以通过微信卡券核销接口进行核销,由于这部分比较简单,这里就不冗余阐述了,直接可以通过查看文档完成:
https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Redeeming_a_coupon_voucher_or_card.html
产品介绍
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为开发者提供高可用、自动弹性扩缩的后端云服务,包含计算、存储、托管等serverless化能力,可用于云端一体化开发多种端应用(小程序,公众号,Web 应用,Flutter 客户端等),帮助开发者统一构建和管理后端服务和云资源,避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。