1. 程式人生 > >微信小程式--使用雲開發完成支付閉環

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

#### 微信小程式--使用雲開發完成支付閉環 #### 1.流程介紹 ![](https://img2020.cnblogs.com/blog/1141382/202102/1141382-20210201004552059-1922933214.png) ![](https://img2020.cnblogs.com/blog/1141382/202102/1141382-20210201004607414-743313710.png) #### 2. 程式碼實現和邏輯思想描述 > 雲函式統一下單 對應雲函式 **unipay** > [【CloudPay.unifiedOrder】](https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/open/pay/CloudPay.unifiedOrder.html) > **函式思路** : 呼叫雲函式封裝功能,用時間戳生成對應訂單號,進行統一下單處理,如果兩個返回結果都是`SUCCESS`,那麼將該訂單記錄寫入資料庫,狀態設定為`waiting` 1. body填寫商戶名稱 2. subMchId填寫商戶ID,在雲函式環境管理後臺獲取 ~~~js 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是定時器,查詢支付結果 ~~~js 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】](https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/open/pay/paymentCallback.html) 訂單在**支付成功**時會觸發該回調函式 該回調函式**必須有返回值**,且必須是固定格式 根據回撥函式攜帶的訂單號,修改對應訂單號的`waiting`狀態為`success`,並且返回對應格式的返回資訊 | 欄位名 | 變數名 | 必填 | 型別 | 描述 | | :------- | :------ | :--- | :----- | :--- | | 錯誤碼 | errcode | 是 | Number | 0 | | 錯誤資訊 | errmsg | 是 | String | | 回撥函式攜帶引數如下 ~~~json { 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: '' } } ~~~ ~~~js 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. 可以使用遞迴疊加器,計算請求次數,到幾次就終止,可自行完成 ~~~js 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 > > 寫文不易,求個