返回顶部
首页 > 问答 > 后端 > 如何在ThinkPHP中实现微信公众号自定义菜单下发卡券消息卡片功能?
0
待解决

如何在ThinkPHP中实现微信公众号自定义菜单下发卡券消息卡片功能?

  • 匿名发布
  • 2023-05-09
  • 发布在 问答/后端
11

其他回答1

邪恶KO骑士

2023-06-14

在ThinkPHP中实现微信公众号自定义菜单下发卡券消息卡片功能需要以下步骤:

  1. 配置微信公众号的接口信息,包括token、AppID、AppSecret等。

  2. 在公众号后台创建自定义菜单,并设置好对应的卡券消息。

  3. 在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字符串,并将卡券消息发送给用户。

相关文章
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作