最省事的uni-app支付方案是uni-pay+uniCloud,但需严格区分前端调起与云端下单:支付参数必须由uniCloud云函数生成并签名,前端仅传参调用uni.requestPayment;微信V3支付需正确配置appId、mchId、v3Key及证书路径;虚拟支付须用uni.requestVirtualPayment并配套uni-pay-co云对象。

直接用 uni-pay + uniCloud 是目前最省事的 uni-app 支付方案,但前提是别把「前端调起」和「云端下单」混为一谈——支付参数必须由服务端生成并签名,前端只负责传参和调用 uni.requestPayment。
uni-pay 云函数必须部署在 uniCloud,不能本地运行
很多开发者本地调试时直接 require('uni-pay'),结果报错 Cannot find module 'uni-pay' 或 crypto not available。这是因为:uni-pay 依赖 Node.js 原生 crypto 模块和 HTTPS 客户端能力,这些在前端或 H5 环境不可用,只能跑在 uniCloud 云函数里。
- 云函数目录结构要规范:比如
cloudfunctions/getOrderInfo/index.js,且该函数已成功部署到阿里云/腾讯云环境 - 不能在
pages或components里 importuni-pay,否则编译会失败或运行时报错 - uniCloud 项目需启用「云对象」或「云函数」功能,并确保已安装
uni-pay插件(HBuilderX 插件市场搜索安装,或 npm install uni-pay --save)
微信 V3 支付初始化必须填对四个关键字段
V3 和 V2 的初始化差异极大,填错任意一个都会导致 getOrderInfo 调用返回签名错误、证书加载失败或 401 unauthorized。重点盯住这四个字段:
-
appId:来自微信公众平台(小程序)或开放平台(App),不是商户平台的 -
mchId:纯数字字符串,从微信商户平台「账户中心 → 商户信息」里复制,不要带空格或字母 -
v3Key:32 位 ASCII 字符,必须和商户平台「API安全 → APIv3密钥」里设置的一致,大小写敏感 -
appCertPath和appPrivateKeyPath:必须是 .pem 格式,且路径指向云函数根目录下的实际文件(如path.resolve(__dirname, './apiclient_cert.pem')),不能是 URL 或 base64 内容
常见错误现象:ERR_CERTIFICATE_REQUIRED 表示证书路径不对;INVALID_SIGNATURE 多半是 v3Key 和商户平台不一致;INVALID_REQUEST 往往因为 appId 用错了环境(比如小程序用了公众号的 appId)。
前端调用 uni.requestPayment 前必须先请求云函数获取支付参数
uni.requestPayment 不接受原始订单数据,它只认云函数返回的标准化对象。这个对象必须包含 provider、orderInfo(微信)、alipaySign(支付宝)等字段,由 uni-pay 的 getOrderInfo 方法生成。
- 前端代码示例(不能漏掉
success和fail回调):uniCloud.callFunction({ name: 'getOrderInfo', data: { amount: 100, subject: '会员续费' } }).then(res => { const { code, data } = res.result; if (code === 0) { uni.requestPayment({ provider: 'wxpay', orderInfo: data, // 注意:这里 data 是已签名的完整对象,不是原始订单 success: () => console.log('支付成功'), fail: (err) => console.error('支付失败', err) }); } }); -
getOrderInfo云函数返回的data字段,是uni-pay封装后可直接喂给uni.requestPayment的,不要二次 JSON.stringify 或解构 - 微信小程序环境下,
provider必须传'wxpay';支付宝小程序传'alipay';App 端则根据打包渠道自动映射,无需手动指定
虚拟支付(短剧类目)必须用 uni.requestVirtualPayment,且仅限微信小程序
如果你的小程序属于「短剧、小说、漫画」等类目,微信强制要求使用虚拟支付,此时 uni.requestPayment 会直接被拒。必须改用 uni.requestVirtualPayment,且它的参数完全不兼容普通支付。
- 前端调用时,
signData、paySig、signature都必须由云端通过uni-pay-co的requestWxpayVirtualApi接口返回,前端不能自行拼接 - 云函数中不能用
uni-pay的getOrderInfo,而要用uni-pay-co云对象(需单独引入)调用createVirtualOrder等方法 - 该 API 在 App、H5、支付宝等所有其他平台均不支持,调用会直接报错
not supported
最容易被忽略的是:虚拟支付的回调地址、代币余额查询、扣减逻辑全部走另一套云 API,和普通支付完全隔离。哪怕你只改一行代码把 uni.requestPayment 换成 uni.requestVirtualPayment,后端也得同步切换整套云对象调用链。


















