从0到1构建,一个SpringBoot对接支付宝沙箱环境案例

简介: 首先,看这篇文章的小伙伴肯定具有Springboot的基础以及更为深刻的技术功底;其次,这篇文章主要是作为个人笔记学习之用,记录自己从0到1构建出一个完整的支付环境,方便后期个人项目整合的时候用得到。如果有总结的不对的地方,希望技术大佬给予指正,我会马上修改。默认您有以下的知识或者技术功底:

写在前面

首先,看这篇文章的小伙伴肯定具有Springboot的基础以及更为深刻的技术功底;
其次,这篇文章主要是作为个人笔记学习之用,记录自己从0到1构建出一个完整的支付环境,方便后期个人项目整合的时候用得到。如果有总结的不对的地方,希望技术大佬给予指正,我会马上修改。
默认您有以下的知识或者技术功底:

支付宝开放平台的认知,详见
https://openhome.alipay.com/platform/home.htm知道支付宝沙箱环境是什么Springboot技术基本的前端技术(Thymeleaf、jsp、Freemarker三者任选其一)

前期准备

言归正传,既然我们需要整合支付宝沙箱支付,肯定需要先去看看官方给我们提供了哪些东西。
百度搜索支付宝开放平台,后面带官方俩字的就是

网络异常,图片无法展示
|

进入首页

网络异常,图片无法展示
|

点击右上角登录,然后登录你的支付宝账号。放心此步骤没有任何的风险,可以放心操作;
登录完成后,会自己跳转到如下页面:

网络异常,图片无法展示
|

我们找到下面的开发服务,点击研发服务

网络异常,图片无法展示
|

进来之后,会给我们如下的界面;

网络异常,图片无法展示
|

我们需要的其实就是APPID和支付宝网关以及密钥对;

网络异常,图片无法展示
|

既然官方需要我们去生成一个密钥,那么肯定需要一个密钥工具;
支付宝官方也为我们提供了一个生成密钥的工具,看看文档部分,复制下面链接:

https://opendocs.alipay.com/open/291/106074

网络异常,图片无法展示
|

我们下载好官方给我们提供的工具,安装打开后是这个样子的。

网络异常,图片无法展示
|

我们点击生成密钥,然后就会自动给我们生成好我们需要的密钥对;

网络异常,图片无法展示
|

生成出来的密钥对会自动给我们保存在文件夹下,也可以直接点击打开密钥文件路径查看;

网络异常,图片无法展示
|

然后我们把刚才生成出来的应用公钥复制一下,回到我们刚才的网站,点击设置密钥:

网络异常,图片无法展示
|

在弹出来的窗口我们选择公钥:

网络异常,图片无法展示
|

把刚才复制的放进去,保存设置,就会自动给我们生成;

网络异常,图片无法展示
|

接下来我们就可以开始撸代码了;

代码部分

首先导入我们必要的依赖环境,根据自己需要自取:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.10.192.ALL</version>
        </dependency>
    </dependencies>

最后面那个依赖就是官方给我们提供的整合依赖要用到的sdk;

接着创建一个Config配置类,把我们需要的配置信息放进去:

网络异常,图片无法展示
|

package com.zxy.config;
import java.io.FileWriter;
import java.io.IOException;
public class AlipayConfig {
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
    public static String app_id = "改成你自己的APPID";
    // 商户私钥,您的PKCS8格式RSA2私钥
    public static String merchant_private_key = "把这儿改成你自己的私钥";
    // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String alipay_public_key = "改成你的支付宝公钥,不是应用公钥,看清楚";
    // 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    public static String notify_url = "http://www.baidu.com";
    // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    public static String return_url = "http://www.baidu.com";
    // 签名方式
    public static String sign_type = "RSA2";
    // 字符编码格式
    public static String charset = "utf-8";
    // 支付宝网关
    public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
    // 支付宝网关
    public static String log_path = "C:\\";
//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
    /**
     * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
     * @param sWord 要写入日志里的文本内容
     */
    public static void logResult(String sWord) {
        FileWriter writer = null;
        try {
            writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
            writer.write(sWord);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

如果你不想这些配置信息写死,那你也可以考虑使用外部配置文件通过注解的形式讲属性注入进去,看个人爱好;

接着创建一个视图层,用来跳转支付:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form th:action="@{/pay}" method="post">
    订单号:<input type="text" name="WIDout_trade_no" required><br/>
    订单名称:<input type="text" name="WIDsubject" required><br/>
    付款金额:<input type="text" name="WIDtotal_amount" required><br/>
    WIDbody:<input type="text" name="WIDbody"><br/>
    <input type="submit" value="下单"> <input type="reset" value="重置">
</form>
</body>
</html>

然后创建一个Controller层,用来实现具体的业务控制。(我这儿做的比较简单,没有用数据层以及服务层来分离架构,读者可以根据自行需要调整,道理都差不多)

package com.zxy.controller;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.zxy.config.AlipayConfig;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @Author Zxy
 * @Date 2020/11/24 16:39
 * @Version 1.0
 */
@Controller
public class PayController {
    @RequestMapping("/pay")
    @ResponseBody
    public void payController(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
        // 获取初始化的AliPayClient
        AlipayClient alipayClient = new DefaultAlipayClient(
                AlipayConfig.gatewayUrl,
                AlipayConfig.app_id,
                AlipayConfig.merchant_private_key,
                "json",
                AlipayConfig.charset,
                AlipayConfig.alipay_public_key,
                AlipayConfig.sign_type);
        // 设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
        //商户订单号,商户网站订单系统中唯一订单号,必填
        String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"),"UTF-8");
        //付款金额,必填
        String total_amount = new String(request.getParameter("WIDtotal_amount").getBytes("ISO-8859-1"),"UTF-8");
        //订单名称,必填
        String subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"),"UTF-8");
        //商品描述,可空
        String body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"),"UTF-8");
        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //若想给BizContent增加其他可选请求参数,以增加自定义超时时间参数timeout_express来举例说明
        //alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
        //    + "\"total_amount\":\""+ total_amount +"\","
        //    + "\"subject\":\""+ subject +"\","
        //    + "\"body\":\""+ body +"\","
        //    + "\"timeout_express\":\"10m\","
        //    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节
        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        //输出
        response.setContentType("text/html;charset="+AlipayConfig.charset);
        response.getWriter().write(result);
        response.getWriter().flush();
        response.getWriter().close();
    }
    @RequestMapping("/")
    public String toIndex(){
        return "index";
    }
}

测试

运行写好的案例,访问首页:

网络异常,图片无法展示
|

如果遇到下面的这样的报错,那么你试试用另一个浏览器打开窗口进行支付测试:

网络异常,图片无法展示
|


网络异常,图片无法展示
|

登录刚才我们那个开放平台为我们提供的账号和密码:

网络异常,图片无法展示
|

当然,这些余额都是自己改的。。。想提现也是不大可能,要是可以的话我就提现了…

网络异常,图片无法展示
|

输入你的支付密码,然后就可以实现支付功能;

网络异常,图片无法展示
|

等几秒钟,会自动给我们跳转到我们前面设置的服务通知页面,由于我设置的是百度,所以就自己跳到百度页面了。

网络异常,图片无法展示
|

至此,整合功能完成;


题外话

我们需要做的其实是电脑端整合网站支付,还有手机端的支付等等,我们可以往下看看给我们提供了哪些功能;

网络异常,图片无法展示
|

后期会出一些整合其他功能的支付,不过都是不变应万变,原理都一样;


小结

虽然这个做出来很简单,但是,还是有很多的不足之处,例如没有用数据库来保存信息,没有分层等等,拿来练手还勉强可以;
如果有更好的想法,不妨分享给我,我们一起实现。

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

相关文章
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
60 4
|
2月前
|
Java API 数据库
如何使用Spring Boot构建RESTful API,以在线图书管理系统为例
【10月更文挑战第9天】本文介绍了如何使用Spring Boot构建RESTful API,以在线图书管理系统为例,从项目搭建、实体类定义、数据访问层创建、业务逻辑处理到RESTful API的实现,详细展示了每个步骤。通过Spring Boot的简洁配置和强大功能,开发者可以高效地开发出功能完备、易于维护的Web应用。
81 3
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
119 62
|
26天前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
89 5
|
1月前
|
消息中间件 Java Kafka
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
44 1
|
1月前
|
Java
SpringBoot构建Bean(RedisConfig + RestTemplateConfig)
SpringBoot构建Bean(RedisConfig + RestTemplateConfig)
45 2
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
102 2
|
1月前
|
消息中间件 NoSQL Java
springboot整合常用中间件框架案例
该项目是Spring Boot集成整合案例,涵盖多种中间件的使用示例,每个案例项目使用最小依赖,便于直接应用到自己的项目中。包括MyBatis、Redis、MongoDB、MQ、ES等的整合示例。
114 1
|
2月前
|
自然语言处理 Java API
Spring Boot 接入大模型实战:通义千问赋能智能应用快速构建
【10月更文挑战第23天】在人工智能(AI)技术飞速发展的今天,大模型如通义千问(阿里云推出的生成式对话引擎)等已成为推动智能应用创新的重要力量。然而,对于许多开发者而言,如何高效、便捷地接入这些大模型并构建出功能丰富的智能应用仍是一个挑战。
284 6
|
2月前
|
文字识别 安全 Java
SpringBoot3.x和OCR构建车牌识别系统
本文介绍了一个基于Java SpringBoot3.x框架的车牌识别系统,详细阐述了系统的设计目标、需求分析及其实现过程。利用Tesseract OCR库和OpenCV库,实现了车牌图片的识别与处理,确保系统的高准确性和稳定性。文中还提供了具体的代码示例,展示了如何构建和优化车牌识别服务,以及如何处理特殊和异常车牌。通过实际应用案例,帮助读者理解和应用这一解决方案。