Update(2024-4-8): 若初次接触可以参考这篇博客 https://www.cnblogs.com/masterchd/p/14840012.html
Update(2024-4-3): 问题已解决,详情请看回复
---------------------------------------------------------------------
以下为原文:
使用微信小程序+云开发,在页面confirm.js中调用payCreateOrder云函数,在payCreateOrder中调用API cloud.cloudPay.unifiedOrder()能够正确生成订单,且回调给confirm.js。小程序端微信支付相关组件也能成功支付。
但是,在unifiedOrder填入的回调云函数中,接收到的event对象中不包含outTradeNo, totalFee等关键信息,以至于影响到后续的对数据库的操作。
我的需求:在confirm.js中将cart购物车信息传给payCreateOrder云函数, 并且在该云函数中计算出价格、生成订单号、随机字符串等参数,调用unifiedOrder函数获取payment,传回给前端confirm.js并完成支付(到这里我都已经实现了),同时云函数payCallBack在订单支付完成后,将订单号、总金额、用户openid、购物车信息等作为一条记录新增到名为orderList的数据表中。(未实现,因为似乎无法从payCreateOrder中传参给payCallBack)
// code1: confirm.js中处理支付的函数
onClickPay(ev) {
// 微信支付
const cart = this.data.cart;
wx.cloud.callFunction({
name: "payCreateOrder",
data: {
cart: cart //传入购物车信息
}
})
.then(res => {
// 成功生成订单,接下来准备支付
const payment = res.result.payment;
console.log("payment: ", payment);
wx.requestPayment({
...payment //把payCreateOrder云函数的返回结果直接拿来用,不用再写一遍了
})
.then(payRes => {
console.log("支付成功", payRes);
})
.catch(payErr => {
console.error("支付失败", payErr);
});
})
.catch(err => {
console.error("云函数调用失败", err);
});
},
Code 2:payCreateOrder云函数代码
const cloud = require("wx-server-sdk");
cloud.init({
env:"xxxxxxxx"
});
const db = cloud.database()
function generateRandomString() {
let result = '';
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let charactersLength = characters.length;
for (let i = 0; i < 30; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
function getCurrentTime() {
//获取当前时间(精确到分钟)
let now = new Date();
let year = now.getFullYear();
let month = (now.getMonth() + 1).toString().padStart(2, '0');
let day = now.getDate().toString().padStart(2, '0');
let hour = now.getHours().toString().padStart(2, '0');
let minute = now.getMinutes().toString().padStart(2, '0');
let dateTime = year + month + day + hour + minute
return dateTime;
}
function generateOrderNo(){
const currentTime = getCurrentTime() //订单号的前12位为时间
const randSuffix = String( Math.floor(1000 + Math.random() * 9000) ) //订单号的后4位为数字
return ( currentTime+randSuffix )
}
function serializeObject(obj) {
try {
return JSON.stringify(obj);
} catch (error) {
console.error("Error while serializing object:", error);
return null;
}
}
exports.main = async (event, context) => {
const cart = event.cart; //获取从小程序端传入的cart对象
const res = await cloud.callFunction({
name: "QueryForCart",
data: { cart: cart }
});
/*这段代码略,计算总价,没有出现异步操作,且经过检查,生成的total是正确无误的*/
total = parseInt(total * 100) //转换为分,整数
//得到总价total以后,开始调用unifiedOrder微信支付
const randomStr = generateRandomString();
const orderNo = generateOrderNo();
return await cloud.cloudPay.unifiedOrder({
"functionName": "payCallBack", //回调云函数
"envId": "xxxxx",
"subMchId": "xxxxxxxxx",
"nonceStr": randomStr,
"body": "bodybodybodybody",
"outTradeNo": orderNo,
"totalFee": total, //应付金额
"spbillCreateIp": "127.0.0.1",
"tradeType": "JSAPI" //微信小程序调起支付
})
};
代码3: payCallBack 云函数
// payReturn
const cloud = require('wx-server-sdk')
cloud.init({ env:"xxxxxxxxxx"}) // 使用当前云环境
const db = cloud.database()
// 云函数入口函数
exports.main = async (event, context) => {
const r = await cloud.database().collection('log').add({
data:{
log:event //将event对象存入数据库中,方便查看(详情见图3)
}
})
return {errcode:0, errmsg:"ok"};
}
图1: 支付成功后
图2:payCreateOrder云函数日志
图3: 回调云函数payCallBack的event对象(我把它存入了数据库中)
设计方式看起来有问题:
1、payCreateOrder 在创建订单时就应该写入数据库,且订单状态可以设置为支付未成功
2、payCallBack 在支付成功后,根据outTradeNo去查询订单,并修改订单状态为已支付
不应该在payCallBack中才去写数据库。回调仅是用于更新订单状态,标记支付成功还是失败的。
https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/open/pay/paymentCallback.html
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7&index=8
经过后续尝试,在创建了两个新的云函数,并且将
cloud.init({ env:"xxxxxxxx" //云开发环境ID });
直接改为
后有效。回调函数被正常地调用,并且event对象中含有如文档所示的参数。