Skip to content

小程序码与二维码实践指南

官方文档(服务端):
获取小程序码(数量有限):wxa/getwxacode
获取小程序码(无限量):wxa/getwxacodeunlimit
老接口(不推荐):wxaapp/createwxaqrcode
能力总览:https://developers.weixin.qq.com/miniprogram/dev/framework/

业务常见需求:生成能直接跳转小程序页面的“小程序码”(圆形码/方形码),并承载参数(如活动 ID、邀请人 ID 等)。这需要在后端调用微信开放接口生成图片,再下发给前端。

🎯 文章目标

  • 了解小程序码类型与差异
  • 在后端生成小程序码并缓存
  • 设计安全与风控策略
  • 与普通二维码的取舍与配合

🧭 小程序码类型概览

  • getwxacode:有限量接口,需指定 path(页面路径),适合固定页面
  • getwxacodeunlimit:不限量接口,使用 scene(自定义参数,推荐短参数 + 后端映射)
  • createwxaqrcode:旧接口,功能受限,不推荐

注意:

  • scene 参数长度有限(官方限制较小,常见约 32 可见字符),推荐将业务长参数做后端映射(如短码/ID)
  • page 需为已发布的小程序页面路径(如 pages/index/index),不要带问号
  • 坐标与颜色可自定义,is_hyaline 可输出透明底 PNG

🛠️ 后端示例(Node.js)

以“无限量小程序码”为例,后端生成并落盘/上传对象存储:

js
import fs from 'node:fs'
import fetch from 'node-fetch'

async function getAccessToken(appid, secret) {
  const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=\${appid}&secret=\${secret}`
  const res = await fetch(url)
  const data = await res.json()
  if (!data.access_token) throw new Error(`get token failed: \${JSON.stringify(data)}`)
  return data.access_token
}

async function genMiniCode({ token, scene, page, width = 430, isHyaline = false }) {
  const url = `https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=\${token}`
  const payload = {
    scene,           // 建议短参数,如 rid=123
    page,            // 如 'pages/index/index'
    width,           // 280~1280
    is_hyaline: isHyaline,
    auto_color: false,
    line_color: { r: 0, g: 0, b: 0 }
  }
  const res = await fetch(url, { method: 'POST', body: JSON.stringify(payload) })
  const buf = Buffer.from(await res.arrayBuffer())

  // 若返回 JSON,说明失败(如 token 过期)
  const text = buf.toString('utf8')
  if (text.startsWith('{')) {
    throw new Error(`gen code failed: \${text}`)
  }
  return buf // PNG
}

// 用法示例
async function main() {
  const appid = process.env.WX_APPID
  const secret = process.env.WX_SECRET
  const token = await getAccessToken(appid, secret)

  const png = await genMiniCode({
    token,
    scene: 'rid=123',          // 后端映射:rid -> 业务记录
    page: 'pages/index/index', // 需为已发布页面
    width: 512,
    isHyaline: true
  })
  fs.writeFileSync('./mini-123.png', png)
}

main().catch(console.error)

落盘后建议上传到对象存储(COS/OSS/S3)+ CDN,前端通过 HTTPS 链接展示/保存。

🏗️ 工程与治理

  • 缓存策略:按 scene + page + 样式 做 Key 缓存;命中直接返回 CDN 链接,降低微信接口调用频率
  • Token 管理:access_token 有效期短(约 2h),用集中缓存,过期自动刷新
  • 安全与风控:
    • scene 仅允许白名单 key(如 rid、uid、from)
    • 参数映射到后端记录,前端禁止直接透传敏感信息
    • 高频生成限流 + 审计日志
  • 文件治理:定期清理低访问图片;或设置对象存储生命周期策略

🧪 常见问题

  • “invalid page”/空白码:page 未发布或路径不正确;不要包含 ? 和参数
  • “invalid scene”/参数丢失:scene 超长/包含非法字符,做编码或短码映射
  • 黑底/色偏:检查 is_hyaline 与颜色配置;透明底在深色背景上会变暗

🔄 与普通二维码(第19篇)配合

  • 普通二维码可跳转 H5/下载页;小程序码可直达小程序页面
  • 二者可同时生成:当用户未安装/不在微信环境时,展示普通二维码;在微信场景内优先小程序码

✅ 适用场景

  • 营销分享、邀请关系、活动页直达
  • 线下海报、物料码、渠道追踪

🔗 参考

📊 总结

小程序码需由后端调用官方接口生成,前端只负责展示与保存。通过“短参映射 + CDN 缓存 + 限流审计”构建稳定可扩展的发码体系。