开发者

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

目录
  • 核心流程
  • 代码实现示例(电脑网站支付)
    • 1. 添加依赖
    • 2. 支付宝配置类
    • 3. 实体类和Mapper
    • 4. 支付服务类
    • 5. 控制器
    • 6. 配置文件
  • 关键流程说明

    核心流程

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

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

    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.signMAgmalPIB_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 = #{http://www.devze.comstatus} 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 boolea编程客栈n 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=MIIEvQIBADAN编程客栈B...
    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 支付宝支付内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)! 

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜