如今許多線下商店都開通了小程序,并實(shí)現(xiàn)了優(yōu)惠券接入,來吸引人流,那么對于開發(fā)新人來說,如何接入優(yōu)惠券功能,下面為大家介紹。
一、開發(fā)前準(zhǔn)備
1:申請微信公眾號 和 微信小程序,這是兩個不同的東西,都需要單獨(dú)申請、不同的帳號;
2:微信公眾號需要開通微信卡券的功能;
3:在微信公眾號里面去綁定小程序;
4:申請微信開放平臺,并將微信公眾號 和 微信小程序綁定到該開放平臺。(注:綁定到開發(fā)平臺下的作用只是為了獲取unionid,因?yàn)橥挥脩粼?公眾號 和 小程序下獲得的openid是不一樣的,如果公眾號 和 小程序都需要領(lǐng)取卡券,則最好通過unionid來跟蹤用戶;如果你只是開發(fā)微信小程序的領(lǐng)取卡券,則完全可以忽略第4點(diǎn),博主本人也沒有去綁定到微信開放平臺,感覺步驟好多,特別麻煩!)
二、開始開發(fā)
1:獲取微信卡券
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025272
這邊可以直接通過微信公眾號提供的接口獲取或者創(chuàng)建微信的卡券,此處不過多介紹,只是提一下這邊要獲取的access_token,網(wǎng)址如下https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183,代碼直接如下:
private static String grantType = "client_credential";
public static String appId = ""; //微信公眾號appid
public static String secret = ""; //微信公眾號密鑰
public static AccessToken token = null; //微信公眾號的accessToken對象,由于請求次數(shù)有限制,這里使用全局靜態(tài)變量保存起來
public static AccessToken getToken() throws WeixinException, JsonParseException, JsonMappingException, IOException{
if(token == null || token.getExpires_in() < System.currentTimeMillis()){
//拼接參數(shù)
String param = "?grant_type=" + grantType + "&appid=" + appId + "&secret=" + secret;
//創(chuàng)建請求對象
HttpsClient http = new HttpsClient();
//調(diào)用獲取access_token接口
Response res = http.get("https://api.weixin.qq.com/cgi-bin/token" + param);
System.out.println(res.asString());
ObjectMapper mapper = new ObjectMapper();
token = mapper.readValue(res.asString(),AccessToken.class);
}
return token;
}
其中需要jackson和weixin4j的jar包,比較普遍,請自行下載;而AccessToken對象也比較簡單,就errcode、errmsg、access_token、expires_in這四個參數(shù),比較簡單,在文章結(jié)尾貼代碼
2:升級微信卡券
其實(shí)這個步驟也可以省略,升級微信卡券的目的是可以直接從微信卡券跳轉(zhuǎn)到對應(yīng)的小程序,博主就偷懶了,直接跳過了這個步驟;
不過升級卡券也比較簡單,就是調(diào)用調(diào)用微信公眾號的更改微信卡券接口(URL:https://api.weixin.qq.com/card/update?access_token=TOKEN),添加幾個字段,可以參考微信官方文檔3.1,鏈接如下:https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&key=1490190158&version=1&lang=zh_CN&platform=2
3:領(lǐng)取卡券
3.1:先獲取openId
小程序端代碼,通過調(diào)用wx.login獲取code,再調(diào)用https://api.weixin.qq.com/sns/jscode2session接口獲取openid,博主看到很多例子是直接從小程序端調(diào)用這個接口,但我事實(shí)中發(fā)現(xiàn)是行不通的,因?yàn)檫@個域名無法添加到小程序的request合法域名中,微信給的說明是不要在前端調(diào)用這個接口,需要通過后臺
wx.login({
success: function (res) {
var service_url = 'https://???/???/weixin/api/login?code=' + res.code;//需要將服務(wù)器域名添加到小程序的request合法域名中,而且必須是https開頭
wx.request({
url: l,
data: {},
method: 'GET',
success: function (res) {
console.log(res);
if (res.data != null && res.data != undefined && res.data != '') {
wx.setStorageSync("openid", res.data.openid);//將獲取的openid存到緩存中
}
}
});
}
});
后端java代碼
/**
* 小程序后臺登錄,向微信平臺發(fā)送獲取access_token請求,并返回openId
* @param code
* @return 用戶憑證
* @throws WeixinException
* @throws IOException
* @throws JsonMappingException
* @throws JsonParseException
*/
@RequestMapping("login")
@ResponseBody
public Map<String, Object> login(String code, HttpServletRequest request) throws WeixinException, JsonParseException, JsonMappingException, IOException {
if (code == null || code.equals("")) {
throw new WeixinException("invalid null, code is null.");
}
Map<String, Object> ret = new HashMap<String, Object>();
//拼接參數(shù)
String param = "?grant_type=" + grant_type + "&appid=" + appid + "&secret=" + secret + "&js_code=" + code;
System.out.println("https://api.weixin.qq.com/sns/jscode2session" + param);
//創(chuàng)建請求對象
HttpsClient http = new HttpsClient();
//調(diào)用獲取access_token接口
Response res = http.get("https://api.weixin.qq.com/sns/jscode2session" + param);
//根據(jù)請求結(jié)果判定,是否驗(yàn)證成功
JSONObject jsonObj = res.asJSONObject();
if (jsonObj != null) {
Object errcode = jsonObj.get("errcode");
if (errcode != null) {
//返回異常信息
throw new WeixinException(getCause(Integer.parseInt(errcode.toString())));
}
ObjectMapper mapper = new ObjectMapper();
OAuthJsToken oauthJsToken = mapper.readValue(jsonObj.toJSONString(),OAuthJsToken.class);
ret.put("openid", oauthJsToken.getOpenid());
}
return ret;
}
其中OAuthJsToken對象的字段為:openid、expires_in、session_key(會話密鑰) ,在文章結(jié)尾貼代碼;
3.2:生成領(lǐng)取卡券的簽名,并調(diào)用wx.addCard方法領(lǐng)取卡券
這邊寫貼java后端代碼
public static ApiTicket ticket = null;//使用全局靜態(tài)變量存儲ApiTicket對象,當(dāng)然如果使用緩存框架保存當(dāng)然更好,這邊只是做一個簡單示例
/**
* @Description: 獲取領(lǐng)取卡券獲取簽名等參數(shù)
* @param cardId:需要領(lǐng)取的卡券的cardId
* @return
* @throws WeixinException
* @throws JsonParseException
* @throws JsonMappingException
* @throws IOException
*/
@RequestMapping("getCardSign")
@ResponseBody
public Map<String, String> getCardSign(String cardId) throws WeixinException, JsonParseException, JsonMappingException, IOException{
Map<String, String> ret = new HashMap<String, String>();
//先要獲取api_ticket,由于請求api_ticket的接口訪問有次數(shù)限制,所以最好將獲得到的api_ticket保存到緩存中,這邊做法比較簡單,直接使用的靜態(tài)變量
if(ticket == null || ticket.getExpires_in() < System.currentTimeMillis()){
//創(chuàng)建請求對象
HttpsClient http = new HttpsClient();
ObjectMapper mapper = new ObjectMapper();
AccessToken token = OpenApi.getToken();//這里獲取的token就是最上方代碼保存的微信公眾號全局靜態(tài)變量token
//通過access_token調(diào)用獲取api_ticket接口
Response res = http.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + token.getAccess_token() + "&type=wx_card");
System.out.println(res.asString());
ticket = mapper.readValue(res.asString(), ApiTicket.class);
}
ret = sign(ticket.getTicket(), cardId);//生成領(lǐng)取卡券需要的簽名,并返回相關(guān)的參數(shù)
for (Map.Entry entry : ret.entrySet()) {
System.out.println(entry.getKey() + ", " + entry.getValue());
}
return ret;
}
/**
* @Description: 生成卡券需要的簽名并返回參數(shù)
* @param api_ticket:
* @param cardId:需要領(lǐng)取的卡券的cardId
* @return
*/
public static Map<String, String> sign(String api_ticket, String cardId) {
Map<String, String> ret = new HashMap<String, String>();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String signature = "";
String param[] = new String[4];
param[0] = nonce_str;
param[1] = timestamp;
param[2] = api_ticket;
param[3] = cardId;
Arrays.sort(param);//對參數(shù)的value值進(jìn)行字符串的字典序排序
StringBuilder sb = new StringBuilder();
for(String b : param){
sb.append(b);
}
System.out.println(sb);
//對上面拼接的字符串進(jìn)行sha1加密,得到signature
try{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(sb.toString().getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
}catch (NoSuchAlgorithmException e){
e.printStackTrace();
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
//返回領(lǐng)取卡券需要的參數(shù),其中nonceStr和timestamp必須和簽名中的保持一致
ret.put("card_id", cardId);
ret.put("api_ticket", api_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
return ret;
}
其中ApiTicket對象的屬性有:errcode、errmsg、ticket、expires_in,在文章結(jié)尾貼出該代碼
再貼小程序端代碼
ok,如果領(lǐng)取成功,可以直接到微信卡包里面查看。下面貼出AccessToken、ApiTicket、OAuthJsToken的jav
以上是這篇微信小程序領(lǐng)取優(yōu)惠券接入流程,希望可以幫助到大家,謝謝。
HiShop小程序工具提供多類型商城/門店小程序制作,可視化編輯 1秒生成5步上線。通過拖拽、拼接模塊布局小程序商城頁面,所看即所得,只需要美工就能做出精美商城。
更多小程序開發(fā)案例,盡在:http://westcoastpropertyservices.com/xiaocx/kaifa.html