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

news2024/9/20 22:52:39

前置条件

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

然后在开发者工具里申请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)
            })
        }
    },
    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)
                    }
                })
            }
        })
    },

云函数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
}

云函数 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
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1229703.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UE5 - ArchvizExplorer - 数字孪生城市模板 - 功能修改

数字孪生项目,大多是双屏互动,而非下方菜单点击,所以要做一番改造 参考:https://blog.csdn.net/qq_17523181/article/details/133853099 1. 去掉提示框 打开BP_MasterMenu_Widget,进入EventGraph,断开Open…

【Docker】从零开始:1.Docker概述

【Docker】从零开始:1.Docker概述 1.什么是Docker2.为什么要使用Docker3.传统虚拟机技术与Linux容器技术的区别(1).传统虚拟机技术(2).Linux容器 4.Docker的特点一次构建、随处运行a.更快速的应用交付和部署b.更便捷的升级和扩缩容:c.更简单的系统运维d.…

windows环境搭建Zblog博客并发布上线公网可访问

文章目录 1. 前言2. Z-blog网站搭建2.1 XAMPP环境设置2.2 Z-blog安装2.3 Z-blog网页测试2.4 Cpolar安装和注册 3. 本地网页发布3.1. Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 想要成为一个合格的技术宅或程序员,自己搭建网站制作网页是绕…

软件测试/测试开发丨人工智能的与软件测试完美结合

随着人工智能(AI)技术的不断发展,软件测试领域也在不断演变。结合ChatGPT、知识图谱、PyTorch深度学习框架以及视觉与图像识别自动化测试,我们探讨了软件测试在人工智能时代的前沿应用,以及如何通过这些创新技术提高软…

Vue3的7种和Vue2的12种组件通信

Vue3 组件通信方式 props$emitexpose / ref$attrsv-modelprovide / injectVuex Vue3 通信使用写法 props 用 props 传数据给子组件有两种方法&#xff0c;如下 方法一&#xff0c;混合写法 // Parent.vue 传送 <child :msg1"msg1" :msg2"msg2">…

公益SRC挖掘小技巧

目录 1、寻找漏洞 1)谷歌语法 2)fofa 2、挖掘漏洞 3、提交报告 第一步&#xff1a;“标题”和“厂商信息”和“所属域名” 第二步&#xff1a;其它内容 第三步&#xff1a;复现步骤 0、IP域名归属证明 1、漏洞页 2、该干啥 3、注入的结果 4、上榜吉时 时间&#x…

Git 笔记之gitignore

解释为&#xff1a;git ignore 即&#xff0c;此类型的文件将会被忽略掉&#xff0c;从而不会进行管理 具体的模板可以从 GitHub 网站上来进行设置 Common_gitignore: gitignoregithub开源项目&#xff0c;增加Kingdee开发内容 例如&#xff1a;Java模板&#xff1a; # Co…

纯CSS实现炫酷文本阴影效果

如图所示&#xff0c;这是一个文本阴影效果&#xff0c;阴影有多个颜色&#xff0c;鼠标悬停时文本阴影效果消失&#xff0c;文本回到正常的效果。让我们逐步分解代码&#xff0c;看看如何使用纯CSS实现这个效果的。 基于以上动图可以分析出以下是本次实现的主要几个功能点&am…

linux高级篇基础理论五(用户安全,口令设置,JR暴力破解用户密码,NMAP端口扫描)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️不能因为人生的道路坎坷,就使自己的身躯变得弯曲;不能因为生活的历程漫长,就使求索的 脚步迟缓。 ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xff1a;云计算技…

git修改commit历史提交时间、作者

1、修改最近的几条记录&#xff0c;进入提交记录列表&#xff0c;修改提交记录模式 git rebase -i HEAD~3 // 修改最近的三条记录&#xff0c;顺序排列按提交时间升序 指令说明&#xff1a; pick&#xff1a;保留该commit&#xff08;缩写:p&#xff09; reword&#xff1a…

linux上交叉编译qt库

linux上交叉编译qt库 Qt程序从X86平台Linux移植到ARM平台Linux需要做什么 1.在ubuntu上使用qt的源码交叉编译出Qt库 2.将编译好的库拷贝到开发板上并设置相应的环境变量&#xff08;库路径啥的&#xff09; 前两步一劳永逸&#xff0c;做一次就行 3.X86上写好程序代码&…

纯CSS动态渐变文本特效

如图所示&#xff0c;这是一个炫酷的文本渐变效果&#xff0c;如同冰岛的极光一般。本次的文章让我们逐步分解代码&#xff0c;了解其实现原理。 基于以上动图效果可以分析以下是本次动效实现的主要几点&#xff1a; 文本中有多个颜色的动画每个颜色显示的半径不同&#xff0…

适合上班族考的证书 - PMP证书

PMP证书是一种专业的项目管理证书&#xff0c;适合上班族考取。随着社会的发展和竞争的加剧&#xff0c;越来越多的企业开始注重项目管理能力的培养和提升。而PMP证书正是国际上公认的项目管理领域的权威认证&#xff0c;具有很高的知名度和影响力。 首先&#xff0c;PMP证书对…

成都优优聚美团代运营:塑造卓越优势,引领电商新时代

在当今这个数字化时代&#xff0c;美团作为中国最大的本地生活服务平台之一&#xff0c;正在为消费者和商家搭建一个无缝链接的桥梁。而在成都&#xff0c;有一家名为优优聚美团代运营的公司&#xff0c;他们凭借着专业的技能和高效的服务&#xff0c;成为了美团平台上的佼佼者…

越南MIC新规针对ICT和ITE产品电气授权标准变更

从2024年1月1日起&#xff0c;所有ICT和ITE产品(如台式电脑、笔记本电脑、平板电脑、DVB-T2电视/机顶盒、DECT电话等)都需要越南MIC授权的电气安全标准——QCVN132:2022。 目前MIC仍未最终确定要求&#xff0c;因为这与另一个监管机构存在冲突。所以目前他们可以接受ISO 17025的…

同创永益联合红帽打造一站式数字韧性解决方案

随着AI技术的快速兴起&#xff0c;IT技术已成为推动业务持续增长的重要驱动力&#xff0c;这要求企业不断尝试新事物&#xff0c;改变固有流程&#xff0c;加强IT技术与业务的合作&#xff0c;同时提升数字韧性能力&#xff0c;以实现业务目标。10月26日&#xff0c;红帽2023中…

UEC++ day6

简易战斗系统 删除替换父类组件 现在需要添加剑的组件&#xff0c;但是一般来说附着到蒙皮骨骼的东西&#xff0c;也是蒙皮骨骼&#xff0c;所以我们可以新建一个类重新编写&#xff0c;也可以直接继承Interoperable类然后不管UStaticMeshComponent这个组件&#xff0c;新建U…

HarmonyOS开发(四):应用程序入口UIAbility

1、UIAbility概述 UIAbility 一种包含用户界面的应用组件用于与用户进行交互系统调度的单元为应用提供窗口在其中绘制界同 注&#xff1a;每一个UIAbility实例&#xff0c;都对应一个最近任务列表中的任务。 一个应用可以有一个UIAbility也可以有多个UIAbility。 如一般的…

微服务学习|Nacos配置管理:统一配置管理、配置热更新、配置共享、搭建Nacos集群

统一配置管理 在微服务当中&#xff0c;提供一个配置中心来将一些配置提取出来&#xff0c;进行统一的使用&#xff0c;Nacos既可以充当注册中心&#xff0c;也提供配置中心的功能。 1.在Nacos中添加配置文件 在Nacos控制台&#xff0c;我们可以在配置管理中&#xff0c;添加…