SpringBoot+MyBatis集成支付宝支付流程

 更新时间:2025年06月06日 09:36:41   作者:yuren_xia  
本文主要介绍了SpringBoot+MyBatis集成支付宝支付流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

核心流程

  • 商户系统生成订单
  • 调用支付宝创建预支付订单
  • 用户跳转支付宝完成支付
  • 支付宝异步通知支付结果
  • 商户处理支付结果更新订单状态
  • 支付宝同步跳转回商户页面

代码实现示例(电脑网站支付)

1. 添加依赖

<!-- pom.xml -->
<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- MyBatis & MySQL -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    
    <!-- 支付宝SDK -->
    <dependency>
        <groupId>com.alipay.sdk</groupId>
        <artifactId>alipay-sdk-java</artifactId>
        <version>4.35.0.ALL</version>
    </dependency>
    
    <!-- Lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

2. 支付宝配置类

@Configuration
public class AlipayConfig {

    @Value("${alipay.app_id}")
    private String appId;
    
    @Value("${alipay.merchant_private_key}")
    private String merchantPrivateKey;
    
    @Value("${alipay.alipay_public_key}")
    private String alipayPublicKey;
    
    @Value("${alipay.notify_url}")
    private String notifyUrl;
    
    @Value("${alipay.return_url}")
    private String returnUrl;
    
    @Value("${alipay.gateway_url}")
    private String gatewayUrl;
    
    @Value("${alipay.sign_type}")
    private String signType;
    
    @Value("${alipay.charset}")
    private String charset;

    @Bean
    public AlipayClient alipayClient() {
        return new DefaultAlipayClient(
            gatewayUrl,
            appId,
            merchantPrivateKey,
            "json",
            charset,
            alipayPublicKey,
            signType
        );
    }
}

3. 实体类和Mapper

// 订单实体
@Data
public class Order {
    private Long id;
    private String orderNo;   // 商户订单号
    private BigDecimal amount;// 支付金额
    private Integer status;   // 0-待支付, 1-已支付
    private LocalDateTime createTime;
}

// MyBatis Mapper
@Mapper
public interface OrderMapper {
    @Insert("INSERT INTO orders(order_no, amount, status, create_time) " +
            "VALUES(#{orderNo}, #{amount}, 0, NOW())")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    void insert(Order order);
    
    @Update("UPDATE orders SET status = #{status} WHERE order_no = #{orderNo}")
    void updateStatus(@Param("orderNo") String orderNo, @Param("status") int status);
}

4. 支付服务类

@Service
public class PayService {

    @Autowired private AlipayClient alipayClient;
    @Autowired private OrderMapper orderMapper;
    @Value("${alipay.return_url}") private String returnUrl;
    @Value("${alipay.notify_url}") private String notifyUrl;

    // 创建支付订单
    public String createPayOrder(Order order) throws AlipayApiException {
        orderMapper.insert(order); // 保存订单到数据库
        
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setReturnUrl(returnUrl);
        request.setNotifyUrl(notifyUrl);
        
        // 构造业务参数
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", order.getOrderNo());
        bizContent.put("total_amount", order.getAmount());
        bizContent.put("subject", "商品支付");
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY"); // 电脑网站支付
        
        request.setBizContent(bizContent.toString());
        
        return alipayClient.pageExecute(request).getBody();
    }

    // 处理异步通知
    public boolean handleNotify(Map<String, String> params) throws AlipayApiException {
        // 1. 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(
                params,
                alipayPublicKey,  // 注入支付宝公钥
                charset,
                signType
        );
        
        if (!signVerified) return false;

        // 2. 验证交易状态
        String tradeStatus = params.get("trade_status");
        if (!"TRADE_SUCCESS".equals(tradeStatus)) return false;

        // 3. 更新订单状态
        String orderNo = params.get("out_trade_no");
        orderMapper.updateStatus(orderNo, 1); // 更新为已支付
        
        return true;
    }
}

5. 控制器

@RestController
@RequestMapping("/pay")
public class PayController {

    @Autowired private PayService payService;

    // 创建支付订单
    @PostMapping("/create")
    public String createOrder(@RequestParam BigDecimal amount) 
        throws AlipayApiException {
        
        Order order = new Order();
        order.setOrderNo(UUID.randomUUID().toString().replace("-", ""));
        order.setAmount(amount);
        
        return payService.createPayOrder(order); // 返回支付页面表单
    }

    // 支付宝异步通知(需公网可访问)
    @PostMapping("/notify")
    public String alipayNotify(HttpServletRequest request) 
        throws UnsupportedEncodingException, AlipayApiException {
        
        Map<String, String> params = parseRequestParams(request);
        boolean success = payService.handleNotify(params);
        return success ? "success" : "failure"; // 通知支付宝处理结果
    }

    // 支付宝同步跳转
    @GetMapping("/return")
    public String alipayReturn(HttpServletRequest request) {
        // 简单展示支付结果(实际需要验签和状态检查)
        return "支付完成!订单号:" + request.getParameter("out_trade_no");
    }

    // 解析请求参数
    private Map<String, String> parseRequestParams(HttpServletRequest request) {
        // 转换参数Map(参考支付宝示例代码)
    }
}

6. 配置文件

# application.properties
# 支付宝配置
alipay.app_id=2021000123456789
alipay.merchant_private_key=MIIEvQIBADANB...
alipay.alipay_public_key=MIIBIjANBgkq...
alipay.notify_url=http://your-domain.com/pay/notify
alipay.return_url=http://your-domain.com/pay/return
alipay.gateway_url=https://openapi.alipay.com/gateway.do
alipay.sign_type=RSA2
alipay.charset=UTF-8

# MySQL配置
spring.datasource.url=jdbc:mysql://localhost:3306/alipay_demo
spring.datasource.username=root
spring.datasource.password=123456

关键流程说明

  • 生成商户订单

    • 生成唯一订单号(推荐雪花算法)
    • 保存订单到数据库(状态=待支付)
  • 调用支付宝接口

    • 使用 AlipayTradePagePayRequest 构建请求
    • 关键参数:订单号、金额、支付标题、回调地址
  • 接收异步通知

    • 必须验证签名(防止伪造请求)
    • 检查 trade_status 是否为 TRADE_SUCCESS
    • 更新订单状态(注意处理幂等性)
  • 安全注意事项

    • 支付金额需与订单金额比对(防止金额篡改)
    • 敏感操作记录日志
    • 异步通知处理需要保证幂等性
  • 扩展功能

    • 订单超时关闭:定时任务扫描未支付订单
    • 支付结果查询:通过 trade_no 调用支付宝查询接口
    • 退款功能:使用 AlipayTradeRefundRequest

提示:实际开发中需要:

替换为正式支付宝账户

配置公网可访问的域名

添加完整的错误处理

实现参数解析工具方法

添加数据库事务管理

到此这篇关于SpringBoot+MyBatis集成支付宝支付流程的文章就介绍到这了,更多相关SpringBoot MyBatis 支付宝支付内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • springboot+mybatis配置clickhouse实现插入查询功能

    springboot+mybatis配置clickhouse实现插入查询功能

    这篇文章主要介绍了springboot+mybatis配置clickhouse实现插入查询功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • Springboot事务失效的原因及解决办法详解

    Springboot事务失效的原因及解决办法详解

    这篇文章主要介绍了Springboot事务失效的原因及解决办法详解,spring中的事务是依赖AOP的,AOP是通过动态代理实现的,只有通过代理类访问的方法才能被拦截,而addMultiFile直接内部调用了addFile方法,所以addFile中的事务就不会生效
    2023-10-10
  • SpringMVC处理multipart请求的示例代码

    SpringMVC处理multipart请求的示例代码

    本篇文章主要介绍了SpringMVC处理multipart请求的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • SpringBoot 应用程序测试实现方案

    SpringBoot 应用程序测试实现方案

    这篇文章主要介绍了SpringBoot 应用程序测试实现方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java异步调用转同步方法实例详解

    Java异步调用转同步方法实例详解

    这篇文章主要介绍了Java异步调用转同步方法实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • 零基础写Java知乎爬虫之先拿百度首页练练手

    零基础写Java知乎爬虫之先拿百度首页练练手

    本来打算这篇文章直接抓取知乎的,但是想想还是先来个简单的吧,初级文章适合初学者,高手们请直接略过
    2014-11-11
  • Java使用TarsosDSP库实现音频的处理和格式转换

    Java使用TarsosDSP库实现音频的处理和格式转换

    在音频处理领域,Java虽然有原生的音频处理类库,但其功能相对基础,而TarsosDSP是一个强大的开源音频处理库,提供了丰富的功能,本文将介绍如何在Java中结合使用TarsosDSP库,来实现音频的处理和格式转换,需要的朋友可以参考下
    2025-04-04
  • Spring Boot 把配置文件和日志文件放到jar外部

    Spring Boot 把配置文件和日志文件放到jar外部

    如果不想使用默认的application.properties,而想将属性文件放到jar包外面,怎么做呢?下面小编给大家带来了两种方法解决Spring Boot 把配置文件和日志文件放到jar外部问题,感兴趣的朋友一起看看吧
    2018-02-02
  • Java日常练习题,每天进步一点点(62)

    Java日常练习题,每天进步一点点(62)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-08-08
  • Java并发编程学习之Unsafe类与LockSupport类源码详析

    Java并发编程学习之Unsafe类与LockSupport类源码详析

    这篇文章主要给大家介绍了关于Java并发编程学习之Unsafe类与LockSupport类源码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧
    2018-06-06

最新评论