前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信小程序--云开发支付闭环

微信小程序--云开发支付闭环

作者头像
Kindear
发布2021-06-10 11:18:56
4K0
发布2021-06-10 11:18:56
举报
文章被收录于专栏:算法与数据结构

云开发支付流程闭环

extends 微信小程序--使用云开发完成支付闭环

在上述文章中,我们对支付结果的处理更多依赖于小程序端的操作

  1. 订单号存储在小程序端
  2. 支付结果采用小程序端定时触发器轮询

现在我对该流程进行了优化处理

1.流程介绍

2.小程序端

  1. 请求统一下单云函数
  2. 调用支付接口
  3. 侦听器获取支付结果
代码语言:javascript
复制
// pages/index/details.js
const app = getApp();
const db = wx.cloud.database();
var watcher = null
Page({

  /**
   * 页面的初始数据
   */
  data: {
    
  },
  //付费解锁
  payUnlock() {
    var that = this;
   
    this.setData({
      vis: true
    })
    //用户ID 即为OPENID
    let userid = this.data.selfcard._id;
    wx.cloud.callFunction({
      name: 'userpay',
      data: {
        fee: 1,
        paydata: {
          userid
        }
      },
      success: res => {
        console.log(res)
        //统一下单云函数中需要返回侦听器 需要的记录id
        that.payWatcher(res.result.docid);
        that.setData({
          vis: false
        })     
        //根据统一下单参数 请求支付接口
        const payment = res.result.payment
        wx.requestPayment({
          ...payment,
          success(ans) {
            console.log(ans)
          },
          fail(ans) {
            that.setData({
              errMsg: '调用支付失败'
            })
          }
        })
      }
    })
  },
  payWatcher(docid){
    var that = this;
    //为用户支付记录表设置侦听器,侦听docid信息的变动
    this.watcher =  db.collection('USERPAYLOG').doc(docid).watch({
      onChange: async function (snapshot) {
        //只打印变动的信息
        // console.log(snapshot)
        if (snapshot.docChanges.length != 0) {
          console.log(snapshot.docChanges)
          let paydoc = snapshot.docChanges[0].doc;
          //侦听到支付成功
          if(paydoc.paystatus == 1){
            that.setData({
              succMsg:'支付成功',
              locked:false,
              bottom:0
            })
          }
          // await that.watcher.close();
        }
      },
      onError: function (err) {
        console.error('the watch closed because of error', err)
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    try {
      this.watcher.close();
    } catch (error) {
      console.log('暂未启动支付侦听器')
    }
  }
})

3.云函数端

userpay

  1. 云调用统一下单【CloudPay.unifiedOrder】
  2. 数据库中存入订单记录并设置为未支付状态

需要配置商户(云开发控制台)

代码语言:javascript
复制
const cloud = require('wx-server-sdk')
//需要在此处修改你的云环境ID
cloud.init({
  env: ''
})
const db = cloud.database();
const _ = db.command;
// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  var openid = event.openid || wxContext.OPENID
  //获取统一下单金额
  var fee = parseInt(event.fee);
  let paydata = event.paydata;
  //生成订单号
  let tradeno = GetTradeNo();
  //调用统一下单接口
  const res = await cloud.cloudPay.unifiedOrder({
    //填写你的商户主体信息 例如 xx商贸
    "body": "",
    "outTradeNo": tradeno,
    "spbillCreateIp": "127.0.0.1",
    //填写你的商户ID -- 可在云开发控制台中绑定获得(上图所示)
    "subMchId": "",
    "totalFee": fee,
    //填写你的云环境ID
    "envId": "",
    //填写你的回调函数名称
    "functionName": "userpaynotify"
  })
  console.log(res)
  res.outTradeNo = tradeno
  res.totalFee = fee
  //支付状态 0 为未支付
  paydata.tradeno = tradeno
  paydata.paystatus = 0
  paydata.totalfee = fee
  paydata.openid = openid
  paydata.paytime = TimeCode()
  //统一下单shuju
  paydata.uniOrder = res
  //拦截处理 为保持数据库字段一致性
  if (res.returnCode == 'SUCCESS' && res.resultCode == 'SUCCESS') {
    //在云数据库中写入未支付的订单信息
    let tdata = await db.collection('USERPAYLOG').add({
      data: paydata
    })
    console.log(tdata)
    //将该记录ID携带返回给小程序端
    res.docid = tdata._id;
    return res;
  }else{
    return res;
  }
}

function GetTradeNo() {
  var outTradeNo = ""; //订单号
  for (var i = 0; i < 6; i++) //6位随机数,用以加在时间戳后面。
  {
    outTradeNo += Math.floor(Math.random() * 10);
  }
  outTradeNo = "COP" + new Date().getTime() + outTradeNo; //时间戳,用来生成订单号。
  return outTradeNo;
}

function TimeCode() {
  var date = new Date();
  var year = date.getFullYear()
  var month = date.getMonth() + 1
  var day = date.getDate()

  var hour = date.getHours()
  var minute = date.getMinutes()
  var second = date.getSeconds()

  return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}

function formatNumber(n) {
  n = n.toString()
  return n[1] ? n : '0' + n
}

支付成功后触发云环境中该回调函数

回调函数携带的请求信息请在参考文档中查看

userpaynotify

  1. 修改数据库中订单状态
  2. 返回给回调请求SUCCESS数据【Cloud.paymentCallback】 订单在支付成功时会触发该回调函数 该回调函数必须有返回值,且必须是固定格式 根据回调函数携带的订单号,修改对应订单号的订单状态,并且返回对应格式的返回信息 字段名 变量名 必填 类型 描述 错误码 errcode 是 Number 0 错误信息 errmsg 是 String
代码语言:javascript
复制
const cloud = require('wx-server-sdk')
//填写你的云环境ID
cloud.init({
  env: ''
})
const db = cloud.database();
const _ = db.command;
// 云函数入口函数
exports.main = async (event, context) => {

  console.log('支付成功回调函数触发')
  console.log(event)
  let tradeno = event.outTradeNo;
  try {
    //修改数据库中订单状态 为已支付
    db.collection('USERPAYLOG').where({
      tradeno:tradeno
    }).update({
      data:{
        paystatus:1
      }
    })
  } catch (error) {
    return {
      errmsg: 'SERVER_ERROR',
      errcode: -1
    }
  }
  return {
    errmsg: 'SUCCESS',
    errcode: 0
  }
}

参考文档

  1. 云开发文档 Cloud.CloudPay | 微信开放文档 (qq.com)
  2. 回调函数请求携带参数
代码语言:javascript
复制
{
	appid: '',

	bankType: 'OTHERS',

	cashFee: 1,

	feeType: 'CNY',

	isSubscribe: 'N',

	mchId: '',

	nonceStr: '',

	openid: '',

	outTradeNo: '',

	resultCode: 'SUCCESS',

	returnCode: 'SUCCESS',

	subAppid: '',

	subIsSubscribe: 'N',

	subMchId: '',

	subOpenid: '',

	timeEnd: '',

	totalFee: 1,

	tradeType: 'JSAPI',

	transactionId: '',

	userInfo:

	{
		appId: '',

		openId: ''
	}
}


 
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-06-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 云开发支付流程闭环
  • 1.流程介绍
  • 2.小程序端
  • 3.云函数端
    • userpay
      • userpaynotify
      相关产品与服务
      云开发 CloudBase
      云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档