这里的“模板”不是指 PHP 的模板引擎(如 Smarty、Twig),而是指微信官方提供的一种标准化的消息格式,用于向用户发送重要的、通知类的内容。

微信公众平台php 的模板
(图片来源网络,侵删)

什么是微信模板消息?

微信模板消息是微信公众平台提供给开发者的一种消息推送能力,它允许开发者按照固定的模板格式,向关注公众号的用户发送服务通知。

核心特点:

  1. 格式固定由微信预先定义好的模板决定,开发者只能填充模板中的变量(如 {name}, {amount}),而不能随意修改整体结构和样式。
  2. 用户授权:用户必须在与公众号的交互中(点击菜单、提交表单等)同意接收服务通知,才能被发送模板消息。
  3. 触发式:通常用于通知用户某个事件的结果,
    • 订单支付成功
    • 快递发货通知
    • 预约成功提醒
    • 账户余额变动
  4. 非营销性:微信严格禁止使用模板消息进行营销推广,如发送广告、优惠券等。

PHP 开发模板消息的完整流程

使用 PHP 发送模板消息主要分为以下几个步骤:

步骤 1:获取模板 ID

  1. 登录 微信公众平台
  2. 进入 设置与开发 -> 模板消息
  3. 在模板库中,根据你的业务场景(如“服务提醒”、“物流通知”等)选择合适的模板。
  4. 点击“添加”,将模板添加到你的账号中,添加成功后,你会得到一个唯一的 模板 IDOPENTM2005151234567890),这个 ID 在后续的 API 调试和代码中至关重要。

步骤 2:获取用户的 OpenID

模板消息是精准推送给某个用户的,所以你必须知道这个用户的 OpenID,OpenID 是用户在当前公众号下的唯一标识符。

微信公众平台php 的模板
(图片来源网络,侵删)
  • 如何获取 OpenID?
    • 用户关注公众号时,可以通过 关注事件推送 获取。
    • 用户在网页授权后,可以获取到 openid(详见微信网页授权文档)。
    • 用户在公众号内进行交互时,可以通过事件推送或客服消息获取。

重要提示:在发送模板消息前,必须确保用户已经同意接收,通常的做法是在需要发送通知的场景(如下单成功后),让用户点击一个“同意接收服务通知”的按钮,此时后台记录下用户的 openid 和授权状态。

步骤 3:后端 PHP 代码实现

这是核心部分,我们使用 PHP 的 cURL 函数来调用微信的 API。

准备工作:获取 Access Token

调用任何微信 API 都需要一个有效的 access_token,它是一个全局唯一的票据,有效期 2 小时。

微信公众平台php 的模板
(图片来源网络,侵删)
  • 获取方式:通过 GET 请求以下地址: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=YOUR_APPID&secret=YOUR_APPSECRET

  • PHP 封装获取 Token 的函数:

<?php
// 你的公众号配置
define('APPID', '你的AppID');
define('APPSECRET', '你的AppSecret');
/**
 * 获取 access_token
 * @return string|false 成功返回token,失败返回false
 */
function getAccessToken() {
    $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . APPID . "&secret=" . APPSECRET;
    // 使用 cURL 请求
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过SSL证书验证
    $output = curl_exec($ch);
    curl_close($ch);
    $json = json_decode($output, true);
    if (isset($json['access_token'])) {
        return $json['access_token'];
    } else {
        // 可以在这里记录错误日志
        error_log("获取AccessToken失败: " . $output);
        return false;
    }
}
?>

发送模板消息的核心函数

现在我们编写一个函数来发送模板消息。

<?php
// ... (包含上面的 getAccessToken 函数) ...
/**
 * 发送模板消息
 * @param string $openid 用户的openid
 * @param string $templateId 模板ID
 * @param array $data 模板数据,格式为 ['key' => 'value']
 * @param string $url 点击模板消息后跳转的URL (可选)
 * @param string $topcolor 顶部颜色 (可选)
 * @return array|false 返回微信API的响应结果,失败返回false
 */
function sendTemplateMessage($openid, $templateId, $data, $url = '', $topcolor = '#FF0000') {
    $accessToken = getAccessToken();
    if (!$accessToken) {
        return false;
    }
    $apiUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $accessToken;
    // 构建请求体
    $requestBody = [
        'touser' => $openid,
        'template_id' => $templateId,
        'url' => $url, // 点击后跳转的链接
        'topcolor' => $topcolor,
        'data' => $data
    ];
    // 将数组转换为JSON字符串
    $jsonBody = json_encode($requestBody, JSON_UNESCAPED_UNICODE); // JSON_UNESCAPED_UNICODE保证中文正常显示
    // 使用 cURL 发送POST请求
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $apiUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonBody);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Content-Length: ' . strlen($jsonBody)
    ]);
    $output = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    // 解析响应
    $response = json_decode($output, true);
    // 检查HTTP状态码和微信返回的errcode
    if ($httpCode == 200 && isset($response['errcode']) && $response['errcode'] == 0) {
        return $response;
    } else {
        // 记录详细错误信息
        error_log("发送模板消息失败: HTTP_CODE={$httpCode}, RESPONSE={$output}");
        return false;
    }
}
?>

步骤 4:调用发送函数

假设你的订单处理逻辑如下,你可以在订单创建成功后调用发送函数。

<?php
// ... (包含上面的所有函数) ...
// --- 模拟业务场景 ---
$userId = 'o6_bmjrPTlm6_2sgVt7hMZopifF0'; // 用户的openid
$orderNo = '20251027123456';
$totalAmount = 99.50;
$templateId = 'OPENTM2005151234567890'; // 你自己的模板ID
// 1. 根据你的模板,定义要填充的数据
// 假设你的模板字段是:{{first}} (订单号)、{{keyword1}} (金额)、{{keyword2}} (状态)、{{remark}} (备注)
$templateData = [
    'first' => ['value' => '您的订单已支付成功', 'color' => '#173177'],
    'keyword1' => ['value' => $orderNo, 'color' => '#173177'],
    'keyword2' => ['value' => '¥' . $totalAmount, 'color' => '#173177'],
    'remark' => ['value' => '感谢您的惠顾,商品将尽快为您发出。', 'color' => '#173177']
];
// 2. 定义点击消息后跳转的URL
$jumpUrl = 'https://www.yourwebsite.com/order/detail?no=' . $orderNo;
// 3. 调用发送函数
$result = sendTemplateMessage($userId, $templateId, $templateData, $jumpUrl);
// 4. 处理结果
if ($result) {
    echo "模板消息发送成功!";
    // 可以在这里更新订单状态,记录发送日志等
} else {
    echo "模板消息发送失败!";
}
?>

模板数据格式详解

在调用 sendTemplateMessage 函数时,$data 参数的格式是固定的。

格式:

{
  "data": {
    "字段名": {
      "value": "显示的文本内容",
      "color": "文本颜色 (可选,如 #FF0000)"
    },
    "字段名": {
      "value": "显示的文本内容",
      "color": "文本颜色"
    }
  }
}

如何确定“字段名”?

这个“字段名”不是你在模板库中看到的中文名称(如“订单金额”),而是微信后台模板中定义的 key

  1. 在微信公众平台,找到你添加的模板。
  2. 点击模板右侧的“详情”。
  3. 你会看到模板的结构,每个可编辑的字段都有一个 key,通常是 keyword1, keyword2, first, remark 等。

firstremark 是特殊字段:

  • first:模板消息的开头部分。
  • remark:模板消息的底部备注部分。

颜色格式: 必须是十六进制颜色代码,如 #FF0000(红色)、#173177(深蓝色)。


常见错误排查

发送模板消息失败时,微信 API 会返回一个 JSON 对象,包含 errcodeerrmsg

常见错误码及解决方案:

错误码 错误信息 原因及解决方案
40003 invalid openid touser 字段的 OpenID 不正确或为空,请检查 OpenID 是否有效。
40037 invalid template id template_id 不正确或模板已被公众号删除,请检查模板 ID。
43101 user refuse to receive the message 用户拒绝接收,这是最常见的问题,用户之前没有授权,或在设置中关闭了接收权限,需要引导用户重新授权。
47003 template message data incomplete data 字段缺少必要的 key,或者 value 为空,请严格按照你模板的 key 来构建数据数组。
41030 invalid pagepath url 字段中的页面路径不正确,请确保跳转链接是合法的 URL。
45009 api frequency limit exceeded API 调用频率超限,模板消息的发送有频率限制,通常是每个用户每月最多发送 4 条(具体以官方文档为准),请勿频繁发送。
0 ok 发送成功。

调试技巧:

  1. 打印日志:在 sendTemplateMessage 函数中,打印出 $jsonBody(发送给微信的数据)和 $output(微信的响应),可以快速定位是数据格式问题还是 API 问题。
  2. 使用在线工具:可以使用 Postman 等工具,手动构造 JSON 请求体并发送到微信 API,来验证你的数据和逻辑是否正确。

重要注意事项

  1. 模板消息的替代方案:微信官方已经逐步弱化模板消息,并推出了更强大的 “统一服务消息”“订阅消息”

    • 订阅消息:是目前推荐的替代方案,它允许用户主动订阅,开发者可以在用户授权后,在特定场景下(如订单状态变更)向用户推送一次性的通知,权限更灵活,用户体验更好。
    • 如果是新项目,强烈建议优先研究和使用 订阅消息
  2. 测试环境:在公众号设置中,可以配置一个测试微信号(微信号或 OpenID),在开发阶段,将模板消息发送给这个测试号,可以避免对真实用户造成打扰,并且不会受到每月发送次数的限制。

  3. 内容合规:发送的内容必须符合微信平台规范,不能包含敏感词汇或违法信息。

希望这份详细的指南能帮助你完全理解和使用 PHP 在微信公众平台开发中发送模板消息!