小程序開發----自定義會員卡卡號和用戶領取,以及簡單介紹卡券功能和注意事項


  前一段時間做項目涉及到這方面的內容,看了技術文檔,小程序頁面沒有詳細介紹,要前往微信公眾號開發文檔,卡券功能是先為微信公眾號開發的功能,后來也提供個小程序,文檔在小程序中沒有過多的介紹,微信文檔我就不想過多的吐槽了,大家都懂。

一、會員卡

  1、在小程序會員卡,其實也是用到微信公眾號的,開始在摸索,在微信公眾號管理后台創建會員卡,在小程序中能調用,但會員卡號不能自定義編號,因為管理后創建的,默認是不能自定義編碼(use_custom _code=false),一鍵開卡(wx_activate=true)、自動激活(auto_activate=true),所以不是我們需要的,應該另辟一條道路,自己通過接口創建會員卡,代碼例子如下:

 1     public function addCard(){
2 $url = 'https://api.weixin.qq.com/card/create?access_token='.$this->getAccessToken(); 4 $post['card']['card_type'] = 'MEMBER_CARD'; 5 $post['card']['member_card']['prerogative'] = '111'; 6 $post['card']['member_card']['auto_activate'] = true; //自動激活 7 $post['card']['member_card']['wx_activate'] = true; //一鍵開卡 8 $post['card']['member_card']['supply_bonus'] = false; 9 $post['card']['member_card']['supply_balance'] = false; 10 $post['card']['member_card']['base_info']['logo_url'] = "http://mmbiz.qpic.cn/mmbiz_png/xxxxxxxxxxxxxxxxxxx=png"; //會員卡圖片路徑 11 $post['card']['member_card']['base_info']['code_type'] = "CODE_TYPE_TEXT"; 12 $post['card']['member_card']['base_info']['brand_name'] = 'brand_name_1'; 13 $post['card']['member_card']['base_info']['title'] = 'title_1'; 14 $post['card']['member_card']['base_info']['color'] = 'Color010'; 15 $post['card']['member_card']['base_info']['notice'] = 'notice'; 16 $post['card']['member_card']['base_info']['description'] = 'description'; 17 $post['card']['member_card']['base_info']['sku']['quantity'] = 1000000000; 18 $post['card']['member_card']['base_info']['date_info']['type'] = 'DATE_TYPE_PERMANENT'; 19 $post['card']['member_card']['base_info']['get_limit'] = 1; //限領一張 20 $post['card']['member_card']['base_info']['can_share'] = false; 21 $post['card']['member_card']['base_info']['can_give_friend'] = false; 22 $post['card']['member_card']['base_info']['use_custom_code'] = true; //開啟自定義編碼 23 $data = http_curl_post_json($url,$post); 24 $data = json_decode($data,true); 25 return $data; 26 }

   2、創建好會員卡后,在小程序中寫入用戶領取會員卡的前端代碼,jssdk的wx.addCard方法,其中加密不同於jssdk的加密方式,加密方式看微信公眾號jssdk說明文檔附錄4,addCard方法的cardExt里的參數很重要

    code:需要給用戶自定義編碼時,才需填入你后台開發生成編碼(會員卡卡號),否則不填為空字符串

    openid:需要給自定的用戶發放會員卡是,才需填入用戶的openid(微信公眾號的openid而不是小程序的openid),否則為空字符串

    ...........等參數

    注意:以上參數需要用到的時候才加入一起加密,如:code的值為空字符串則不需加了加密,否則領取會員卡時會出簽名錯誤

    加密方法如下:

  1 <?php
  2 class Jssdk {
  3 
  4     private $appId = '';
  5     private $appSecret = '';
  6     public function __construct($appId,$appSecret){
  7         $this->appId = $appId;
  8         $this->appSecret = $appSecret;
  9     }
 10     /*
 11     *實現微信jssdk加密
 12     */
 13     public function getSignPackage($url) {
 14         $jsapiTicket = $this->getJsApiTicket();
 15         // 注意 URL 一定要動態獲取,不能 hardcode. //ajax頁面url則必須要前端傳輸url地址
 16         // $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
 17         // $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
 18         $timestamp = time();
 19         $nonceStr = $this->createNonceStr();
 20 
 21         // 這里參數的順序要按照 key 值 ASCII 碼升序排序
 22         $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
 23 
 24         $signature = sha1($string);
 25 
 26         $signPackage = array(
 27             "appId"     => $this->appId,
 28             "nonceStr"  => $nonceStr,
 29             "timestamp" => $timestamp,
 30             "url"       => $url,
 31             "signature" => $signature,
 32             "rawString" => $string
 33         );
 34         return $signPackage;
 35     }
 36 
 37     //獲取access_token
 38     public function getAccessTokenInfo(){
 39         return $this->getAccessToken();
 40     }
 41 
 42     private function createNonceStr($length = 16) {
 43         $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 44         $str = "";
 45         for ($i = 0; $i < $length; $i++) {
 46             $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
 47         }
 48         return $str;
 49     }
 50 
 51     private function getJsApiTicket() {
 52         // jsapi_ticket 應該全局存儲與更新,以下代碼以寫入到文件中做示例
 53         $data = json_decode(file_get_contents("xxxx/jsapi_ticket.json")); //xxxx/jsapi_ticket.json 是存放路徑
 54         if ($data->expire_time < time()) {
 55             $accessToken = $this->getAccessToken();
 56             $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
 57             $res = json_decode($this->curl($url));
 58             $ticket = $res->ticket;
 59             if ($ticket) {
 60                 $data->expire_time = time() + 7000;
 61                 $data->jsapi_ticket = $ticket;
 62                 $fp = fopen("xxxx/jsapi_ticket.json", "w");
 63                 fwrite($fp, json_encode($data));
 64                 fclose($fp);
 65             }
 66         } else {
 67             $ticket = $data->jsapi_ticket;
 68         }
 69         return $ticket;
 70     }
 71 
 72     private function getAccessToken() {
 73         // access_token 應該全局存儲與更新,以下代碼以寫入到文件中做示例
 74         $data = json_decode(file_get_contents("xxxx/access_token.json"));
 75         if ($data->expire_time < time()) {
 76             $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
 77             $res = json_decode($this->curl($url));
 78             $access_token = $res->access_token;
 79             if ($access_token) {
 80                 $data->expire_time = time() + 7000;
 81                 $data->access_token = $access_token;
 82                 $fp = fopen("xxxx/access_token.json", "w");
 83                 fwrite($fp, json_encode($data));
 84                 fclose($fp);
 85             }
 86         } else {
 87             $access_token = $data->access_token;
 88         }
 89         return $access_token;
 90     }
 91 
 92     private function curl( $url , $postFields = NULL )
 93     {
 94         $ch = curl_init();
 95         curl_setopt( $ch , CURLOPT_TIMEOUT , 3 );
 96         curl_setopt( $ch , CURLOPT_URL , $url );
 97         curl_setopt( $ch , CURLOPT_FAILONERROR , FALSE );
 98         curl_setopt( $ch , CURLOPT_RETURNTRANSFER , TRUE );
 99         //https 請求
100         if ( strlen( $url ) > 5 && strtolower( substr( $url , 0 , 5 ) ) == 'https' ){
101             curl_setopt( $ch , CURLOPT_SSL_VERIFYPEER , FALSE );
102             curl_setopt( $ch , CURLOPT_SSL_VERIFYHOST , FALSE );
103         }
104  
105         if ( is_array( $postFields ) && 0 < count( $postFields ) ){
106             $postBodyString = '';
107             $postMultipart  = FALSE;
108             foreach ( $postFields as $k => $v ) {
109                 if ( '@' != substr( $v , 0 , 1 ) ) //判斷是不是文件上傳
110                 {
111                     $postBodyString .= "$k=" . urlencode( $v ) . "&";
112                 } else {
113                     //文件上傳用multipart/form-data,否則用www-form-urlencoded
114                     $postMultipart = TRUE;
115                 }
116             }
117             $postFields = trim( $postBodyString , '&' );
118             unset( $k , $v );
119             curl_setopt( $ch , CURLOPT_POST , TRUE );
120             if ( $postMultipart ){
121                 curl_setopt( $ch , CURLOPT_POSTFIELDS , $postFields );
122             } else {
123                 curl_setopt( $ch , CURLOPT_POSTFIELDS , $postFields );
124             }
125         }
126  
127         $reponse = curl_exec( $ch );
128         curl_close( $ch );
129         return $reponse;
130     }
131 
132     //卡券等簽名,
133     private function apiTicket() {
134         // api_ticket 應該全局存儲與更新,以下代碼以寫入到文件中做示例
135         $data = json_decode(file_get_contents("xxxx/api_ticket.json"));
136         if ($data->expires_in < time()) {
137             $accessToken = $this->getAccessToken();
138             $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$accessToken&type=wx_card";
139             $res = json_decode($this->curl($url));
140             $ticket = $res->ticket;
141             if ($ticket) {
142                 $data->expires_in = time() + 7000;
143                 $data->ticket = $ticket;
144                 $fp = fopen("xxxx/api_ticket.json", "w");
145                 fwrite($fp, json_encode($data));
146                 fclose($fp);
147             }
148         } else {
149             $ticket = $data->ticket;
150         }
151         return $ticket;
152     }
153     //由於歷史原因,卡券的JS接口先於JSSDK出現,當時的JSAPI並沒有鑒權體系,所以在卡券的簽名里也加上了appsecret/api_ticket這些身份信息
154     public function getApiTicket($cardId='',$code='') {
155         $apiTicket = $this->apiTicket();
156         $timestamp = time();
157         $nonceStr = $this->createNonceStr();
158         // 這里參數的順序要按照 key 值 ASCII 碼升序排序
159         $tmpArr = array($nonceStr,$apiTicket,$cardId,$timestamp);
160         if($code){
161             array_push($tmpArr, $code);
162         }
163         sort($tmpArr,SORT_STRING);
164         $tmpStr = implode($tmpArr);
165         $signature = sha1($tmpStr);
166         $signPackage = array(
167             "cardId"     => $cardId,
168             "nonceStr"  => $nonceStr,
169             "timestamp" => $timestamp,
170             "signature" => $signature,
171         );
172         return $signPackage;
173     }
174 }
175 ?>

  3、領取會員卡,回調給后台領取信息,在addCard方法領取成功會返回用戶領取的相關信息,success中把領取的信息提交后台保存,從而確認領取成功。

  4、很多jssdk功能最先在微信公眾號的,之后小程序在這基礎之上引用,所以在小程序引用jssdk的方法涉及到的appid和appid密碼都是微信公眾號的而不是小程序的,卡券也如此,千萬不要搞錯,否則會造成簽名錯誤等問題,這點微信官網沒有說明。

  5、熟悉會員卡,其它卡券類型也差不多。

以下會運用到的方法: 
1
//post方式提交json格式的數據 2 function http_curl_post_json($url,$post){ 3 $data_string = json_encode($post); 4 $ch = curl_init($url); 5 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); 6 curl_setopt($ch, CURLOPT_POSTFIELDS,$data_string); 7 curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); 8 curl_setopt($ch, CURLOPT_HTTPHEADER, array( 9 'Content-Type: application/json', 10 'Content-Length: ' . strlen($data_string)) 11 ); 12 $result = curl_exec($ch); 13 return $result; 14 }

 是


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM