springboot实现支付宝支付(沙箱环境)

news2024/12/24 20:59:27

springboot实现支付宝支付

  • 1. 获取应用id,应用私钥和支付宝公钥
  • 2. 开始开发
  • 3. 内网穿透
  • 4. 测试支付功能

1. 获取应用id,应用私钥和支付宝公钥

进入支付宝控制台:https://open.alipay.com/develop/manage

找到沙箱
在这里插入图片描述
在这里插入图片描述
这里可以看到应用id
在这里插入图片描述
可以看到应用私钥支付宝公钥,获取这三后就可以开始敲代码了

2. 开始开发

依赖:

        <!--支付宝-->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.34.0.ALL</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

在resources/templates目录下创建一个pay.html文件,用于展示支付宝支付页面。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>支付宝支付</title>
</head>
<body onload="document.forms[0].submit();">
	<div th:utext="${form}"></div>
</body>
</html>

创建同步通知页面
在resources/templates目录下创建一个return.html文件,用于展示同步通知结果。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<title>支付结果</title>
</head>
<body>
	<h1 th:text="${message}"></h1>
</body>
</html>
# 支付宝支付参数配置
alipay:
  # 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
  appId: 111111111111111111
  # 应用私钥,您的PKCS8格式RSA2私钥
  privateKey: 11111111111111111
  # 支付宝公钥
  publicKey: 111111111111111111111111
  # 支付宝网关
  gatewayUrl: https://openapi.alipaydev.com/gateway.do
  # 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
  notifyUrl: http://花生壳地址:花生壳端口/api/alipay/notify
  # 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
  returnUrl: http://花生壳地址:花生壳端口/returnView.html
/**
 * 支付配置类
 */
@Configuration
@ConfigurationProperties(prefix = "alipay")
@Data
public class PayAliConfig {

    /**
     * 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
     */
    public  String appId;
    
    /**
     * 应用私钥,您的PKCS8格式RSA2私钥
     */
    public String privateKey;

    /**
     * 支付宝公钥
     */
    public String publicKey;
    
    /**
     * 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
     */
    public  String notifyUrl;

    /**
     * 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
     */
    public  String returnUrl;

    /**
     * 支付宝网关
     */
    public String gatewayUrl;

}
/**
 * 初始化AlipayClient
 * @version 1.0.0
 * @date 2023/6/7
 */
@Component
public class AliPayClient {

    @Autowired
    private PayAliConfig payAliConfig;

    @Bean
    public AlipayClient AlipayClient()  throws AlipayApiException {
        AlipayConfig alipayConfig = new AlipayConfig();
        //设置网关地址
        alipayConfig.setServerUrl(payAliConfig.gatewayUrl);
        //设置应用ID
        alipayConfig.setAppId(payAliConfig.appId);
        //设置应用私钥
        alipayConfig.setPrivateKey(payAliConfig.privateKey);
        //设置请求格式,固定值json
        alipayConfig.setFormat(AlipayConstants.FORMAT_JSON);
        //设置字符集
        alipayConfig.setCharset(AlipayConstants.CHARSET_UTF8);
        //设置支付宝公钥
        alipayConfig.setAlipayPublicKey(payAliConfig.publicKey);
        //设置签名类型
        alipayConfig.setSignType(AlipayConstants.SIGN_TYPE_RSA2);
        //构造client
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
        return alipayClient;
    }
}
/**
 * @version 1.0.0
 * @date 2023/6/6
 */
@RestController
@RequestMapping("/api/alipay")
@Api(tags = "网站支付宝支付")
@Slf4j
public class AlipayController {
    @Autowired
    private AliPayService alipayService;

    /**
     * 创建支付订单,返回支付页面
     */
    @GetMapping("/pay")
    @Timing(remark = "创建支付订单")
    public ModelAndView pay(){

        String outTradeNo= IdUtil.simpleUUID();
        String subject="测试商品";
        BigDecimal totalAmount = BigDecimal.valueOf(250);

        PayRequest payRequest = new PayRequest();
        payRequest.setOut_trade_no(outTradeNo);
        payRequest.setSubject(subject);
        payRequest.setTotal_amount(totalAmount);
        payRequest.setBody("这是一个测试商品描述哦");
        payRequest.setQr_pay_mode("2");

        AlipayTradePagePayResponse response = alipayService.pay(payRequest);
        if (response == null) {
            return null;
        }
        log.info("响应:{}",response.getBody());
        // 返回支付页面
        ModelAndView modelAndView = new ModelAndView("pay");
        modelAndView.addObject("form", response.getBody());

        return modelAndView;
    }


    /**
     * 处理支付宝异步通知
     */
    @PostMapping("/notify")
    @Timing(remark = "处理支付宝异步通知")
    public void notify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        boolean signVerified = alipayService.rsaCheckV1(request);
        // 将请求参数转换为Map
        if (signVerified) {
            // 处理支付成功逻辑,更新订单状态等操作
            response.getWriter().write("success"); // 告诉支付宝已经收到通知并处理成功
        } else {
            response.getWriter().write("failure"); // 告诉支付宝验签失败
        }
    }
}
/**
 * @version 1.0.0
 * @date 2023/6/7
 */
public interface AliPayService {

    AlipayTradePagePayResponse pay(PayRequest payRequest);

    boolean rsaCheckV1(HttpServletRequest request);
}

/**
 * @version 1.0.0
 * @date 2023/6/7
 */
@Service
@Slf4j
public class AliPayServiceImpl implements AliPayService {

    @Autowired
    private AlipayClient alipayClient;

    @Autowired
    private PayAliConfig payAliConfig;

    @Override
    public AlipayTradePagePayResponse pay(PayRequest payRequest) {
        // 构造请求参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setReturnUrl(payAliConfig.getReturnUrl());
        request.setNotifyUrl(payAliConfig.getNotifyUrl());
        log.info("生成的字符串:{}", JSONUtil.toJsonStr(payRequest));

        request.setBizContent(JSONUtil.toJsonStr(payRequest));
//        request.setBizContent("{\"out_trade_no\":\"" + UUID.randomUUID().toString().replaceAll("-", "") + "\","
//                + "\"total_amount\":\"0.01\","
//                + "\"subject\":\"测试商品\","
//                + "\"body\":\"测试商品详情\","
//                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        // 调用SDK生成表单
        try {
            return alipayClient.pageExecute(request);
        } catch (AlipayApiException e) {
            log.error("支付宝请求失败");
        }
        return null;
    }

    @Override
    public boolean rsaCheckV1(HttpServletRequest request) {
        boolean flag = false;
        Map<String, String> params = new HashMap<>();
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String paramName = parameterNames.nextElement();
            String paramValue = request.getParameter(paramName);
            params.put(paramName, paramValue);
        }
        // 调用SDK验证签名
        try {
            flag =AlipaySignature.rsaCheckV1(params, payAliConfig.publicKey, AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2);
        } catch (AlipayApiException e) {
            log.error("验签失败");
        }
        return flag;
    }
}

3. 内网穿透

花生壳:https://hsk.oray.com/
下载安装配置一下就好了

4. 测试支付功能

启动Spring Boot应用,访问http://localhost:8889/api/alipay/pay,即可看到支付宝支付页面。输入支付密码后,会自动跳转到同步通知页面,并显示支付结果。

账号密码在沙箱账号中看到

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

Zoho:集成ChatGPT、开发大型语言模型,加紧布局AI+SaaS

在企业的数字化转型进程中&#xff0c;管理层和员工的数字化意识会随着建设的推进而不断提高&#xff0c;对于办公场景的数字化应用需求也不断产生。传统的办公系统建设中&#xff0c;系统的应用能力需要支撑越来越丰富的场景需求。 《今日人工智能》采访到Zoho中国VP兼SaaS事业…

【编程语言 · C语言 · for语句】

for 语句 C语言中&#xff0c;使用for语句也可以控制一个循环&#xff0c;并且在每一次循环时修改循环变量。在循环语句中&#xff0c;for语句的应用最为灵活&#xff0c;不仅可以用循环次数已经确定的情况&#xff0c;而且可以用于循环次数不确定而只给出循环结束条件的情况。…

jenkins构建pipline无法执行shell命令原因

问题表现 新的服务器上&#xff0c;新安装的jenkins&#xff0c;在上面创建了一个pipline项目&#xff0c;脚本里有shell命令&#xff0c;但是jenkins每次执行都卡住&#xff0c;经过尝试&#xff0c;无论多简单的命令都执行不了&#xff0c;cp&#xff0c;mv等都不行&#xf…

华为路由器:ospf协议三张表及邻居建立过程

说明&#xff1a;本篇接上一篇继续讲解 拓扑图 为了方便&#xff0c;我把R1/2/3/4/5的router id改成了回环网卡的IP。 ospf协议三张表 邻居表&#xff08;neighbortable&#xff09; OSPF用邻居机制来发现和维持路由的存在&#xff0c;邻居表存储了双向通信的邻居关系OSPF路…

矩形图:数据之美在图形中展现

在当今信息爆炸的时代&#xff0c;数据已经成为决策和洞察的重要基石&#xff0c;但海量的数据如果不经过整理和呈现&#xff0c;往往难以得出有意义的结论。这时候&#xff0c;可视化工具的作用就变得尤为重要了。在众多可视化形式中&#xff0c;矩形图以其简洁直观的特点受到…

团队管理之性能实施团队日志9

最近项目进入胶着状态。 混合场景在有些项目组里已经可以开始了&#xff0c;但还是有两三个项目组现在是完全没办法混合起来的。 本周计划是把基准测试、容量测试跑完&#xff0c;稳定性测试每个项目组至少能跑一遍。 但是从进度上来看&#xff0c;容量测试至少有四个系统不能跑…

各类动态路由协议汇总简介

目录 一、前言 二、OSPF协议 &#xff08;一&#xff09;OSPF是什么 &#xff08;二&#xff09;OSPF的工作原理 &#xff08;三&#xff09;OSPF的特点 &#xff08;四&#xff09;OSPF的使用 &#xff08;五&#xff09;OSPF的优点 &#xff08;六&#xff09;总结 …

ROS——从深度图转换到octomap(C++)

文章目录 介绍环境准备三维灰度栅格图三维RGB栅格图对点云进行过滤处理参考介绍 八叉树是用于在3D视觉中细分空间的数据结构。每个立方体都可以逐级地细分为8个子立方体,直到达到了给定的最小体积(体素)尺寸。且该最小体积(体素)决定了八叉树的分辨率。 octomap的作用:…

代码随想录算法训练营第五十一天|309.最佳买卖股票时机含冷冻期|714.买卖股票的最佳时机含手续费

LeetCode309.最佳买卖股票时机含冷冻期 动态规划五部曲&#xff1a; 1&#xff0c;确定dp数组以及下标的含义&#xff1a;dp[i][j]&#xff0c;第i天状态为j&#xff0c;所剩的最多现金为dp[i][j]。出现冷冻期之后&#xff0c;状态其实是比较复杂度&#xff0c;例如今天买入股…

接口自动化【七】__包装响应结果的数据为key-value

文章目录 前言 一、本章学习的思路 二、用接口新建商品_使用步骤 ​​​​​​​步骤一&#xff1a;先用抓包的方式拿到新建商品的接口 步骤二&#xff1a;我们先用单接口的形式&#xff0c;把这个商品添加成功 三、处理响应接口_&#xff08;包装响应结果的数据为&#xf…

Flume自定义拦截器 - ETL拦截器和分类拦截器

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 目录 一、拦截器&#xff08;Interceptor&#xff09;和选择器&#xff08;Selector&#xff09; 拦截器&#xff08;Interceptor&#xff09; 选择器&#xff08;Selector&#xff09; 二、自定…

【机器学习 | 深度学习】Colab是什么?以及如何使用它?

文章目录 一、介绍二、如何使用 Colaboratory 创建代码三、实例测试 一、介绍 Colaboratory&#xff08;简称为Colab&#xff09;是由Google开发的一种基于云端的交互式笔记本环境。它提供了免费的计算资源&#xff08;包括CPU、GPU和TPU&#xff09;&#xff0c;可让用户在浏…

本地部署gitlab学习git使用

文章目录 前言一、安装gitlab二、nginx反向代理三、本地配置hosts&#xff0c;自定义域名四、配置gitlab独立ngxin实现域名访问五、其他总结 前言 最近想学习git使用了&#xff0c;在本地部署一个gitlab社区版玩玩吧~ gitlab只能部署在liunx系统上面&#xff0c;可以使用云服务…

TLD2314EL-ASEMI代理英飞凌汽车芯片TLD2314EL

编辑&#xff1a;ll TLD2314EL-ASEMI代理英飞凌汽车芯片TLD2314EL 型号&#xff1a;TLD2314EL 品牌&#xff1a;Infineon(英飞凌) 封装&#xff1a;SSOP-14-EP-150mil 特性&#xff1a;LED驱动、汽车芯片 宽温度范围&#xff1a;-40C~150C 封装&#xff1a;SSOP-14&…

虚拟云网络系列 | 如何将 NSX NVDS 迁移到 VDS

1.NVDS 迁移到 VDS 的主要原因 在早期的 vsphere6.7 的版本上安装 NSX-T 采用的都是 NVDS&#xff0c;而随着 NSX 版本的升级&#xff0c;从 NSX 4.0 开始&#xff0c;NSX 已经不在支持在 ESXi 上部署 NVDS&#xff0c;仅能使用 vsphere7.0 上的 VDS。所以&#xff0c;对于早期…

linux系统编程-----下

linux网络编程 tcp通信 Berkeley Socket TCP/IP协议族标准只规定了网络各个层次的设计和规范&#xff0c;具体实现则需要由各个操作系统厂商完成。最出名的网络库由BSD 4.2版本最先推出&#xff0c;所以称作伯克利套接字&#xff0c;这些API随后被移植到各大操作系统中&…

Android Key Hash生成

在接入FaceBook 安卓第三方登录的时候&#xff0c;就需要获取Debug Android Hash Key。 Android Hah Key有两种&#xff0c;即开发密钥散列和发布密钥散列 获得散列值需要借助openssl工具。 下载并配置openssl 1、下载 到https://code.google.com/archive/p/openssl-for-win…

校验表格里的表单

<template><el-dialogtitle"收货地址":visible.sync"dialogFormVisible">{{ form }}<el-formref"form":model"form":rules"rules"label-width"100px"><el-form-itemlabel"活动名称&quo…

Roop:单图离线版软件包及使用方法!

你们要的“单图换脸”离线一键运行版来了。Roop发布几十个小时后&#xff0c;马不停蹄地搞了Colab在线版。其实这东西都挺好的&#xff0c;又快又方便&#xff0c;几乎没有任何硬件要求&#xff0c;点一点就可以搞定了。但是它有一个问题&#xff0c;就是没有“魔法” 就没法使…

国际电商网站APP开发-国际电商网站,跨境方案

跨境电商一种在国际贸易中进行电子商务的策略。它涉及到在线销售产品或服务给海外消费者&#xff0c;通常涉及到国际支付、物流和海外市场营销的问题。以下是一些跨境电商方案的例子&#xff1a; 跨境电商平台&#xff1a;建立自己的跨境电商平台&#xff0c;提供海外消费者便捷…