SpringBoot實現(xiàn)支付寶沙箱支付的完整步驟
1、進入支付寶開放平臺
支付寶開發(fā)者平臺開放平臺
1.1 登錄支付寶賬號后下拉選擇網(wǎng)頁/移動應(yīng)用開發(fā)

1.2 創(chuàng)建網(wǎng)頁應(yīng)用

1.3 創(chuàng)建成功后進入沙箱
沙箱比較不好找到 沙箱地址在這里:
登錄 - 支付寶
歡迎登錄支付寶,支付寶-全球領(lǐng)先的獨立第三方支付平臺,致力于為廣大用戶提供安全快速的電子支付/網(wǎng)上支付/安全支付/手機支付體驗以及轉(zhuǎn)賬收款/水電煤繳費/信用卡還款等生活服務(wù)應(yīng)用;為廣大為從事電子商務(wù)的網(wǎng)站提供支付產(chǎn)品/支付服務(wù)的在線訂購和技術(shù)支持等服務(wù),幫助商家快速接入支付工具,高效、安全、快捷地開展電子商務(wù)。

1.4 點擊啟用公鑰(有重要作用!springboot整合時會用到)

2、開始springboot與支付寶沙箱的整合
2.1導入支付寶api的依賴
<!--引入支付寶支付 -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.22.113.ALL</version>
</dependency>2.2 配置 application.yml 沙箱參數(shù)
#支付寶 alipay: appId: appPrivateKey: alipayPublicKey: notifyUrl: returnUrl:
這五個參數(shù)都是什么意思呢?
appId: 沙箱中的應(yīng)用id
appPrivateKey: 應(yīng)用私鑰
alipayPublicKey: 支付寶公鑰
notifyUrl: 調(diào)用支付寶支付接口后產(chǎn)生的回調(diào),需要內(nèi)網(wǎng)穿透,后面詳細講,先不配置
returnUrl: 支付成功后的頁面跳轉(zhuǎn),設(shè)置成你項目中的成功支付界面(可不填)
appPrivateKey: 應(yīng)用私鑰與 alipayPublicKey: 支付寶公鑰在這里:點擊查看


import com.alipay.api.DefaultAlipayClient;
/**
* @method: $
* @description:
* @date: $
* @author: myth
* @return $
*/
public class AliPayUtils {
public static AlipayClient alipayClient;
static {
alipayClient =
new DefaultAlipayClient(
"https://openapi-sandbox.dl.alipaydev.com/gateway.do",
"123123123",
"MIIEvgIBADANBgkq.......",
"json",
//UTF-8編碼格式
"UTF-8",
"MIIBIjANBgkqhk......",
//RSA非對稱加密
"RSA2");
}
public static AlipayClient getAlipayClient() {
return alipayClient;
}
}2.3 在過濾器和攔截器中忽略掉alipay的系列端口
package com.gyp.studytour.common;
import com.gyp.studytour.common.JwtInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor())
.addPathPatterns("/**").excludePathPatterns("/alipay/**");
super.addInterceptors(registry);
}
@Bean
public JwtInterceptor jwtInterceptor() {
return new JwtInterceptor();
}
}2.4 新建AlipayController.java,定義了支付接口與支付回調(diào)接口:
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @Author myth
* @Date Created in 2024/4/23 15:23
* @DESCRIPTION:
* @Version V1.0
*/
@RestController
@RequestMapping("alipay")
@Transactional(rollbackFor = Exception.class)
public class AliPayController {
@Resource
AliPayConfig aliPayConfig;
@Resource
AddressBookMapper addressBookMapper;
@Autowired
OrderServiceImpl orderServiceImpl;
private static final String GATEWAY_URL ="https://openapi-sandbox.dl.alipaydev.com/gateway.do";
private static final String FORMAT ="JSON";
private static final String CHARSET ="utf-8";
private static final String SIGN_TYPE ="RSA2";
@GetMapping("/pay") // 前端路徑參數(shù)格式?subject=xxx&traceNo=xxx&totalAmount=xxx
public void pay(AliPay aliPay, HttpServletResponse httpResponse) throws Exception {
AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setNotifyUrl(aliPayConfig.getNotifyUrl());
request.setReturnUrl(aliPayConfig.getReturnUrl());
request.setBizContent("{\"out_trade_no\":\"" + aliPay.getTraceNo() + "\","
+ "\"total_amount\":\"" + aliPay.getTotalAmount() + "\","
+ "\"subject\":\"" + aliPay.getSubject() + "\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
String form = "";
try {
// 調(diào)用SDK生成表單
form = alipayClient.pageExecute(request).getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}
httpResponse.setContentType("text/html;charset=" + CHARSET);
// 直接將完整的表單html輸出到頁面
httpResponse.getWriter().write(form);
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}
@PostMapping("/notify") // 注意這里必須是POST接口
public String payNotify(HttpServletRequest request) throws Exception {
if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
}
String tradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
String alipayTradeNo = params.get("trade_no");
// 支付寶驗簽
if (Factory.Payment.Common().verifyNotify(params)) {
// 驗簽通過
System.out.println("交易名稱: " + params.get("subject"));
System.out.println("交易狀態(tài): " + 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";
}
}前端頁面調(diào)用
async function handleBuy(){ window.open('http://localhost:80/alipay/pay') }2.5 編寫AliPay.java 接收前端傳來的參數(shù)
package com.songqiao.waimai.alipay.payparameter;
import lombok.Data;
/**
* @Author myth
* @Date Created in 2024/4/23 15:26
* @DESCRIPTION: alipay接口參數(shù)
* @Version V1.0
*/
@Data
public class AliPay {
//訂單編號
private String traceNo;
//商品金額
private double totalAmount;
//商品名稱
private String subject;
//訂單追蹤號,商戶自己生成,可已不使用
private String alipayTraceNo;
}在application.yml中還有一個重要的參數(shù) notifyUrl 沒有配置,這個參數(shù)是支付成功后支付寶的回調(diào)函數(shù)訪問本地系統(tǒng)的路徑,需要以內(nèi)網(wǎng)穿透的方式讓支付寶訪問本地系統(tǒng)。
3、使用natapp進行內(nèi)網(wǎng)穿透
3.1 進入natapp官網(wǎng)注冊賬號,并進行實名認證、與支付寶賬號進行綁定。
NATAPP-內(nèi)網(wǎng)穿透 基于ngrok的國內(nèi)高速內(nèi)網(wǎng)映射工具
natapp是基于ngrok的國內(nèi)高速內(nèi)網(wǎng)穿透專業(yè)服務(wù)商,獨家徹底解決ngrok1.7內(nèi)存泄漏問題.穩(wěn)定拒絕掉線,適用于微信開發(fā)調(diào)試,本地架設(shè)演示服務(wù)器,外網(wǎng)可以訪問,遠程服務(wù)器,遠程桌面,遠程辦公,游戲聯(lián)機等
NATAPP-內(nèi)網(wǎng)穿透 基于ngrok的國內(nèi)高速內(nèi)網(wǎng)映射工具
3.2 下載指定版本的natapp應(yīng)用

我這里選用的是Windows 64位下載,下載并解壓成功后的內(nèi)容為:

3.2.1 運行natapp.exe
出現(xiàn)以下界面

3.2.2 配置natapp中的隧道
回到natapp官網(wǎng),點擊購買隧道->免費隧道->創(chuàng)建隧道并配置程序中的端口等信息

創(chuàng)建成功后點擊我的隧道->點擊配置->點擊復制獲取authtoken


3.2.3 啟動自己本機的web服務(wù)
在natapp.exe啟動后的命令行輸入natapp -authtoken=剛剛復制的token,就會與本機的8080端口映射成功!

出現(xiàn)如圖所示狀態(tài)后,那么恭喜你!外網(wǎng)即可訪問你的本機的8080端口,支付寶api支付成功后即可完成回調(diào)!
3.3 配置application.yml中notifyUrl參數(shù)

4、支付寶沙箱支付前端Vue代碼
調(diào)用后端接口并拼接get請求的參數(shù),完成
async goToPaySuccess(){
//在這里我選擇了window.open(url,'_self')形式,也就是不跳轉(zhuǎn)新的頁面,在本頁面直接跳轉(zhuǎn)
window.open("http://127.0.0.1:8080/alipay/pay?subject="+"魚頭,"+this.note+"&traceNo="+Math.floor(Math.random() * 900000) + 100000+"&totalAmount="+this.goodsPrice,'_self')
},5、啟動項目并測試功能
點擊支付按鈕后跳轉(zhuǎn)支付界面,為了避免被當做違規(guī)圖片,我把二維碼遮蓋了。

注意!大坑!此時要求你登錄的支付寶賬號密碼是支付寶沙箱的賬號密碼!不要混淆!
支付寶沙箱賬號密碼在沙箱中查看!
登錄 - 支付寶
歡迎登錄支付寶,支付寶-全球領(lǐng)先的獨立第三方支付平臺,致力于為廣大用戶提供安全快速的電子支付/網(wǎng)上支付/安全支付/手機支付體驗以及轉(zhuǎn)賬收款/水電煤繳費/信用卡還款等生活服務(wù)應(yīng)用;為廣大為從事電子商務(wù)的網(wǎng)站提供支付產(chǎn)品/支付服務(wù)的在線訂購和技術(shù)支持等服務(wù),幫助商家快速接入支付工具,高效、安全、快捷地開展電子商務(wù)。

輸入賬號密碼后即可進行付款

確認付款后會有兩種結(jié)果:1.付款成功界面 2.付款成功后跳轉(zhuǎn)到你指定的頁面(在前面的application.yml的配置中設(shè)置) 如果沒有配置就會展示成功界面,配置了就會在幾秒后跳轉(zhuǎn)到你配置的界面中去!

以上就是SpringBoot實現(xiàn)支付寶沙箱支付的完整步驟的詳細內(nèi)容,更多關(guān)于SpringBoot沙箱支付的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java數(shù)據(jù)類型實現(xiàn)自動與強制轉(zhuǎn)換的示例代碼
Java數(shù)據(jù)類型之間的轉(zhuǎn)換有自動轉(zhuǎn)換和強制類型轉(zhuǎn)換,這篇文章主要給大家介紹Java數(shù)據(jù)類型如何實現(xiàn)自動轉(zhuǎn)換與強制轉(zhuǎn)換,需要的朋友可以參考下2023-05-05
Java中的stream流的概念解析及實際運用總結(jié)
流是指傳輸時的數(shù)據(jù),Java為流準備了很多內(nèi)置類,尤其是IO輸入輸出流非常常用,這里我們來看一下Java中的stream流的概念解析及實際運用總結(jié)2016-06-06

