跳到主要内容

集成微信支付技能

场景

让 AI 在小程序内帮用户完成微信支付全流程:下单、查询订单、关闭订单、退款、查询退款、商家转账、查询转账。用户只需说"帮我付 25 元买咖啡"或"查一下订单状态",AI 就能调用对应接口完成操作并展示结果卡片。

本文基于预置的 payment-skill 模板来快速集成微信支付能力:一键安装模板 → 配置商户凭证 → 部署上线,支付逻辑通过 HTTP 云函数处理。

前置条件

  • 已完成 从头构建 AI 小程序,项目能在开发者工具中正常运行
  • 小程序已开通 AI 开发模式(微信公众平台 → 基础功能 → AI 能力 → 接入模式选择「开发模式」)
  • 微信开发者工具 Nightly 版 已安装
  • Node.js ≥ 18
  • npx mp-skills --version 可正常输出版本号
  • 已开通微信支付商户号(商户平台 注册)
  • 已开通云开发环境(微信公众平台 → 开发管理 → 云开发)
  • 已准备好商户凭证(商户号、证书序列号、APIv3 密钥、商户私钥、微信支付公钥)

实现步骤

第 1 步:安装 payment-skill 模板

# 在项目根目录下执行
npx mp-skills add TencentCloudBase/awesome-miniprogram-skills --skill payment-skill

预期输出:

从 TencentCloudBase/awesome-miniprogram-skills 获取...

* 安装 Skill: payment-skill
* skills/payment-skill/
* skills/_shared/mp-skills-shared/
* 已记录版本
* 查看 skills/payment-skill/README.md 了解功能详情

[OK] 安装完成!

有 setup 脚本待执行,建议运行:
mp-skills setup

安装后获得的完整文件结构:

miniprogram/skills/payment-skill/
├── config.js # ⚡ 需配置:云函数名 + 环境 ID
├── cloudbaserc.json # ⚡ 需配置:部署凭证 + 环境变量
├── SKILL.md # ✅ 已就绪:技能描述(AI 引擎读此文件判断何时触发)
├── mcp.json # ✅ 已就绪:原子接口声明(7 个支付接口的参数和返回值)
├── index.js # ✅ 已就绪:入口(注册所有原子接口)
├── apis/ # ✅ 已就绪:原子接口实现
│ ├── createOrder.js # 创建订单 + 调起支付
│ ├── queryOrder.js # 查询订单
│ ├── closeOrder.js # 关闭订单
│ ├── refundOrder.js # 申请退款
│ ├── queryRefund.js # 查询退款
│ ├── transferMoney.js # 商家转账
│ └── queryTransfer.js # 查询转账
├── components/ # ✅ 已就绪:UI 组件
│ ├── payment-card/ # 支付结果卡片
│ ├── order-status-card/ # 订单状态卡片
│ ├── refund-card/ # 退款结果卡片
│ └── transfer-card/ # 转账结果卡片
├── cloudfunctions/ # ✅ 已就绪:后端云函数
│ └── pay-common/ # HTTP 云函数(微信支付 V3 服务)
└── utils/ # ✅ 已就绪:前端工具函数
├── util.js # 云函数调用封装
├── id.js # 单号生成
└── storage.js # 本地存储

💡 模板已包含完整的接口实现、UI 组件和云函数代码,你只需完成后续的凭证配置即可使用。

第 2 步:配置后端凭证

2.1 准备商户凭证

微信支付商户平台 获取以下凭证:

凭证获取位置格式
商户号 (merchantId)商户平台首页10 位数字
证书序列号 (merchantSerialNumber)账户中心 → API 安全 → API 证书40 位十六进制
APIv3 密钥 (apiV3Key)账户中心 → API 安全 → 设置 APIv3 密钥32 字节字符串
商户私钥 (privateKey)申请证书时下载的 apiclient_key.pemPEM 格式
微信支付公钥 (wxPayPublicKey)账户中心 → API 安全 → 微信支付公钥PEM 格式
公钥 ID (wxPayPublicKeyId)同上与公钥配对

⚠️ 微信支付公钥 ≠ 商户 API 公钥。务必使用「微信支付公钥」,不是申请证书时生成的商户公钥。

2.2 完善 cloudbaserc.json

打开 miniprogram/skills/payment-skill/cloudbaserc.json,将所有占位符替换为你的实际值:

{
"version": "2.0",
"envId": "你的云开发环境ID",
"functions": [
{
"name": "pay-common",
"type": "http",
"timeout": 30,
"runtime": "Nodejs18.15",
"handler": "index.main",
"memorySize": 256,
"installDependency": true,
"dir": "cloudfunctions/pay-common",
"envVariables": {
"signMode": "sdk",
"appId": "你的小程序AppID",
"merchantId": "你的商户号",
"merchantSerialNumber": "你的证书序列号",
"apiV3Key": "你的APIv3密钥",
"privateKey": "-----BEGIN PRIVATE KEY-----\\nMIIEvgIBA...\\n-----END PRIVATE KEY-----",
"wxPayPublicKey": "-----BEGIN PUBLIC KEY-----\\nMIIBIjAN...\\n-----END PUBLIC KEY-----",
"wxPayPublicKeyId": "你的微信支付公钥ID",
"notifyURLPayURL": "https://<envId>.service.tcloudbase.com/pay-common/wx-pay/unifiedOrderTrigger",
"notifyURLRefundsURL": "https://<envId>.service.tcloudbase.com/pay-common/wx-pay/refundTrigger",
"transferNotifyUrl": "https://<envId>.service.tcloudbase.com/pay-common/wx-pay/transferTrigger"
}
}
],
"database": {
"collections": [
{
"name": "payment_records",
"description": "支付记录",
"indexes": [
{
"field": "openid",
"unique": false
},
{
"field": "orderId",
"unique": false
},
{
"field": "outTradeNo",
"unique": false
}
],
"aclTag": "PRIVATE"
},
{
"name": "refund_records",
"description": "退款记录",
"indexes": [
{
"field": "openid",
"unique": false
},
{
"field": "outRefundNo",
"unique": false
},
{
"field": "outTradeNo",
"unique": false
}
],
"aclTag": "PRIVATE"
},
{
"name": "transfer_records",
"description": "转账记录",
"indexes": [
{
"field": "openid",
"unique": false
},
{
"field": "outBillNo",
"unique": false
}
],
"aclTag": "PRIVATE"
}
]
}
}

关键配置说明:

字段说明
envId你的云开发环境 ID
signModesdk(自验签,推荐)或 gateway(集成中心代验签)
privateKey将 PEM 文件换行替换为 \n(字面两个字符),写成一行
notifyURLPayURL支付回调 URL,必须填写部署后的实际完整地址
notifyURLRefundsURL退款回调 URL
transferNotifyUrl转账回调 URL

回调 URL 格式规则:https://<envId>.service.tcloudbase.com/<函数名>/wx-pay/<路由>

示例:https://test-wxpay-5gy4ugzreef15cfe.service.tcloudbase.com/pay-common/wx-pay/unifiedOrderTrigger

2.3 完善 config.js

打开 miniprogram/skills/payment-skill/config.js,填入与 cloudbaserc.json 一致的值:

module.exports = {
// 云函数名称(须与 cloudbaserc.json 中 functions 里的 name 一致)
functionName: "pay-common",

// 云开发环境 ID(须与 cloudbaserc.json 中的 envId 一致)
envId: "",
};

⚠️ 小程序运行时无法读取 JSON 文件,所以 config.js 需要与 cloudbaserc.json 手动保持同步。如果修改了 cloudbaserc.json 中的函数名或环境 ID,请同步更新此文件。

第 3 步:一键部署后端

npx mp-skills setup

mp-skills setup 自动完成:

步骤说明
合并配置Skill 级 cloudbaserc.json → 项目级
安装依赖cloudfunctions/pay-common/ 的 npm 包
部署云函数部署为 HTTP 云函数
创建数据库自动创建 payment_recordsrefund_recordstransfer_records 集合及索引

部署完成后,需要在 云开发控制台 → 云函数 → pay-common → HTTP 触发 中将以下回调路径设为免鉴权

  • /wx-pay/unifiedOrderTrigger(支付回调)
  • /wx-pay/refundTrigger(退款回调)
  • /wx-pay/transferTrigger(转账回调)

微信支付服务器直接调用回调路径,无法携带鉴权 token,必须免鉴权。安全由内部签名验证保证。

第 4 步:validate 校验

npx mp-skills validate

预期输出:

[OK] 项目配置检查通过
[OK] 接口定义与实现一致
[OK] 原子组件定义完整

如果校验失败,检查以下常见问题:

  • mcp.json 的接口名与 index.js 注册名不一致
  • componentPath 指向的组件文件不存在
  • cloudbaserc.json 中回调 URL 包含模板变量未替换

第 5 步:在开发者工具中验证

# macOS
/Applications/wechatwebdevtools.app/Contents/MacOS/cli open --project /your/path/to/my-ai-app

# Windows
"C:\Program Files (x86)\Tencent\微信web开发者工具\cli.bat" open --project "D:\...\my-ai-app"

在开发者工具中:

  1. 基础库版本切换到 3.16.1 或以上
  2. 编译模式切换到「小程序 AI 编译
  3. 左侧 SKILL 列表中应出现 payment-skill
  4. 选中后右侧显示 7 个原子接口
  5. 测试 createOrder:填入 {"description": "咖啡", "totalFee": 100} 执行
  6. 查看返回的支付结果卡片渲染效果

验证清单

  • npx mp-skills validate 全部通过
  • npx mp-skills setup 部署成功,云函数状态正常
  • 回调路由已设为免鉴权
  • 开发者工具中 createOrder 可正常调起微信支付(或预览模式返回 mock)
  • 支付成功后 payment-card 组件正确渲染
  • queryOrder / closeOrder / refundOrder / queryRefund / transferMoney / queryTransfer 接口可正常调用
  • 各结果卡片(order-status-card、refund-card、transfer-card)正确展示
  • mcp.json 声明与 index.js 注册名一致
  • config.jscloudbaserc.json 的 envId、functionName 保持一致

支付架构

关键设计决策:

决策选择理由
支付是否走云函数,通过 HTTP 云函数支付涉及密钥签名,必须在后端处理。前端通过 wx.cloud.callHTTPFunction 调用,平台自动鉴权
openid 获取方式后端自动从 header 获取wx.cloud.callHTTPFunction 自动注入 x-wx-openid,无需前端传递,避免伪造
金额来源Demo 演示从前端传入生产环境必须从后端数据库获取,禁止信任前端金额
回调验签signMode: sdk 自验签无需依赖外部服务,云函数独立完成验签 + 解密
结果展示4 种自定义卡片组件支付场景需要丰富的状态展示(金额、状态图标、操作按钮)

业务约束(跨接口铁律)

1. 执行顺序

  • refundOrder 必须在 queryOrder 确认订单为 SUCCESS 状态后调用
  • closeOrder 必须在 queryOrder 确认订单为 NOTPAY 状态后调用
  • 禁止并发调用支付接口;须等上一笔结束后再发起下一笔

2. 数据来源

  • outTradeNo 必须来自 createOrder 返回的原值,禁止编造
  • outRefundNo 必须来自 refundOrder 返回的原值,禁止编造
  • outBillNo 必须来自 transferMoney 返回的原值,禁止编造

3. 金额处理

  • 所有金额单位为(如 1 元 = 100 分)
  • 退款金额不能超过订单总金额
  • 转账金额范围:0.3 元(30 分)~ 2000 元(200000 分)

4. 安全约束

  • 后端通过 wx.cloud.callHTTPFunction 调用,平台自动鉴权
  • payer.openid 由后端自动获取,前端无需传递
  • 禁止在前端硬编码任何密钥或证书信息

常见问题

报错 "当前环境不支持 wx.cloud.callHTTPFunction"?

  1. 确认基础库版本 >= 3.15.1
  2. 已在 app.js 中调用 wx.cloud.init()
  3. 使用真机调试或体验版(非模拟器)

支付总是返回 mock 数据?

检查 mp_skills_preview_mode 是否为 true,以及后端云函数是否已部署。切换方式:

// 开启预览模式
wx.setStorageSync("mp_skills_preview_mode", true);

// 关闭预览模式(使用真实支付)
wx.setStorageSync("mp_skills_preview_mode", false);

退款报错 "订单状态不允许退款"?

只有 SUCCESS(已支付)状态的订单才能退款:

  • NOTPAY → 使用 closeOrder 关闭
  • SUCCESS → 使用 refundOrder 退款
  • CLOSED → 已关闭,无法操作

商家转账有什么限制?

  • 单笔:0.3 元 ~ 2000 元
  • 需在商户平台开通「商家转账到零钱」功能
  • 用户需在微信确认收款

如何在生产环境使用?

  1. 关闭预览模式
  2. 金额从后端获取(禁止前端直传金额)
  3. 配置好回调 URL(必须是实际部署后的完整地址)
  4. 确保无密钥暴露在前端
  5. 回调处理需实现幂等逻辑

config.jscloudbaserc.json 的区别?

文件用途运行时
cloudbaserc.json云开发 CLI 部署用,包含完整凭证仅部署时使用
config.js小程序端运行时配置小程序运行时 require

两者的 functionNameenvId 必须保持一致。

参考