弥生生的小本子
想到啥就写啥,有啥就写啥

背景

最近接了个做微信小程序的需求,主要是要用到微信公众号的一物一码功能,申请一批二维码并进行激活,将这些二维码分发到商品上,用户通过扫描二维码可以跳转到小程序,然后进入到我们自己的业务逻辑存储数据进行后续分析。

然而我也是第一次做小程序,所以拿到需求之后就去看官方的开发文档了,发现这个一物一码功能刚上线两个月而已,百度出来的内容都是“微信上线了一物一码功能XXX”等等之类的新闻,并没有开发人员试水的一些经验。硬着头皮折腾了一个星期,终于弄好了,也说不上复杂,就算是一个新功能的试水贴,如果有人也要用这个功能但是不太理解官方文档,希望这篇文章能帮上你的忙。

前期准备&开发

1. 申请一物一码功能

这个部分一般让产品去申请,申请通过后会收到邮件得到一串秘钥,这个秘钥要留着用来解密二维码包

2. 申请及获取二维码

公众号申请一物一码功能通过之后就可以进行二维码的申请及获取了。这里附上微信公众号一物一码接口文档


该图是文档中的业务流程。这里我们需要做的首先是调用申请二维码接口,如下:


code_count是你要申请码的数量,最少一万个,外部单号是我们自定义的一个字符串,例如我们要申请一个商品的码,就可以用这个商品的名称例如keaiduo-01作为外部单号,然后外部单号和商品类型的映射关系自己要记好,因为在后面的步骤中还要用到。这里申请二维码的操作我们可以直接通过postman完成,先去用公众号的AppID和AppSecret调用获取access_token的接口,然后用access_token去调用申请接口就可以了。

调用申请接口成功后,会返回一个application_id:


在这里最好是把外部单号和申请单号(isv_application_id和application_id)这两个参数统一保存好,excel也好云文档也好,总之就是能够找到对应商品就行。下一步我们就可以查询二维码申请单的状态了。

查询使用的接口如下:


这里的参数就用到了我们上一步申请时使用的外部单号以及接口得到的申请单号,用这两个参数去进行查询,返回参数如下:


status参数从INIT到FINISH,大概要经过三到五分钟左右,FINISH之后就可以去下载二维码包了。

3. 下载及解密二维码包


这里建议用postman来调下载二维码包接口,申请单号依旧来自之前的接口,code_start和code_end文档中没有说明,实践中发现一次最多只能下载1w个,超过了就会报错,所以如果申请了5w个二维码,那么就需要调用五次接口,分五段下载。

在postman中我们选择send选项中的send and download,就可以直接将返回的数据保存到json文件中。如果点击send之后等待数据返回再保存为文件那么有很大的可能会导致卡死,建议使用send and download。


包含1w个二维码的码包数据是5Mb左右,返回的数据中buffer参数是经过base64加密的,如下所示:


拿到返回的数据后我们就可以进行解密处理。官方文档的描述如下:

3.1 解密说明
实名数据的加密方式使用AES的CBC模式,iv使用加解密钥,填充使用PKCS7Padding,最后使用base64进行编码。
解密时,先进行base64解码,然后使用密钥及AES/CBC/PKCS7Padding进行解密。 密钥在申请实名接口权限时,会提供到申请方。

解密秘钥就是在申请一物一码功能通过后通过邮件发送到申请人的一串码,我这里用nodejs写了解密的方法,引了crypto解密,解密方法如下:

function jiemi(body) {
    var iv = 'YVN+HNPxfJVPxMwS' // 一物一码的秘钥
    var clearEncoding = 'utf8'
    var cipherEncoding = 'base64'
    var key = 'YVN+HNPxfJVPxMwS'
    var cipherChunks = []
    var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv)
    cipherChunks.push(decipher.update(body, cipherEncoding, clearEncoding))
    cipherChunks.push(decipher.final(clearEncoding))
    var decryption = cipherChunks.join('')
    return decryption
}
let bitmap = jsonFile.buffer;
let jie = jiemi(bitmap)
fs.writeFileSync('data.txt', jie);

将buffer的值进行解密,解密后写入文件即可得到二维码的原始数据。二维码包数据如下:

1111111100111111111100000110001100000110111010110010111011011101011101011101101110100100101110110000011010110000011111111110111111111110001100010110001100011011010000011001000110010010111101101110100101101101111000110100101001111111111111000100110100000110011111000110111010101011110111011101010100000001101110100100011011110000011001010110101111111100011000111	043E.NS%E	0	P.URL.CN/0HSHWR.AZKSYOC7UYZG
1111111100111111111100000111011100000110111010101010111011011101010001011101101110101110101110110000011101110000011111111110111111111110001100100110001100100111110101111100010100110111101000111100100001011111111000110101101000001111111110101100110100000111001000000010111010011001010011011101000101010100101110101111001001110000011001000111011111111100110000111	043E.NS%F	1	P.URL.CN/0EPQ.X3B$DLKAQLVZ/I

官方文档说明:

在我们处理好所有的二维码包数据后,就可以将文件发给印刷厂进行印刷,那边会有解析程序解析二维码,作为开发只要关心9位的原始码数据即可,也是后面我们进行扫码操作时要用到的数据。

4. 激活二维码

因为申请码、激活码以及开发小程序这几个动作都可以并行,所以我们可以先去申请二维码拿去印刷,在这期间进行小程序的开发,等到二维码要投入应用时再进行激活。

二维码的激活可以多次重复激活,建议在批量印刷前先拿到几个样码单独激活给开发人员测试用,等到投入生产在重新激活。激活二维码接口如下:


申请单号依旧是之前获取到的单号,活动名称、商品品牌、商品标题、商品条码这些都是自定义的参数,应该由产品来确定;appid是我们扫码要跳转的小程序id,path就是要跳进来的小程序路径(例如'pages/index/index'),wxa_type可以设置正式版开发版体验版,想要开发测试就传1或2,最后生产环境再重新激活就可以了。

5. 小程序扫码

在激活成功后可以进行扫码了,扫码后我们会获得一个参数code_ticket,这个参数在onLoad回调方法中可以拿到:

onLoad: function (options) {
    console.log(options.code_ticket)
  },

然后再通过wx.login方法以及jscode2session方法拿到扫码用户的openid,用这两个参数调用公众号的tickettocode接口:


接口返回的code参数就是二维码的原始码值,我们就可以继续走自己的业务逻辑进行相应的处理了。

这里需要注意的是,要区分好小程序和公众号的接口以及access_token的获取,在我们自己的业务后台应该将两种appId和appSecret区分,获取的access_token不要混淆了,以免在调试过程中浪费时间(没错说的就是我自己233)

总结

以上就是一物一码功能开发的流程以及扫码跳转小程序的开发流程,希望能为其他开发者节省一些时间~

posted on 2019-10-09 16:27  弥生生  阅读(7248)  评论(4编辑  收藏  举报