小程序智能聊天机器人(二)

article/2025/9/28 2:06:57

小程序实战之会员支付流程

  • 背景
  • 会员套餐设置
  • 获取套餐
  • 订单创建
  • 支付订单申请
  • 支付回调
  • 更新用户权益
  • 总结

背景

接上篇小程序智能聊天机器人(一),
无论何种程序,在我们没有其他收益来源时,用户付费,是让我们回笼成本的重要渠道之一,所以在一个项目中,会员支付就比较重要了,接下来我们继续进行。

会员套餐设置

所谓会员,就要有不同的会员套餐,就像我们用QQ,各类影视平台一样,有一个月,两个月,三个月,等等。所以我们也先来搞个套餐。我们先来建个表:

CREATE TABLE `t_vip_package` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',`vip_name` varchar(100) DEFAULT NULL COMMENT '会员名称',`vip_description` varchar(1000) DEFAULT NULL COMMENT '会员描述',`original_price` decimal(10,2) DEFAULT NULL COMMENT '原价',`price` decimal(10,2) DEFAULT NULL COMMENT '价格',`show_status` char(1) DEFAULT NULL COMMENT '显示状态:0隐藏 1显示',`vip_type` char(1) DEFAULT NULL COMMENT '会员类型:0天 1月 2年 3永久',`duration` int(11) DEFAULT NULL COMMENT '时长仅在永久时可为空',`day_times` bigint(20) DEFAULT NULL COMMENT '每日提问数',`choose_status` varchar(100) DEFAULT NULL COMMENT '默认选中:0未选中 1选中',`create_time` datetime DEFAULT NULL COMMENT '创建时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='会员套餐';

表创建完了,自己加几个套餐数据进去用来测试

获取套餐

我们开放接口给小程序端获取所有的套餐列表:

	@PostMapping("getAllVipPackages")public AjaxResult getAllVipPackages(){startPage();List<VipPackage> vipPackages = vipPackageService.list(new QueryWrapper<VipPackage>().eq("show_status", "1"));vipPackages.forEach(vipPackage -> {//这里我们计算一下每天多少钱,用于前台展示vipPackage.setDayPrice(new BigDecimal("0"));if(!"3".equals(vipPackage.getVipType())){String vipType = vipPackage.getVipType();BigDecimal o = new BigDecimal("1");if ("1".equals(vipType)){o = new BigDecimal("30");}if ("2".equals(vipType)){o = new BigDecimal("365");}BigDecimal totalDay = new BigDecimal(vipPackage.getDuration()).multiply(o);vipPackage.setDayPrice(vipPackage.getPrice().divide(totalDay, BigDecimal.ROUND_CEILING));}});return AjaxResult.success(getDataTable(vipPackages));}

前台效果是这样:
在这里插入图片描述

订单创建

小程序端选中套餐之后,我们后台提供一个订单生成接口,存储一些基本信息,然后把订单主键返回给前端。这里我们也可以直接向微信官方发起支付申请,因为小程序内只能进行微信支付,因为我的项目不仅在小程序端,所以进行了这一步操作。

    @PostMapping("createOrder")@RestApipublic AjaxResult createOrder(Long vipId){Long userId = JwtTokenUtil.getUserId;VipPackage vipPackage = vipPackageService.getById(vipId);if (StringUtils.isNull(vipPackage)){return AjaxResult.error("该套餐不存在");}Order order = new Order();order.setVipName("充值"+vipPackage.getVipName());order.setPrice(vipPackage.getPrice());order.setVipId(vipId);order.setUserId(userId);order.setDuration(vipPackage.getDuration());order.setUnits(vipPackage.getVipType());order.setIsAll("3".equals(vipPackage.getVipType()) ? "1" : "0");orderService.save(order);Map<String, Long> retObj = new HashMap<>();retObj.put("orderId", order.getId());return AjaxResult.success("订单创建成功!", retObj);}

支付订单申请

前端拿到我们的主键之后,可申请发起支付,这个时候,我们再向微信发起支付申请:

	@PostMapping("/toPay")@ApiOperation("支付订单")@RestApipublic AjaxResult toPay(Long orderId, String payType){Order order=orderService.getById(orderId);if (StringUtils.isNull(order)){return AjaxResult.error("订单不存在");}if (order.getStatus().equals("1")){return AjaxResult.error("该订单已支付");}order.setOrderNo(RandomUtil.randomNumbers(13));order.setPayType(payType);orderService.updateById(order);switch (payType){case "1": //支付宝return aliPayConfig.AliPay(order);case "2"://微信支付,参考官方api进行一些参数配置就好。return wxPayConfig.WxPay(order);default:return AjaxResult.error("请选择支付方式");}}

把官方的数据,返回给前端,前端就可以拉起支付了。

支付回调

用户支付完成之后,微信官方会给我们回调通知,也就是告诉我们支付的结果,我们需要在拿到成功支付结果后,再更新一下用户的会员权益

 public String wxPayNotify(HttpServletRequest request) {String xmlMsg = HttpKit.readData(request);log.info("微信支付通知=" + xmlMsg);Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);String returnCode = params.get("return_code");//获取创建时候的 商户订单号(唯一就行)String orderNo = params.get("out_trade_no");Map<String, String> xml;// 注意此处签名方式需与统一下单的签名类型一致
//		if (WxPayKit.verifyNotify(params, "初始密钥", SignType.HMACSHA256)) {if (WxPayKit.verifyNotify(params,PaySetConfig.KEY, SignType.HMACSHA256)) {if (WxPayKit.codeIsOk(returnCode)) {// 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态Order order = orderService.getOne(new QueryWrapper<Order>().lambda().eq(Order::getOrderNo, orderNo));if (order.getStatus().equals("1")) {xml = new HashMap<>(2);xml.put("return_code", "-1");xml.put("return_msg", "订单状态失效或已支付,请重新下单");return WxPayKit.toXml(xml);}// 更新订单信息aliPayConfig.updateOrder(order);// 发送通知等xml = new HashMap<>(2);xml.put("return_code", "200");xml.put("return_msg", "回调成功");return WxPayKit.toXml(xml);}}return null;}

我们先给官方回复个消息,告诉他,我收到通知了!

更新用户权益

接下来更新下用户权益,整个流程就完成了:

/** 修改订单及业务逻辑*/public void updateOrder(Order order){order.setStatus("1");//        AppUser appUser=appUserService.getOne(new QueryWrapper<AppUser>().eq("userName", order.getUserId()));AppUser appUser = appUserService.getById(order.getUserId());if(StringUtils.isNull(appUser) || appUser.getUserType().equals("3")){orderService.updateById(order);return;}VipPackage vipPackage = vipPackageService.getById(order.getVipId());appUser.setUserType("1");//会员appUser.setDayLimitTimes(vipPackage.getDayTimes());//充值套餐if (vipPackage.getVipType().equals("3")) {//是否永久appUser.setUserType("3");//永久} else {//过期时间 TODO//用户过期时间appUser.setVipExpTime(getUserExpTime(StringUtils.isNull(appUser.getVipExpTime()) ? new Date(): appUser.getVipExpTime(),vipPackage.getDuration(), vipPackage.getVipType()));//该会员过期时间order.setExpTime(getUserExpTime(new Date(), vipPackage.getDuration(), vipPackage.getVipType()));//其他会员顺延setOtherVipExpTime(appUser.getId(), order.getId(), vipPackage.getDuration(), vipPackage.getVipType());}if(StringUtils.isNull(appUser.getVipExpTime()) || appUser.getVipExpTime().before(new Date())){//处理下生效时间,若是已失效,则从当前开始appUser.setVipEffTime(new Date());}orderService.updateById(order);appUserService.updateById(appUser);
//        order.set(getUserExpTime();
//        AsyncManager.me().execute(MyMessageFactory.socketSendToAll(appUser,"expTime"));}

总结

文章内我对整个流程代码没有做细节的讲述,我觉得开发主要是你针对项目的业务场景,有个大概的流程框架,这个东西具备之后,你可以慢慢往里面填写你的业务代码,反正我每次都是先这么干的,先评估整个项目大概需要后端做哪些接口,然后再去把接口中的业务逻辑慢慢填充起来。重要的就是思路要清晰,每一步要做什么先搞清楚!


http://chatgpt.dhexx.cn/article/dSNZlaHN.shtml

相关文章

图灵机器人( 智能回复微信)及(智能聊天)

目录 一、什么是图灵机器人&#xff1f;二、帮你自动微信回复&#xff08;Python版&#xff09;三、图灵机器人智能聊天&#xff08;微信小程序版&#xff09; 一、什么是图灵机器人&#xff1f; 1、 图灵机器人简介&#xff1a; 是中文语境下智能度最高的“机器人大脑”&…

linux系统抓包命令

IP地址抓包&#xff1a;tcpdump -i any host 1.1.1.2 -n 端口抓包&#xff1a; tcpdump -i any port 6789 -n wireshak工具抓包&#xff1a;tcp.port 6789 过滤源ip、目的ip。在wireshark的过滤规则框Filter中输入过滤条件。如查找目的地址为192.168.101.8的包&#xff0c;ip.…

Linux 抓包命令,你会用吗?

点击关注公众号&#xff0c;Java干货及时送达 tcpdump是一个功能强大的命令行数据包分析器&#xff0c;它是通过监听服务器的网卡来获取数据包&#xff0c;所有通过网络访问的数据包都能获取到。它也提供了过滤器的功能&#xff0c;可以获取指定的网络、端口或协议的数据包 程序…

网络高级命令使用,Linux测试带宽,抓包,一篇解决。

目录 一&#xff0c;iperf测试带宽命令 二&#xff0c;详细网络设备信息 三&#xff0c;当前网络状态 四&#xff0c;抓包tcpdump 一&#xff0c;iperf测试带宽命令 iper -s 作为服务器 -c 作为客户机 -u 使用udp协议 -t 测试时间 -i 间隔时间 -n 要测试的量 -p 通过的端…

linux如何抓包如何分析

为什么要抓包 今天遇到一个bug&#xff0c;访问某接口的时候遇到了HTTP 413报错&#xff0c;意思就是&#xff0c;在网络中的某个节点觉得这个请求太大了&#xff0c;就拒绝了&#xff0c;返回了HTTP 413虽然理解是这么回事&#xff0c;但是要想解决这个问题&#xff0c;首先第…

Linux抓包命令集锦

相信抓包是程序员&#xff0c;运维工程师&#xff0c;架构师&#xff0c;都必不可少的一项技能。但是能够深入掌握好这门技艺的人&#xff0c;确实需要有开发&#xff0c;网络&#xff0c;运维&#xff0c;架构等"跨界”背景才能比较好的发挥抓包神技的威力。本文是纯干货…

怎么在Linux上抓包分析

怎么在Linux上抓包分析 1、在Linux上抓包 例如在Ubuntu上&#xff0c;用命令抓包&#xff0c; tcpdump tcp -i any -s0 -w desk.cap 用 sz desk.cap 把数据包导入本地Windows 2、在windows上用wireshark分析 用wireshark打开desk.cap wireshark筛选条件&#xff1a;tcp…

Linux之tcpdump抓包命令详解

目录 前言 1. 控制抓包行为 2. 控制信息如何显示 3. 控制显示什么数据 4. 过滤命令 4.1 地址过滤 4.2 协议及端口过滤 4.3 报文特征过滤 4.3.1 IP选项设置&#xff08;20字节&#xff0c;可变部分&#xff08;0-20)B&#xff0c;最大40字节&#xff09; 4.3.2 TCP选项…

纯干货:Linux抓包命令集锦

/****************************************************************************************** *              版权声明 *   本文为本人原创&#xff0c;本人拥有此文的版权。鉴于本人持续受益于开源软件社区&#xff0c; * 本人声明&#xff1a;任何个人…

MySQL数据库约束

文章目录 一、表的约束二、空属性三、默认值四、列描述五、zerofill六、主键1.primary key2.复合主键 七、自增长八、唯一键九、外键 一、表的约束 MySQL数据库是有唯一性约束的&#xff0c;真正对表的字段进行约束的是字段类型&#xff0c;比如我们字段类型规定的取值范围是多…

MySql 数据库【约束】

MySql 数据库【约束】 1. 什么是约束&#xff1f;2. 约束包括哪些&#xff1f;3. 非空约束4. 唯一性约束1. 单字段唯一性约束2. 多字段唯一性约束 5. 主键约束1. 主键约束的相关术语&#xff1f;2. 什么是主键&#xff1f;有啥用&#xff1f;3. 单一主键4. 复合主键5. 其他主键…

MySQL_数据库的约束

文章目录 1. NULL约束 2. UNIQUE(唯一约束) 3. DEFAULT(默认值约束) 4. PRIMARY KEY(主键约束) 5. FOREIGN KEY(外键约束) 数据库的约束就是关系型数据库给我们提供的一种"校验数据"合法性的机制 1. NULL约束 创建表时,可以指定某列不为空 create table stud…

MYSQL--数据库约束

文章目录 1.数据库约束1.1约束类型1.2 null约束1.3 unique:唯一约束条件1.4 default:默认值约束1.5 primary key1.6 foreign key:外键约束 2.表的设计2.1一对一2.2一对多2.3多对多 1.数据库约束 1.1约束类型 not null: 指示某列不能存储null值&#xff1b;unique: 保证某列的…

MySQL 数据库约束

目录 一、数据库约束 1、约束类型 二、NULL 约束 三、unique 约束 四、default 约束 五、primary key 约束 自增主键 六、foreign key 外键约束 七、check 约束 一、数据库约束 我们使用数据库来存储数据&#xff0c;一般是希望这里存储的数据是靠谱的&#xff0c;…

数据库的约束和设计(完整版)

第一部分(约束和表设计) 1、DQL查询语句-limit语句(掌握) LIMIT是限制的意思&#xff0c;所以LIMIT的作用就是限制查询记录的条数 LIMIT语句格式: SELECT 字段 FROM 表名 LIMIT 索引, 显示条数; 索引&#xff1a;从0开始&#xff0c;一直变化 显示条数&#xff1a;每页显示…

MySQL数据库之数据库约束,一文带你了解

前言 从今天开始本系列就带各位小伙伴学习数据库技术。数据库技术是Java开发中必不可少的一部分知识内容。也是非常重要的技术。本系列教程由浅入深, 全面讲解数据库体系。 非常适合零基础的小伙伴来学习。 全文大约 【1785】字&#xff0c;不说废话&#xff0c;只讲可以让你学…

数据库的约束和设计

约束 作用 对表中的数据进行进一步的限制, 保证数据的正确性, 有效性和完整性 种类 primary key : 主键约束unique : 唯一约束not null : 非空约束default : 默认值foreign key : 外键约束auto_increment : 自增约束(适用于int数据类型) 主键约束 特点 非空且唯一 注意事项 …

MySQL:数据库的约束

目录 1.数据库约束 1.1 非空&#xff1a;not null 1.2 唯一&#xff1a;unique ​​​​​​​ 1.3 默认值&#xff1a;default 1.4 列描述&#xff1a;comment 1.5 主键约束&#xff1a;primary key 1.6 外键约束 1.7 综合案例 2.插入查询结果 3.聚合函数 4.group by…

oracle数据库:约束

约束简介 约束是数据库用来确保数据满足业务规则的手段&#xff0c;不过在真正的企业开发中&#xff0c;除了主键约束这类具有强需求的约束&#xff0c;像外键约束&#xff0c;检查约束更多时候仅仅出现在数据库设计阶段&#xff0c;真实环境却很少应用&#xff0c;更多是放到…

[数据库]表的约束

●&#x1f9d1;个人主页:你帅你先说. ●&#x1f4c3;欢迎点赞&#x1f44d;关注&#x1f4a1;收藏&#x1f496; ●&#x1f4d6;既选择了远方&#xff0c;便只顾风雨兼程。 ●&#x1f91f;欢迎大家有问题随时私信我&#xff01; ●&#x1f9d0;版权&#xff1a;本文由[你帅…