微信小程序--使用雲開發完成支付閉環
1.流程介紹
2. 代碼實現和邏輯思想描述
雲函數統一下單 對應雲函數 unipay
函數思路 : 調用雲函數封裝功能,用時間戳生成對應訂單號,進行統一下單處理,如果兩個返回結果都是
SUCCESS
,那么將該訂單記錄寫入數據庫,狀態設置為waiting
- body填寫商戶名稱
- 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
}
根據統一下單返回參數,調用微信支付接口
- fee 需要根據訂單計算 fee單位為
0.01
- paydata是商品訂單參數,形式為
Object
,可存放顧客手機號,支付總金額,支付哪一項費用等信息 - 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
訂單在支付成功時會觸發該回調函數
該回調函數必須有返回值,且必須是固定格式
根據回調函數攜帶的訂單號,修改對應訂單號的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
- 沒間隔一秒查詢一次,查詢到該訂單記錄為
success
清除定時觸發器,並展示成功信息 - 可以使用遞歸疊加器,計算請求次數,到幾次就終止,可自行完成
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
寫文不易,求個關注