微信小程序发起微信支付的流程(页面获取实现与云函数实现)

637 阅读5分钟

一. 基本流程

1. 准备工作

image.png 1、申请微信小程序账号

申请成功可拿到 AppID(小程序 id)和 AppSecret(小程序密钥)
申请类型为企业性质,否则无法接入微信支付

2、微信小程序认证

通过认证的小程序才能接入微信支付和绑定商户平台

3、申请商户平台账号

需要第一步申请的 AppID
申请成功可拿到 MchID(商户 id)和 MchKey(商户密钥)

4、微信小程序关联商户号

微信和商户都认证成功后,在微信后台微信支付菜单中进行关联

5、接入微信支付

在微信后台微信支付菜单中进行接入

二. 代码注释详解

1. 页面获取openid实现微信支付流程

  • 支付前的操作

因为严格意义上来说这不属于支付流程中的步骤,但支付过程中需要用到用户唯一标识openid,所以建议在用户进入小程序时就进行这一步的操作(应用生命周期)

  • 在app.js中通过wx.login()获取code
  • 在成功的回调中发送请求获取openid(code在此处作为参数传入)
  • 成功后将openid存储至本地 (实际开发可存储至数据库中,此处使用本地存储方便演示)
// app.js
App({
  onLaunch: function () {
    // 发起login请求,获取用户code
    wx.login({
      // 获取code成功的回调
      success: res => {
        // 成功时发送请求获取openid
        wx.request({
          // url属性为获取openid的接口地址
          url: '获取openid的接口地址',
          data: {
            // code参数为获取过来的code,必填参数
            code: res.code
          },
          // 获取openid成功的回调
          success: res => {
            // 把openid存储至本地
            wx.setStorageSync('openid', res.data.openid)
          },
          // 获取openid失败的回调
          fail: err => {
            console.error(err);
          }
        })
      },
      // 获取code失败的回调
      fail: err => {
        console.error(err);
      }
    })
    this.globalData = {};
  }
});
  • 页面中定义事件toPay,在页面的js中编辑支付逻辑
  • 发送预支付订单请求,传递所需参数,成功时接收预支付订单信息
  • 在预支付信息成功回调时调用wx.requestPayment()把预支付信息发送出去,生成订单,进行支付
  • 完成后提示用户支付成功或进行其他提示
// pages/index/index.js
Page({
  // 点击支付
  toPay() {
   // 发送预支付订单请求
    wx.request({
      // 预支付订单接口
      url: '预支付订单接口地址',
      //请求方式一般为POST,安全性能高
      method: 'POST',
      //data中参数分别为 
      //openid (使用存储的openid)
      //body (描述) 
      //out_trade_no (用于生成订单编号) 
      //total_fee (支付金额,实际开发为变量,此处为固定值)
      data: {
        openid: wx.getStorageSync('openid'),
        body: '支付',
        out_trade_no: new Date().getTime(),
        total_fee: 1
      },
      //预支付订单接口请求成功的回调
      success: res => {
        //调用wx.requestPayment()把预支付信息发送出去,生成订单,进行支付
        wx.requestPayment({
          ...res.data,
          //支付成功的回调
          success:res=>{
            //此处可以与res返回信息做为提示,在此不做演示
            wx.showToast({
              title: '支付成功',
              icon: "success",
              duration:2000
            })
          },
          //支付失败的回调
          fail:err=>{
            console.error(err);
          }
        })
      },
      //预支付订单接口请求失败的回调
      fail: err => {
        console.error(err);
      }
    })
  },
})

2.使用云函数实现微信支付流程

基本流程

  • 1、用户在小程序端点击支付时使用wx.cloud.callFunction调用云函数(比如云函数名为pay),并将商品名称、商品价格等信息传递给pay云函数;
  • 2、在pay云函数中调用统一下单接口CloudPay.unifiedOrder(),参数包括接收的商品信息、云函数环境id,以及需要填写结果通知回调函数(比如函数名为paynotice)用来接收异步支付结果;pay云函数会返回的成功结果对象中会包含payment字段;
  • 3、在小程序端wx.cloud.callFunction的success回调函数(也就是拿到云函数返回的对象)里调用wx.requestPayment接口发起支付,而从pay云函数返回的payment对象(字段)就包含这个接口所需要的所有信息(参数);这时会弹出微信支付的界面;
  • 4、用户在小程序端支付成功,paynotice就会接受到异步的支付结果,我们可以在paynotice云函数里进行发送订阅消息以及将支付成功的信息更新到数据库等操作

页面js

  • 页面按钮定义事件yunCloud
  • 调用的支付云函数名称为pay(名称任意,对应云函数),具体逻辑如下:
  // 云开发微信支付
  yunCloud () {
    wx.cloud.callFunction({
      name: 'pay', //云函数的名称
      success: res => {
        console.log(res)
        const payment = res.result.payment
        wx.requestPayment({
          ...payment,
          success(res) {
            console.log('支付成功', res)
            //支付成功后的处理函数,写在这里
          },
          fail(err) {
            console.error('支付失败', err),
            //支付失败之后的处理函数,写在这里
          }
        })
      },
      fail: (err)=>{
          //调用云函数失败的回调
          console.error(err)
      },
    })
  },

云函数逻辑

  • 参数详情

  • body为你的商家名(店名)-销售商品的类名,代码里有参考;

  • outTradeNo是商户订单号,32个字符内,只能是数字、大小写字母_-;

  • subMchId你的商户ID或子商户ID,也可以填写云开发控制台设置其他设置微信支付配置里的商户号;

  • totalFee是支付的金额,单位是分,填写100,就是一块钱,注意这个是数值格式,不要写成了字符串格式(不要加单引号或者双引号);

  • envId是你的结果通知回调云函数所在的环境ID,functionName结果通知云函数的名称(可以自定义);可以在云开发控制台设置环境设置里看到,注意是环境ID,不是环境名称;

  • 实现流程

  • 在云函数根目录文件夹cloudfunctions右键,选择“新建Nodejs云函数”,新建一个云函数pay,然后再在index.js里编辑,页面逻辑如下 :

  • 修改完之后保存,右键云函数pay文件夹,选择“上传并部署:云端安装依赖(不上传Node_modules) ”(注意此处第一次提示为)

//pay云函数中index.js的页面逻辑
const cloud = require('wx-server-sdk')
cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})
exports.main = async (event, context) => {
  const res = await cloud.cloudPay.unifiedOrder({
    "body": "描述信息",
    "outTradeNo": new Date().getTime() + '', //不能重复 (注意此处数据类型为字符串)
    "spbillCreateIp": "127.0.0.1", //默认IP 尽量不要变动
    "subMchId": "商户ID", //你的商户ID或子商户ID
    "totalFee": 1, //单位为分
    "envId": "环境ID", //你的云开发环境ID
    "functionName": "paysuc", //支付成功的回调云函数
    "nonceStr": "F8B31E62AD42045DFB4F2", //随机32位字符串
    "tradeType": "JSAPI" //默认是JSAPI
  })
  return res
}
  • 友情提示
  • 点击上传云函数第一次提示为下图

b6fc66334827239d8b3b76fc398bdeb.png

  • 等待二十秒左右(网络状态影响上传速度),弹出第二次提示为上传成功

e626bfb6d2e0e25421205c5d172fcbb.png