本文是一個循序漸進的文章,你順着思路看到底部,就可以掌握微信卡券功能的基本概念及開發了,雖然贅述了一些官方文檔上的東西但是並不多,目的只是為了串聯你的思路。
關於微信卡券的流程大家可以參考下微信官方文檔http://mp.weixin.qq.com/wiki/9/4f455120b50741db79b54fde8896b489.html
其中的“微信卡券接口”——>“微信卡券接口說明”了解下什么是卡券,怎么玩的這里不再多做贅述,可以使用測試帳號按照“微信卡券接口說明”中的步驟,從獲取token到創建卡券設置白名單,然后是投放卡券,卡券領取及核銷等流程,測試帳號申請的地方也是在上面文檔中的“開發者工具”——>“接口測試號申請”,另外在線調試可以使用“開發者工具”——>“接口在線調試”。
OK,等你玩夠了上面的在線調試,整個卡券流程差不多有個概念的時候,再來看我下面的東西。
理論上,公眾號后台是有個卡券的功能的,在那里面可以創建卡券,也就跟文檔里面的在線調試的創建卡券功能一樣。
類似下圖這個:
也就是說,如果你有了正式微信平台帳號,登錄后台后,可以在卡券中填入一些規則,然后產生一個card_id,那么這個card_id就唯一標識一種類型的卡券。
OK,那么卡券產生了,如何讓用戶能夠領取到卡券呢?
相信你看了上面的,“微信卡券接口說明”以及“接口在線調試”之后已經知道了一種領取卡券的方法,那就是下面這種,通過調用接口傳入card_id等信息后,產生一個二維碼,用戶掃一下二維碼,就可以跳到領取卡券的頁面了。
這里的這個show_qrcode_url就是二維碼的地址了,訪問之后會出現一張二維碼一掃就可以跳到領取卡券頁面了,自己可以嘗試下,掃描后應該會跳到下面這樣一個頁面這個頁面完全是微信自己的,如果顯示未通過審核請去設置下測試白名單,在接口在線調試的卡券接口里有。
好,那么我來說一下另一種方法用戶手動領取卡券的方法。
作為一個網站的運營,如果他要發放卡券一定會在微信公眾平台帳號的后台去,創建他要發放的卡券,假設我要做一個活動,下單就可以領取卡券,但只能領取其中一種卡券。
1.優惠100元卡券
2.5折卡券
暫時就這兩種,那么我可能需要用戶提交完訂單后,跳轉到一個頁面,這個頁面上有兩個卡片,然后下面有兩個單選按鈕,如下圖
由於我們事先已經創建好了這兩種卡券,那么我們實際上已經知道了這兩個券的card_id,所以此時我就想,選中某個卡券后,點“領取卡券”按鈕就可以跳轉到上面掃描后跳轉到的微信的領取卡券頁面。
OK那么這里就需要用到微信卡券的JS-SDK了。
下面這個喚起微信領取卡券頁面的js只能在微信里面才能夠使用。
所以當點擊上面頁面的“領取卡券”按鈕后,實際上是執行了一個js,如下:
這個js一定要記得引入否則不好使!
debug: true,
appId: '${appId}',
timestamp: '${configtimestamp}',
nonceStr: '${nonceStr}',
signature: '${signature}',
jsApiList: [
// 所有要調用的 API 都要加到這個列表中
'addCard'
]
});
function addCard(cardid){
wx.addCard({
cardList: [{
cardId: cardid,
cardExt: '{"code":"","openid":"","timestamp":"${timestamp}","nonce_str":"${nonceStr}","signature":"${signature1}"}'
}], // 需要添加的卡券列表
success: function (res) {
var cardList = res.cardList; // 添加的卡券列表信息
}
});
}
所以這里這個addCard所做的事情就是打開微信里面領取卡券的頁面了。盡管官方文檔上將這個addCard叫做“批量添加卡券”,這個名字我是覺得很尷尬很容易誤導,即使他做的真的是這個事情,那么也是內部程序的事情,而對於外部調用者看到的效果而言,這個名字太容易誤導別人了。
所以這里點擊領取卡券的時候會執行addCard方法,把你頁面上選的那個卡券對應的cardid傳進去,這時微信就會開始響應,並打開下面的頁面了。
OK,聽上去很簡單,但是你肯定會對上述js中的參數感到疑惑,好的,看下面的官方文檔中的介紹:
這里面的“通過config接口注入權限驗證配置”
好,簡單的類似appid的字段我就不說了,直接看附錄1
這里面的“批量添加卡券”
然后附錄4介紹了一大堆東西
可以了吧,其實就是簽名的方式而已,這里面主要說了兩個東西是簽名時要注意的,一個是jsapi_ticket,這個是wx.config用的,另一個是api_ticket,這個是wx.addCard用到的,這兩個參數都要單獨去請求,時效性是2小時,文檔上建議我們本地做緩存,另外兩個參數的請求地址文檔上也有介紹我就不詳細介紹了,下面給出個后台的例子代碼,前面給的是html中的js,后面這里是該html對應的后台java代碼。
@RequestMapping("/wxTest")
public String wxTest(Model model,HttpServletRequest request) throws JSONException{
Map param = new HashMap<>();
param.put("grant_type", "client_credential");
param.put("appid", "wx2332f2349f061ec8");
param.put("secret", "36947076e00378ec11e0a7a41b805d58");
String urlGet1 = HttpUtils.URLGet("https://api.weixin.qq.com/cgi-bin/token", param, "UTF-8");
System.out.println(urlGet1);
JSONObject jsonObject = new JSONObject(urlGet1);
// 首先是請求access_token,這個有效期是2個小時,所以可以緩存2個小時,我這里就先不寫怎么緩存了
String access_token = (String) jsonObject.get("access_token");
Map params = new HashMap<>();
params.put("access_token", access_token);
params.put("type", "jsapi");
String urlGet = HttpUtils.URLGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket", params, "UTF-8");
System.out.println("jsapi_ticket : " + urlGet);
JSONObject jsonObject1 = new JSONObject(urlGet);
// 根據access_token請求jsapi_ticket,可以緩存2個小時,下面簽名會用到
String jsapi_ticket = (String) jsonObject1.get("ticket");
Map params1 = new HashMap<>();
params1.put("access_token", access_token);
params1.put("type", "wx_card");
String urlGet2 = HttpUtils.URLGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket", params1, "UTF-8");
System.out.println("api_ticket : " + urlGet2);
JSONObject jsonObject2 = new JSONObject(urlGet2);
// 根據access_token請求api_ticket,可以緩存2個小時,下面簽名會用到
String api_ticket = (String) jsonObject2.get("ticket");
long time = new Date().getTime();
Map map = new HashMap();
map.put("noncestr", "signstr");
map.put("jsapi_ticket", jsapi_ticket);
map.put("timestamp", time + "");
map.put("url", "http://458757617.51vip.biz/wxTest.htm");
map.put("api_ticket", api_ticket);
map.put("card_id", "pXz8nwK3qkr2bkRexA2UtxOQDw3M");
map.put("code", "");
map.put("openid", "");
// wx.config的
String[] str = { "noncestr", "jsapi_ticket", "timestamp", "url" };
Arrays.sort(str);
String url = "";
for (int i = 0; i < str.length; i++){
url += str[i] + "=" + map.get(str[i]) + "&";
}
int lastIndexOf = url.lastIndexOf("&");
String lastUrl = url.substring(0, lastIndexOf);
String signature = DigestUtils.shaHex(lastUrl);
// wx.addCard的注意,兩者的簽名方式不一樣
String[] str1 = { "openid", "code", "timestamp", "card_id", "api_ticket", "noncestr" };
String[] valStr = new String[str.length];
String url = "";
for (int i = 0; i < str.length; i++){
valStr[i] = map.get(str[i]);
}
Arrays.sort(valStr);
for (int j = 0; j < valStr.length; j++){
url += valStr[j];
}
String signature1 = DigestUtils.shaHex(url);
;
model.addAttribute("appid", "wx2332f2349f061ec8");
model.addAttribute("noncestr", "signstr");
model.addAttribute("signature", signature);
model.addAttribute("configtimestamp", time+"");
model.addAttribute("timestamp", time/1000);
model.addAttribute("signature1", signature1);
return "wxtest";
}
如果你按照上面實現不了,那么請看下面這段代碼:
map.put("url", "http://458757617.51vip.biz/wxTest.htm");
這個url也就是上面說的領取卡券的頁面的url,但是他的域名一定要在微信公眾平台配置,否則jsapi是調不通的,如下圖:
切記這里,域名一定不要加“http://”如果加了就不好使了。
一定要注意,config和addCard的簽名方式不一樣,仔細看文檔!另外addCard的timestamp使用的是秒,不是毫秒!一定要注意!還有noncestr這個應該是個隨機數,每次都不一樣最好,因為api上說了,如果有一樣的場合,那么會領取卡券失敗!請注意這幾個常見容易忽略的問題!
OK,這樣就實現了我們想要的功能,另外關於自定義卡券,其實也無非是多了一步就是導入自定義卡券號碼的過程而已,這個都是在微信公眾平台帳號里面去做的,好了就寫這么多了,其實還有很多東西,但了解了這一套流程,其他的就多看看api就大概知道怎么玩了。
大家要是還有什么不懂的留言問或者加群問也行~~~