微信模板消息无实时回调机制,需主动调用getTemplateMsgEvent接口轮询拉取发送结果;小程序适用,须用小程序access_token,返回含msgid、status等字段的JSON数组,需本地存储msgid关联状态并注意幂等处理。
微信模板消息发送后,不会主动回调你的服务器——这是最常被误解的一点。所谓“模板消息回调”,实际并不存在官方支持的实时回调机制;你看到的“发送结果通知”,其实是通过 getTemplateMsgEvent 接口(即「获取模板消息发送结果」)**主动轮询拉取**的,且仅限于开通了「消息推送」权限的小程序或部分认证服务号(公众号模板消息已停用)。PHP 侧要“接收处理”,核心是调用该接口 + 解析返回的 JSON 事件。
微信模板消息(尤其是公众号)自 2025 年起已全面下线「发送成功/失败实时回调」能力。小程序虽保留 getTemplateMsgEvent,但它是 HTTP 拉取接口,不是服务端 POST 回调。如果你在文档里看到“回调 URL”配置项,那大概率混淆了「订阅消息」或「支付结果通知」等其他能力。
send_template_message 接口调用后只返回 msgid,无后续事件推送getTemplateMsgEvent 拉取发送状态,但需满足:scope = subscribe_msg 权限、调用频率 ≤ 2000 次/天、每次最多拉取 10 条必须使用小程序 access_token 调用 https://api.weixin.qq.com/wxa/gettemplatetmsgevent?access_token=ACCESS_TOKEN,返回的是 JSON 数组,每条含 msgid、status(success / fail)、fail_reason(仅失败时有)等字段。
$access_token = 'your_access_token_here';
$url = "https://api.weixin.qq.com/wxa/gettemplatetmsgevent?access_token={$access_token}";
$response = file_get_contents($url);
$data = json_decode($response, true);
if (isset($data['errcode']) && $data['errcode'] !== 0) {
error_log('getTemplateMsgEvent failed: ' . $data['errmsg']);
} else {
foreach ($data['list'] as $event) {
if ($event['status'] === 'fail') {
error_log("Template send failed for msgid {$event['msgid'
]}: {$event['fail_reason']}");
}
}
}
access_token 必须是小程序的,公众号的无效;且需提前在「小程序管理后台 → 接口权限」中开通 获取模板消息发送结果
errcode: 45009)靠 msgid 字段双向绑定。调用 sendUniformMessage(小程序推荐)或旧版 sendTemplateMessage 时,响应体中的 msgid 是唯一数字 ID;拉取到的 getTemplateMsgEvent 返回数据里也有同名字段,二者严格一致。
msgid + 用户 openid + 模板ID + 发送时间msgid 查询本地记录,更新状态字段(如 status 改为 'sent' 或 'failed')"user reject"(用户拒收)、"invalid template_id" 等,可用于运营分析或触发重发逻辑真正容易被忽略的是:这个拉取机制没有事务保证,也没有幂等标识。如果 PHP 脚本拉取后崩溃,或网络超时未收到响应,那批事件就丢了——下次再拉会跳过它们。所以关键操作(如更新数据库状态)必须放在解析成功且确认写入后再执行,不能依赖“拉到了就认为处理完了”。