网友真实露脸自拍10p,成人国产精品秘?久久久按摩,国产精品久久久久久无码不卡,成人免费区一区二区三区

小程序模板網

微信小程序領取卡券(java)

發布時間:2017-12-29 18:09 所屬欄目:小程序開發教程

最近做了個領取微信卡券的小程序,看了很多文檔資料以及花了很多時間才算搞定的,不過也算是好事多磨,這邊記錄分享一下,也算給一點提升。

一、開發前準備

1:申請微信公眾號 和 微信小程序,這是兩個不同的東西,都需要單獨申請、不同的帳號;

2:微信公眾號需要開通微信卡券的功能;

3:在微信公眾號里面去綁定小程序;

4:申請微信開放平臺,并將微信公眾號 和 微信小程序綁定到該開放平臺。(注:綁定到開發平臺下的作用只是為了獲取unionid,因為同一用戶在 公眾號 和 小程序下獲得的openid是不一樣的,如果公眾號 和 小程序都需要領取卡券,則最好通過unionid來跟蹤用戶;如果你只是開發微信小程序的領取卡券,則完全可以忽略第4點,博主本人也沒有去綁定到微信開放平臺,感覺步驟好多,特別麻煩!)

 

二、開始開發

1:獲取微信卡券

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025272

這邊可以直接通過微信公眾號提供的接口獲取或者創建微信的卡券,此處不過多介紹,只是提一下這邊要獲取的access_token,網址如下https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183,代碼直接如下:

 

[java] view plain copy
 
  1. private static String grantType = "client_credential";  
  2.     public static String appId = "";            //微信公眾號appid  
  3.         public static String secret = "";           //微信公眾號密鑰  
  4.     public static AccessToken token = null;         //微信公眾號的accessToken對象,由于請求次數有限制,這里使用全局靜態變量保存起來  
  5.     public static AccessToken getToken() throws WeixinException, JsonParseException, JsonMappingException, IOException{  
  6.         if(token == null || token.getExpires_in() < System.currentTimeMillis()){  
  7.             //拼接參數  
  8.             String param = "?grant_type=" + grantType + "&appid=" + appId + "&secret=" + secret;  
  9.             //創建請求對象  
  10.                 HttpsClient http = new HttpsClient();  
  11.                 //調用獲取access_token接口  
  12.                 Response res = http.get("https://api.weixin.qq.com/cgi-bin/token" + param);  
  13.                 System.out.println(res.asString());  
  14.                 ObjectMapper mapper = new ObjectMapper();  
  15.                 token = mapper.readValue(res.asString(),AccessToken.class);  
  16.         }  
  17.             return token;  
  18.     }  


 

其中需要jackson和weixin4j的jar包,比較普遍,請自行下載;而AccessToken對象也比較簡單,就errcode、errmsg、access_token、expires_in這四個參數,比較簡單,在文章結尾貼代碼

 

2:升級微信卡券

其實這個步驟也可以省略,升級微信卡券的目的是可以直接從微信卡券跳轉到對應的小程序,博主就偷懶了,直接跳過了這個步驟;

不過升級卡券也比較簡單,就是調用調用微信公眾號的更改微信卡券接口(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:領取卡券

3.1:先獲取openId

小程序端代碼,通過調用wx.login獲取code,再調用https://api.weixin.qq.com/sns/jscode2session接口獲取openid,博主看到很多例子是直接從小程序端調用這個接口,但我事實中發現是行不通的,因為這個域名無法添加到小程序的request合法域名中,微信給的說明是不要在前端調用這個接口,需要通過后臺,那沒辦法嘍

 

[javascript] view plain copy
 
  1. wx.login({  
  2.   success: function (res) {  
  3.     var service_url = 'https://???/???/weixin/api/login?code=' + res.code;//需要將服務器域名添加到小程序的request合法域名中,而且必須是https開頭  
  4.     wx.request({  
  5.       url: l,  
  6.       data: {},  
  7.       method: 'GET',  
  8.       success: function (res) {  
  9.         console.log(res);  
  10.         if (res.data != null && res.data != undefined && res.data != '') {  
  11.           wx.setStorageSync("openid", res.data.openid);//將獲取的openid存到緩存中  
  12.         }  
  13.       }  
  14.     });  
  15.   }  
  16. });  

 

后端java代碼

 

[java] view plain copy
 
  1. /** 
  2.   * 小程序后臺登錄,向微信平臺發送獲取access_token請求,并返回openId 
  3.   * @param code 
  4.   * @return 用戶憑證 
  5.   * @throws WeixinException 
  6.   * @throws IOException  
  7.   * @throws JsonMappingException  
  8.   * @throws JsonParseException  
  9.   */  
  10.  @RequestMapping("login")  
  11.  @ResponseBody  
  12.  public Map<String, Object> login(String code, HttpServletRequest request) throws WeixinException, JsonParseException, JsonMappingException, IOException {  
  13.      if (code == null || code.equals("")) {  
  14.          throw new WeixinException("invalid null, code is null.");  
  15.      }  
  16.        
  17.      Map<String, Object> ret = new HashMap<String, Object>();  
  18.      //拼接參數  
  19.      String param = "?grant_type=" + grant_type + "&appid=" + appid + "&secret=" + secret + "&js_code=" + code;  
  20.        
  21.      System.out.println("https://api.weixin.qq.com/sns/jscode2session" + param);  
  22.        
  23.      //創建請求對象  
  24.      HttpsClient http = new HttpsClient();  
  25.      //調用獲取access_token接口  
  26.      Response res = http.get("https://api.weixin.qq.com/sns/jscode2session" + param);  
  27.      //根據請求結果判定,是否驗證成功  
  28.      JSONObject jsonObj = res.asJSONObject();  
  29.      if (jsonObj != null) {  
  30.          Object errcode = jsonObj.get("errcode");  
  31.          if (errcode != null) {  
  32.              //返回異常信息  
  33.              throw new WeixinException(getCause(Integer.parseInt(errcode.toString())));  
  34.          }  
  35.            
  36.          ObjectMapper mapper = new ObjectMapper();  
  37.          OAuthJsToken oauthJsToken = mapper.readValue(jsonObj.toJSONString(),OAuthJsToken.class);  
  38.          ret.put("openid", oauthJsToken.getOpenid());  
  39.      }  
  40.      return ret;  
  41.  }  


 

其中OAuthJsToken對象的字段為:openid、expires_in、session_key(會話密鑰) ,在文章結尾貼代碼;

 

3.2:生成領取卡券的簽名,并調用wx.addCard方法領取卡券

這邊寫貼java后端代碼

 

[java] view plain copy
 
  1.        public static ApiTicket ticket = null;//使用全局靜態變量存儲ApiTicket對象,當然如果使用緩存框架保存當然更好,這邊只是做一個簡單示例  
  2. /** 
  3.  * @Description: 獲取領取卡券獲取簽名等參數 
  4.  * @param cardId:需要領取的卡券的cardId 
  5.  * @return 
  6.  * @throws WeixinException 
  7.  * @throws JsonParseException 
  8.  * @throws JsonMappingException 
  9.  * @throws IOException 
  10.  */  
  11. @RequestMapping("getCardSign")  
  12. @ResponseBody  
  13. public Map<String, String> getCardSign(String cardId) throws WeixinException, JsonParseException, JsonMappingException, IOException{  
  14.     Map<String, String> ret = new HashMap<String, String>();  
  15.     //先要獲取api_ticket,由于請求api_ticket的接口訪問有次數限制,所以最好將獲得到的api_ticket保存到緩存中,這邊做法比較簡單,直接使用的靜態變量  
  16.     if(ticket == null || ticket.getExpires_in() < System.currentTimeMillis()){  
  17.         //創建請求對象  
  18.             HttpsClient http = new HttpsClient();  
  19.           
  20.             ObjectMapper mapper = new ObjectMapper();  
  21.           
  22.             AccessToken token = OpenApi.getToken();//這里獲取的token就是最上方代碼保存的微信公眾號全局靜態變量token  
  23.                   
  24.                 //通過access_token調用獲取api_ticket接口  
  25.             Response res = http.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + token.getAccess_token() + "&type=wx_card");  
  26.             System.out.println(res.asString());  
  27.             ticket = mapper.readValue(res.asString(), ApiTicket.class);  
  28.             }  
  29.         
  30.             ret = sign(ticket.getTicket(), cardId);//生成領取卡券需要的簽名,并返回相關的參數  
  31.   
  32.             for (Map.Entry entry : ret.entrySet()) {  
  33.                 System.out.println(entry.getKey() + ", " + entry.getValue());  
  34.             }  
  35.             return ret;  
  36. }  
  37. /** 
  38.  * @Description: 生成卡券需要的簽名并返回參數 
  39.  * @param api_ticket: 
  40.  * @param cardId:需要領取的卡券的cardId 
  41.  * @return 
  42.  */  
  43. public static Map<String, String> sign(String api_ticket, String cardId) {  
  44.        Map<String, String> ret = new HashMap<String, String>();  
  45.        String nonce_str = create_nonce_str();  
  46.        String timestamp = create_timestamp();  
  47.        String signature = "";  
  48.          
  49.        String param[] = new String[4];  
  50.          
  51.        param[0] = nonce_str;  
  52.        param[1] = timestamp;  
  53.        param[2] = api_ticket;  
  54.        param[3] = cardId;  
  55.          
  56.        Arrays.sort(param);//對參數的value值進行字符串的字典序排序  
  57.          
  58.        StringBuilder sb = new StringBuilder();  
  59.     for(String b : param){  
  60.         sb.append(b);  
  61.     }  
  62.     System.out.println(sb);  
  63.        //對上面拼接的字符串進行sha1加密,得到signature  
  64.        try{  
  65.            MessageDigest crypt = MessageDigest.getInstance("SHA-1");  
  66.            crypt.reset();  
  67.            crypt.update(sb.toString().getBytes("UTF-8"));  
  68.            signature = byteToHex(crypt.digest());  
  69.        }catch (NoSuchAlgorithmException e){  
  70.            e.printStackTrace();  
  71.        }catch (UnsupportedEncodingException e){  
  72.            e.printStackTrace();  
  73.        }  
  74.   
  75.     //返回領取卡券需要的參數,其中nonceStr和timestamp必須和簽名中的保持一致  
  76.        ret.put("card_id", cardId);  
  77.        ret.put("api_ticket", api_ticket);  
  78.        ret.put("nonceStr", nonce_str);  
  79.        ret.put("timestamp", timestamp);  
  80.        ret.put("signature", signature);  
  81.   
  82.        return ret;  
  83.    }  


 

其中ApiTicket對象的屬性有:errcode、errmsg、ticket、expires_in,在文章結尾貼出該代碼

再貼小程序端代碼

 

[javascript] view plain copy
 
  1. var that = this;  
  2. var service_url = 'https://???/???/weixin/api/getCardSign?cardId=' + cardId;//需要將服務器域名添加到小程序的request合法域名中,而且必須是https開頭  
  3. wx.request({  
  4.   url: service_url,  
  5.   data: {},  
  6.   method: 'GET',  
  7.   success: function (res) {  
  8.     console.log(res);  
  9.       wx.addCard({  
  10.         cardList: [{  
  11.           cardId: that.data.cardId,  
  12.           cardExt: '{"code":"","openid":"","timestamp":' + res.data.timestamp + ',"nonce_str":"' + res.data.nonceStr + '","signature":"' + res.data.signature + '"}'  
  13.         }],//這里需要注意的是cardExt參數的value值是 String類型,不要使用對象發送;另外openid如果在創建優惠券的時候沒有指定,則這邊為空,千萬不要填寫當前用戶的openid  
  14.         success: function (result) {  
  15.           console.log(res);  
  16.   
  17.           wx.showToast({  
  18.             title: '領取成功',  
  19.             icon: 'success',  
  20.             duration: 2000  
  21.           });  
  22.         },  
  23.         fail: function (res) {  
  24.           console.log('領取失敗');  
  25.           console.log(res);  
  26.         }  
  27.       })  
  28.       
  29.   }  
  30. });  


 

ok,如果領取成功,可以直接到微信卡包里面查看。下面貼出AccessToken、ApiTicket、OAuthJsToken的java模型代碼

 

[java] view plain copy
 
  1. public class BaseResponse {  
  2.     private int errcode;  
  3.     private String errmsg;  
  4.       
  5.     public int getErrcode() {  
  6.         return errcode;  
  7.     }  
  8.     public void setErrcode(int errcode) {  
  9.         this.errcode = errcode;  
  10.     }  
  11.     public String getErrmsg() {  
  12.         return errmsg;  
  13.     }  
  14.     public void setErrmsg(String errmsg) {  
  15.         this.errmsg = errmsg;  
  16.     }  
  17. }  
  18. public class AccessToken extends BaseResponse{  
  19.     private String access_token;  
  20.     private long expires_in;  
  21.       
  22.     public String getAccess_token() {  
  23.         return access_token;  
  24.     }  
  25.     public void setAccess_token(String access_token) {  
  26.         this.access_token = access_token;  
  27.     }  
  28.     public long getExpires_in() {  
  29.         return expires_in;  
  30.     }  
  31.     public void setExpires_in(long expires_in) {  
  32.         this.expires_in = System.currentTimeMillis() + (expires_in - 100) * 1000;//原expires_in是有效時長,比如:7200,現改為過期的時間戳  
  33.     }  
  34. }  
  35. public class ApiTicket extends BaseResponse{  
  36.     private String ticket;  
  37.     private long expires_in;  
  38.       
  39.     public String getTicket() {  
  40.         return ticket;  
  41.     }  
  42.     public void setTicket(String ticket) {  
  43.         this.ticket = ticket;  
  44.     }  
  45.     public long getExpires_in() {  
  46.         return expires_in;  
  47.     }  
  48.     public void setExpires_in(long expires_in) {  
  49.         this.expires_in = System.currentTimeMillis() + (expires_in - 100) * 1000;//原expires_in是有效時長,比如:7200,現改為過期的時間戳  
  50.     }  
  51. }  
  52. public class OAuthJsToken {  
  53.     private String openid;              //用戶唯一標識  
  54.     private int expires_in = 7200;      //憑證有效時間,單位:秒  
  55.     private String session_key;         //會話密匙  
  56.     private long exprexpiredTime;           //過期時間  
  57.       
  58.     public String getOpenid() {  
  59.         return openid;  
  60.     }  
  61.     public void setOpenid(String openid) {  
  62.         this.openid = openid;  
  63.     }  
  64.     public int getExpires_in() {  
  65.         return expires_in;  
  66.     }  
  67.     public void setExpires_in(int expires_in) {  
  68.         this.expires_in = expires_in;  
  69.         this.exprexpiredTime = System.currentTimeMillis() + expires_in * 1000;  
  70.     }  
  71.     public String getSession_key() {  
  72.         return session_key;  
  73.     }  
  74.     public void setSession_key(String session_key) {  
  75.         this.session_key = session_key;  
  76.     }  
  77.       
  78.     public long getExprexpiredTime() {  
  79.         return exprexpiredTime;  
  80.     }  
  81.     public void setExprexpiredTime(long exprexpiredTime) {  
  82.         this.exprexpiredTime = exprexpiredTime;  
  83.     }  
  84.     /** 
  85.      * 判斷用戶憑證是否過期 
  86.      * 
  87.      * @return 過期返回 true,否則返回false 
  88.      */  
  89.     public boolean isExprexpired() {  
  90.         return System.currentTimeMillis() >= this.exprexpiredTime;  
  91.     }  
  92. }  
  93.  


易優小程序(企業版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://www.xiuhaier.com/wxmini/doc/course/18311.html 復制鏈接 如需定制請聯系易優客服咨詢:800182392 點擊咨詢
QQ在線咨詢
AI智能客服 ×