SpringBoot+MyBatis集成支付寶支付流程
核心流程
- 商戶系統(tǒng)生成訂單
- 調(diào)用支付寶創(chuàng)建預(yù)支付訂單
- 用戶跳轉(zhuǎn)支付寶完成支付
- 支付寶異步通知支付結(jié)果
- 商戶處理支付結(jié)果更新訂單狀態(tài)
- 支付寶同步跳轉(zhuǎn)回商戶頁面
代碼實(shí)現(xiàn)示例(電腦網(wǎng)站支付)
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. 實(shí)體類和Mapper
// 訂單實(shí)體
@Data
public class Order {
private Long id;
private String orderNo; // 商戶訂單號(hào)
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. 支付服務(wù)類
@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;
// 創(chuàng)建支付訂單
public String createPayOrder(Order order) throws AlipayApiException {
orderMapper.insert(order); // 保存訂單到數(shù)據(jù)庫
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl(returnUrl);
request.setNotifyUrl(notifyUrl);
// 構(gòu)造業(yè)務(wù)參數(shù)
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"); // 電腦網(wǎng)站支付
request.setBizContent(bizContent.toString());
return alipayClient.pageExecute(request).getBody();
}
// 處理異步通知
public boolean handleNotify(Map<String, String> params) throws AlipayApiException {
// 1. 驗(yàn)證簽名
boolean signVerified = AlipaySignature.rsaCheckV1(
params,
alipayPublicKey, // 注入支付寶公鑰
charset,
signType
);
if (!signVerified) return false;
// 2. 驗(yàn)證交易狀態(tài)
String tradeStatus = params.get("trade_status");
if (!"TRADE_SUCCESS".equals(tradeStatus)) return false;
// 3. 更新訂單狀態(tài)
String orderNo = params.get("out_trade_no");
orderMapper.updateStatus(orderNo, 1); // 更新為已支付
return true;
}
}
5. 控制器
@RestController
@RequestMapping("/pay")
public class PayController {
@Autowired private PayService payService;
// 創(chuàng)建支付訂單
@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); // 返回支付頁面表單
}
// 支付寶異步通知(需公網(wǎng)可訪問)
@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"; // 通知支付寶處理結(jié)果
}
// 支付寶同步跳轉(zhuǎn)
@GetMapping("/return")
public String alipayReturn(HttpServletRequest request) {
// 簡(jiǎn)單展示支付結(jié)果(實(shí)際需要驗(yàn)簽和狀態(tài)檢查)
return "支付完成!訂單號(hào):" + request.getParameter("out_trade_no");
}
// 解析請(qǐng)求參數(shù)
private Map<String, String> parseRequestParams(HttpServletRequest request) {
// 轉(zhuǎn)換參數(shù)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
關(guān)鍵流程說明
生成商戶訂單
- 生成唯一訂單號(hào)(推薦雪花算法)
- 保存訂單到數(shù)據(jù)庫(狀態(tài)=待支付)
調(diào)用支付寶接口
- 使用
AlipayTradePagePayRequest構(gòu)建請(qǐng)求 - 關(guān)鍵參數(shù):訂單號(hào)、金額、支付標(biāo)題、回調(diào)地址
- 使用
接收異步通知
- 必須驗(yàn)證簽名(防止偽造請(qǐng)求)
- 檢查 trade_status 是否為 TRADE_SUCCESS
- 更新訂單狀態(tài)(注意處理冪等性)
安全注意事項(xiàng)
- 支付金額需與訂單金額比對(duì)(防止金額篡改)
- 敏感操作記錄日志
- 異步通知處理需要保證冪等性
擴(kuò)展功能
- 訂單超時(shí)關(guān)閉:定時(shí)任務(wù)掃描未支付訂單
- 支付結(jié)果查詢:通過 trade_no 調(diào)用支付寶查詢接口
- 退款功能:使用
AlipayTradeRefundRequest
提示:實(shí)際開發(fā)中需要:
替換為正式支付寶賬戶
配置公網(wǎng)可訪問的域名
添加完整的錯(cuò)誤處理
實(shí)現(xiàn)參數(shù)解析工具方法
添加數(shù)據(jù)庫事務(wù)管理
到此這篇關(guān)于SpringBoot+MyBatis集成支付寶支付流程的文章就介紹到這了,更多相關(guān)SpringBoot MyBatis 支付寶支付內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot對(duì)接支付寶支付接口(詳細(xì)開發(fā)步驟總結(jié))
- springboot+vue+對(duì)接支付寶接口+二維碼掃描支付功能(沙箱環(huán)境)
- SpringBoot集成支付寶沙箱支付(支付、退款)
- springboot調(diào)用支付寶第三方接口(沙箱環(huán)境)
- SpringBoot集成支付寶沙箱支付的實(shí)現(xiàn)示例
- SpringBoot接入支付寶支付的方法步驟
- SpringBoot實(shí)現(xiàn)支付寶沙箱支付的完整步驟
- SpringBoot集成支付寶支付的實(shí)現(xiàn)示例
- SpringBoot下如何實(shí)現(xiàn)支付寶接口的使用
相關(guān)文章
springboot+mybatis配置clickhouse實(shí)現(xiàn)插入查詢功能
這篇文章主要介紹了springboot+mybatis配置clickhouse實(shí)現(xiàn)插入查詢功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
SpringMVC處理multipart請(qǐng)求的示例代碼
本篇文章主要介紹了SpringMVC處理multipart請(qǐng)求的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01
SpringBoot 應(yīng)用程序測(cè)試實(shí)現(xiàn)方案
這篇文章主要介紹了SpringBoot 應(yīng)用程序測(cè)試實(shí)現(xiàn)方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Java異步調(diào)用轉(zhuǎn)同步方法實(shí)例詳解
這篇文章主要介紹了Java異步調(diào)用轉(zhuǎn)同步方法實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
Java使用TarsosDSP庫實(shí)現(xiàn)音頻的處理和格式轉(zhuǎn)換
在音頻處理領(lǐng)域,Java雖然有原生的音頻處理類庫,但其功能相對(duì)基礎(chǔ),而TarsosDSP是一個(gè)強(qiáng)大的開源音頻處理庫,提供了豐富的功能,本文將介紹如何在Java中結(jié)合使用TarsosDSP庫,來實(shí)現(xiàn)音頻的處理和格式轉(zhuǎn)換,需要的朋友可以參考下2025-04-04
Spring Boot 把配置文件和日志文件放到j(luò)ar外部
如果不想使用默認(rèn)的application.properties,而想將屬性文件放到j(luò)ar包外面,怎么做呢?下面小編給大家?guī)砹藘煞N方法解決Spring Boot 把配置文件和日志文件放到j(luò)ar外部問題,感興趣的朋友一起看看吧2018-02-02
Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(62)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你2021-08-08
Java并發(fā)編程學(xué)習(xí)之Unsafe類與LockSupport類源碼詳析
這篇文章主要給大家介紹了關(guān)于Java并發(fā)編程學(xué)習(xí)之Unsafe類與LockSupport類源碼的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧2018-06-06

