评论

出现subscribeMessage.send:fail missing wxCloudApiToken的解决办法

解决使用subscribeMessage.send 发送订阅消息时,遇到 errCode: -501007, errMsg: fail missing wxCloudApiToken的错误

1.问题背景

使用腾讯云模板的微信支付模板处理支付,在回调函数中发送订阅消息会出现errCode: -501007  |  errMsg: subscribeMessage.send:fail missing wxCloudApiToken的错误,但是手动触发订阅函数却可以发送消息。

2.问题分析

根本原因

微信支付/退款回调是系统触发,不是用户通过小程序调用:

用户操作 → 小程序 → 云函数 → cloud.openapi.*  有用户上下文

微信系统 → 直接回调云函数 → cloud.openapi.*     无用户上下文

查看 cloud.getWXContext() 返回值:

// 手动调用(成功)
{
  OPENID: "12345...",
  APPID: "wx1234...",
  ENV: "cloudbase-...",
  SOURCE: "wx_client"
}
// 支付回调(失败)
{
  APPID: "wx1234...",
  ENV: "cloudbase-...",
  SOURCE: ",scf"  // ← 注意这里
  // 缺少 OPENID!
}

结论:cloud.openapi.* 需要 wxCloudApiToken,Token 来自用户会话上下文

回调场景缺少用户会话 → 无法获取 Token


3.解决办法

使用微信服务端 HTTP API 替代 cloud.openapi.*

1. 创建 access_token 管理工具

// utils/accessToken.js
const { cloud, db } = require("./database");

async function getAccessToken() {
  // 1. 检查缓存
  const cached = await getCachedAccessToken();
  if (cached) return cached;
  
  // 2. 从微信服务器获取
  //const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`;
  //使用以上网址获取access_token,appid为微信小程序ID,secret为小程序密钥
  const { access_token } = await fetchAccessToken();
  
  // 3. 缓存7200秒
  await saveAccessToken(access_token);
  return access_token;
}

2. 修改订阅消息发送方法

// utils/subscribeMessage.js
async function sendSubscribeMessageViaHTTP(params) {
  const accessToken = await getAccessToken();
  const url = `https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=${accessToken}`;
  
  const axios = require("axios");
   //参数与subscribeMessage.send一致
  const response = await axios.post(url, params);
  
  return response.data;
}

3. 获取用户 openid

方法一:从回调参数中获取(支付回调)

// 支付回调数据
resource: {
  payer: { openid: '1234......' }
}
const payerOpenid = event.resource?.payer?.openid;

方法二:从数据库查询(退款回调)

// 订单 → userId → openid
const userResult = await db.collection("users")
  .doc(order.userId)
  .get();
const openid = userResult.data.openid;



这样就可以实现回调函数中发送订阅消息,希望能帮到大家

最后一次编辑于  2025-12-16  
点赞 1
收藏
评论

1 个评论

登录 后发表内容