SpringBoot實(shí)現(xiàn)支付寶沙箱支付的完整步驟
1、進(jìn)入支付寶開放平臺(tái)
支付寶開發(fā)者平臺(tái)開放平臺(tái)
1.1 登錄支付寶賬號(hào)后下拉選擇網(wǎng)頁/移動(dòng)應(yīng)用開發(fā)
1.2 創(chuàng)建網(wǎng)頁應(yīng)用
1.3 創(chuàng)建成功后進(jìn)入沙箱
沙箱比較不好找到 沙箱地址在這里:
登錄 - 支付寶
歡迎登錄支付寶,支付寶-全球領(lǐng)先的獨(dú)立第三方支付平臺(tái),致力于為廣大用戶提供安全快速的電子支付/網(wǎng)上支付/安全支付/手機(jī)支付體驗(yàn)以及轉(zhuǎn)賬收款/水電煤繳費(fèi)/信用卡還款等生活服務(wù)應(yīng)用;為廣大為從事電子商務(wù)的網(wǎng)站提供支付產(chǎn)品/支付服務(wù)的在線訂購和技術(shù)支持等服務(wù),幫助商家快速接入支付工具,高效、安全、快捷地開展電子商務(wù)。
1.4 點(diǎn)擊啟用公鑰(有重要作用!springboot整合時(shí)會(huì)用到)
2、開始springboot與支付寶沙箱的整合
2.1導(dǎo)入支付寶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:
這五個(gè)參數(shù)都是什么意思呢?
appId: 沙箱中的應(yīng)用id
appPrivateKey: 應(yīng)用私鑰
alipayPublicKey: 支付寶公鑰
notifyUrl: 調(diào)用支付寶支付接口后產(chǎn)生的回調(diào),需要內(nèi)網(wǎng)穿透,后面詳細(xì)講,先不配置
returnUrl: 支付成功后的頁面跳轉(zhuǎn),設(shè)置成你項(xiàng)目中的成功支付界面(可不填)
appPrivateKey: 應(yīng)用私鑰與 alipayPublicKey: 支付寶公鑰在這里:點(diǎn)擊查看
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非對(duì)稱加密 "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"); // 支付寶驗(yàn)簽 if (Factory.Payment.Common().verifyNotify(params)) { // 驗(yàn)簽通過 System.out.println("交易名稱: " + params.get("subject")); System.out.println("交易狀態(tài): " + params.get("trade_status")); System.out.println("支付寶交易憑證號(hào): " + params.get("trade_no")); System.out.println("商戶訂單號(hào): " + params.get("out_trade_no")); System.out.println("交易金額: " + params.get("total_amount")); System.out.println("買家在支付寶唯一id: " + params.get("buyer_id")); System.out.println("買家付款時(shí)間: " + 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 { //訂單編號(hào) private String traceNo; //商品金額 private double totalAmount; //商品名稱 private String subject; //訂單追蹤號(hào),商戶自己生成,可已不使用 private String alipayTraceNo; }
在application.yml中還有一個(gè)重要的參數(shù) notifyUrl 沒有配置,這個(gè)參數(shù)是支付成功后支付寶的回調(diào)函數(shù)訪問本地系統(tǒng)的路徑,需要以內(nèi)網(wǎng)穿透的方式讓支付寶訪問本地系統(tǒng)。
3、使用natapp進(jìn)行內(nèi)網(wǎng)穿透
3.1 進(jìn)入natapp官網(wǎng)注冊(cè)賬號(hào),并進(jìn)行實(shí)名認(rèn)證、與支付寶賬號(hào)進(jìn)行綁定。
NATAPP-內(nèi)網(wǎng)穿透 基于ngrok的國內(nèi)高速內(nèi)網(wǎng)映射工具
natapp是基于ngrok的國內(nèi)高速內(nèi)網(wǎng)穿透專業(yè)服務(wù)商,獨(dú)家徹底解決ngrok1.7內(nèi)存泄漏問題.穩(wěn)定拒絕掉線,適用于微信開發(fā)調(diào)試,本地架設(shè)演示服務(wù)器,外網(wǎng)可以訪問,遠(yuǎn)程服務(wù)器,遠(yuǎn)程桌面,遠(yuǎn)程辦公,游戲聯(lián)機(jī)等
NATAPP-內(nèi)網(wǎng)穿透 基于ngrok的國內(nèi)高速內(nèi)網(wǎng)映射工具
3.2 下載指定版本的natapp應(yīng)用
我這里選用的是Windows 64位下載,下載并解壓成功后的內(nèi)容為:
3.2.1 運(yùn)行natapp.exe
出現(xiàn)以下界面
3.2.2 配置natapp中的隧道
回到natapp官網(wǎng),點(diǎn)擊購買隧道->免費(fèi)隧道->創(chuàng)建隧道并配置程序中的端口等信息
創(chuàng)建成功后點(diǎn)擊我的隧道->點(diǎn)擊配置->點(diǎn)擊復(fù)制獲取authtoken
3.2.3 啟動(dòng)自己本機(jī)的web服務(wù)
在natapp.exe啟動(dòng)后的命令行輸入natapp -authtoken=剛剛復(fù)制的token,就會(huì)與本機(jī)的8080端口映射成功!
出現(xiàn)如圖所示狀態(tài)后,那么恭喜你!外網(wǎng)即可訪問你的本機(jī)的8080端口,支付寶api支付成功后即可完成回調(diào)!
3.3 配置application.yml中notifyUrl參數(shù)
4、支付寶沙箱支付前端Vue代碼
調(diào)用后端接口并拼接get請(qǐng)求的參數(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、啟動(dòng)項(xiàng)目并測(cè)試功能
點(diǎn)擊支付按鈕后跳轉(zhuǎn)支付界面,為了避免被當(dāng)做違規(guī)圖片,我把二維碼遮蓋了。
注意!大坑!此時(shí)要求你登錄的支付寶賬號(hào)密碼是支付寶沙箱的賬號(hào)密碼!不要混淆!
支付寶沙箱賬號(hào)密碼在沙箱中查看!
登錄 - 支付寶
歡迎登錄支付寶,支付寶-全球領(lǐng)先的獨(dú)立第三方支付平臺(tái),致力于為廣大用戶提供安全快速的電子支付/網(wǎng)上支付/安全支付/手機(jī)支付體驗(yàn)以及轉(zhuǎn)賬收款/水電煤繳費(fèi)/信用卡還款等生活服務(wù)應(yīng)用;為廣大為從事電子商務(wù)的網(wǎng)站提供支付產(chǎn)品/支付服務(wù)的在線訂購和技術(shù)支持等服務(wù),幫助商家快速接入支付工具,高效、安全、快捷地開展電子商務(wù)。
輸入賬號(hào)密碼后即可進(jìn)行付款
確認(rèn)付款后會(huì)有兩種結(jié)果:1.付款成功界面 2.付款成功后跳轉(zhuǎn)到你指定的頁面(在前面的application.yml的配置中設(shè)置) 如果沒有配置就會(huì)展示成功界面,配置了就會(huì)在幾秒后跳轉(zhuǎn)到你配置的界面中去!
以上就是SpringBoot實(shí)現(xiàn)支付寶沙箱支付的完整步驟的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot沙箱支付的資料請(qǐng)關(guān)注腳本之家其它相關(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+MyBatis集成支付寶支付流程
相關(guān)文章
JFreeChart實(shí)現(xiàn)實(shí)時(shí)曲線圖
這篇文章主要為大家詳細(xì)介紹了JFreeChart實(shí)現(xiàn)實(shí)時(shí)曲線圖的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06Java數(shù)據(jù)類型實(shí)現(xiàn)自動(dòng)與強(qiáng)制轉(zhuǎn)換的示例代碼
Java數(shù)據(jù)類型之間的轉(zhuǎn)換有自動(dòng)轉(zhuǎn)換和強(qiáng)制類型轉(zhuǎn)換,這篇文章主要給大家介紹Java數(shù)據(jù)類型如何實(shí)現(xiàn)自動(dòng)轉(zhuǎn)換與強(qiáng)制轉(zhuǎn)換,需要的朋友可以參考下2023-05-05Java中的stream流的概念解析及實(shí)際運(yùn)用總結(jié)
流是指?jìng)鬏敃r(shí)的數(shù)據(jù),Java為流準(zhǔn)備了很多內(nèi)置類,尤其是IO輸入輸出流非常常用,這里我們來看一下Java中的stream流的概念解析及實(shí)際運(yùn)用總結(jié)2016-06-06