--- title: WeChat Pay 微信小程序支付集成 permalink: /notes/zh/paymentMethods/WeChatPay/miniProgram/ createTime: '2025/08/28 15:16:33' description: >- 微信小程序支付集成通过统一下单API实现,支持在小程序内完成支付。适用于中国大陆地区,主要特点包括无需跳转、基于微信小程序安全机制、标准化API调用流程及流畅快速的支付体验。关键参数包括用户openid、小程序AppID和订单终端标识。 ---
使用统一下单API,实现微信小程序支付集成。商户在小程序内获取用户openid,通过后端调用 API获取prepay_id,然后在小程序中调起微信支付完成交易。
## 🚀 快速开始 **核心特点**: - ✅ 无需跳转,小程序内完成支付 - 🛡️ 基于微信小程序安全机制 - 🔌 标准化API调用流程 - ⚡ 支付体验流畅快速 ## 微信小程序支付交互流程 ```mermaid %%{init: { 'theme': 'base', 'themeVariables': { 'primaryColor': '#E3F2FD', 'primaryTextColor': '#0D47A1', 'primaryBorderColor': '#1976D2', 'lineColor': '#1565C0', 'secondaryColor': '#BBDEFB', 'tertiaryColor': '#90CAF9', 'background': '#F8FBFF', 'mainBkg': '#E3F2FD', 'secondBkg': '#BBDEFB', 'tertiaryBkg': '#90CAF9', 'actorBkg': '#2196F3', 'actorBorder': '#1976D2', 'actorTextColor': '#FFFFFF', 'actorLineColor': '#1565C0', 'signalColor': '#0D47A1', 'signalTextColor': '#0D47A1', 'c0': '#E8F4FD', 'c1': '#D1E7DD', 'c2': '#B3D9FF', 'c3': '#81C784', 'noteBkgColor': '#E1F5FE', 'noteTextColor': '#01579B', 'noteBorderColor': '#0288D1', 'loopTextColor': '#0D47A1', 'activationBkgColor': '#B3E5FC', 'activationBorderColor': '#0277BD' } }}%% sequenceDiagram participant User as 👤 用户 participant MiniApp as 📱 小程序前端 participant Merchant as 🏪 商户后端 participant PP as 🔄 PingPongCheckout服务端 participant WeChat as 💬 微信支付平台 Note over User, WeChat: 🚀 微信小程序支付流程 Note over User, MiniApp: 📋 准备阶段:用户在小程序内发起支付 User->>MiniApp: 1. 用户点击支付按钮 MiniApp->>MiniApp: 2. 获取用户openid Note right of MiniApp: 调用wx.getUserProfile()
或使用授权登录 MiniApp->>+Merchant: 3. 发送支付请求 Note right of Merchant: 包含商品信息、金额
和用户openid Merchant->>Merchant: 4. 业务验证 Note right of Merchant: 订单验证、库存检查
风控校验等 Merchant->>+PP: 5. 调用统一下单API Note right of PP: 包含小程序特有参数:
wxOpenId、wxAppId
device.orderTerminal=06 PP->>+WeChat: 6. 调用微信统一下单 Note right of WeChat: PSP调用微信
机构平台API WeChat-->>-PP: 7. 返回prepay_id等参数 PP-->>-Merchant: 8. 返回支付参数 Note right of PP: 包含extraParam.wxPrepayId
和其他必要参数 Merchant->>Merchant: 9. 构造小程序支付参数 Note right of Merchant: 生成支付签名
准备wx.requestPayment参数 Merchant-->>-MiniApp: 10. 🔟 返回支付参数到小程序 MiniApp->>MiniApp: 11. 1️⃣ 调用wx.requestPayment() Note right of MiniApp: 使用返回的参数
调起微信支付 MiniApp->>+WeChat: 12. 2️⃣ 唤起微信支付界面 User->>WeChat: 13. 3️⃣ 用户完成支付认证 WeChat-->>-MiniApp: 14. 4️⃣ 支付结果回调 alt ✅ [支付成功] WeChat->>+PP: 15. 5️⃣ 异步支付结果通知 PP->>PP: 16. 处理支付结果 PP->>+Merchant: 17. 6️⃣ 异步通知商户 Merchant-->>-PP: 18. 确认接收通知 PP-->>-WeChat: 19. 确认处理完成 MiniApp->>+Merchant: 20. 7️⃣ 查询支付结果 Merchant-->>-MiniApp: 21. 返回支付成功状态 MiniApp-->>User: 22. 8️⃣ 显示支付成功页面 else ❌ [支付失败/取消] MiniApp-->>User: 23. 显示支付失败信息 Note right of MiniApp: 用户可重试支付 end Note over User, PP: 🎯 微信小程序支付流程完成 ``` ## 集成导航 ::: note 提示 1. 微信小程序支付仅在微信小程序环境内可用,需要获取用户openid。 2. 您需要提前完成微信小程序的基础配置和支付权限申请。 3. 建议在沙箱环境充分测试后再上线生产环境。 ::: ### 前置条件 #### 🔧 微信小程序配置 **必要条件**: - ✅ 已开通微信小程序并通过认证 - ✅ 已获得微信支付商户号 - ✅ 已在微信支付商户平台开通JSAPI支付权限 - ✅ 已配置支付授权目录 ### 请求下单并支付 使用下单并支付接口创建微信小程序支付订单。 在API下单并支付的响应中: - status 为 `SUCCESS` 时,订单已支付成功 - status 为 `PROCESSING` 时,订单已创建,返回`extraParam.wxPrepayId`供小程序调用 - status 为 `FAILED` 时,订单创建失败 **关键参数:** | 参数 | 类型 | 必传 | 说明 | |--------------------------|--------|-----|-----------------------------| | `paymentMethod.wxOpenId` | String | 是 | 用户在小程序内的唯一标识,通过wx.login()获取 | | `paymentMethod.wxAppId` | String | 是 | 微信小程序的AppID,在小程序后台获取 | | `device.orderTerminal` | String | 是 | 固定传 `06`(微信小程序标识) | | `paymentMethod.type` | String | 是 | 固定传 `WeChat Pay` | **参数示例:** ### 小程序前端调用微信支付 获取API返回的`extraParam.wxPrepayId`后,在小程序中调用[`wx.requestPayment()`](https://developers.weixin.qq.com/miniprogram/dev/api/payment/wx.requestPayment.html)完成支付。 ::: steps 1. **获取用户openid** 使用[`wx.login()`](https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html)获取code,后端换取openid ```javascript wx.login({ success: (res) => { // 发送code到后端换取openid this.getOpenIdFromBackend(res.code); } }); ``` 2. **发起支付请求** 将openid等参数传给商户服务端,商户服务端调用统一下单API ```javascript wx.request({ url: 'https://yourapi.com/payment/create', method: 'POST', data: { openid: this.data.openid, amount: this.data.amount, // 其他订单信息 } }); ``` 3. **调起微信支付** 使用返回的prepayId调用[`wx.requestPayment()`](https://developers.weixin.qq.com/miniprogram/dev/api/payment/wx.requestPayment.html) ```javascript wx.requestPayment({ timeStamp: paymentData.timeStamp, nonceStr: paymentData.nonceStr, package: `prepay_id=${prepayId}`, signType: 'RSA', paySign: paymentData.paySign, success: (res) => { // 支付成功,查询支付状态 this.queryPaymentResult(); }, fail: (err) => { // 支付失败处理 console.log('支付失败', err); } }); ``` 4. **处理支付结果** 监听支付回调,查询支付状态 ```javascript onPaymentSuccess() { // 向后端查询最终支付结果 wx.request({ url: 'https://yourapi.com/payment/query', success: (res) => { if (res.data.status === 'SUCCESS') { wx.redirectTo({ url: '/pages/success/success' }); } } }); } ``` ::: ## 完整代码示例 ### 📱 小程序前端实现 ```javascript // pages/payment/payment.js Page({ data: { orderInfo: {}, loading: false }, onLoad(options) { this.setData({ orderInfo: { amount: options.amount || '100', productName: options.productName || '测试商品' } }); }, // 获取用户openid async getOpenId() { return new Promise((resolve, reject) => { wx.login({ success: (res) => { wx.request({ url: 'https://yourapi.com/wechat/auth', method: 'POST', data: { code: res.code }, success: (result) => resolve(result.data.openid), fail: reject }); } }); }); }, // 发起支付 async requestPayment() { try { this.setData({ loading: true }); wx.showLoading({ title: '支付中...' }); const openid = await this.getOpenId(); const paymentRes = await this.createPaymentOrder(openid); if (paymentRes.code === '000000') { const paymentData = JSON.parse(paymentRes.bizContent); const prepayId = paymentData.extraParam.wxPrepayId; // 获取支付签名并调起支付 const signData = await this.getPaymentSign(prepayId); this.callWechatPay(signData, prepayId); } } catch (error) { console.error('支付请求异常', error); wx.showToast({ title: '支付请求失败', icon: 'error' }); } finally { this.setData({ loading: false }); wx.hideLoading(); } }, // 调起微信支付 callWechatPay(signData, prepayId) { wx.requestPayment({ timeStamp: signData.timeStamp, nonceStr: signData.nonceStr, package: `prepay_id=${prepayId}`, signType: 'RSA', paySign: signData.paySign, success: () => this.onPaymentSuccess(), fail: (err) => this.onPaymentFail(err) }); }, // 支付成功处理 onPaymentSuccess() { wx.showToast({ title: '支付成功', icon: 'success' }); setTimeout(() => { wx.navigateBack(); }, 1500); }, // 支付失败处理 onPaymentFail(error) { if (error.errMsg.includes('cancel')) { wx.showToast({ title: '支付已取消', icon: 'none' }); } else { wx.showToast({ title: '支付失败', icon: 'error' }); } } }); ``` ## 常见问题与解决方案 ### ⚠️ openid获取失败 **常见原因**: - 🔥 小程序登录流程不正确 - ⏰ code超过**有效期(5分钟)**使用 - 🔑 小程序AppID和AppSecret配置错误 **解决方案**: ```javascript // ✅ 正确的openid获取流程 wx.login({ success: (res) => { if (res.code) { // 🔥 立即发送到后端,不要延迟 this.getOpenIdFromServer(res.code); } else { console.log('登录失败!' + res.errMsg); } } }); ``` ::: tip 重要提醒 **code的有效期只有5分钟**,获取后应立即使用,避免缓存或延迟处理。 ::: ### ⏱️ prepayId无效或过期 **原因分析**: - 🔗 API调用未成功返回 - ⏰ prepayId**有效期为2小时**,已过期 - 🌐 网络延迟影响使用时效 ::: tip 最佳实践 获取prepayId后应**立即调起支付**,避免因延迟导致过期。建议在前端设置合理的超时提醒。 ::: ### 🔐 支付权限问题 **小程序支付权限未开通**: - ✅ 确认已开通**JSAPI支付权限** - 🔗 检查小程序与商户号的绑定关系 **支付目录配置错误**: - ⚙️ 在微信支付商户平台配置支付授权目录 - 🌐 确保支付页面的域名在授权目录范围内 ## 技术支持 ### 📚 参考文档 - **微信官方文档**: [小程序支付接入指南](https://pay.weixin.qq.com/doc/v3/merchant/4012791911) - **微信小程序API**: [wx.login() 登录接口](https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html) - **微信支付API**: [wx.requestPayment() 支付接口](https://developers.weixin.qq.com/miniprogram/dev/api/payment/wx.requestPayment.html) ### 🛠️ 推荐工具 - **微信开发者工具**: 小程序开发和调试的官方工具 --- ::: important 上线前检查清单 在生产环境上线前,请确保完成以下检查: - 验证所有错误场景的处理逻辑 - 确认异步通知处理的正确性和==幂等性== - 检查支付金额、订单信息的准确性 - 配置生产环境的==HTTPS证书==和域名 - 设置合适的日志记录和==监控告警== :::