坑在哪里
前提:使用小程序云支付且使用小程序的云数据库来记录用户支付信息,没有后台接口参与的场景
坑:wx.requestPayment,该方法是用于微信的拉起支付请求,该方法的success回调触发节点是点击图中完成按钮。 如果用户没有点击完成,直接关闭了小程序,则无法触发wx.requestPayment这个方法的success回调。
如何解决:如果你自己使用云支付且记录小程序自己的云数据库的话,支付的云函数一定要在 cloud.cloudPay.unifiedOrder生成订单填写回调函数,在这个云支付回调函数内,去更新数据库订单信息,如下图所示
正常的云支付流程
-
编写云支付函数
// 云函数代码
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database()
function pad(num) {
return num.toString().padStart(2, "0");
}
function formatDateTime(date) {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hour = date.getHours();
const minute = date.getMinutes();
const second = date.getSeconds();
return `${year}-${pad(month)}-${pad(day)} ${pad(hour)}:${pad(minute)}:${pad(
second
)}`;
}
exports.main = async (event, context) => {
const outTradeNo = "1675520950" + new Date().getTime() + Math.floor(Math.random() * 10)
const res = await cloud.cloudPay.unifiedOrder({
"body": event.goodName, // 商品描述
"outTradeNo": outTradeNo, // 商户订单号
"spbillCreateIp": "127.0.0.1", // 终端 IP
"subMchId": "", // 商户号
"totalFee": event.totalFee, // 总金额
"envId": "", // 云函数环境名称
"functionName": "payCallBack" // 支付结果通知回调云函数名
})
let nowTime = formatDateTime(new Date())
console.log('统一下单', outTradeNo, nowTime)
// 这里落库数据记录用户有支付的操作,并不代表支付成功了
await db.collection('xxxxx').add({
data: {
_openid: event.openId,
outTradeNo: outTradeNo,
payStatus: false, // 这里记录是未支付成功
time: nowTime,
payMoney: event.payMoney
}
})
return res
}
-
编写云支付回调函数
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
}) // 使用当前云环境
const db = cloud.database()
// 云函数入口函数
exports.main = async (event, context) => {
let {
returnCode,
outTradeNo
} = event
// 这里是真正支付成功之后才会更新数据的订单状态
if (returnCode == 'SUCCESS') {
// 这里的xxxx是云数据库的表名
await db.collection('xxxx').where({
outTradeNo: outTradeNo
}).update({
data: {
payStatus: true
}
})
}
return {
errcode: 0,
errmsg: ''
}
}
-
业务场景调用支付
goPay(formData) {
let opid = wx.getStorageSync('openid')
wx.showLoading({
title: '加载中',
})
wx.cloud.callFunction({
name: 'pay',
data: {
goodName: 'xxxx',
totalFee: Number(this.data.payMoney) * 100,
openId: opid,
payMoney: this.data.payMoney,
...formData,
},
success: res => {
const payment = res.result.payment
wx.requestPayment({
...payment,
success: (res) => {
wx.hideLoading()
wx.setStorageSync('payMoney', this.data.payMoney)
this.clearFormData()
wx.navigateTo({
url: '/pages/business/paySuccess/index',
});
console.log('支付成功', res)
},
fail: (err) => {
wx.hideLoading()
wx.showToast({
title: '支付失败',
icon: 'none',
duration: 4000,
});
console.log('支付失败', err)
}
})
},
fail: (res) => {
console.log('云函数错误', res)
}
})
},