在ThinkPHP中实现微信公众号自定义菜单下发卡券消息卡片功能需要以下步骤:
-
配置微信公众号的接口信息,包括token、AppID、AppSecret等。
-
在公众号后台创建自定义菜单,并设置好对应的卡券消息。
-
在ThinkPHP中编写对应的控制器和方法,用于接收微信服务器发送的消息事件。
以下是示例代码:
<?php
namespace appwechatcontroller;
use thinkController;
use thinkRequest;
class WechatController extends Controller
{
// 处理微信服务器发送的消息事件
public function index(Request $request)
{
// 验证消息的真实性
$token = "your_token";
$timestamp = $request->param("timestamp");
$nonce = $request->param("nonce");
$signature = $request->param("signature");
$echostr = $request->param("echostr");
$tmpArr = [$token, $timestamp, $nonce];
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if ($tmpStr == $signature) {
// 验证成功,返回echostr
if ($echostr) {
echo $echostr;
exit;
}
// 处理消息事件
$postXml = file_get_contents("php://input");
if (!empty($postXml)) {
$postObj = simplexml_load_string($postXml, "SimpleXMLElement", LIBXML_NOCDATA);
$msgType = $postObj->MsgType;
switch ($msgType) {
case "event":
$event = $postObj->Event;
switch ($event) {
case "CLICK":
$eventKey = $postObj->EventKey;
if ($eventKey == "your_card_event_key") {
$cardId = "your_card_id";
$cardExt = [
"code" => "your_code",
"openid" => $postObj->FromUserName,
"timestamp" => time(),
"nonce_str" => uniqid()
];
$cardSign = $this->getCardSign($cardExt, "your_api_ticket");
$cardExt["signature"] = $cardSign;
$cardExt = json_encode($cardExt);
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" . $this->getAccessToken();
$data = [
"touser" => $postObj->FromUserName,
"msgtype" => "wxcard",
"wxcard" => [
"card_id" => $cardId,
"card_ext" => $cardExt
]
];
$this->httpPost($url, $data);
}
break;
}
break;
}
}
}
}
// 获取access_token
private function getAccessToken()
{
$accessToken = cache("access_token");
if (!$accessToken) {
$appId = "your_app_id";
$appSecret = "your_app_secret";
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appId . "&secret=" . $appSecret;
$result = $this->httpGet($url);
$accessToken = $result["access_token"];
cache("access_token", $accessToken, $result["expires_in"] - 100);
}
return $accessToken;
}
// 获取卡券签名
private function getCardSign($cardExt, $apiTicket)
{
ksort($cardExt);
$params = [];
foreach ($cardExt as $key => $value) {
$params[] = $key . "=" . $value;
}
$params[] = "api_ticket=" . $apiTicket;
$paramsStr = implode("&", $params);
return sha1($paramsStr);
}
// 发送POST请求
private function httpPost($url, $data)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
// 发送GET请求
private function httpGet($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result, true);
}
}
在上面的代码中,我们实现了处理微信服务器发送的消息事件、获取access_token、获取卡券签名和发送POST请求等功能。在处理CLICK事件时,我们判断EventKey是否等于我们设置的卡券事件Key,如果是,则获取卡券ID和卡券Ext信息,然后生成卡券签名和卡券Ext字符串,并将卡券消息发送给用户。