1.课程发布数据的查询

  1. 查询的原因:
  • 校验课程发布的正确性
  • 课程发布后两个数据
    • coursePub、coursePubMsg
  1. 查询课程内容走索引库的原因
  • 索引库性能好:
    • 承受大并发量
  • 查询效率高:

    • 数据结构倒排索引、数据可以基于内存来存储

      2. 学员学习记录的查询

      查询的原因
  • 查询学员对收费课程是否有购买

  • 用户对于收费课程购买后,会自动创建出一个学习记录(默认:第一章第一小节)
  • 学习记录中有收费是否支付的标识:paid

    3.学员选课支付前的业务操作流程

    image.png
  1. 学员通过UAA认证系统登录成功
  2. 进入课程详情页面时需要调用以下两个后端服务
  • 课程搜索服务
    • 从索引库中查询课程内容,查询课程发布信息
  • 学习中心微服务
    • 从数据库中查询记录,查询学员课程学习记录

3.学员购买课程进入课程订单支付页面,调用订单微服务

  • 创建订单需要远程调用课程搜索服务查询课程信息,判断课程是否存在
  • 课程收费的话会创建订单新增或修改订单表
  • 调用第三方支付系统创建订单支付表,保存订单支付记录

    4.微信支付统一下单流程

    image.png
  1. 当用户在支付页面中,选择某支付方式并确认时,前端向订单服务请求创建支付接口
  2. 订单服务 通过订单id获取要支付的订单信息,并将订单信息组装为第三方支付的下单请求数据,调用第三方支付服务下单。
  3. 订单服务 接收第三方支付返回的支付二维码url,并将此url返回给前端
  4. 前端将url生成为二维码,展示给用户

    5.开通商户后的关键数据

  5. 微信公众账号或开放平台APP的唯一标识

  6. 商户号
  7. 商户密钥

以下是示例
appid:微信公众账号或开放平台APP的唯一标识 wx8397f8696b538317
mch_id:商户号 1473426802
key:商户密钥 T6m9iK73b0kn9g5v426MKfHQH7X8rKwb

6.订单数据和订单支付数据的区别

订单数据是一个人对一个收费课程的购买数据记录,包含订单状态,课程信息,订单支付人的信息
订单支付数据是一个人对订单的支付情况数据记录,包含支付状态,第三方支付的数据

7.第三方支付平台交互

  1. 实现方
    • 微信支付系统
  2. 使用版本
    • v2
  3. 支付方式
    • 二维码支付
  4. 官方支付版本v2,v3的最大不同点
    • v2数据交互格式xml
    • v3数据交互格式 json
  5. 商户支付需要开发的功能

    • 开发和第三方支付统一下单
      • 获得二维码的链接地址
    • 支付通知结果
      • 获得用户支付的结果数据—第三方主动通知商户支付结果

        8.订单支付数据和微信统一下单的执行顺序

        先进行订单支付数据的保存,本地事务可以回滚
        后执行微信统一下单,微信事务我们操作不了
        先调用第三方的场景,尽量避免此类场景
        需要记录第三方支付的数据,先走第三方,再去数据库操作
        image.png
        微信支付集成流程
  6. 商户后台根据用户选购的商品生成订单

  7. 用户确认后,调用微信支付系统的统一下单API生成预支付交易,并返回预支付交易链接code_url
  8. 商户系统前端将链接生成二维码
  9. 用户扫描二维码,微信支付系统验证链接有效,然后要求用户授权
  10. 用户确认支付输入密码,提交支付授权
  11. 微信支付系统验证授权,完成支付交易,并向用户返回交易结果
  12. 微信支付系统通过发送异步消息通知商户后台支付结果(主动通知位24小时04分),超时后需商户主动调用接口获取

支付结果通知

  1. 微信支付系统主动发送异步消息通知商户(时间:24h4min内发送)
  2. 商户在时间内未收到通知,需自行调用查询订单API主动查询结果通知

    9. 创建订单和订单支付业务分析实现

    1. 创建订单

    订单表数据模型
    image.png
  • 规范字段描述:id,创建、修改时间
  • 用户信息描述:用户id, 用户名
  • 课程信息描述:机构id,课程id,课程名称等
  • 订单信息描述:订单号,定价,交易价,课程有效性,起始时间没结束时间,交易状态等

接口定义
image.png
image.png

  1. 业务分析
  2. 0.是否开启事务(开启)
  3. 1.判断关键数据
  4. coursePubIdusername
  5. 2.判断业务数据
  6. 课程发布数据-远程调用课程搜索服务
  7. 判断是否存在
  8. 判断是否收费(CoursePub表中的change
  9. 只有收费课程需要创建订单
  10. 3.构建用户订单数据
  11. 判断订单数据是否存在:CoursePubId(课程id)、username(用户名)
  12. 如果没有
  13. 创建订单数据:订单状态为初始态
  14. 如果有
  15. 判断订单状态:必须为初始态
  16. 修改订单价格:修改为最新的价格数据CoursePub表中的price
  17. 4.将结果数据转为DTO并返回

2.订单支付

订单支付数据模型
image.png
规范字段描述:id,创建时间
用户信息描述:用户账号
订单信息描述:订单号,机构id
订单支付信息:支付状态,支付方式,交易状态,支付系统订单号,支付方式,支付时间等

支付前的字段:用户账号,机构id,订单号,交易状态(未支付),订单金额(可以不加),创建时间(mp自动赋值)
支付后的字段:支付系统订单号,支付方式,支付时间,支付响应
接口定义
image.png
image.png
业务分析
PS:由于前端对于支付的链接地址返回内容有要求
不管成功与失败必须返回PayCodeUrlResult
service正常业务操作,如果遇到业务操作的异常,还是直接抛出
controller需要进行接受,并转化为PayCodeUrlResult,异常统一抛出

  1. 业务分析:
  2. 0.是否开启事务(开启)
  3. 1.判断关键数据
  4. orderNo username
  5. 2.判断业务数据
  6. 订单数据:orderNo username
  7. 判断是否存在
  8. 判断订单的状态:必须为初始态(未支付)
  9. 3.创建订单支付数据
  10. 判断订单支付数据是否存在
  11. 不存在,创建订单支付(默认状态:0 PayCodeUrlResult.NOT_PAY
  12. 存在,不需要做操作
  13. 根据表中的字段来赋值
  14. 支付前的字段:user_name companyid orderid status(未支付) total_amount(可以不加) create_date(mp自动赋值)
  15. 支付后的字段:pay_number pay_method pay_date pay_response
  16. 4.和第三方支付系统交互获得支付的链接地址

今日重点

  • 微信支付通知的特点和注意事项
  • 学员支付后业务操作流程
  • seata环境搭建
  • 支付通知订单服务业务流程和学习记录业务流程

    10.微信支付通知的特点和注意事项

    微信支付开发文档
    特点:微信支付通知V2版本采用XML格式响应数据
    注意事项:签名认证,幂等性,支付金额和订单金额对比

    11.学员支付后业务操作流程

    image.png
    业务流程:
  1. 当前业务是由第三方支付发起调用,发送支付成功通知
  2. 对业务进行操作
  • 订单服务:
    • 解析支付平台结果数据
    • 更新本地订单状态和订单支付状态
    • 远程调用创建学习记录
  • 学习中心:
    • 添加课程学习记录:默认第一章第一节
  1. 返回结果给第三方平台

技术说明:
怎么实现互联网的请求调用本地局域网的接口

怎么解析微信通知数据,怎么给第三方支付响应已经接收到通知

  • 参照第三方api和微信接口文档

两个数据表的一致性怎么处理
使用分布式事务Seata的at模式—同步调用

12.Seata环境构建

1.构建Seata服务端

  • 构建Seata的docker环境
  • 构建Seata服务端链接的数据库内容
  • 配置Seata发注册中心和配置中心

registery.conf
2.构建Seata客户端

  • 在微服务中添加Seata的依赖包
  • 在各个微服务中构建数据库的快照表
  • 配置Seata环境

    13.支付通知订单服务业务流程和学习中心业务流程

    1.订单服务

    接口
    无请求方式 /order/order-pay/wx-pay/notify-result
    @RequestMapping(“order-pay/wx-pay/notify-result”)
    业务分析
    1. 业务分析:
    2. 1.判断关键数据并解析
    3. 判断第三方支付是否成功:return_code result_code 必须为SUCCESS
    4. 2.判断消息的幂等性(第三方支付平台会有重复通知的消息)
    5. 数据库的记录表:Orders(订单存在和订单支付状态:初始态-未支付)
    6. orderNo订单号,Status交易状态
    7. 3.判断业务数据
    8. 订单数据(已经在第二步操作完毕)
    9. PS:wx文档中强调--用户所支付的金额要和本地的订单金额一致
    10. 订单支付数据
    11. 判断订单支付数据是否存在和支付状态:未支付
    12. orderId,status
    13. 4.操作本地数据库表
    14. 订单数据
    15. 修改订单的状态:已支付
    16. 订单支付数据
    17. pay_number--第三方支付的订单号
    18. pay_method--支付方式(wx
    19. pay_date--用户在第三方支付平台支付的金额的时间
    20. 金额
    21. 订单总金额 total_amount 订单应支付金额receipt_amount 订单实际支付金额 buyer_pay_amount
    22. 交易状态 Status
    23. pay_response--第三方支付平台通知的所有数据结果内容(xml
    24. 5.调用学习中心
    25. 创建用户对于收费课程的学习记录数据

    2.学习中心

    接口
    post /learning/l/course-record/paid/{username}/{coursePubId}
    传入参数
username String 购课人的名称
coursePubId Long 课程发布id

业务分析

  1. 1.判断关键数据
  2. username coursePubId
  3. 2.判断业务数据
  4. 课程发布信息
  5. 判断是否存在
  6. 判断课程是否是收费的
  7. 课程计划数据获得(Json转换)
  8. 从课程发布信息中
  9. 3.保存用户的学习记录
  10. 构建前,查询并判断学习记录是否存在
  11. 由于是先执行订单服务修改订单状态,在没有问题的情况下再创建学习记录
  12. 不存在学习记录:
  13. 创建学习记录
  14. 默认章节为:第一章第一小节
  15. coursePub中获取课程计划teachplanJsonString通过JsonUtil转为DTO
  16. 要给paid赋值为已经支付:1
  17. 存在学习记录--收费课程支付后,要重置数据(用户体验不好,方便后期操作,
  18. 但是可以解决大部分的问题)
  19. 4.将新增的数据查询并转化为dto并返回
  20. PS
  21. 如果出现业务上出操作数据问题,本业务层直接抛出异常,无需返回RestResponse规范接口数据
  22. 原因:本次的操作事务都是由Seata环境来控制,如果抛出异常,会是的整个的事务进行回滚操作