【业务功能篇104】 补充【业务功能篇99】微服务-springcloud-springboot-电商订单模块--整合支付

2023-11-19

在前面我们业务功能篇98-99中,我们介绍了电商项目中的订单模块服务,那么最后就是需要进行支付动作,那么我们这里就通过订阅第三方平台支付宝的支付调用接口功能,来进一步完成订单提交后的支付动作,支付宝的接口使用可以登录官网开发指南详情去了解

SDK依赖引入

在我们对应需要进行支付调用的订单服务中的pom文件加入依赖,其他服务不涉及的不需要加

        <!-- 支付宝SDK -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.31.12.ALL</version>
        </dependency>

配置支付宝的配置文件类

  • 根据支付宝的接口使用方式,传递对应订单封装类对象,进行支付操作,并且还有同步回调地址,在支付完成之后自动跳转到我们指定页面
  •  回调地址:public static String return_url = "http://order.msb.com/orderPay/returnUrl"; 指定到该接口,该接口会进行支付完成后需要的操作,比如修改订单的状态为已完成,发货状态为待发货等等.. 然后return指定的html订单详情页面list.html


/**
 * 支付宝的配置文件
 */
//@ConfigurationProperties(prefix = "alipay")
@Component
@Data
public class AlipayTemplate {

    // 商户appid 沙箱账号: tklalf8880@sandbox.com
    public static String APPID = "2021000121601310";
    // 私钥 pkcs8格式的
    public static String RSA_PRIVATE_KEY = "xx";
    // 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    public static String notify_url = "http://order.msb.com/payed/notify";
    // 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
    public static String return_url = "http://order.msb.com/orderPay/returnUrl";
    // 请求网关地址
    public static String URL = "https://openapi.alipaydev.com/gateway.do";
    // 编码
    public static String CHARSET = "UTF-8";
    // 返回格式
    public static String FORMAT = "json";
    // 支付宝公钥
    public static String ALIPAY_PUBLIC_KEY = "xx";
    // 日志记录目录
    public static String log_path = "/log";
    // RSA2
    public static String SIGNTYPE = "RSA2";

    public String pay(PayVo payVo){
        // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
        //调用RSA签名方式
        AlipayClient client = new DefaultAlipayClient(URL,
                APPID,
                RSA_PRIVATE_KEY,
                FORMAT,
                CHARSET,
                ALIPAY_PUBLIC_KEY,
                SIGNTYPE);
        AlipayTradeWapPayRequest alipay_request=new AlipayTradeWapPayRequest();

        // 封装请求支付信息
        AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
        model.setOutTradeNo(payVo.getOut_trader_no());
        model.setSubject(payVo.getSubject());
        model.setTotalAmount(payVo.getTotal_amount());
        model.setBody(payVo.getBody());
        model.setTimeoutExpress("5000");
        model.setProductCode("11111");
        alipay_request.setBizModel(model);
        // 设置异步通知地址
        alipay_request.setNotifyUrl(notify_url);
        // 设置同步地址
        alipay_request.setReturnUrl(return_url);

        // form表单生产
        String form = "";
        try {
            // 调用SDK生成表单
            form = client.pageExecute(alipay_request).getBody();
            return form;
        } catch (AlipayApiException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return  null;
    }
}

支付接口 

controller层  

payOrder:在订单页面中,点击 支付宝发起支付请求的方法
orderPay:支付完成之后,会同步回调到订单详情的方法,同时执行支付完成后需要的动作,比如修改订单状态为 关闭, 发货状态为待发货等等..
@Controller
public class OrderWebController {

    @Autowired
    private OrderService orderService;

    @Autowired
    AlipayTemplate alipayTemplate;

 /**
     * 获取订单相关信息
     * 然后跳转到支付页面  tklalf8880@sandbox.com
     * @param orderSn
     * @return
     */
    @GetMapping(value = "/payOrder",produces = "text/html")
    @ResponseBody
    public String payOrder(@RequestParam("orderSn") String orderSn){
        // 根据订单编号查询出相关的订单信息,封装到PayVO中
        PayVo payVo = orderService.getOrderPay(orderSn);
        String pay = alipayTemplate.pay(payVo);
        //System.out.println(pay);
        return pay;
    }

    @GetMapping("/orderPay/returnUrl")
    public String orderPay(@RequestParam(value = "orderSn",required = false) String orderSn,
                           @RequestParam(value = "out_trade_no",required = false) String out_trade_no){
        // TODO 完成相关的支付操作
        System.out.println("orderSn = " + orderSn);
        if(StringUtils.isNotBlank(orderSn)){
            orderService.handleOrderComplete(orderSn);

        }else{
            //orderService.updateOrderStatus(out_trade_no,OrderConstant.OrderStateEnum.TO_SEND_GOODS.getCode());
            orderService.handleOrderComplete(out_trade_no);
        }
        return "list";
    }

service层

    @Override
//封装订单号对应的信息 返回给支付宝配置类的方法
    public PayVo getOrderPay(String orderSn) {
        // 根据订单号查询相关的订单信息
        OrderEntity orderEntity = this.getBaseMapper().getOrderByOrderSn(orderSn);
        // 通过订单信息封装 PayVO对象
        PayVo payVo = new PayVo();
        payVo.setOut_trader_no(orderSn);
        payVo.setTotal_amount(orderEntity.getTotalAmount().setScale(2, RoundingMode.UP).toString());
        // 订单名称和订单描述
        payVo.setSubject(orderEntity.getOrderSn());
        payVo.setBody(orderEntity.getOrderSn());
        return payVo;
    }


    @Override
    //支付完成之后,修改订单状态
    public void handleOrderComplete(String orderSn) {
        // 1.更新订单状态
        this.updateOrderStatus(orderSn,OrderConstant.OrderStateEnum.TO_SEND_GOODS.getCode());
        // TODO
        // 2.更新库存信息 库存数量递减

        // 3.购物车中的已经支付的商品移除

        // 4.更新会员积分 ....
    }

前端核心请求跳转

 

   <form action="/orderPay/returnUrl" method="get">
              <input type="hidden" name="orderSn" th:value="${orderResponseVO.orderEntity.orderSn}">
              <li>
                <input type="submit" value="立即支付">

              </li>
            </form>


		  <li>
            <img src="/static/order/pay/img\zhifubao.png" style="weight:auto;height:30px;" alt="">
            <a th:href="'/payOrder?orderSn='+${orderResponseVO.orderEntity.orderSn}">
              支付宝
            </a>

          </li>

支付宝支付完成之后的回调请求需要放过拦截器,否则会报错需要重新登录的,因为是不同的一个域名跳转,所以之前保存的用户登录session会话就不会带过来,所以需要放过这个请求接口

new AntPathMatcher().match("/orderPay/**", requestURI)

public class AuthInterceptor implements HandlerInterceptor {

    public static ThreadLocal threadLocal = new ThreadLocal();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 支付宝的回调我们放过
        String requestURI = request.getRequestURI();

        boolean match = new AntPathMatcher().match("/orderPay/**", requestURI);
        if(match){
            return true;
        }
        // 通过HttpSession获取当前登录的用户信息
        HttpSession session = request.getSession();
        Object attribute = session.getAttribute(AuthConstant.AUTH_SESSION_REDIS);
        if(attribute != null){
            MemberVO memberVO = (MemberVO) attribute;
            threadLocal.set(memberVO);
            return true;
        }
        // 如果 attribute == null 说明没有登录,那么我们就需要重定向到登录页面
        session.setAttribute(AuthConstant.AUTH_SESSION_MSG,"请先登录");
        response.sendRedirect("http://auth.msb.com/login.html");
        return false;
    }
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【业务功能篇104】 补充【业务功能篇99】微服务-springcloud-springboot-电商订单模块--整合支付 的相关文章

随机推荐

  • Qt框架及模块认识

    小白自工作就接触Qt 一直都在使用Qt5 3 1版本 所以没有经历过大牛们把项目从Qt4程序到Qt5的烦恼 没准以后会碰到 对Qt所有的丰富的API表示惊叹 对于Qt的框架及模块认识也是极为模糊的 文中有不对之处希望大牛们打脸 虽然脸都已经
  • AFX_MANAGE_STATE(AfxGetStaticModuleState())的使用

    MSDN By default MFC uses the resource handle of the main application to load the resource template If you have an export
  • jsp上显示JFreeChart生成的饼状图

    文件配置
  • UE4(Unreal Engine4)在蒙太奇动画中添加音频轨道通知

    UE4系列文章目录 文章目录 UE4系列文章目录 前言 一 遇到的问题 二 操作步骤 前言 UE4 Unreal Engine4 在蒙太奇动画中添加音频轨道通知 我们想在某一帧动画中添加声音 比如我们想在动画的第13帧这里添加音效 一 遇到
  • 对于单向链表的排序与去重

    include bits stdc h using namespace std struct node int num node next class Chain public Chain head tail new node void G
  • 【计算机科学】【2017】变分推理与深度学习

    本文为荷兰阿姆斯特丹大学 作者 Kingma D P 的博士论文 共174页 在本文中 我们提出了变分 贝叶斯 推理 生成建模 表示学习 半监督学习和随机优化问题的新的解决方案 我们提出了一种有效的变分推理算法 Kingmaand Well
  • 解析目标检测全流程!附代码数据

    关注后 星标 Datawhale 每日干货 每月组队学习 不错过 Datawhale干货 作者 王程伟 算法工程师 Datawhale成员 在计算机视觉中 红外弱小目标检测是一个重要的方向 但直到近一两年 才开始运用一些深度学习的方法 深度
  • 二叉树的递归遍历、非递归遍历、层次遍历

    1 递归遍历 2 非递归遍历 3 层次遍历 1 递归遍历 在使用递归遍历的时候 每个节点会经过三次 public class PreInPosTraversal public static class Node public int val
  • Java 基础--- Object Class

    Java 基础 Object Class Object Class 结构 toString clone finalize getClass equals Object obj hashCode 什么是hashcode hashcode的主要
  • 【MACOS(M1)编译Risc-v版OpenOCD】

    MACOS编译Risc v版OpenOCD 准备 1 执行顺序 常见问题 问题1 AC PROG CC C99 告警 2 问题2 texinfo 版本不匹配 问题2 libtool版本不匹配 问题3 编译错误 验证一下 准备1 Instal
  • document this 插件 mac_又一个折腰的 VSCode 插件

    1 最近这两周周末都在折腾 VSCode 白板插件 其主要原理是将 Excalidraw 1 嵌入到 VSCode 的 WebView 中 如果所有功能正常 那么相比于在 Web 中使用 在 VSCode 中将会更方便 截至目前 该插件的功
  • Power BI——SUMX函数(对列操作)

    1 语法 说明 第一个参数为被运算的表 table 第二个参数是对表中的每一行计算的表达式 2 步骤 SUMX 将迭代第一个参数中指定的表 一次一行 并完成第二个参数中指定的计算 3 案例 总销售额SUMX SUMX 销售表 销售表 数量
  • 【路径规划】基于A*算法和Dijkstra算法的路径规划(Python代码实现)

    个人主页 研学社的博客 欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Python代码实现 1 概述 Dijkstr
  • 基于 tensorflow 的鲜花识别

    本文中 采用了卷积神经网络的深度学习方法来实现对鲜花种类的高精度识别 先是对原始图像进行预处理 然后是以LeNet 5 卷积神经网络模型为基础建立网络模型 再进行模型训练后得到鲜花识别分类器 最后分析实验结果并与其它花卉识别的算法进行对比
  • MySQL的JDBC操作入门案例 IDEA 实现

    package cn itcast jdbc import java sql public class JdbcDemo01 public static void main String args throws SQLException 1
  • 设计模式学习笔记(一)如何评判代码质量的好坏?

    1 评判代码质量好坏的角度 在目前的面板项目中 经常听到同事用 代码写的很烂 这是什么鬼 我去 这个思路很棒啊 等字眼来评判项目中部分代码逻辑的好坏 经过阅读一些文章和学习技术大神分享的内容 了解到真正评判代码好坏不应该笼统的用 好 烂 这
  • java实现starteam配置库中checkout对应的文件

    1 所属jar包 starteam sdk 5 2 jar 2 样例代码 package com comtop qcms base starteam import java io IOException import com comtop
  • 结果解读_染色体CNV检测结果解读

    染色体CNV检测的结果 大致可以分三类 完全正常或多态性 致病性片段 及 临床意义未明 值得一提的是 由于分子遗传学检测技术的发展 比如染色体CNV检测 染色体层面的产前诊断的时间不再局限于细胞培养的最佳时间 18 26周 脐血穿刺也几乎被
  • 编译mysql出现CMake Error at cmake/readline.cmake:83 (MESSAGE)

    本文转载至 http blog 163 com sz2273 pr blog static 41264296201361354426670 Could NOT find Curses missing CURSES LIBRARY CURSE
  • 【业务功能篇104】 补充【业务功能篇99】微服务-springcloud-springboot-电商订单模块--整合支付

    在前面我们业务功能篇98 99中 我们介绍了电商项目中的订单模块服务 那么最后就是需要进行支付动作 那么我们这里就通过订阅第三方平台支付宝的支付调用接口功能 来进一步完成订单提交后的支付动作 支付宝的接口使用可以登录官网开发指南详情去了解