SpringBoot應(yīng)用輕松接入支付寶支付服務(wù)~
點(diǎn)擊關(guān)注公眾號,Java干貨及時送達(dá)
現(xiàn)如今的應(yīng)用都少不了支付業(yè)務(wù),本篇文章教你如何將支付寶接入到你的應(yīng)用中。
準(zhǔn)備環(huán)境
若是想接入真實的支付寶支付業(yè)務(wù),需要大量的材料審核,所以,我們以支付寶提供的沙箱環(huán)境為例進(jìn)行介紹,首先下載官方DEMO,地址為 https://opendocs.alipay.com/open/270/106291/:

將JAVA版的DEMO下載好,它是一個Eclipse的項目,將其導(dǎo)入Eclipse打開,目錄結(jié)構(gòu)如下:

在AlipayConfig類中有著大量的配置:
public class AlipayConfig {
//↓↓↓↓↓↓↓↓↓↓請在這里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 應(yīng)用ID,您的APPID,收款賬號既是您的APPID對應(yīng)支付寶賬號
public static String app_id = "";
// 商戶私鑰,您的PKCS8格式RSA2私鑰
public static String merchant_private_key = "";
// 支付寶公鑰,查看地址:https://openhome.alipay.com/platform/keyManage.htm 對應(yīng)APPID下的支付寶公鑰。
public static String alipay_public_key = "";
// 服務(wù)器異步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
public static String notify_url = "http://工程公網(wǎng)訪問地址/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";
// 頁面跳轉(zhuǎn)同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
public static String return_url = "http://工程公網(wǎng)訪問地址/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";
// 簽名方式
public static String sign_type = "RSA2";
// 字符編碼格式
public static String charset = "utf-8";
// 支付寶網(wǎng)關(guān)
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
// 支付寶網(wǎng)關(guān)
public static String log_path = "C:\\";
//↑↑↑↑↑↑↑↑↑↑請在這里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
}
我們需要對這些配置項進(jìn)行配置,來到支付寶的沙箱環(huán)境管理后臺 https://openhome.alipay.com/platform/appDaily.htm?tab=info:

在這里可以看到APPID和支付寶網(wǎng)關(guān)的相關(guān)信息,將這兩項配置到AlipayConfig中:
// 應(yīng)用ID,您的APPID,收款賬號既是您的APPID對應(yīng)支付寶賬號
public static String app_id = "2021000116684033";
// 支付寶網(wǎng)關(guān)
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
加密方式
但凡涉及到金錢的交易,操作都是相當(dāng)敏感的,安全問題絕對不容忽視,所以在其它應(yīng)用與支付寶進(jìn)行數(shù)據(jù)傳輸?shù)倪^程中一定要將數(shù)據(jù)進(jìn)行加密,加密一般分為兩種方式:
對稱加密 非對稱加密
對稱加密指的是對原數(shù)據(jù)(稱為明文)進(jìn)行加密時所使用的密鑰與對密文進(jìn)行解密所使用的密鑰是相同的,如下所示:

這種方式有著很大的安全隱患,當(dāng)發(fā)送方或接收方的某一方密鑰泄露后,不法分子便可以拿著這個密鑰與發(fā)送方和接收方進(jìn)行無障礙的數(shù)據(jù)傳輸,因為它既可以通過該密鑰加密數(shù)據(jù)傳給接收方,也可以接收到發(fā)送方發(fā)送的數(shù)據(jù)進(jìn)行解密。
第二種加密方式便是非對稱加密,與對稱加密不同的是,非對稱加密在加密數(shù)據(jù)與解密數(shù)據(jù)的過程中使用的密鑰并不相同,如下:

當(dāng)發(fā)送方使用密鑰A對明文進(jìn)行加密并傳輸給接收方后,接收方需要使用密鑰B進(jìn)行解密,當(dāng)接收方想要發(fā)送數(shù)據(jù)給發(fā)送方時,就是用密鑰D進(jìn)行加密,發(fā)送方再使用密鑰C進(jìn)行解密。這樣做的好處是即使某個密鑰泄露了也不會發(fā)生安全問題,比如密鑰B被不法分析竊取了,那么它將可以對發(fā)送方發(fā)送過來的數(shù)據(jù)進(jìn)行解密,但僅限于解密,它將無法發(fā)送消息給發(fā)送方,因為發(fā)送消息使用的是密鑰D,只有四個密鑰都掌握了,才能夠在發(fā)送方和接收方之間無障礙地通信。
支付寶使用的便是非對稱加密方式:

第三方應(yīng)用在給支付寶發(fā)送數(shù)據(jù)前會使用私鑰A進(jìn)行加密,這個私鑰A是不會對外暴露的,但是第三方應(yīng)用會提供一個公鑰A給支付寶,此時支付寶便可以使用這個公鑰對數(shù)據(jù)進(jìn)行解密;同理,支付寶在發(fā)送數(shù)據(jù)給應(yīng)用時也會使用私鑰B對數(shù)據(jù)進(jìn)行加密,并提供一個公鑰B給應(yīng)用讓其能夠進(jìn)行解密;但是支付寶的私鑰是沒有人能夠竊取到的,所以保證了支付的安全。
為了支付流程的絕對安全,支付寶有一個簽名環(huán)節(jié),當(dāng)數(shù)據(jù)準(zhǔn)備傳輸時會使用私鑰對其進(jìn)行簽名:

當(dāng)前數(shù)據(jù)和簽名是對應(yīng)的,假如有人攔截了這串?dāng)?shù)據(jù)并將金額進(jìn)行了修改,那么支付寶收到數(shù)據(jù)之后,便會對數(shù)據(jù)進(jìn)行驗簽,驗簽過程就能夠發(fā)現(xiàn)數(shù)據(jù)被篡改了,因為簽名和數(shù)據(jù)已經(jīng)不對應(yīng)了,而不法分子是無法成功得到自己修改后的數(shù)據(jù)對應(yīng)的簽名的。
接下來就對這四把鑰匙進(jìn)行配置,仍然來到沙箱后臺:
點(diǎn)擊RSA2密鑰后面的 設(shè)置/查看 :

選擇公鑰,并點(diǎn)擊支付寶密鑰生成器:

此處便可下載支付寶的密鑰生成器,下載完成后安裝一下,然后打開:

選擇RSA2和PKCS8,并點(diǎn)擊生成密鑰,應(yīng)用的私鑰需要妥善保管,然后將下方的應(yīng)用公鑰告知支付寶:

將其粘貼到此處,點(diǎn)擊保存設(shè)置:

此時支付寶便會將它的公鑰告訴你,將這些內(nèi)容都配置到AlipayConfig中:
public class AlipayConfig {
//↓↓↓↓↓↓↓↓↓↓請在這里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 應(yīng)用ID,您的APPID,收款賬號既是您的APPID對應(yīng)支付寶賬號
public static String app_id = "2021000116684033";
// 商戶私鑰,您的PKCS8格式RSA2私鑰
public static String merchant_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDA+HnzPriAFTLYuk/uHR1wPooA4FdkahthRa/rq/ZmzOgZ+Gn3HmET1qYy7DyOWeGIKCiad7Lpb/a6idRHtEADha2/NTQMgUC+cnPfFnliC97LPwl6imik84GO5XZ0yxNvqzHIurIXBEJegfSSm1mKuDU6DavGSQlRUKDSiLcL/EOKJyWfrcEeZWLy5TbZccdiurb7Gm5wWeaYUSm0qSpZaxrhhkB24UzFEc9DZZvhmtFyZ+WzeImofX9254pNIKXgeDpVO0e2KKXdcdPVpL0pzg/3RjPaZhPcgrOwVLum8Nj8haA0HjkJqbI5JzWU6XiKi889ihYeI/imETXz+wgDAgMBAAECggEAMKy8fhndChnOyJI+ZS6c5VoxD0WHZcHKBEBCvqySq52WEi7x866LCCkFpSSnpbSQSfrvOv9kdrOSRb1MeYXC++B1UhzGcz0LKr7N8YDGv2+FFDljV7Cf8rOlg3jn50/uKCXDmgFVuK6PWy1mlrBu5qnOa0VVhd+YZRV0a4amvXPFDfKisSxMI1+oIgqC9LmyMz5gDhahlFKmpI9EHN0zno/eycw6xo/aCXagAmPU4UMOck1o9S1PhRQvyRlWSll9xuGWiimUi/a1j61hNTkD6XLLnH6cewBeGHKr9mOKBT9PywEj1qeX50AHHaVbX1HlUnOLlRuldYMO+r/B7GKmkQKBgQDoExEuna52PsNbp0SmTid+lqOoVAr5oi5xYABiXa0VruOvR7ZEikWzk1uq4deTwzzWpqy6S1ZHw/j8wxQ1SweZy187W6cFFAbJ4hsZFLE7m95NMGTGmgP0M+WbmDElAQmrQV6cYOXl09rU2d0M1QAqMNItQlLtBwLaT4zk4PZO2wKBgQDU3WBBzvSSQP83OrzHv4um9BDvhLeX8aUOEGjNeGIcYcCe0YABVQVEF+q9rWR6e1C+XRnY50kh0KNYa8xHpglfk9RyvK+k5kBfywnnq2ArbeaDxm2TcjRMhkzWyeVMFgRWmAfzzNk7ZSJv8+rjgEJvETDENftEY8r2Q1VuE9SP+QKBgF583OMI6i5UkX+wk7/OVEAzHwD67tkCkjww5RcnosAQS71iyjAPyB88IPdrKjWMKSoQBIV5BPEFNkvbNVAZc0fHyMdHIrJrm/P4biYBCcQGSzVMPcuqi2+S7aozBddWG9SxMc8jmJbBcfh1l42Q75c992Tb+x1sXFn8R5Ysjbw/AoGAM/zVM31eEhI5wr1fudE4RFA7iqP5SuzDiQnM7tHF9HSTXLaB8tFW9eh5dlXQwnE3qSaH14e1PsL8Ae5h9+W/SE6MhnE63KU3d63Y/3HFjRXMRMbDoE02JLJwNc0daVW/PX7oAk03iOAMZxdFeMascv/ZzzH36h4NRdPwG3BQa9ECgYEAxDcRdAHmpGFGenqqT8Z5eugHrSWz1bCSA9KrWZ7ymIsPfqk96/UpQDD/grB06uIrPahenFqOlWo9KEWl7+nHtPq6RzHHWgDcXKnjpeT4KxqmmTmJt3Vshb4z4znsHV1/wLuPtDC3hV8mDDoXVlpZ6ohgf3niFExQL4oQwT4Vtmo=";
// 支付寶公鑰,查看地址:https://openhome.alipay.com/platform/keyManage.htm 對應(yīng)APPID下的支付寶公鑰。
public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlt4bnL/TPec6FVf0+4v5SE+qYADh5iKPyLYhMXsKPyfETGkxK36fzOyp/lACX7AGLejGGjte7lE964GvfLXyuG0ecd6WWuLOepWZKlgi1XMiMzuZj/Gsb5aqvKPvi2/nWTlTUCceQ2sIpFtbnxQ29Aiq9b36qCIwHSCHH96SJRqT8DmiBTsGgAOEnJzy1knG/mPecD5jwIYP4NtLa0G6Px3EVz7ZFhZmR5LjxaqUpT/hIOG4Umjlkixf6g4Ga7rXXw8kzZBcSYTKq9LeBWqGGP1gt1dYv9m3ADAvd+wJn8U9T6veuawtExMSwyJkI/LzuzxqyaR8qB863C/3Mh+bEwIDAQAB";
// 支付寶網(wǎng)關(guān)
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
//↑↑↑↑↑↑↑↑↑↑請在這里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
}
現(xiàn)在就可以啟動這個DEMO項目了,啟動完成后便可以對支付進(jìn)行測試:

點(diǎn)擊付款會要求登錄:
登錄信息仍然在沙箱后臺中:

最后輸入支付密碼即可支付成功:

內(nèi)網(wǎng)穿透
在AlipayConfig配置類中有這么兩項配置:
// 服務(wù)器異步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
public static String notify_url = "http://工程公網(wǎng)訪問地址/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";
// 頁面跳轉(zhuǎn)同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
public static String return_url = "http://工程公網(wǎng)訪問地址/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";
它們分別表示支付完成后需要支付寶跳轉(zhuǎn)的頁面和接收支付寶響應(yīng)數(shù)據(jù)的接口,由于我們處于內(nèi)網(wǎng),支付寶是無法找到我們的電腦的,當(dāng)然也就訪問不到我們的應(yīng)用,而且注釋里也說了這兩項配置必須外網(wǎng)可以正常訪問,所以我們需要使用到內(nèi)網(wǎng)穿透。
支持內(nèi)網(wǎng)穿透的工具有很多,這里以續(xù)斷為例 https://www.zhexi.tech/,新用戶會贈送一條隧道,登錄到后臺系統(tǒng),點(diǎn)擊安裝客戶端:

安裝完成后再點(diǎn)擊建立隧道,輸入相關(guān)信息:
此時我們就能夠得到一個域名:

通過它就能夠訪問到我們的電腦了,所以修改AlipayConfig中的配置:
// 服務(wù)器異步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
public static String notify_url = "http://00ocvc6g0e.52http.tech/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";
// 頁面跳轉(zhuǎn)同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
public static String return_url = "http://00ocvc6g0e.52http.tech/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";
SpringBoot整合支付寶
創(chuàng)建一個SpringBoot應(yīng)用,并引入依賴:
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.16.2.ALL</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
編寫一個工具類用于生成頁面模板:
@ConfigurationProperties(prefix = "alipay")
@Component
@Data
public class AlipayTemplate {
// 應(yīng)用ID,您的APPID,收款賬號既是您的APPID對應(yīng)支付寶賬號
public static String app_id = "2021000116684033";
// 商戶私鑰,您的PKCS8格式RSA2私鑰
public static String merchant_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDA+HnzPriAFTLYuk/uHR1wPooA4FdkahthRa/rq/ZmzOgZ+Gn3HmET1qYy7DyOWeGIKCiad7Lpb/a6idRHtEADha2/NTQMgUC+cnPfFnliC97LPwl6imik84GO5XZ0yxNvqzHIurIXBEJegfSSm1mKuDU6DavGSQlRUKDSiLcL/EOKJyWfrcEeZWLy5TbZccdiurb7Gm5wWeaYUSm0qSpZaxrhhkB24UzFEc9DZZvhmtFyZ+WzeImofX9254pNIKXgeDpVO0e2KKXdcdPVpL0pzg/3RjPaZhPcgrOwVLum8Nj8haA0HjkJqbI5JzWU6XiKi889ihYeI/imETXz+wgDAgMBAAECggEAMKy8fhndChnOyJI+ZS6c5VoxD0WHZcHKBEBCvqySq52WEi7x866LCCkFpSSnpbSQSfrvOv9kdrOSRb1MeYXC++B1UhzGcz0LKr7N8YDGv2+FFDljV7Cf8rOlg3jn50/uKCXDmgFVuK6PWy1mlrBu5qnOa0VVhd+YZRV0a4amvXPFDfKisSxMI1+oIgqC9LmyMz5gDhahlFKmpI9EHN0zno/eycw6xo/aCXagAmPU4UMOck1o9S1PhRQvyRlWSll9xuGWiimUi/a1j61hNTkD6XLLnH6cewBeGHKr9mOKBT9PywEj1qeX50AHHaVbX1HlUnOLlRuldYMO+r/B7GKmkQKBgQDoExEuna52PsNbp0SmTid+lqOoVAr5oi5xYABiXa0VruOvR7ZEikWzk1uq4deTwzzWpqy6S1ZHw/j8wxQ1SweZy187W6cFFAbJ4hsZFLE7m95NMGTGmgP0M+WbmDElAQmrQV6cYOXl09rU2d0M1QAqMNItQlLtBwLaT4zk4PZO2wKBgQDU3WBBzvSSQP83OrzHv4um9BDvhLeX8aUOEGjNeGIcYcCe0YABVQVEF+q9rWR6e1C+XRnY50kh0KNYa8xHpglfk9RyvK+k5kBfywnnq2ArbeaDxm2TcjRMhkzWyeVMFgRWmAfzzNk7ZSJv8+rjgEJvETDENftEY8r2Q1VuE9SP+QKBgF583OMI6i5UkX+wk7/OVEAzHwD67tkCkjww5RcnosAQS71iyjAPyB88IPdrKjWMKSoQBIV5BPEFNkvbNVAZc0fHyMdHIrJrm/P4biYBCcQGSzVMPcuqi2+S7aozBddWG9SxMc8jmJbBcfh1l42Q75c992Tb+x1sXFn8R5Ysjbw/AoGAM/zVM31eEhI5wr1fudE4RFA7iqP5SuzDiQnM7tHF9HSTXLaB8tFW9eh5dlXQwnE3qSaH14e1PsL8Ae5h9+W/SE6MhnE63KU3d63Y/3HFjRXMRMbDoE02JLJwNc0daVW/PX7oAk03iOAMZxdFeMascv/ZzzH36h4NRdPwG3BQa9ECgYEAxDcRdAHmpGFGenqqT8Z5eugHrSWz1bCSA9KrWZ7ymIsPfqk96/UpQDD/grB06uIrPahenFqOlWo9KEWl7+nHtPq6RzHHWgDcXKnjpeT4KxqmmTmJt3Vshb4z4znsHV1/wLuPtDC3hV8mDDoXVlpZ6ohgf3niFExQL4oQwT4Vtmo=";
// 支付寶公鑰,查看地址:https://openhome.alipay.com/platform/keyManage.htm 對應(yīng)APPID下的支付寶公鑰。
public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlt4bnL/TPec6FVf0+4v5SE+qYADh5iKPyLYhMXsKPyfETGkxK36fzOyp/lACX7AGLejGGjte7lE964GvfLXyuG0ecd6WWuLOepWZKlgi1XMiMzuZj/Gsb5aqvKPvi2/nWTlTUCceQ2sIpFtbnxQ29Aiq9b36qCIwHSCHH96SJRqT8DmiBTsGgAOEnJzy1knG/mPecD5jwIYP4NtLa0G6Px3EVz7ZFhZmR5LjxaqUpT/hIOG4Umjlkixf6g4Ga7rXXw8kzZBcSYTKq9LeBWqGGP1gt1dYv9m3ADAvd+wJn8U9T6veuawtExMSwyJkI/LzuzxqyaR8qB863C/3Mh+bEwIDAQAB";
// 服務(wù)器[異步通知]頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
// 服務(wù)器異步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
public static String notify_url = "http://00ocvc6g0e.52http.tech/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";
// 頁面跳轉(zhuǎn)同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
public static String return_url = "http://00ocvc6g0e.52http.tech/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";
// 簽名方式
private String sign_type = "RSA2";
// 字符編碼格式
private String charset = "utf-8";
// 支付寶網(wǎng)關(guān);https://openapi.alipaydev.com/gateway.do
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
public String pay(PayVo vo) throws AlipayApiException {
//AlipayClient alipayClient = new DefaultAlipayClient(AlipayTemplate.gatewayUrl, AlipayTemplate.app_id, AlipayTemplate.merchant_private_key, "json", AlipayTemplate.charset, AlipayTemplate.alipay_public_key, AlipayTemplate.sign_type);
//1、根據(jù)支付寶的配置生成一個支付客戶端
AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl,
app_id, merchant_private_key, "json",
charset, alipay_public_key, sign_type);
//2、創(chuàng)建一個支付請求 //設(shè)置請求參數(shù)
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(return_url);
alipayRequest.setNotifyUrl(notify_url);
//商戶訂單號,商戶網(wǎng)站訂單系統(tǒng)中唯一訂單號,必填
String out_trade_no = vo.getOut_trade_no();
//付款金額,必填
String total_amount = vo.getTotal_amount();
//訂單名稱,必填
String subject = vo.getSubject();
//商品描述,可空
String body = vo.getBody();
alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
+ "\"total_amount\":\"" + total_amount + "\","
+ "\"subject\":\"" + subject + "\","
+ "\"body\":\"" + body + "\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
String result = alipayClient.pageExecute(alipayRequest).getBody();
//會收到支付寶的響應(yīng),響應(yīng)的是一個頁面,只要瀏覽器顯示這個頁面,就會自動來到支付寶的收銀臺頁面
System.out.println("支付寶的響應(yīng):" + result);
return result;
}
}
@Data
public class PayVo {
private String out_trade_no; // 商戶訂單號 必填
private String subject; // 訂單名稱 必填
private String total_amount; // 付款金額 必填
private String body; // 商品描述 可空
}
配置信息記得修改為自己的配置。現(xiàn)在有一個頁面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/pay?orderSn=12345">去支付</a>
</body>
</html>
內(nèi)容非常簡單,有一個超鏈接,點(diǎn)擊它便可以進(jìn)行訂單支付,并且會攜帶當(dāng)前訂單的訂單號,來模擬一個真實的訂單支付業(yè)務(wù)。編寫一個Controller:
@Controller
public class PayController {
@Autowired
private AlipayTemplate alipayTemplate;
@GetMapping({"/","/index"})
public String toIndex(){
return "index";
}
@GetMapping(value = "/pay",produces = "text/html")
@ResponseBody
public String pay(@RequestParam String orderSn) throws AlipayApiException {
// 通過orderSn查詢訂單的詳細(xì)信息
PayVo payVo = new PayVo();
payVo.setBody("暫無"); // 訂單備注
payVo.setOut_trade_no(orderSn); // 訂單號
payVo.setSubject("測試標(biāo)題"); // 訂單標(biāo)題
payVo.setTotal_amount("1000"); // 訂單金額
// 返回的是一個支付頁面,直接返回即可
return alipayTemplate.pay(payVo);
}
}
按照真實的業(yè)務(wù)場景,頁面會傳遞給我們一個訂單號,然后拿著這個訂單號去數(shù)據(jù)庫查詢指定訂單的詳細(xì)信息,并將這些信息設(shè)置到PayVo中,這里就簡單模擬一下。當(dāng)調(diào)用alipayTemplate的pay方法時,該方法會渲染一個form表單,并通過script腳本自動提交,所以我們只需將該方法的返回值直接作為頁面內(nèi)容返回出去即可。
啟動項目,點(diǎn)擊去支付即可跳轉(zhuǎn)至支付寶的支付頁面:
這些內(nèi)容也確實是我們自己設(shè)置的,當(dāng)輸入支付密碼成功支付后,我們應(yīng)該讓其自動跳轉(zhuǎn)至支付成功后的頁面,修改AlipayTemplate類中的同步跳轉(zhuǎn)地址:
// 頁面跳轉(zhuǎn)同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
public static String return_url = "http://localhost:9090/index";
這里也簡單模擬一下,讓其支付成功后跳轉(zhuǎn)回首頁即可。
若是想知道支付后的具體信息,也可以通過配置異步通知url來實現(xiàn):
// 服務(wù)器異步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
public static String notify_url = "http://00ocvc6g0e.52http.tech/notify";
需要注意異步通知的url一定要讓外網(wǎng)能夠訪問,否則支付寶是無法發(fā)送請求給我們的。接下來就需要處理這個請求:
@PostMapping("/notify")
public String notifyPay(HttpServletRequest request) {
Map<String, String[]> map = request.getParameterMap();
for (String key : map.keySet()) {
System.out.println(key + "===>" + request.getParameter(key));
}
return "success";
}
這個方法的返回值一定要是success,因為支付寶只有接收到success才會認(rèn)為應(yīng)用已經(jīng)接收到了支付成功的通知,否則支付寶會不停地向應(yīng)用發(fā)送通知,以下便是支付寶提供給我們的所有參數(shù):
gmt_create===>2021-08-13 17:40:35
charset===>utf-8
gmt_payment===>2021-08-13 17:40:45
notify_time===>2021-08-13 17:40:47
subject===>測試標(biāo)題
sign===>I2FtU9GmmHWQRExJ9q+wYLhOe/50HqFMcQLHLVBQalIGrK3FlEcflCnDO1coFd+Feqp0Pr+xh5EDsyi9aU4fT3huKQhENceLWVNiEiyoV5oykT/73W3FKMbwd8fS4YB1zTiw/tzY0KMNFFJU5p1hgWGioksFmpM11FUGgb6DeDv2L+JJ3tglBmRmVNTd2RCKM6xKKyWkuDenHDfeVLbjjNwEUtAyx6rKCLmEal7R1uFx7pg4gC/gekCWSLOu7Jsv2N/06uvv88F1PlUSJA8vrXyyrKAhA0MATOq4Rx/Yqvvlr3uJMQ/pj7IrG8OgPdoaqnBC2qaBMs3mVtXgwNP0lQ==
buyer_id===>2088622955266335
body===>暫無
invoice_amount===>1000.00
version===>1.0
notify_id===>2021081300222174046066330512882319
fund_bill_list===>[{"amount":"1000.00","fundChannel":"ALIPAYACCOUNT"}]
notify_type===>trade_status_sync
out_trade_no===>123456789
total_amount===>1000.00
trade_status===>TRADE_SUCCESS
trade_no===>2021081322001466330501314710
auth_app_id===>2021000116684033
receipt_amount===>1000.00
point_amount===>0.00
app_id===>2021000116684033
buyer_pay_amount===>1000.00
sign_type===>RSA2
seller_id===>2088621955014522
通過這些屬性即可對后續(xù)的業(yè)務(wù)進(jìn)行相關(guān)的操作,關(guān)于這些屬性的詳情可以參照支付寶的官方文檔:https://opendocs.alipay.com/open/270/105902
為了防止出現(xiàn)用戶一直沒有付款,導(dǎo)致訂單超時關(guān)閉之后,用戶再去付款的問題,可以為支付功能設(shè)置一個超時時間,只需修改AlipayTemplate類中setBizConent的內(nèi)容即可:
alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
+ "\"total_amount\":\"" + total_amount + "\","
+ "\"subject\":\"" + subject + "\","
+ "\"body\":\"" + body + "\","
+ "\"timeout_express\":\"1m\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
添加 "\"timeout_express\":\"1m\" ,此時如果打開付款頁面后超過1分鐘,將無法繼續(xù)付款。
以上為個人經(jīng)驗,希望能給大家一個參考。如有錯誤或未考慮完全的地方,望不吝賜教。
往 期 推 薦
1、靈魂一問:你的登錄接口真的安全嗎? 2、HashMap 中這些設(shè)計,絕了~ 3、在 IntelliJ IDEA 中這樣使用 Git,賊方便了! 4、計算機(jī)時間到底是怎么來的?程序員必看的時間知識! 5、這些IDEA的優(yōu)化設(shè)置趕緊安排起來,效率提升杠杠的! 6、21 款 yyds 的 IDEA插件 7、真香!用 IDEA 神器看源碼,效率真高! 點(diǎn)分享
點(diǎn)收藏
點(diǎn)點(diǎn)贊
點(diǎn)在看





