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

前置条件

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

iOS自动化测试方案(五):保姆级VMware虚拟机安装MacOS

文章目录 一、前言二、VMwareMacOS镜像2.1、先下载vmware-workstation2.2、再下载macOS Big Sur(11.6) 三、图解安装过程3.1、双击VMware-WorkStation Pro图标 四、总结 一、前言 为什么会有虚拟机这种东西?它存在的意义是什么[能解决什么问题]?哈哈~你以…

解锁数据分析的神器:ChatGPT引领人工智能革命

💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 在当今数字化时代,数据分析成为决策…

数据结构(7-2广度~~7-15)所有代码

7-2 迷宫-广度策略 一个陷入迷宫的老鼠如何找到出口的问题。老鼠希望系统性地尝试所有的路径之后走出迷宫。如果它到达一个死胡同,将原路返回到上一个位置,尝试新的路径。在每个位置上老鼠可以向八个方向运动,顺序是从正东开始按照顺时针进行…

【设计模式】结构型设计模式

结构型设计模式 文章目录 结构型设计模式一、概述二、适配器模式(Adapter Pattern)2.1 类适配器模式2.2 对象适配器模式2.3 接口适配器模式2.4 小结 三、桥接模式(Bridge Pattern)四、装饰器模式(Decorator Pattern&am…

《微信小程序开发从入门到实战》学习二十一

3.3 开发创建投票页面 3.3.9 使用picker选择器组件 使用picker选择器组件增加一个设置截止时间的功能。picker是一个从底部弹出的滚动选择器组件。picker通用属性如下: mode 选择器类型(selector、multiSelector、time、date、region) disabled …

USB转CAN的使用说明

前言 USB转CAN是将 TTL 信号转换为 CAN 信号的模块。采用串口作为嵌入式系统的接口,数据传输简单,无需要学习 CAN 协议,缩短开发周期,降低开发成本。模块兼容 3.3V、5V 电源,搭载一个 32 位的 STM32 处理芯片和一个 C…

buildadmin+tp8表格操作(7.1)表格的事件监听(el-table中的事件)

因为buildAdmin是封装的 el-table的组件,所以el-table中的事件, 也是可以使用的, 两者有几个事件是有共同的(比如 双击事件), 这时可以根据自己的需要自行选择 以下代码是 buildadmin 使用 el-table中的事…

键盘映射笔记

dumpkeys命令用于显示当前系统中定义的键盘映射表。它可以帮助用户查看和理解系统中的键盘布局和键盘映射规则。 当用户执行dumpkeys命令时,它会读取系统中的键盘映射表文件(通常是/etc/keymaps或/etc/console/boottime.kmap.gz),…

麒麟KYLINOS2303系统上禁用新功能介绍页面

原文链接:麒麟KYLINOS2303系统上禁用新功能介绍页面 hello,大家好啊,今天给大家带来一篇在麒麟KYLINOS2303系统上禁用新功能介绍页面的文章,在我们安装完系统登录后,会发现有新功能介绍这个界面,我们可以通…

buildadmin+tp8表格操作(8) 表格下方添加 合计行

表格的下方可以自定义添加一个合计行&#xff0c;如果有其它的需求&#xff0c; 我们可以添加我们自已需要的行&#xff0c; 并不局限于合计行 以上就可以给表格的最下方添加一个合计行了 完整代码如下 <template><div class"default-main ba-table-box"&…

Blender烘焙AO操作及对应的python代码

&#xff08;一&#xff09;Blender软件操作 1. 导入模型&#xff08;这里省略&#xff09; 2. 材质设置 模型使用的所有材质都需要删除Surface Shader&#xff0c;没有其他多余的计算&#xff0c;可以大量缩短烘焙时间。删除之后的只留下一个材质输出节点&#xff0c;如图所…

Vatee万腾携手Wiki EXPO 2023悉尼峰会 共谱辉煌未来

悉尼&#xff0c;这座充满活力和创新的城市&#xff0c;即将成为全球商业的焦点。2023年11月16日&#xff0c;由WikiEXPO主办的Wiki Finance Expo Sydney 2023在悉尼马丁广场1号富丽敦酒店隆重开幕&#xff0c;这场金融博览会是澳大利亚今年规模最宏大、备受期待的金融科技盛会…

网上被吹爆的Spring Event事件订阅有缺陷,不要用

Spring Event事件订阅框架&#xff0c;被网上一些人快吹上天了&#xff0c;然而我们在新项目中引入后发现&#xff0c;这个框架缺陷很多&#xff0c;玩玩可以&#xff0c;千万不要再公司项目中使用。还不如自己手写一个监听者设计模式&#xff0c;那样更稳定、可靠。 之前我已…

电磁场与电磁波part5--均匀平面波在无界空间的传播

目录 1、相位速度 2、波阻抗 3、理想介质中均匀平面波的传播特点 4、色散现象 5、导电媒质中均匀平面波的传播特点 6、趋肤效应 7、电磁波的极化 1、相位速度 电磁波的等相位面在空间中的移动速度&#xff08;相速&#xff09; 在自由空间&#xff08;自由空间的光速&a…

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

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

仅需1分钟,搭建一个你自己的工具站

{alert type"info"} 站长工具在工作中应该会有很多人使用&#xff0c;比如说 JSON格式化&#xff0c;UUID生成器&#xff0c;密码生成、URL编码等 今天给大家分享一个英文版的IT-TOOL的搭建教程。 是个开源的项目&#xff0c;地址&#xff1a;https://github.com/Cor…

JZM-D30室温探针台技术参数

概况&#xff1a; JZM-D30室温探针台的诸多设计都是专用的&#xff0c;探针台的配置主要是根据用户的需求进行选配及设计。例如&#xff0c;要求的磁场型号&#xff0c;电源型号&#xff0c;磁场值&#xff0c;样品台的尺寸等&#xff0c;除此之外&#xff0c;该探针台和我司自…

el-tree结合el-switch实现状态切换

<template><div><el-col :span"24"><el-card class"tree-card"><div class"sketch_content selectFile"><span class"span_title">组织列表 </span><div style"display: flex; jus…

【文末送书】计算机网络 | IO多路转接技术 | poll/epoll详解

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

DAY59 503.下一个更大元素II + 42. 接雨水

503.下一个更大元素II 题目要求&#xff1a; 给定一个循环数组&#xff08;最后一个元素的下一个元素是数组的第一个元素&#xff09;&#xff0c;输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序&#xff0c;这个数字之后的第一个比它更大的数&am…