本文適合想學習微信公眾平臺開發的入門、初級、中級的開發人員。

微信卡券的投放有多種方式,如 支援二維碼、公眾號圖文、群發、搖周邊等多種形式投放。

本文介紹的是H5頁面透過抽獎領取微信卡券,根據H5頁面領取改編而成。使用者進入一個H5抽獎頁面,抽中則開放領取卡券介面。

HTML5中領取卡券是微信JS SDK介面的一個功能。在生成卡券ID之後,將其傳入到HTML5頁面中,再使用JS SDK介面來進行領取。

前期準備:開發需要一定的程式設計基礎,需要一個認證的訂閱號或服務號,該功能使用ThinkPHP5進行開發,ThinkPHP5原始碼可在ThinkPHP框架 | 中文最佳實踐PHP開源框架,專注WEB應用快速開發8年!下載!如果你是新手,建議根據本文原始碼使用原生PHP進行開發。

開始開發

開始之前,我們得知道什麼是微信JS-SDK。

根據官方文件微信公眾平臺描述:

微信JS-SDK是微信公眾平臺面向網頁開發者提供的基於微信內的網頁開發工具包。

透過使用微信JS-SDK,網頁開發者可藉助微信高效地使用拍照、選圖、語音、位置等手機系統的能力,同時可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信使用者提供更優質的網頁體驗。

步驟一:繫結域名

先登入微信公眾平臺進入“公眾號設定”的“功能設定”裡填寫“JS介面安全域名”。

備註:登入後可在“開發者中心”檢視對應的介面許可權。

實戰篇:HTML5頁面透過抽獎領取微信卡券

實戰篇:HTML5頁面透過抽獎領取微信卡券

步驟二:引入JS檔案

在需要呼叫JS介面的頁面引入如下JS檔案,(支援https):

http://

res。wx。qq。com/open/js/j

weixin-1。2。0。js

備註:支援使用 AMD/CMD 標準模組載入方法載入

在HTML5抽獎頁面引用JS檔案

實戰篇:HTML5頁面透過抽獎領取微信卡券

實戰篇:HTML5頁面透過抽獎領取微信卡券

步驟三:獲取Access_Token和JSAPI Ticket

獲取jsapi_ticket前,我們得知道什麼是access_token和jsapi_ticket?

access_token

是公眾號的全域性唯一介面呼叫憑據,公眾號呼叫各介面時都需使用access_token。開發者需要進行妥善儲存。access_token的儲存至少要保留512個字元空間。access_token的有效期目前為2個小時,需定時重新整理,重複獲取將導致上次獲取的access_token失效。由於獲取access_token的api呼叫次數非常有限,頻繁重新整理access_token會導致api呼叫受限,影響自身業務,必須在自己的服務全域性快取access_token。

jsapi_ticket

是公眾號用於呼叫微信JS介面的臨時票據。正常情況下,jsapi_ticket的有效期為7200秒,透過access_token來獲取。由於獲取jsapi_ticket的api呼叫次數非常有限,頻繁重新整理jsapi_ticket會導致api呼叫受限,影響自身業務,必須在自己的服務全域性jsapi_ticket。

如上描述,我們知道,獲取jsapi_ticket前,得先獲取access_token(進入高階介面的鑰匙)。

獲取access_token

微信公眾賬號可以使用AppID和AppSecret呼叫本介面來獲取access_token。

AppID和AppSecret可在開發模式中獲得(需要已經成為開發者,且帳號沒有異常狀態)。注意呼叫所有微信介面時均需使用https協議。

呼叫獲取access_token介面時,需要設定IP白名單(你的伺服器IP地址)

實戰篇:HTML5頁面透過抽獎領取微信卡券

實戰篇:HTML5頁面透過抽獎領取微信卡券

實戰篇:HTML5頁面透過抽獎領取微信卡券

實戰篇:HTML5頁面透過抽獎領取微信卡券

編寫獲取access_token模型程式碼

使用程式碼編輯器,如

Sublime Text

,在已經下載好的ThinkPHP5原始碼檔案路徑application/index/model 下,新建Access_token獲取模型檔案,取名Access_token。php

由於每天獲取access_token的次數有限,所以我們呼叫該介面時,需要把access_token快取起來,我們利用ThinkPHP5框架自帶的快取功能,也可以使用資料庫把access_token存起來。

Access_token.php 模型程式碼如下

<?php

namespace app\index\model;

use think\Cache;

use think\Model;

//////////////////////

// Access_token獲取模型 //

//////////////////////

class Access_token extends Model

{

function obtain()

{

$options = [

// 快取型別為File

‘type’ => ‘File’,

// 快取有效期為7200

‘expire’ => 7200,

// 指定快取目錄

‘path’ => APP_PATH 。 ‘runtime/cache/’,

];

// 快取初始化

// 不進行快取初始化的話,預設使用配置檔案中的快取配置

cache($options);

// ps 首次使用先快取一個值

$access_token=cache(‘access_token’);

if(!empty($access_token))

{

return $access_token;

}

else

{

// 你的公眾號appid,自填

$appid = “”;

// 你的公眾號appsecret,自填

$appsecret = “”;

// Access Token的介面如下

$url = “https://api。weixin。qq。com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret”;

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$output = curl_exec($ch);

curl_close($ch);

$jsoninfo = json_decode($output, true);

$value = $jsoninfo[“access_token”];

// 設定快取資料

cache(‘access_token’, $value, 7200);

// 獲取快取資料

$access_token=cache(‘access_token’);

// 獲取Access token

return $access_token;

}

}

}

由於是model,ThinkPHP5不能直接訪問,我們為了測試是否請求成功,可以在檔案路徑application/index/controller/index編寫訪問access_token模型,輸出access_token

編寫Index.php控制器程式碼

<?php

namespace app\index\controller;

use think\Db;

use app\index\model\Access_token;

//入口檔案

class Index

{

public function index()

{

// 引用獲取access_token模型

$access_token_model=new Access_token;

$access_token=$access_token_model->obtain();

echo $access_token;

}

}

執行上述請求後,介面返回如下:

Ul24w0iK4_-g5te8UqjU9CKw0Cf-Iks7wr8YGjsV3cO2wIJhZlwMLs8rtBiB-cJ3MdTeSgkYMbjtrfaDmUTsn2rEjldKd59HOdftaPxDTPmCj3uJBXGjNz9P6LkMsl384G6HSEh-uLgixB8gmgOveA

輸出該字串即是access_token值

由於我們的access_token模型是直接輸出access_token,如果程式碼錯誤或請求錯誤,無法知道

錯誤時微信會返回錯誤碼等資訊,JSON資料包示例如下(該示例為AppID無效錯誤):

{“errcode”:40013,“errmsg”:“invalid appid”}

可以根據返回碼進行修改,如果需要測試是否請求成功,我們可以在access_token模型程式碼中,在獲取到$jsoninfo下插入

var_dump($jsoninfo); die();

儲存執行

執行上述請求後,介面返回如下:

{

“access_token”: “Ul24w0iK41212e8UqjU9CKw0Cf-Iks7wr8YGjsV3cO2wIJhZlwMLs8rtBiB-cJ3MdTeSgkYMbjtrfaDmUTsn2rEjldKd59HOdftaPxDTPmCj3uJBXGjNz9P6LkMsl384G6HSEh-uLgixB8gmgOveA”,

“expires_in”: 7200

}

開發微信公眾號需要請求諸多介面,我們可以寫一個Https請求模型,每次請求,直接呼叫該模型,傳入相應的url和data引數即可。在model下,新建https_request。php檔案

Https_request.php 模型

<?php

namespace app\index\model;

use think\Model;

/**

* https_request請求模型

*/

class Https_request extends Model

{

function obtain($url,$data = null)

{

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, $url);

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);

curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

if (!empty($data)){

curl_setopt($curl, CURLOPT_POST, 1);

curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

}

curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$output = curl_exec($curl);

curl_close($curl);

return $output;

}

}

編寫獲取Jsapi_ticket模型程式碼

使用程式碼編輯器,如

Sublime Text

,在已經下載好的ThinkPHP5原始碼檔案路徑application/index/model 下,新建Jsapi_ticket獲取模型檔案,取名Jsapi_ticket。php

同理,由於每天獲取Jsapi_ticket的次數有限,所以我們呼叫該介面時,需要把Jsapi_ticket快取起來,我們利用ThinkPHP5框架自帶的快取功能,也可以使用資料庫把Jsapi_ticket存起來。

Jsapi_ticket.php 模型程式碼如下

<?php

namespace app\index\model;

use think\Model;

use app\index\model\Access_token;

use app\index\model\Https_request;

//////////////////////

// Jsapi_ticket 獲取模型 JS API //

//////////////////////

class Jsapi_ticket extends Model

{

function obtain()

{

$options = [

// 快取型別為File

‘type’ => ‘File’,

// 快取有效期為7200

‘expire’ => 7200,

// 指定快取目錄

‘path’ => APP_PATH 。 ‘runtime/cache/’,

];

// 快取初始化

// 不進行快取初始化的話,預設使用配置檔案中的快取配置

cache($options);

// ps 首次使用先快取一個值

$jsapi_ticket=cache(‘jsapi_ticket’);

if(!empty($jsapi_ticket))

{

return $jsapi_ticket;

}

else

{

// 引用獲取access_token模型

$access_token_model=new Access_token;

$access_token=$access_token_model->obtain();

// 獲取jsapi_ticket介面url

$url = “https://api。weixin。qq。com/cgi-bin/ticket/getticket?access_token=$access_token&type=jsapi”;

// $url = “https://api。weixin。qq。com/cgi-bin/menu/create?access_token=”。$access_token;

$https_request=new Https_request;

$result =$https_request->obtain($url);

$jsoninfo = json_decode($result, true);

// 獲取Jsapi_ticket

$value = $jsoninfo[“ticket”];

// 設定快取資料

cache(‘jsapi_ticket’, $value, 7200);

// 獲取快取資料

$jsapi_ticket=cache(‘jsapi_ticket’);

// 返回Jsapi_ticket

return $jsapi_ticket;

}

}

}

同理,由於是model,ThinkPHP5不能直接訪問,我們為了測試是否請求成功,可以在檔案路徑application/index/controller/index修改訪問jsapi_ticket模型,輸出jsapi_ticket

修改Index.php控制器程式碼

<?php

namespace app\index\controller;

use think\Db;

use app\index\model\Access_token;

use app\index\model\Jsapi_ticket;

//入口檔案

class Index

{

public function index()

{

// 獲取jsapi_ticket

$jsapiTicket_model = new Jsapi_ticket;

$jsapi_ticket = $jsapiTicket_model->obtain();

echo $jsapi_ticket;

}

}

執行上述請求後,介面返回如下:

b135JkRXSbfPdHSM05e5u5sUoXNKd8-54O3MhKoyN5OfkWITDGgnr2sdJ0m9hgNYzWKVZvdVtaUgWvsdshFKA

輸出該字串即是jsapi_ticket 值

由於我們的jsapi_ticket 模型是直接輸出jsapi_ticket ,如果程式碼錯誤或請求錯誤,無法知道

錯誤時微信會返回錯誤碼等資訊

可以根據返回碼進行修改,如果需要測試是否請求成功,我們可以在jsapi_ticket 模型程式碼中,在獲取到$jsoninfo下插入

var_dump($jsoninfo); die();

儲存執行

執行上述請求後,介面返回如下:

{

“errcode”:0,

“errmsg”:“ok”,

“ticket”:“b135JkRXSbfPdHSM05e5u5sUoXNKd8-54O3MhKoyN5OfkWITDGgnr2sdJ0m9hgNYzWKVZvdVtaUgWvsdshFKA”,

“expires_in”:7200

}

上述資料中,ticket值就是jsapi_ticket。

獲得jsapi_ticket之後,就可以生成

JS-SDK許可權驗證的簽名

了。這樣子,我們可以取得高階介面的入門鑰匙。

步驟四:獲取JS SDK簽名

JS SDK簽名生成規則如下:參與簽名的欄位包括noncestr(隨機字串), 有效的jsapi_ticket, timestamp(時間戳), url(當前網頁的URL,不包含#及其後面部分)。對所有待簽名引數按照欄位名的ASCII 碼從小到大排序(字典序)後,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字串string1。這裡需要注意的是所有引數名均為小寫字元。對string1作sha1加密,欄位名和欄位值都採用原始值,不進行URL 轉義。

先對所有待簽名引數按照欄位名的ASCII 碼從小到大排序(字典序)後,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字串string1:

jsapi_ticket=sdfbyVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wKKKJHkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=

http://

mp。weixin。qq。com

?params=value

再對對string1進行sha1簽名,得到signature:

1f6de63fce7ff9a083d5c99e95123ceb56c24ed

編寫獲取JS SDK簽名模型 Getsignpackage.php

在application/index/model 下,新建JS SDK獲取模型檔案,取名Getsignpackage。php

同理,由於每天獲取Getsignpackage的次數有限,所以我們呼叫該介面時,需要把Getsignpackage快取起來,我們利用ThinkPHP5框架自帶的快取功能,也可以使用資料庫把Getsignpackage存起來。

Getsignpackage.php 模型程式碼如下

<?php

namespace app\index\model;

use think\Model;

use app\index\model\Access_token;

use app\index\model\Https_request;

use app\index\model\Jsapi_ticket;

//////////////////////

// GetSignPackage簽名包獲取模型 //

//////////////////////

class Getsignpackage extends Model

{

function obtain()

{

// 獲取jsapi_ticket

$jsapiTicket_model = new Jsapi_ticket;

$jsapi_ticket = $jsapiTicket_model->obtain();

$protocol = (!empty($_SERVER[‘HTTPS’]) && $_SERVER[‘HTTPS’] !== ‘off’ || $_SERVER[‘SERVER_PORT’] == 443) ? “https://” : “http://”;

$url = “$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]”;

// 生成時間

$timestamp = time();

//生成長度16的隨機字串

$chars = “abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789”;

$nonceStr = “”;

for ($i = 0; $i < 16; $i++)

{

$nonceStr 。= substr($chars, mt_rand(0, strlen($chars) - 1), 1);

}

// 拼接字串

$string = “jsapi_ticket=$jsapi_ticket&noncestr=$nonceStr×tamp=$timestamp&url=$url”;

$signature = sha1($string);

$signPackage = array(

“appId” => ‘你的公眾號appid’,

“nonceStr” => $nonceStr,

“timestamp” => $timestamp,

“url” => $url,

“signature” => $signature,

“rawString” => $string

);

// var_dump($signPackage); die();

return $signPackage;

}

}

同理,由於是model,ThinkPHP5不能直接訪問,我們為了測試是否請求成功,可以在檔案路徑application/index/controller/index修改訪問Index。php控制器,輸出

JS SDK簽名signpackage

修改Index.php控制器程式碼

<?php

namespace app\index\controller;

use think\Db;

use app\index\model\Access_token;

use app\index\model\Jsapi_ticket;

//入口檔案

class Index

{

public function index()

{

// 獲取JS SDK簽名

$Getsignpackage_model=new Getsignpackage;

$signPackage =$Getsignpackage_model->obtain();

echo $signPackage ;

}

}

執行上述請求後,介面返回如下:

nsdfnj43490f9a083d5c5adasdm434lmks

輸出該字串即是signPackage 值

步驟五:獲取卡券Ticket和卡券簽名

卡券ticket(是呼叫卡券臨時票據),jsapi_ticket(呼叫微信JS介面的臨時票據)兩個值不同的,大家不要混淆。

卡券 api_ticket 是用於呼叫卡券相關介面的臨時票據,有效期為 7200 秒,透過 access_token 來獲取。由於獲取卡券 api_ticket 的 api 呼叫次數有限,頻繁重新整理卡券 api_ticket 會影響自身業務,開發者必須在自己的服務全域性快取卡券 api_ticket 。

卡券的簽名步驟說明如下

步驟一:將 api_ticket(特別說明:api_ticket 相較 appsecret 安全性更高,同時相容老版本文件中使用的 appsecret 作為簽名憑證。)、timestamp、card_id、code、openid、nonce_str的value值進行字串的字典序排序。

步驟二:將所有引數字串拼接成一個字串進行sha1加密,得到

微信卡券簽名signature

application/index/model 下,新建Card_api_ticket獲取模型檔案,取名Card_api_ticket。php

同理,由於每天獲取Card_ticket的次數有限,所以我們呼叫該介面時,需要把Card_ticket快取起來,我們利用ThinkPHP5框架自帶的快取功能,也可以使用資料庫把Card_ticket存起來。

編寫獲取卡券ticket和卡券簽名模型 Card_api_ticket.php 程式碼如下

<?php

namespace app\index\model;

use think\Model;

use app\index\model\Access_token;

use app\index\model\Https_request;

use app\index\model\Jsapi_ticket;

//////////////////////

// 微信卡券 Card_api_ticket 獲取模型 //

//////////////////////

class Card_api_ticket extends Model

{

function obtain()

{

$options = [

// 快取型別為File

‘type’ => ‘File’,

// 快取有效期為7200

‘expire’ => 7200,

// 指定快取目錄

‘path’ => APP_PATH 。 ‘runtime/cache/’,

];

// 快取初始化

cache($options);

$card_jsapi_ticket=cache(‘card_jsapi_ticket’);

if(!empty($card_jsapi_ticket))

{

return $card_jsapi_ticket;

}

else

{

$access_token_model=new Access_token;

$access_token=$access_token_model->obtain();

$url = “https://api。weixin。qq。com/cgi-bin/ticket/getticket?type=wx_card&access_token=$access_token”;

$https_request=new Https_request;

$result =$https_request->obtain($url);

$jsoninfo = json_decode($result, true);

// 獲取card_Jsapi_ticket

$value = $jsoninfo[“ticket”];

// 設定快取資料

cache(‘card_jsapi_ticket’, $value, 7200);

// 獲取快取資料

$card_jsapi_ticket=cache(‘card_jsapi_ticket’);

// 返回carf_Jsapi_ticket

return $card_jsapi_ticket;

}

}

// 獲取卡券簽名

function get_cardsign($bizObj)

{

//字典序排序

asort($bizObj);

//URL鍵值對拼成字串

$buff = “”;

foreach ($bizObj as $k => $v){

$buff 。= $v;

}

//sha1簽名

return sha1($buff);

}

}

同理,由於是model,ThinkPHP5不能直接訪問,我們為了測試是否請求成功,可以在檔案路徑application/index/controller/index修改訪問Index。php控制器,輸出

卡券ticket

修改Index.php控制器程式碼

<?php

namespace app\index\controller;

use think\Db;

use app\index\model\Access_token;

use app\index\model\Jsapi_ticket;

use app\index\model\Card_api_ticket;

//入口檔案

class Index

{

public function index()

{

// 卡券Card_api_ticket

$Card_api_ticket_model=new Card_api_ticket;

$Card_api_ticket =$Card_api_ticket_model->obtain();

echo $Card_api_ticket;

}

}

執行上述請求後,介面返回如下:

bxLdikRTPdHSM05e5nalsdkasdnllmalsdXNKd8-41ZO3MhKo6OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA

輸出該字串即是卡券Ticket值

步驟六:在微信公眾平臺建立微信卡券

建立微信卡券有兩種方式

1。在微信公眾平臺建立微信卡券,簡單粗暴

2。呼叫建卡券介面是微信卡券的基礎介面,用於建立一類新的卡券,獲取card_id,建立成功並透過稽核後,商家可以透過文件提供的其他介面將卡券下發給使用者,每次成功領取,庫存數量相應扣除。

下面我們採用第一種方式建立微信卡券,登入微信公眾平臺,點選卡券功能->優惠券->新建優惠券,根據提示填入卡券相關資訊,稽核透過即可。

實戰篇:HTML5頁面透過抽獎領取微信卡券

實戰篇:HTML5頁面透過抽獎領取微信卡券

建立成功後,在卡券詳情中,複製卡券id,放在控制器index。php //card id 中

實戰篇:HTML5頁面透過抽獎領取微信卡券

實戰篇:HTML5頁面透過抽獎領取微信卡券

步驟七:HTML5抽獎頁面訪問控制器 Index.php

根據上述步驟,我們已經獲取到access_token,jsapi_ticket,JS SDK簽名,卡券ticket及簽名

下面,我們可以編寫H5抽獎頁面訪問控制器Index。php

在application/index/controller/下,開啟入口Index。php控制檔案

編寫HTML5抽獎頁面訪問控制器 Index.php 程式碼如下

<?php

namespace app\index\controller;

use think\Controller;

use think\Db;

use app\index\model\Getsignpackage;

use app\index\model\Card_api_ticket;

///////////

// HTML5抽獎頁面訪問控制器 //

///////////

class Luckdraw extends Controller

{

public function index()

{

$Getsignpackage_model=new Getsignpackage;

// 獲取js sdk簽名

$signPackage =$Getsignpackage_model->obtain();

$Card_api_ticket_model=new Card_api_ticket;

// 卡券Card_api_ticket

$Card_api_ticket =$Card_api_ticket_model->obtain();

// 複製卡券id

$card_id = “”;

// 卡券Card_api_ticket

$obj[‘api_ticket’] = $Card_api_ticket;

// 字串時間戳

$obj[‘timestamp’] = strval(time());

//生成長度16的隨機字串

$chars = “abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789”;

$nonceStr = “”;

for ($i = 0; $i < 16; $i++)

{

$nonceStr 。= substr($chars, mt_rand(0, strlen($chars) - 1), 1);

}

$obj[‘nonce_str’] = $nonceStr;

$obj[‘card_id’] = $card_id;

// 獲取卡券簽名

$signature =$Card_api_ticket_model->get_cardsign($obj);

//傳入三個引數

$this->assign(‘obj’,$obj);

$this->assign(‘signPackage’,$signPackage);

$this->assign(‘signature’,$signature);

//HTML5抽獎頁面

return $this->fetch(‘index’);

}

}

步驟八:HTML5抽獎頁面 Index.html

application/index/view/index

下,新建H5抽獎頁面 Index。html 檔案

抽獎頁面多種多樣,本文使用移動端動效庫下的遊戲寶箱遊戲寶箱,下載原始碼即可。

部分HTML5抽獎頁面訪問控制器 Index.html 程式碼如下

<!DOCTYPE HTML>

<!—— ——>

HTML5頁面抽獎領取微信卡券

高校喵給你發了一個寶箱

恭喜你!抽中旅遊媒婆發的免費門票寶箱

(提取後可在廣西景點內中使用)

未抽中旅遊媒婆的免費門票

(提取後可在廣西景點內中使用)

<!—— 抽中 ——>

<!——

實戰篇:HTML5頁面透過抽獎領取微信卡券
x 500 ——>

你太幸運了!!

<!—— 批次新增卡券介面 ——>

<!—— ——>

<!—— 未抽中 ——>

你來晚啦,下次早點吧!

你來晚啦,下次早點吧!