springboot3+vue3支付宝交易案例-结算支付

news2024/9/20 10:45:23

springboot3+vue3支付宝交易案例-结算支付!今天下午整理了一下结算的内容。遇到了很多问题。汇总分享给大家。

第一个问题:支付宝结算后,返回的交易编码,和交易时间,交易状态,都应该使用varchar来存。

第二个问题:它交易支付完成后,会自动返回购物车的页面地址。


package com.example.demo.controller;

import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;


import com.alipay.api.internal.util.AlipaySignature;
import com.example.demo.config.AliPayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.example.demo.bean.Orders;
import com.example.demo.service.IOrdersService;
import com.example.demo.service.impl.OrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/alipay")
public class AlipayController {
    //支付宝沙箱测试网关地址
    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "UTF-8";
    private static final String SIGN_TYPE = "RSA2";
    @Resource
    private IOrdersService ordersService;
    @Resource
    private AliPayConfig alipayConfig;

    /**
     * 向支付宝发送支付的接口。
     * @param orderNo
     * @param httpResponse
     * @throws IOException
     */
    @GetMapping("/pay")
    public void pay(Integer orderNo, HttpServletResponse httpResponse) throws IOException {
        //查询订单信息
        List<Orders> ordersList= ordersService.getOneOrdersByOrderNo(orderNo);
        Orders order = ordersList.get(0);
        if(order == null){
            return;
        }
        //private static final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";

        // 1. 创建Client,通用SDK提供的Client,负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, alipayConfig.getAppId(),
                alipayConfig.getAppPrivateKey(), FORMAT, CHARSET, alipayConfig.getAlipayPublicKey(), SIGN_TYPE);

        // 2. 创建 Request并设置Request参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();  // 发送请求的 Request类

        request.setNotifyUrl(alipayConfig.getNotifyUrl());//疑惑之一。
        JSONObject bizContent = new JSONObject();
        bizContent.set("out_trade_no", orderNo);  // 我们自己生成的订单编号
        bizContent.set("total_amount", order.getTotal()); // 订单的总金额
        bizContent.set("subject", order.getGoodsName());   // 支付的名称
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");  // 固定配置
        request.setBizContent(bizContent.toString());
        request.setReturnUrl("http://127.0.0.1:5173/cart_list");


        // 执行请求,拿到响应的结果,返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        //官方回传了一个页面,输入账户,密码,完成支付。
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    @PostMapping("/notify")  // 注意这里必须是POST接口
    public void payNotify(HttpServletRequest request) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
                // System.out.println(name + " = " + request.getParameter(name));
            }

            String tradeNo = params.get("out_trade_no");//订单原始编码
            String gmtPayment = params.get("gmt_payment");//支付的时间
            String alipayTradeNo = params.get("trade_no");//支付交易的编码
            String status = params.get("trade_status");//交易状态
            String sign = params.get("sign");
            String content = AlipaySignature.getSignCheckContentV1(params);
            boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, alipayConfig.getAlipayPublicKey(), "UTF-8"); // 验证签名
            // 支付宝验签
            if (checkSignature) {
                // 验签通过
                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));

                // 更新订单未已支付(更新数据库信息)
                //tradeNo, "已支付", gmtPayment, alipayTradeNo
                //查询订单信息
                Integer orderNo = Integer.valueOf(tradeNo);
                List<Orders> ordersList= ordersService.getOneOrdersByOrderNo(orderNo);
                Orders order = ordersList.get(0);
                order.setStatus(status);
                order.setAlipayNo(alipayTradeNo);
                order.setPayTime(gmtPayment);
                ordersService.updateOneOrders(order);
            }
        }

    }
}

这里面就是支付宝交易的控制器内容。里面有2个方法。一个是支付的,一个是回调的。


package com.example.demo.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {
    private String appId;
    private String appPrivateKey;
    private String alipayPublicKey;
    private String notifyUrl;
}

这个是一个配置类,读取了我们的配置信息。


alipay.appId=9021000134634591
alipay.appPrivateKey=MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQCvWMRgjeKZdKnT8tT7nh1Yh6RiLhYCablc5a67CojvWRk5NrooIpP39oXkisV7H2nf5J8zfLmS2l2qroDlwAx4Zx3+Woloo6rcLZ42G0QuB8yBZm4doa73/lMurenmucSgCDaS+ap1opEGvlAFZnRi2O0KZy5t9g9WhwzC/D2EWJMSwroclfSTpVxr/on0MLw7l+jTeqcZTul4czXUhnGufWgVjmA7qAd3we7FhAMCqUcWXa3pLCCGIeSaBkqiaoToyql7eqYuwoV2UkT1DeqCN0fW/Zc5h7YpbuGTDfm2SSB/lfQAvHeV5Y+aNIOFJ1G25VKDnAIQgfQgrDYU3Eg1AgMBAAECgf99V/cJDmPtTngYCn41X9Gad1wK0ubo0qquvYEqM12vuwFM5NIt3onnt1H/DTQdz1bftY4YQBBn6bELUbLSiXZgm1XVfOK86kI5ImL2SodyYCDQX2hXxjxNCoBr3eZWCHWF8FkSt2YisRL6vxB0y8hm4KqRxTBranmMYP2+ZJGVCIyimxHAespfG47yPy42fk02DXf9StJpWqOTw5juCfUNDjDbgYLkk6B5gEmH9sj8jeG2OrNOxxjTLRnMgxxsRGV1goRQqAHD7wUAUYu1oFQCAMz3QAQeIv29OvXklRh9AxohridPImQxqzGOm9AnVB0US2GbnXYNBUEdrADn0+ECgYEA4SF+br+uTANdLANvHjP6uzG7UrOef6imUw0Yoepwzbc4pimxkH8p3lQZFpR9i06/7skIu/u7YAOgrcMVFcDQkmprqLDSXeML/YgQzocCqPg4cwYU6EDrMFrjAT7uBRXJFHaRdVNuEpTdtWWQMMdJe/WbNVxQMf2XBe8NM5AO3PkCgYEAx2PCm//PHkeuaEoOi0hcdCmKf67iA3uahyCl3+IzLO7bgEtpldLAlMiNMxNL+HiuxnGMUxmJXb5GkGeSNPjajMGmYY+pOx2h2SiJcMuHtMLjHwBmnEVWbMzWcD5huF//66jMI8NJN8eXZcfNxcjcD/BIEhlP6bi2vnCs1PInQB0CgYAZWR8WMyjZ0CsmcICLYwjhGNlhl23KK+AGS9wxJudqki2jr+AZR+gb61Yjz7ZPAB/mL+Z23AId7mqiBewS1fHl+muCw937yjuoYTCbQGJRShl5Af9KozyX5jPXCRHdqrVIQ41fK3SiTPalnPjeNSIV/fJq0KkK5+WgOmk/HAJAaQKBgBEat7kWKrhYQdfkcnb0UCoO3jix0eWmlsz8uf4Is4cpPl81GOunVqnswmAdSakZATU4zGbci/IkvnzoxZwRtP3aJuG7pzLRCe9NEO1CKHQTO9SO/j5tnEpdEBA06cEdSyD2K/ztZbyJPK2YhEhxQJ+FZ0lWLorIM7UGiW0DEObpAoGAUaWp+93D8VLYKzLlutCrZXmXw7gFfFXkmr5rd0ylFW7OqTtGPbvXwREpByyoKGyXZSIR9gnyYtjw4PQctKrXNvqqPevFEJ1I8EWm+sKsN9E8Sg7j0M9BhRaJ+9B4/OwDv9+G1N6WOjaia88RBx45s8lVb9l6Fjd5wsI2O5p/1Xw=
alipay.alipayPublicKey=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoBuX6xKYpLdexDoGc+jmfGGijjFnsv/0jvPmPydnt+bUgIWF8ghk2v3ddbY2C6toqdk1n367CyIF/swQl2gZFscWg83tvPHOho+fyHJ9ZANzJqQDeEXD2YVfrOGcTJQt0dnX6w5rfZerzsrD685C1OhAIttP5HKff2iplyvx1ZPaHEhghacYjD4ObFREXo6M1+pkKJJBo5mUmPQ6MBwWwkKqtIaQMMUnszO+o7GyVbVd7CttS/VDXwqTNay0pPlWyyBpH9rSl45XClGGHOFgpkN//CVNO7dBtskLOCKDZ++fGIBPKqU5vEkZXoGanlYBOKhrh38gALiR2CaENPdCIwIDAQAB
alipay.notifyUrl=http://8btgff.natappfree.cc/alipay/notify

这个就是配置参数文件内的配置参数信息。


如图,我们都是使用的字符串存储的。否则很容易报错。存不下。 


 

如图,使用沙箱测试账户(用户角色)jiuky可以支付完成了。


这个就是刚刚结算的订单信息。第一个是支付宝回传过来的交易编码。第二个是交易结算时间,第三个是交易结算状态。 

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

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

相关文章

Python面向对象编程:探索代码的结构之美

文章目录 一、引言二、为什么学习面向对象编程2.1 提高代码的可维护性&#xff1a;通过封装、继承和多态实现模块化设计2.2 提升代码的复用性&#xff1a;通过类和对象的创建实现代码的重用 三、类和对象的基本概念3.1 类和对象的定义和关系&#xff1a;类是对象的模板&#xf…

【数据结构 06】二叉树

一、原理 二叉树算法核心思维&#xff1a;递归 满二叉树&#xff1a;二叉树的层数为K&#xff0c;节点数为 完全二叉树&#xff1a;二叉树的层数为K&#xff0c;前K-1层是满的&#xff0c;第K层是连续的 满二叉树是完全二叉树的子集。 任意二叉树&#xff1a;若叶子节点的…

NC248:左叶子之和(C++)

1.题目描述 2.题目分析 我们以一个二叉树为例 左叶子的特点是什么&#xff1f; 是左节点并且没有左右孩子节点 所以我们用leftnode保存root->lefe节点&#xff0c;判断条件为leftnode存在&#xff0c;并且不存在leftnode->left和leftnode->right&#xff0c;如果满…

事务、MVCC、锁

目录 事务MVCC锁 事务 四大特性&#xff1a;ACID 脏读&#xff1a;事务A读取到未提交事务B修改的数据 不可重复读&#xff1a;事务A修改了未提交事务B读取的数据 幻读&#xff1a;事务A增删了未提交事务B读取的数据 不可重复读与幻读都是读取的结果不同&#xff0c;前者侧重于…

常用芯片学习——CD4094芯片

CD4094 8位移位寄存器/3态输出缓冲器 使用说明 CD4094是由一个 8 位串行移位寄存器和一个 3 态输出缓冲器组成的 CMOS 集成电路。寄存器带有存储锁存功能&#xff0c;集成电路根据 STROBE 信号确定锁存器是否接收移位寄存器各位数据&#xff0c;数据是否由锁存器传输到 3 态输…

单元测试 | Junit4“单元测试“ ( Java中可用 )

目录: 使用JUnit4进行“单元测试” 作者简介 &#xff1a;一只大皮卡丘&#xff0c;计算机专业学生&#xff0c;正在努力学习、努力敲代码中! 让我们一起继续努力学习&#xff01; 文章用于本人学习使用 &#xff0c; 同时希望能帮助大家。 欢迎大家点赞&#x1f44d; 收藏⭐ …

HarmonyOS 鸿蒙驱动消息机制管理

驱动消息机制管理 使用场景 当用户态应用和内核态驱动需要交互时&#xff0c;可以使用HDF框架的消息机制来实现。 接口说明 消息机制的功能主要有以下两种&#xff1a; 用户态应用发送消息到驱动。 用户态应用接收驱动主动上报事件。 表1 消息机制接口 方法描述struct …

扩展学习|商业智能和大数据分析的研究前景(比对分析)

文献来源&#xff1a; Liang T P , Liu Y H .Research Landscape of Business Intelligence and Big Data analytics: A bibliometrics study[J].Expert Systems with Applications, 2018, 111(NOV.):2-10.DOI:10.1016/j.eswa.2018.05.018. 信息和通信技术的快速发展导致了数字…

【LVGL源码移植环境搭建】

LVGL源码移植&环境搭建 ■ LVGL源码移植■ 下载LVGL源码■ 修改LVGL文件夹■■■■ 视频链接 Ubuntu模拟器环境建置 ■ LVGL源码移植 ■ 下载LVGL源码 LVGL源码 我们以选择v8.2.0为例&#xff0c;选择8.2.0下载 ■ 修改LVGL文件夹 1.我们只需要关注这5个文件即可&…

公司在数字化过程中犯的7个错误,及其解决方法

今天&#xff0c;大多数公司都意识到技术提供了转变其业务模式和产品的机会。但是&#xff0c;没有多少人知道他们在采用时所犯的错误。 既然我们现在都同意数字化转型不是一种选择&#xff0c;我们不妨拥抱变化并学习如何最好地采用它。但说起来容易做起来难&#xff0c;不是…

网页版idea、pycharm搭建

官网教程提供了两种方法&#xff1a;1、有给应用版idea或pycharm安装插件来开放网页服务&#xff1b;2、使用docker创建容器开放网页服务。这边推荐并介绍第二种步骤。 基本过程为&#xff1a;拉取相关镜像&#xff1b;开启服务&#xff1b;使用网页版 &#xff08;细节和注意点…

目标检测算法训练数据准备——Penn-Fudan数据集预处理实例说明(附代码)

目录 0. 前言 1. Penn-Fudan数据集介绍 2. Penn-Fudan数据集预处理过程 3. 结果展示 4. 完整代码 0. 前言 按照国际惯例&#xff0c;首先声明&#xff1a;本文只是我自己学习的理解&#xff0c;虽然参考了他人的宝贵见解及成果&#xff0c;但是内容可能存在不准确的地方。如…

Python爬虫获取淘宝商品详情页数据|实现自动化采集商品信息

近年来&#xff0c;随着互联网的发展&#xff0c;越来越多的数据以网页的形式存在于各个网站上。对于数据分析师、研究员或者仅仅是对数据感兴趣的人来说&#xff0c;如何高效地提取和分析网页数据成为了一项重要的技能。Python作为一门强大的编程语言&#xff0c;通过其丰富的…

【pytorch】nn.linear 中为什么是y=xA^T+b

我记得读教材的时候是yWxb, 左乘矩阵W&#xff0c;这样才能表示线性变化。 但是pytorch中的nn.linear中&#xff0c;计算方式是yxA^Tb&#xff0c;其中A是权重矩阵。 为什么右乘也能表示线性变化操作呢&#xff1f;因为pytorch中&#xff0c;照顾到输入是多个样本一起算的&…

【Ubuntu 22.04.3 LTS】apt-get下载安装有关问题可能原因及解决方法

ubuntu 22.04.3 LTS unaccountably error 装啥啥没依赖 可能是用了不合适的源&#xff0c;换个就好了 Now, let’s take a look at the lsb_release output, with a special focus on the Codename, which could be a crucial piece of information. The lsb_release comm…

使用ChatGPT学习大象机器人六轴协作机械臂mechArm

引言 我是一名机器人方向的大学生&#xff0c;近期学校安排自主做一个机器人方面相关的项目。学校给我们提供了一个小型的六轴机械臂&#xff0c;mechArm 270M5Stack&#xff0c;我打算使用ChatGPT让它来辅助我学习如何使用这个机械臂并且做一个demo。 本篇文章将记录我是如何使…

Windows编程入门-窗口控件-资源操作

window控件&#xff1a; 控件是常见的窗口上的交互元素例如&#xff1a;一个按钮&#xff0c;一个复选框&#xff0c;一个列表框等。 当控件的特定功能被触发后&#xff0c;会主动发送消息通知父窗口&#xff0c;父窗口可以通过发送消息给控件控制控件的行为。 控件的本质是一个…

使用visual studio写一个简单的c语言程序

官网下载visual studio&#xff0c;社区版免费的 https://visualstudio.microsoft.com/zh-hans/ 下载好以后选择自己的需求进行安装&#xff0c;我选择了两个&#xff0c;剩下的是默认。 创建文件&#xff1a;

Linux编辑器之vim的使用

文章目录 一、vim简介二、vim的基本概念三、vim的基本操作四、vim正常模式命令集移动光标删除文字复制替换撤销上一次操作更改跳至指定的行vim末行模式命令集列出行号跳到文件中的某一行查找字符保存文件离开vim 五、进阶vim玩法打开文件批量注释代码执行shell命令指定注释窗口…

如何判断 LM358 芯片是否损坏或故障?

LM358 芯片是一种流行的低功耗双运放&#xff0c;广泛应用于各种电子电路中&#xff0c;包括放大器、滤波器、积分器、比较器等。它以其低成本、高性价比和广泛的工作电源范围&#xff08;3V至32V单电源或1.5V至16V双电源&#xff09;而被广泛使用。 然而&#xff0c;像所有电…