小程序云开发 ——微信支付

云开发的微信支付:免鉴权、免签名计算、免 access_token,在云函数内原生调用微信支付接口。以前的实现微信支付,必须要有自己的服务器,有自己的备案域名,还有后端部分代码

云开发—微信支付,官方教程

微信支付关键的开发流程:
    1. 小程序调用云函数,在云函数中调用统一下单CloudPay.unifiedOrder() 接口
    1. 统一下单接口返回的成功结果中有 payment 字段,该字段即是小程序端发起支付的接口(wx.requestPayment)所需的参数
    1. 支付完成后,在统一下单接口中配置的支付通知的云函数将收到支付结果通知(可以在这里更新订单状态为已支付)

一、支付云函数pay

// pay云函数

const cloud = require('wx-server-sdk')
cloud.init()
const db=cloud.database()

function genOrderNo() {
  let vNow = new Date()
  let sNow = String(vNow.getFullYear()) + '-'
  sNow += String(vNow.getMonth() + 1) + '-'
  sNow += String(vNow.getDate()) + '|'
  sNow += String(vNow.getHours() + 8)  + '-'
  sNow += String(vNow.getMinutes())
  const $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
  let maxPos = $chars.length
  let leftLength = 32 - sNow.length
  for (i = 0; i < leftLength; i++) {
    sNow += $chars.charAt(Math.floor(Math.random() * maxPos))
  }
  return sNow
}

// 云函数入口函数
exports.main = async (event, context) => {
  let params = {
    "body": event.body || "小程序支付",
    "outTradeNo": event.outTradeNo || genOrderNo(),
    // 小程序端可以wx.request:https://pv.sohu.com/cityjson  获取IP地址
    "spbillCreateIp": event.ip || "127.0.0.1",
    "totalFee": event.fee || 1, // 分为单元
    // 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
    "attach": event.attach
  }
  const res = await cloud.cloudPay.unifiedOrder({
    ...params,
    "subMchId": "188888888",
    "tradeType": 'JSAPI',
    "envId": "cloud1-xxxxxxxxx",
    "functionName": "pay_cb"   // 支付的回调云函数名
  })
  if (res['errMsg'] == 'cloudPay.unifiedOrder:ok') { // 下单成功
    params['nonceStr'] = res['nonceStr']
    params['prepayId'] = res['prepayId']
    params['sign'] = res['sign']
    params['appid'] = res['appid']
    params['mchId'] = res['mchId']
    db.collection("pre_order").add({
      data: {
        ...params,  // 保存支付信息
        openid: event.openid, // 用户openid
        phone: event.phone,
        orderTime: new Date().getTime(),
        payStatus: 0 // 0:未支付, 1:已支付, -1:失效
      }
    })
  }
  return res
}

二、小程序端调用支付的云函数

wx.cloud.callFunction({
      name: 'pay', // 对应云函数名
      data: {
        body: '预订xxx',
        fee: 1 * 100,
        ip: paddr, // ip地址 
        phone: phone, // 手机号
        attach: phone+ ','  + 'xxxx' + ',' +  'yyyy' // 用于支付通知
      },
      success: res => {
        const payment = res.result.payment
        console.log('pay res.result', res.result)
        wx.requestPayment({
          ...payment,
          success(res) {
            console.log('pay success', res)
            wx.showToast({
              title: '支付成功',
              icon: 'none'
            })
          },
          fail(err) {
            console.log('pay fail', err)
            let errStr = String(err.errMsg)
            if (errStr.indexOf('cancel')) {
              wx.showToast({
                title: '您已取消支付',
                icon: 'none'
              })
            }
          }
        })
      }
    })

三、支付回调的云函数pay_cb

对应上面cloud.cloudPay.unifiedOrder中的 "functionName": "pay_cb" 支付回调方法名

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()
const db = cloud.database();

// 云函数入口函数
exports.main = async (event, context) => {
  if (event['returnCode'] == 'SUCCESS') {
    try {
      db.collection('pre_order').where({
        outTradeNo: event['outTradeNo']
      })
        .update({
          data: {
            transactionId: event['transactionId'],
            payTime: new Date().getTime(),
            payStatus: 1 // 0:未支付, 1:已支付
          },
        })
      const attachInfo = event['attach'] && event['attach'].split(',')
      // 添加 order 记录
      db.collection("order").add({
        data: {
          _createTime: new Date().getTime(),
          phone: attachInfo[0],
          xxx: attachInfo[1] + '',
          yyy: attachInfo[2] + '',
          transactionId: event['transactionId'],
          outTradeNo: event['outTradeNo'],
          money: event['totalFee'] / 100
        }
      })
    } catch (e) {
      console.error(e)
    }
  }
  return { "errcode": 0 }
}

你可能感兴趣的:(小程序,vue.js,后端,javascript)