微信小程序--使用雲開發完成支付閉環


微信小程序--使用雲開發完成支付閉環

優化版支付流程

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

寫文不易,求個關注


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM