跳到主要内容

小程序接入微信支付流程

场景介绍

本篇文档主要介绍在云开发平台搭建的小程序应用,如何使用微信支付云模板接入支付流程

实现流程

安装微信支付模板会自动生成云函数、工作流和 微信支付 APIs,实现下单、支付及回调流程如下:

1 微信支付模板安装

  1. 在云开发平台模板中心找到小程序微信支付模板

  2. 安装模板

  3. 模板安装中

  4. 模板安装完成

  5. 查看模板详情

  6. 在模板参数配置中,需要配置支付商户信息,相关参数说明可参考支付商户配置

2 在编辑器中实现下单和发起支付

注意事项

支付场景需要在真机环境或者微信开发者工具中预览真实效果,编辑器中无法唤起支付

前置准备

在正式调用支付流程之前,您需要先了解:

调用流程

2.1. 在编辑器中,新建 js 方法,用来触发云函数中的微信支付下单方法以及唤起支付

2.2. js 方法代码如下:

说明

代码中 const orderInfo = event.detail 为编辑器中调用 js 方法的入参,请根据业务实际情况和小程序 JSAPI 下单相关参数进行传递

export default async function ({ event, data }) {
const orderInfo = event.detail;
const ordeResult = await $w.cloud.callFunction({
//云函数名称
name: "wxpayFunctions",
data: {
//调用云函数的下单方法
type: "wxpay_order",

// 小程序全托管授权方式,在编辑器中请使用下面方法传递用户openid,需要预先开启openid登录或手机号授权登录方式
// openid:$w.auth.currentUser.openId,

//业务其它参数
...orderInfo,
},
});
const paymentData = ordeResult.result?.data;
//唤起微信支付组件,完成支付
return new Promise((resolve, reject) => {
wx.requestPayment({
timeStamp: paymentData?.timeStamp, // "1414561699",
nonceStr: paymentData?.nonceStr, // "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
package: paymentData?.packageVal, //"prepay_id=wx201410272009395522657a690389285100"
signType: paymentData?.signType, //"RSA",
paySign: paymentData?.paySign, //"oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ\/X+QBhcCYL21N7cHCTUxbQ+EAt6Uy+lwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuT+Cdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZV+JSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8Fu+LozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2+AehHvz+n64GDmXxbX++IOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq\/xDg==",
success: function (res) {
resolve(orderInfo._id);
},
fail: function (res) {
reject(orderInfo._id);
},
});
});
}

2.3. 如果小程序和云开发平台是全托管授权方式,云函数中接收 openid 方法需要进行以下改造:

注意

如果小程序和云开发平台是扫码授权的方式,该步骤可以忽略

云函数中需要使用event.openid的方式接收前端 js 方法中传递的用户 openid

 payer: {
// 扫码授权方式服务端云函数中直接获取当前用户openId,全托管方式需要使用event.openid来接收
openid: wxContext.OPENID? wxContext.OPENID:event.openid,
},

2.4. 事件触发上述 js 方法,这里以点击事件为例

2.5. 支付云函数中可以通过 event 参数接收前端传递的变量,并在云函数内部进行处理

3 在小程序原生代码中调用

如果业务需要在原生小程序代码中(例如自定义开发的页面、已有的原生小程序项目)调用云模板下单接口,可以参考本节的方式直接通过微信开发者工具调用模板内置的云函数,无需在编辑器中编写逻辑。

适用场景

当小程序为原生开发混合开发,且希望复用云开发平台微信支付模板中已有的云函数(wxpayFunctions)时,使用本方式。

前置准备

模板已内置了云函数代码,可以直接在微信开发者工具中下载到本地后修改后使用。也可以手动创建云函数来完成,点击在线代码示例,可以查看云函数示例代码。

3.1 下载模板云函数代码到本地

打开微信开发者工具界面,在 cloudfunctions 目录点击右键,选择同步云函数列表,同步模板中的云函数 wxpayFunctions 到本地;然后在云函数 wxpayFunctions 目录右键,选择下载,即可下载模板内置的云函数代码到本地。如下图所示:

3.2 编辑下单云函数

下载到本地后,可根据业务实际情况调整下单参数。云函数目录下的 wxpay_order 方法即为下单入口,默认参数可参考小程序 JSAPI 下单相关参数

修改完成后,在云函数目录右键选择上传并部署:云端安装依赖(不上传 node_modules),将修改后的云函数重新部署到云端。

3.3 在小程序页面中调用云函数并发起支付

在小程序页面的 JS 文件中,通过 wx.cloud.callFunction 调用云函数 wxpayFunctionswxpay_order 方法获取支付参数,然后调用 wx.requestPayment 唤起微信支付:

// pages/pay/pay.js
Page({
async handlePay() {
try {
// 1. 调用云函数下单
const orderResult = await wx.cloud.callFunction({
name: "wxpayFunctions",
data: {
type: "wxpay_order",
// 业务订单参数,按实际情况传递
description: "商品描述",
out_trade_no: "订单号",
amount: {
total: 1, // 金额,单位分
currency: "CNY",
},
// 如果是全托管授权方式,需要显式传递 openid
// openid: 'xxx',
},
});

const paymentData = orderResult.result?.data;
if (!paymentData) {
wx.showToast({ title: "下单失败", icon: "none" });
return;
}

// 2. 调用微信支付
wx.requestPayment({
timeStamp: paymentData.timeStamp,
nonceStr: paymentData.nonceStr,
package: paymentData.packageVal,
signType: paymentData.signType,
paySign: paymentData.paySign,
success: (res) => {
wx.showToast({ title: "支付成功" });
console.log("支付成功", res);
},
fail: (err) => {
wx.showToast({ title: "支付失败", icon: "none" });
console.error("支付失败", err);
},
});
} catch (err) {
console.error("调用失败", err);
}
},
});
说明
  • 使用前需确保小程序已初始化云能力,即在 app.jsonLaunch 中调用 wx.cloud.init({ env: '云环境ID' })
  • 如果云开发平台与小程序是全托管授权方式,云函数内需使用 event.openid 接收前端传入的用户 openid;如果是扫码授权方式,云函数直接通过 cloud.getWXContext().OPENID 获取即可。详见上文 2.3 全托管授权方式改造

3.4 支付回调处理

原生调用方式的支付回调处理逻辑与编辑器方式完全一致,参考 4 支付回调处理 章节即可,无需额外配置。

4 支付回调处理

使用云函数接收微信支付通知

微信支付会异步发送支付通知,这里使用云函数接收微信支付发送的通知,判断是否支付成功,开发者可以根据云函数收到的微信支付通知,判断是否支付成功,然后处理订单支付状态

  1. 新建云函数,假设函数名为:wxpayOrderCallback,作为接收支付通知的回调函数,示例代码如下

    "use strict";
    exports.main = async (event, context) => {
    // event 中包含上面所有列出的json参数,按需取用
    // 这里使用event_type==="TRANSACTION.SUCCESS"来判断支付成功
    const { event_type } = event;
    if (event_type === "TRANSACTION.SUCCESS") {
    // 处理支付成功相关的业务逻辑,比如数据模型中订单状态变更
    }
    return event;
    };
  2. 在参数设置中配置“接收支付通知的云函数”字段,值为:scf:wxpayOrderCallback

  3. 微信支付发送过来的参数

    说明

    不同支付类型返回的参数结构有一定出入,以回调函数收到的实际参数为准

    {
    "id": "EV-2018022511223320873", // 回调通知的唯一编号
    "create_time": "2015-05-20T13:29:35+08:00", // 本次回调通知创建的时间
    "resource_type": "encrypt-resource", // 通知的资源数据类型,固定为encrypt-resource
    "event_type": "TRANSACTION.SUCCESS", // 微信支付回调通知的类型。支付成功通知的类型为TRANSACTION.SUCCESS。
    "summary": "支付成功", // 微信支付对回调内容的摘要备注。
    "resource": {
    "amount": {
    "currency": "CNY",
    "payerCurrency": "CNY",
    "payerTotal": 1,
    "payer_currency": "CNY",
    "payer_total": 1,
    "total": 1
    },
    "appid": "wx480c*****aa44a43",
    "attach": "",
    "bankType": "BOC_DEBIT",
    "bank_type": "BOC_DEBIT",
    "mchid": "1613752320",
    "outTradeNo": "8206022981401",
    "out_trade_no": "8206022981401",
    "payer": {
    "openid": "ou*********************3zM"
    },
    "promotionDetail": null,
    "promotion_detail": null,
    "successTime": "2025-03-21T17:27:37+08:00",
    "success_time": "2025-03-21T17:27:37+08:00",
    "tradeState": "SUCCESS",
    "tradeStateDesc": "支付成功",
    "tradeType": "JSAPI",
    "trade_state": "SUCCESS",
    "trade_state_desc": "支付成功",
    "trade_type": "JSAPI",
    "transactionId": "4200002********8510115762",
    "transaction_id": "42000026********8510115762"
    }
    }

微信支付模板核心模块介绍

  1. 云函数wxpayFunctions,包含以下方法:

    • wxpay_order: 小程序下单
    • wxpay_query_order_by_transaction_id: 微信支付订单号查询订单
    • wxpay_query_order_by_out_trade_no: 商户订单号查询订单
    • wxpay_refund: 申请退款
    • wxpay_refund_query: 通过商户退款单号查询单笔退款

  2. 工作流:连接云函数和 APIs 方法,实现支付流程打通

  3. APIs:将微信支付相关的接口进行封装,其中 JSAPI 下单方法为发起支付的关键前置流程

常见问题 FAQ

1 为什么编辑器中不能唤起支付?

编辑器中实际是 web 效果,无法模拟真实的支付环境

2 怎么才知道云函数是否执行成功?

可以在云开发平台查看云函数执行日志

3 在真机上点击支付没有反应?

  • 检查 jsapi 下单参数是否正确,可以看上述实现流程步骤说明

  • 对云函数进行断点查询,可以在云函数下单方法中加一些 console 打印日志,在执行日志的时候,通过云函数日志或者小程序vconsole 模式进行查看