收藏
回答

(已解决)如何正确使用cloudPay.unifiedOrder传参?

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对象(我把它存入了数据库中)

最后一次编辑于  04-08
回答关注问题邀请回答
收藏

2 个回答

  • Alfred Huang
    Alfred Huang
    03-29

    设计方式看起来有问题:

    1、payCreateOrder 在创建订单时就应该写入数据库,且订单状态可以设置为支付未成功

    2、payCallBack 在支付成功后,根据outTradeNo去查询订单,并修改订单状态为已支付

    不应该在payCallBack中才去写数据库。回调仅是用于更新订单状态,标记支付成功还是失败的。

    03-29
    有用 1
    回复 7
    查看更多(2)
  • 哄哄
    哄哄
    04-03

    经过后续尝试,在创建了两个新的云函数,并且将

    cloud.init({
      env:"xxxxxxxx" //云开发环境ID
    });  
    

    直接改为

    cloud.init();  
    

    后有效。回调函数被正常地调用,并且event对象中含有如文档所示的参数。


    04-03
    有用 1
    回复
登录 后发表内容