• 微信小程序云开发 微信支付功能 逻辑+踩坑


    前置条件

    首先开通微信支付商户号
    然后小程序后台里关联商户号
    在这里插入图片描述

    然后在开发者工具里申请api权限
    云开发》设置》其他设置》微信支付配置
    申请一下权限和绑定
    在这里插入图片描述
    显示已通过即可。

    逻辑请添加图片描述

    首先用户点击支付按钮,就会触发unlock()

    在unlock函数中创建新订单(给order数据库里新加项目)

    创建成功之后返回的_id作为订单id发给pay()

    pay()里共有三个参数(费用,订单id,回调函数),其中回调函数就是支付成功的行为动作,写在了unlock函数里面

    pay函数里面会调用pay云函数

    云函数的写法如下,参考文档来写即可
    坑就是注意费用的单位是分不是元

    pay云函数执行成功后会返回一些参数给wx.requestPayment要求支付,支付成功后会调用pay_success修改订单数据库,然后再在js里面查询订单数据库是否被成功修改,成功修改的话则执行callback逻辑,支付功能完成。

        unlock(e) {
            const Callback1 = res=>{
                //解锁1条的回调操作
                if (res) {
                    //、
                    console.log("好的我已经知道支付成功了!可以获取新answer了!");
                    db.collection("Answer").where({
                        _id: this.data.nowClickAnswer
                    }).update({
                        data: {
                            lock: false
                        }
                    }).then(res => {
                        console.log("解锁" + e.currentTarget.dataset.answerid + "成功!");
                        //付费提示框消失
                        this.setData({
                            peekBubbleVisible: false,
                            unlockSuccessVisible: true
                        })
                        this.getAnswer() //重新渲染一下
                    })
                } else {
                    console.log("最终支付失败");
                }
            };
    
    
            const Callback2 = res=>{
                //解锁全部的回调操作
                if (res) {
                    //、
                    console.log("ALL:好的我已经知道支付成功了!可以获取新answer了!");
                    // 获取集合 "Answer" 中所有文档
                    db.collection("Answer").get().then(res => {
                        const documents = res.data;
                        console.log(res.data);
                        // 遍历所有文档并更新它们的 "lock" 字段为 false
                        const updatePromises = documents.map(doc => {
                            return db.collection("Answer").doc(doc._id).update({
                                data: {
                                    lock: false
                                }
                            });
                        });
                        // 等待所有更新操作完成
                        return Promise.all(updatePromises);
                    }).then(() => {
                        console.log("解锁所有数据成功!");
                        //付费提示框消失
                        this.setData({
                            peekBubbleVisible: false,
                            unlockSuccessVisible: true
                        })
                        this.getAnswer() //重新渲染一下
                    }).catch(err => {
                        console.error("解锁数据失败:", err);
                    });
                } else {
                    console.log("最终支付失败");
                }
            };
    
            console.log("子组件传来的", e.detail.unlock);
            let unlockAnswerId = "all" //用于存入数据库,all就是解锁了全部
            //注意这个费用的单位是分!
            let allFEE = 2 //解锁全部的价钱
            let singleFEE = 1 //单条的价钱
            if (e.detail.unlock == 1) {
                //解锁了本条
                unlockAnswerId = this.data.nowClickAnswer //替换成单条id
                db.collection("orders").add({
                    data: {
                        questionid: this.data.qid,
                        answerid: unlockAnswerId,
                        fee: singleFEE,
                        time: Date.now(),
                        pay_status: false
                    }
                }).then(res => {
                    console.log(res._id); //得到了订单id
                    this.pay(singleFEE, res._id, Callback1)
                })
    
            } else if (e.detail.unlock == 2) {
                //解锁了全部
                console.log("解锁了全部!");
                db.collection("orders").add({
                    data: {
                        questionid: this.data.qid,
                        answerid: unlockAnswerId,
                        fee: allFEE,
                        time: Date.now(),
                        pay_status: false
                    }
                }).then(res => {
                    console.log(res._id); //得到了订单id
                    this.pay(allFEE, res._id, Callback2)
                })
            }
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
        pay(totalFee, id, Callback) {
            //微信支付
            wx.showLoading({
                title: '正在支付',
            })
            wx.cloud.callFunction({
                name: "pay",
                data: {
                    nonceStr: id, //随机字符串,String(32)
                    outTradeNo: id, //商户订单号,String(32)
                    totalFee: totalFee, //Int
                },
                success: res => {
                    console.log("订单发起成功");
                    console.log(res);
                    const payment = res.result.payment
                    wx.hideLoading();
                    console.log(payment);
                    wx.requestPayment({
                        ...payment, //把payment展开
                        success: (res) => {
                            console.log("支付成功", res);
                            //查询支付结果
                            //支付成功则执行修改数据库操作
                            db.collection("orders").where({
                                _id: id
                            }).get().then(res => {
                                console.log("订单结果:", res);
                                if (res.data[0].pay_status) {
                                    console.log("这回是真的支付成功了!");
                                    Callback(true)
                                } else {
                                    Callback(false)
                                }
                            })
                            wx.showToast({
                                title: '支付成功',
                                icon: "success",
                            })
                        },
                        fail: (err) => {
                            console.log("支付失败", err);
                            Callback(false)
                        }
                    })
                }
            })
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    云函数pay

    // 云函数入口文件
    const cloud = require('wx-server-sdk')
    
    cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境
    
    // 云函数入口函数
    exports.main = async (event, context) => {
        const res = await cloud.cloudPay.unifiedOrder({
            "functionName": "pay_success", // 支付结果通知回调云函数名
            "envId": "cloud1-5g85u1hc88261a8f", // 结果通知回调云函数环境
            "subMchId" : "1659317918", // 商户号
            "nonceStr":event.nonceStr,//随机字符串,主要保证签名不可预测
            "body" : "解锁悄悄话", // 商品描述
            "outTradeNo" : event.outTradeNo, // 商户订单号
            "totalFee" : event.totalFee, // 总金额
            "spbillCreateIp" : "127.0.0.1", // 终端 IP,社区说可以随便填,不知道为什么,可能会出bug
            "tradeType":"JSAPI",//交易类型
          })
          return res
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    云函数 pay_success

    // 云函数入口文件
    const cloud = require('wx-server-sdk')
    
    cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境
    
    // 云函数入口函数
    exports.main = async (event, context) => {
        const returnCode = event.returnCode
        const openid = event.userInfo.openid
        const orderid = event.outTradeNo
        const db = cloud.database();
        if(returnCode == 'SUCCESS'){
            //支付成功的处理逻辑
            await db.collection("orders").where({
                _id:orderid,
                _openid:openid,
            }).update({
                data:{
                    pay_status:true
                }
            })
            const res = {errCode:0,errmag:"6666666办款完毕!"}
            return res
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    UIKit Inside: frame bounds position anchorPoint center
    MySQL定时调用预置函数完成数据更新
    Vue3.3指北(四)
    《数理统计》第4章
    37基于MATLAB平台的图像去噪,锐化,边缘检测,程序已调试通过,可直接运行。
    关于产研项目管理的一些思考与记录
    Python常见工厂函数用法
    初学Rabbit MQ
    基于PCA主成分分析的BP神经网络回归预测研究(Matlab代码实现)
    【代码学习】聚类方法及实现记录
  • 原文地址:https://blog.csdn.net/weixin_44986776/article/details/134505354