背景
最近接了個做微信小程序的需求,主要是要用到微信公眾號的一物一碼功能,申請一批二維碼並進行激活,將這些二維碼分發到商品上,用戶通過掃描二維碼可以跳轉到小程序,然后進入到我們自己的業務邏輯存儲數據進行后續分析。
然而我也是第一次做小程序,所以拿到需求之后就去看官方的開發文檔了,發現這個一物一碼功能剛上線兩個月而已,百度出來的內容都是“微信上線了一物一碼功能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)
總結
以上就是一物一碼功能開發的流程以及掃碼跳轉小程序的開發流程,希望能為其他開發者節省一些時間~
