zoukankan      html  css  js  c++  java
  • 微信小程序--使用云开发完成支付闭环

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

    优化版支付流程

    1.流程介绍


    2. 代码实现和逻辑思想描述

    云函数统一下单 对应云函数 unipay

    【CloudPay.unifiedOrder】

    函数思路 : 调用云函数封装功能,用时间戳生成对应订单号,进行统一下单处理,如果两个返回结果都是SUCCESS,那么将该订单记录写入数据库,状态设置为waiting

    1. body填写商户名称
    2. subMchId填写商户ID,在云函数环境管理后台获取
    const cloud = require('wx-server-sdk')
    cloud.init({
      env: ''
    })
    const db = cloud.database();
    const _ = db.command;
    exports.main = async (event, context) => {
      var fee = parseInt(event.fee);
      let paydata = event.paydata;
      let tradeno = GetTradeNo();
      const res = await cloud.cloudPay.unifiedOrder({
        "body": "",
        "outTradeNo": tradeno,
        "spbillCreateIp": "127.0.0.1",
        "subMchId": "",
        "totalFee": fee,
        "envId": "云函数环境ID",
        "functionName": "unipaynotify"
      })
      res.outTradeNo = tradeno
      res.totalFee = fee
      //在此处写入订单表
      paydata.paytimestamp = res.payment.timeStamp;
      paydata.orderid = res.outTradeNo;//订单号
      paydata.paystatus = 'waiting'
      paydata.orderamount = fee
      paydata.paytime = TimeCode()
      paydata.mchid = res.subMchId
    
      if(res.returnCode=='SUCCESS' && res.resultCode=='SUCCESS'){
        db.collection('pay_record').add({
          data:paydata
        })
      }
      
      return res
    }
    
    function GetTradeNo() {
      var outTradeNo = ""; //订单号
      for (var i = 0; i < 6; i++) //6位随机数,用以加在时间戳后面。
      {
        outTradeNo += Math.floor(Math.random() * 10);
      }
      outTradeNo = "LHZHWY" + 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 TimeCodeYmd(){
      var date = new Date();
      var year = date.getFullYear()
      var month = date.getMonth() + 1
      var day = date.getDate()
    
      return [year, month, day].map(formatNumber).join('-');
    }
    function formatNumber(n) {
      n = n.toString()
      return n[1] ? n : '0' + n
    }
    

    根据统一下单返回参数,调用微信支付接口

    1. fee 需要根据订单计算 fee单位为0.01
    2. paydata是商品订单参数,形式为Object,可存放顾客手机号,支付总金额,支付哪一项费用等信息
    3. TimerQuery是定时器,查询支付结果
    let fee = 1
    //该费用只是代指,以实际开发为准
    wx.cloud.callFunction({
      name: 'unipay',
      data: {
        fee: fee,
        paydata: paydata
      },
      success: res => {
        const payment = res.result.payment
        console.log(res)
        //在此处获得支付订单号信息,支付时间,支付状态
        var tradeno = res.result.outTradeNo
        wx.requestPayment({
          ...payment,
          success(res) {
            //成功回调,这个时候微信支付后台会触发回调函数
            console.log(res)
            that.TimerQuery(tradeno, paydata);
    
          },
          fail(res) {
            that.setData({
              error: '支付失败'
            })
          }
        })
      },
      fail: r => {
        console.log(r)
        that.setData({
          error: '云服务器错误'
        })
      }
    })
    

    回调函数unipaynotify

    【Cloud.paymentCallback】

    订单在支付成功时会触发该回调函数

    该回调函数必须有返回值,且必须是固定格式

    根据回调函数携带的订单号,修改对应订单号的waiting状态为success,并且返回对应格式的返回信息

    字段名 变量名 必填 类型 描述
    错误码 errcode Number 0
    错误信息 errmsg String

    回调函数携带参数如下

    {
    	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: ''
    	}
    }
    
    const cloud = require('wx-server-sdk')
    cloud.init({
      env: '填写你的云环境ID'
    })
    const db = cloud.database();
    const _ = db.command;
    // 云函数入口函数
    exports.main = async (event, context) => {
    
      console.log('支付成功回调函数触发')
      console.log(event)
      let tradeno = event.outTradeNo;
      console.log(tradeno)
      try {
        let res = await db.collection('pay_record').where({
          orderid:tradeno
        }).update({
          data:{
            paystatus:'success'
          }
        })
        console.log(res)
      } catch (error) {
        return {
          errmsg: 'SERVER_ERROR',
          errcode: -1
        }
      }
      return {
        errmsg: 'SUCCESS',
        errcode: 0
      }
    }
    

    定时查询器,查询结果TimerQuery

    1. 没间隔一秒查询一次,查询到该订单记录为success清除定时触发器,并展示成功信息
    2. 可以使用递归叠加器,计算请求次数,到几次就终止,可自行完成
    TimerQuery(tradeno, paydata) {
    //查询订单支付结果
    var that = this;
    //将计时器赋值给setInter
    that.data.setInter = setInterval(
      function () {
        db.collection('pay_record').where({
          orderid: tradeno,
          paystatus: 'success'
        }).get({
            success: res => {
              if (res.data.length > 0) {
                that.setData({
                  sinfo: '缴费成功'
                })
            clearInterval(that.data.setInter)
    
          }
        }
      })
    }, 1000);
    }
    

    参考 - 我的未开源项目

    Gitee地址:https://gitee.com/Kindear

    写文不易,求个关注

  • 相关阅读:
    VMWARE Linux环境下如何设置共享文件夹?
    linux本地源#如何挂载本地iso镜像作为本地源
    centos7修改系统语言为简体中文
    Redhat镜像-RHEL-官方镜像下载大全
    如何连接到Oracle数据库?
    Oracle 数据库创建导入
    Oracle 12C安装教程
    Oracle 11g安装
    Linux下安装Oracle11g服务器
    Oracle简介
  • 原文地址:https://www.cnblogs.com/masterchd/p/cloudpay.html
Copyright © 2011-2022 走看看