ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringBoot接入支付宝教程

2021-08-19 18:31:25  阅读:238  来源: 互联网

标签:alipay 支付宝 教程 return SpringBoot java import String


码云地址:

 

前言:

今天在一个公众号看到了这样一篇文章,写的是:SpringBoot接入支付宝,看了那篇文章发现写的比较一般,本着求知的心态,今天想着接触下接入支付宝,然后写个博客~

参考博客:

  springboot接入支付宝支付-新版SDK(2020/11/03)

使用到的支付宝开发网址:

  支付宝开发助手

  支付宝开放平台-沙箱环境

  MiniU研发工作台

  ngrok:内网穿透

下面需要使用到的链接或者秘钥我都会用红色标注出来

一、环境搭建

1、应用公钥/私钥的获取

  进入到支付宝开发助手-->MiniU研发工作台,以前的话应该是让下载软件什么的获取秘钥,现在可以直接通过网页进行获取了

复制下来生成的公钥跟私钥,记到小本子上面~

 2、APPID、支付宝公钥的获取

进入到支付宝开放平台-沙箱环境,复制我们刚刚生成的公钥,放在对应的框框中即可生成"支付宝公钥"

复制你的APPID

 复制生成的支付宝公钥~

记得复制下来支付宝提供的测试账号,下面测试要用:

 

 

3、内网穿透设置

我使用的是Windows环境,这里我就下载Windows版本的ngrok,这是国外的网站有的小伙伴下载比较慢,可以使用蓝奏云下载:https://wws.lanzoui.com/izXZZsuw9wb

 下载完成之后,使用命令行进入到解压后的目录,复制内网穿透的链接:注意先别把窗口关闭了。

1、进入目录:鼠标放到导航栏上面,输入cmd,即可快速进入

2、启动应用:ngrok http 端口

二、代码整理

新建SpringBoot项目(只需添加SpringBootWeb依赖即可),项目结构如下:

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-easysdk</artifactId>
    <version>2.1.0</version>
</dependency>

application.properties  

## 端口
server.port=8080
## 支付宝配置
# 应用ID
alipay.appId=把你的应用id填到这里
# 应用私钥
alipay.privateKey=把你的应用私钥填到这里
# 支付宝公钥,注意不是生成的应用公钥
alipay.publicKey=把你的支付宝公钥填到这里
#支付网关配置,这一项是写死的,正式环境是openapi.alipay.com
alipay.gateway=openapi.alipaydev.com
# 支付宝前台跳转地址
alipay.returnUrl=生成的外网穿透链接/return_url.html
# 支付宝后台通知地址
alipay.notifyUrl=生成的外网穿透链接/api/alipay/notify_url
# 支付宝前台手机网页支付中途取消跳转地址
alipay.errorUrl=生成的外网穿透链接/error_url.html

config/AlipayConfig.java

/**
 * @author zhangzhixi
 * @version 1.0
 * @date 2021-8-19 15:02
 */
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class AlipayConfig implements ApplicationRunner {

    // 应用id
    @Value("${alipay.appId}")
    private String appId;

    // 私钥
    @Value("${alipay.privateKey}")
    private String privateKey;

    // 公钥
    @Value("${alipay.publicKey}")
    private String publicKey;

    // 支付宝网关
    @Value("${alipay.gateway}")
    private String gateway;

    // 支付成功后的接口回调地址,不是回调的友好页面,不要弄混了
    @Value("${alipay.notifyUrl}")
    private String notifyUrl;

    /**
     *  项目初始化事件
     * */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        //初始化支付宝SDK
        Factory.setOptions(getOptions());
        System.out.println("**********支付宝SDK初始化完成**********");
    }

    private Config getOptions() {
        //这里省略了一些不必要的配置,可参考文档的说明

        Config config = new Config();
        config.protocol = "https";
        config.gatewayHost = this.gateway;
        config.signType = "RSA2";

        config.appId = this.appId;

        // 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中
        config.merchantPrivateKey = this.privateKey;

        // 注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可
        config.alipayPublicKey = this.publicKey;

        // 可设置异步通知接收服务地址(可选)
        config.notifyUrl = notifyUrl;

        return config;
    }

}
View Code

controller/AlipayController.java

/**
 * @author zhangzhixi
 * @version 1.0
 * @date 2021-8-19 15:06
 */

import com.alipay.easysdk.factory.Factory;
import com.zhixi.aliyunpay.service.AlipayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/alipay")
public class AlipayController {

    private final AlipayService alipayService;

    @Autowired
    public AlipayController(AlipayService alipayService) {
        this.alipayService = alipayService;
    }

    /**
     * 支付宝电脑网页支付
     * @param subject: 订单名称
     * @param total:   金额
     * @return java.lang.String
     */
    @PostMapping("/page")
    public String page(String subject, String total) {
        subject = "测试支付";
        total = "1000";

        return alipayService.page(subject, total);
    }

    /**
     * 支付宝手机网页支付
     * @param subject: 订单名称
     * @param total:   金额
     * @return java.lang.String
     */
    @PostMapping("/wap")
    public String wap(String subject, String total) {
        subject = "测试支付";
        total = "1000";

        return alipayService.wap(subject, total);
    }

    /**
     * @param request: 请求
     * @return java.lang.String
     * @description: 支付宝异步回调
     * @date: 2020/11/3
     */
    @PostMapping("/notify_url")
    public String notify_url(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));
            }

            // 支付宝验签
            if (Factory.Payment.Common().verifyNotify(params)) {
                // 验签通过
                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"));
            }
        }

        return "success";
    }

    /**
     * @param outTradeNo:   商家订单号
     * @param refundAmount: 退款金额(不能大于交易金额)
     * @return java.lang.String
     * @description: 支付宝退款
     * @date: 2020/11/3
     */
    @PostMapping("/refund")
    public String refund(String outTradeNo, String refundAmount) {
        return alipayService.refund(outTradeNo, refundAmount);
    }

}
View Code

service/AlipayService.java

/**
 * @author zhangzhixi
 * @version 1.0
 * @date 2021-8-19 15:04
 */
public interface AlipayService {

    /**
     * @description: 支付宝电脑网页支付
     * @param subject: 订单名称
     * @param total: 金额
     * @date: 2020/11/3
     * @return java.lang.String
     */
    String page(String subject, String total);

    /**
     * @description: 支付宝手机网页支付
     * @param subject: 订单名称
     * @param total: 金额
     * @date: 2020/11/3
     * @return java.lang.String
     */
    String wap(String subject, String total);

    /**
     * @description: 支付宝退款
     * @param outTradeNo: 商家订单号
     * @param refundAmount: 退款金额(不能大于交易金额)
     * @date: 2020/11/3
     * @return java.lang.String
     */
    String refund(String outTradeNo, String refundAmount);
}
View Code

service/impl/AlipayService.java

/**
 * @author zhangzhixi
 * @version 1.0
 * @date 2021-8-19 15:04
 */

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.common.models.AlipayTradeRefundResponse;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.alipay.easysdk.payment.wap.models.AlipayTradeWapPayResponse;
import com.zhixi.aliyunpay.service.AlipayService;
import com.zhixi.aliyunpay.util.OrderUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class AlipayServiceImpl implements AlipayService {

    // 支付成功后要跳转的页面
    @Value("${alipay.returnUrl}")
    private String returnUrl;

    // 支付宝前台手机网页支付中途取消跳转地址
    @Value("${alipay.errorUrl}")
    private String errorUrl;

    @Override
    public String page(String subject, String total) {

        try {
            AlipayTradePagePayResponse response = Factory.Payment
                    // 选择电脑网站
                    .Page()
                    // 调用支付方法(订单名称, 商家订单号, 金额, 成功页面)
                    .pay(subject, OrderUtil.getOrderNo(), total, returnUrl);

            return response.body;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public String wap(String subject, String total) {

        try {
            AlipayTradeWapPayResponse response = Factory.Payment
                    //选择手机网站
                    .Wap()
                    // 调用支付方法(订单名称, 商家订单号, 金额, 中途退出页面, 成功页面)
                    .pay(subject, OrderUtil.getOrderNo(), total, errorUrl, returnUrl);

            return response.body;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public String refund(String outTradeNo, String refundAmount) {
        try {
            AlipayTradeRefundResponse response = Factory.Payment
                    .Common()
                    // 调用交易退款(商家订单号, 退款金额)
                    .refund(outTradeNo, refundAmount);

            if (response.getMsg().equals("Success")) {
                return "退款成功";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "退款失败";
    }
}
View Code

util/OrderUtil.java

/**
 * @author zhangzhixi
 * @version 1.0
 * @date 2021-8-19 15:03
 */

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class OrderUtil {

    /**
     * 根据时间戳生成订单号
     */
    public static String getOrderNo() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
        LocalDateTime localDateTime = Instant.ofEpochMilli(System.currentTimeMillis()).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
        return df.format(localDateTime);
    }
}
View Code

html页面:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试支付</title>
</head>
<body>
<div>
    <h2>测试支付</h2>
    <form enctype="multipart/form-data" action="/api/alipay/page" method="post">
        <button type="submit">电脑确认支付</button>
    </form>
    <form enctype="multipart/form-data" action="/api/alipay/wap" method="post">
        <button type="submit">手机确认支付</button>
    </form>
</div>
</body>
</html>
View Code

return_url.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>支付成功</title>
</head>
<body>
<div>
    <h2>支付成功</h2>

    <a href="http://78ff7c27cdb6.ngrok.io/return_url.html">主页</a>
    <a href="index.html">主页</a>
</div>
</body>
</html>
View Code

error_url.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>支付失败</title>
</head>
<body>
<div>
    <h2>支付失败</h2>
</div>
</body>
</html>
View Code

三、测试

电脑测试访问:

 

 

手机测试访问:

 

 

 

 

标签:alipay,支付宝,教程,return,SpringBoot,java,import,String
来源: https://www.cnblogs.com/zhangzhixi/p/15163301.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有