微信小程序--使用云开发完成支付闭环
<h4 id="微信小程序--使用云开发完成支付闭环">微信小程序--使用云开发完成支付闭环</h4><p>优化版支付流程</p>
<h4 id="1流程介绍">1.流程介绍</h4>
<p><img src="https://img2020.cnblogs.com/blog/1141382/202102/1141382-20210201004552059-1922933214.png" alt="" loading="lazy"><br>
<img src="https://img2020.cnblogs.com/blog/1141382/202102/1141382-20210201004607414-743313710.png" alt="" loading="lazy"></p>
<h4 id="2-代码实现和逻辑思想描述">2. 代码实现和逻辑思想描述</h4>
<blockquote>
<p>云函数统一下单 对应云函数 <strong>unipay</strong></p>
</blockquote>
<blockquote>
<p>【CloudPay.unifiedOrder】</p>
</blockquote>
<blockquote>
<p><strong>函数思路</strong> : 调用云函数封装功能,用时间戳生成对应订单号,进行统一下单处理,如果两个返回结果都是<code>SUCCESS</code>,那么将该订单记录写入数据库,状态设置为<code>waiting</code></p>
</blockquote>
<ol>
<li>body填写商户名称</li>
<li>subMchId填写商户ID,在云函数环境管理后台获取</li>
</ol>
<pre><code class="language-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 .map(formatNumber).join('-') + ' ' + .map(formatNumber).join(':')
}
function TimeCodeYmd(){
var date = new Date();
var year = date.getFullYear()
var month = date.getMonth() + 1
var day = date.getDate()
return .map(formatNumber).join('-');
}
function formatNumber(n) {
n = n.toString()
return n ? n : '0' + n
}
</code></pre>
<blockquote>
<p>根据<strong>统一下单</strong>返回参数,调用微信支付接口</p>
</blockquote>
<ol>
<li>fee 需要根据订单计算 fee单位为<code>0.01</code></li>
<li>paydata是商品订单参数,形式为<code>Object</code>,可存放顾客手机号,支付总金额,支付哪一项费用等信息</li>
<li>TimerQuery是定时器,查询支付结果</li>
</ol>
<pre><code class="language-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: '云服务器错误'
})
}
})
</code></pre>
<blockquote>
<p>回调函数<strong>unipaynotify</strong></p>
<p>【Cloud.paymentCallback】</p>
</blockquote>
<p>订单在<strong>支付成功</strong>时会触发该回调函数</p>
<p>该回调函数<strong>必须有返回值</strong>,且必须是固定格式</p>
<p>根据回调函数携带的订单号,修改对应订单号的<code>waiting</code>状态为<code>success</code>,并且返回对应格式的返回信息</p>
<table>
<thead>
<tr>
<th style="text-align: left">字段名</th>
<th style="text-align: left">变量名</th>
<th style="text-align: left">必填</th>
<th style="text-align: left">类型</th>
<th style="text-align: left">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">错误码</td>
<td style="text-align: left">errcode</td>
<td style="text-align: left">是</td>
<td style="text-align: left">Number</td>
<td style="text-align: left">0</td>
</tr>
<tr>
<td style="text-align: left">错误信息</td>
<td style="text-align: left">errmsg</td>
<td style="text-align: left">是</td>
<td style="text-align: left">String</td>
<td style="text-align: left"></td>
</tr>
</tbody>
</table>
<p>回调函数携带参数如下</p>
<pre><code class="language-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: ''
}
}
</code></pre>
<pre><code class="language-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
}
}
</code></pre>
<blockquote>
<p>定时查询器,查询结果<strong>TimerQuery</strong></p>
</blockquote>
<ol>
<li>没间隔一秒查询一次,查询到该订单记录为<code>success</code>清除定时触发器,并展示成功信息</li>
<li>可以使用递归叠加器,计算请求次数,到几次就终止,可自行完成</li>
</ol>
<pre><code class="language-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);
}
</code></pre>
<blockquote>
<p>参考 - 我的未开源项目</p>
<p>Gitee地址:https://gitee.com/Kindear</p>
<p>写文不易,求个关注</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/masterchd/p/cloudpay.html
頁:
[1]