用uQRCode插件生成核销二维码最稳,因其兼容多端、自动处理像素比与离屏渲染;而uni.createCanvasContext易出错,如canvas为空、H5不支持、安卓模糊等。

直接生成带核销参数的二维码,用 uQRCode 插件最稳,比原生 uni.createCanvasContext 更可靠,尤其在弱网或低端安卓机上不会白屏或渲染失败。
为什么不用 uni.createCanvasContext 生成核销码
原生 Canvas 方式需要手动调用 uni.canvasToTempFilePath,但实际中容易遇到:canvasToTempFilePath: fail canvas is empty 错误;H5 端不支持部分 API;APP 端在某些 Android 机型上 canvas 尺寸计算异常导致二维码模糊或缺失。而 uQRCode 内部做了平台兼容兜底,自动处理像素比、离屏渲染和 fallback 图片。
- 必须确保 canvas-id 唯一且与 JS 中传入一致,否则 H5 端完全不显示
-
uni.createCanvasContext('myCanvas')的上下文在 nvue 页面中不可用,APP 端会静默失败 - 动态内容(如订单 ID)拼接进 URL 时,未 encodeURIComponent 会导致扫码后参数截断
uQRCode 插件安装与路径写法
从插件市场安装 Sansnn 版本的 uQRCode 后,务必用绝对路径引入,避免 HBuilderX 升级或项目重构后引用失效:
import UQRCode from '@/uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js'
不要写成相对路径如 ../../uni_modules/...,否则在分包或云打包时可能找不到模块。
- 插件需在
manifest.json的 “App 模块配置” 中勾选 “Barcode(扫码)” 才能用于 APP 端扫描验证(虽生成不依赖,但后续核销流程需要) - H5 端无需额外配置,但域名必须是 HTTPS,否则微信内无法跳转到核销页
- 小程序端注意校验
value中的域名是否已在微信公众平台「业务域名」中备案
核销二维码的 URL 构造要点
二维码内容本质是一个跳转链接,必须携带服务端可验证的唯一标识和防重放信息。典型结构为:
https://yourdomain.com/#/pages/verify/verify?orderId=123456&nonce=abc789&ts=1730320440&sign=xxxx
其中 nonce 和 ts 用于防止链接被重复扫码,sign 是服务端签名,前端只负责拼接,不参与计算。
- 所有 query 参数必须
encodeURIComponent,尤其是中文商品名或特殊符号,否则扫码后uni.getStorageSync取到的值会乱码或截断 - 不要把敏感字段(如用户手机号、金额)明文塞进 URL,应由服务端通过
orderId查库返回 - 建议加
expire参数(单位秒),让核销页打开时主动校验时效性,避免过期码被恶意复用
APP 端自定义扫码页如何对接核销码
商家用 APP 扫码时,不能依赖微信的 uni.scanCode(它只在微信环境有效),得用 barcode 组件 + nvue 页面实现真机摄像头控制:
<barcode ref="barcode" class="barcode" :autostart="true" @marked="onMarked" @error="onError"></barcode>
关键点在于 @marked 回调拿到的是原始字符串,需和服务端约定好解析规则(比如以 VERIFY: 开头才触发核销逻辑)。
- nvue 页面中
barcode必须设置固定宽高(如width: 300px; height: 300px;),否则在部分华为/小米机型上识别率骤降 - APP 端扫码后需立即调用接口验证,不能仅前端判断
status === 0,否则存在本地篡改风险 - 扫码成功后建议调用
uni.vibrateShort()给操作反馈,避免商家反复扫同一张码
真正容易被忽略的是签名时效性和跨平台 URL 路径一致性:同一个核销码,在微信里打开是 /pages/verify/verify,在 APP 里也得走相同页面路径并复用同一套参数解析逻辑,否则会出现“微信能核、APP 核不了”的问题。


















