Spring Boot整合支付寶電腦網站支付功能

語言: CN / TW / HK
ead>

highlight: an-old-hope theme: channing-cyan


我報名參加金石計劃1期挑戰——瓜分10萬獎池,這是我的第6篇文章,點選檢視活動詳情

接入準備

登入

訪問支付寶開放平臺:http://open.alipay.com/ 登入後補充開發者資訊,然後在開發接入項,點選網頁/移動應用開發項跳轉建立應用。 在這裡插入圖片描述

建立應用

填寫應用基礎資訊 在這裡插入圖片描述

新增能力

建立應用後,配置應用的能力,在新增能力項加入需要的能力,如電腦網站支付能力 在這裡插入圖片描述

生成私鑰與公鑰

訪問http://opendocs.alipay.com/common/02khjo下載密匙生成工具,然後生成公鑰與私鑰 在這裡插入圖片描述

開發設定

在這裡插入圖片描述 設定自己生成的公鑰 在這裡插入圖片描述 將自己生成的公鑰告訴支付寶,支付寶返回一個支付寶公鑰 在這裡插入圖片描述 最終得到3個密匙:1.應用公鑰 2.應用私鑰 3.支付寶公鑰

沙箱環境

沙箱地址:http://open.alipay.com/develop/sandbox/app

參考上述生成私鑰與公鑰開發設定,在介面加簽方式處進行設定。最終得到3個密匙:1.應用公鑰 2.應用私鑰 3.支付寶公鑰 在這裡插入圖片描述 沙箱賬號用於支付測試 在這裡插入圖片描述

示例Demo的使用與學習

下載Demo

在文件中心:http://openhome.alipay.com/docCenter/docCenter.htm找到需要接入應用型別的對應文件 在這裡插入圖片描述 或者直接搜尋,如電腦網站支付 在這裡插入圖片描述 找到需要文件後,檢視文件中的SDK&Demo項,下載對應語言Demo,用於學習 在這裡插入圖片描述

啟動專案

在這裡插入圖片描述

引數配置

在Demo專案中的AlipayConfig類中配置:應用ID,商戶私鑰(應用私鑰)、支付寶公鑰、非同步通知、同步通知地址等引數。

注意:如果這裡使用沙箱環境測試,一定要修改支付寶閘道器,否則除錯錯誤 在這裡插入圖片描述

沙箱環境閘道器為: http://openapi.alipaydev.com/gateway.do

正式環境閘道器為:http://openapi.alipay.com/gateway.do

```java / * 類名:AlipayConfig 功能:基礎配置類 詳細:設定帳戶有關資訊及返回路徑 修改日期:2017-04-05 說明: 以下程式碼只是為了方便商戶測試而提供的樣例程式碼,商戶可以根據自己網站的需要,按照技術文件編寫,並非一定要使用該程式碼。 該程式碼僅供學習和研究支付寶介面使用,只是提供一個參考。 */

public class AlipayConfig {

//↓↓↓↓↓↓↓↓↓↓請在這裡配置您的基本資訊↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

// 應用ID,您的APPID,收款賬號既是您的APPID對應支付寶賬號
public static String app_id = "20166660581647";

// 商戶私鑰,您的PKCS8格式RSA2私鑰
public static String merchant_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCKNOWSnUMsaeEZZMDy+DvbdUMVTuJ/jQ4Ks8lQEatRjXS7ZWX+NMszQir3HyRWe1q8+8n6ZvJSiMGpS2Ku7ZeTHyZvOB9BTG3vgapDKKJAQ0NYaB3561FaU3ZRnCay5ls50WVCZ82pO//NZ5xRYND53+ZjSvOZi58FV1uKnCEAx8tPZKeGi5c2hQ6epjjzcjsdD/1fZEF5B667AM8nLe3zZWftvBxJe8Z1yoRP/w4aWW451myFViQWaKiWsERz7KAHCJEu+wAyvgqB18MOoNk76svqr71Z0whjrTF/1eEHaoictzMdao8hWYNhveaPA4Ic46rWoBTyHOHdt9p+hF1NAgMBAAECggEAQP39E4RWyeXbYlyw+nq+Y/ch0WP4Q5lFY0iIGSfW2D+P9xp4QHGQNr4mUsxho9BMjU0KyZ41/j5LfpqO0s+abeQgAvwP3WXm9EkgcDP1UulCG74YQmXa7e+ORT3+3Vmt6lC/rY3SurFLl2HNkH1dBHhO2+XpYV/WGDDRFJ/WxI3gFdWF31sqT9n75HsozFtA5vp90ZOq3SxqtQKBgQDZDqfj6Aw5jCI+rPapmp4NISDLUHtcIKKfRx/2yjmCPZ/WCnIW4R7jxyf3rvd4beNMqVHfAhdwISfug5C3n2nZJV4aMY/o52DEH38d2dYqkJX78V+Jaw0vy8DvuxGtVCB/5r3tK4zbza9g2uFPUb9/8QBo3h8KKbjs6haOxBLFqwKBgQCjAKqhTsrZwI0AR1NQ76U558CkR5NbR15pROgzXvzLwnr5L2pOhrf+IEsGOZklXgv727jc907Gp/VlBQrsFU5rPKMc091HdLV7fmsVY/CIb9P+oSGj7nZ5X6O2n3wY2nJzlnWT4+wZSLQDiThuUA+awDe1TZZ4jVX4Y9kDOLwA5wKBgHWhsLEdp8pkPIbU+9SMu80HwBsPYdtawGcrh5IapDIGLaI1BQGLPU9aNjnP88OrYfzA4mLGYmddQKPNX1d0KEwLKUVuyLwC8Pk4zI4j6SImO3JPrGPvxTS66rPBIOJbbkWCijmHWY4hmUMXO/Xdqreup3ctsYqzc8nJTzJN5pKDAoGAQxOuI81BypPjMj8nuQG1E3wcGT5fFEvtPRKfHyyyiMMSSeLKM2Ba7NerJ/eh3u+xrMYBb+TRZQyO/jAyC27FI3oDgYRp5dLQL+6Y8Gd8/xhNu9Xg+w3RcSb7Ptaoga27NXewENjVOp5hfacFMtf9Y+g/xHsWNauruhiUoC/DpfcCgYEA2KjZndyY4iKQg2ia3PrRREZukoTAiYVE36i66YVYhwnrqjP3VRwrrK8kpG/HMhcPYFEuO1d7pKLShoxn10UdDlAX1R7mkFSGS/t8KNp7LqNHaDxL0lWeUq7/WEHn7vxvlHtB3dIB+cuq5iC/VuTvnQhXPOGU/6hgJu1ImuDz5uQ=";

// 支付寶公鑰,檢視地址:http://openhome.alipay.com/platform/keyManage.htm 對應APPID下的支付寶公鑰。
public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1j83H1RmHZeuLbYyxhWAn80GTK/963/SnGHfZAujXsB4/EWn+BqHK6zOmBwXAZAsvjrG+oFakMagANwBVEpwIHF7o9DdX6skYlyO2HRfc/XZMKBg1snAXA/OBjUjTcKTeFJx75zezxgTwrHl3MSrXEr4WnGPAxu+jC9cFrsFdTTGz1gp4K25OBbsSNFdEnqaVbWmJT/U0wAAE8eOcHSk5TYgQfmvqFLuSpjOwDWF0m6/Ymr7EKagsBvtb/Y+IUyQKWi62nqJrDbuduaRiC43hUp6nU3E2VNDuxdexkuQF/cjz5l3/GEeRtFgb00RmkmjtnC+FwIDAQAB";

// 伺服器非同步通知頁面路徑  需http://格式的完整路徑,不能加?id=123這類自定義引數,必須外網可以正常訪問
public static String notify_url = "http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";

// 頁面跳轉同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義引數,必須外網可以正常訪問
public static String return_url = "http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";

// 簽名方式
public static String sign_type = "RSA2";

// 字元編碼格式
public static String charset = "utf-8";

// 支付寶閘道器

// public static String gatewayUrl = "http://openapi.alipay.com/gateway.do"; public static String gatewayUrl = "http://openapi.alipaydev.com/gateway.do";

// 支付寶閘道器
public static String log_path = "C:\\";

//↑↑↑↑↑↑↑↑↑↑請在這裡配置您的基本資訊↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

/**
 * 寫日誌,方便測試(看網站需求,也可以改成把記錄存入資料庫)
 * @param sWord 要寫入日誌裡的文字內容
 */
public static void logResult(String sWord) {
    FileWriter writer = null;
    try {
        writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
        writer.write(sWord);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (writer != null) {
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

} ```

執行測試

發起一個付款操作 在這裡插入圖片描述 跳到轉支付頁面,輸入沙箱環境中的測試賬號進行登入 在這裡插入圖片描述

選擇支付方式,輸入支付密碼 在這裡插入圖片描述 支付成功,最終會跳轉到配置的回撥地址 在這裡插入圖片描述 至此,支付寶Demo的支付功能就測試通過,具體實現就可以參考原始碼進行學習。

Spring Boot整合支付寶支付功能

獲取SDK

在開發工具包(SDK)下載頁面:http://opendocs.alipay.com/open/02nk0x找到依賴座標 在這裡插入圖片描述 java <dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>4.33.39.ALL</version> </dependency>

新增依賴

```xml org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat

    <!-- 新增 Undertow 容器 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>com.alipay.sdk</groupId>
        <artifactId>alipay-sdk-java</artifactId>
        <version>4.9.28.ALL</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

```

配置application.properties

在application.properties檔案中配置支付相關配置

```java

--------------------支付寶相關的配置--------------------

應用ID

alipay.app_id=201607712345681647

商戶私鑰

alipay.merchant_private_key=MIIEvQIqqANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCKNOWSnUMsaeEZZMDy+DvbdUMVTuJ/jQ4Ks8lQEatRjXS7ZWX+NMszQir3HyRWe1q8+8n6ZvJSiMGpS2Ku7ZeTHyZvOB9BTG3vgapDKKJAQ0NYaB3561FaU3ZRnCay5ls50WVCZ82pO//NZ5xRYND53+ZjSvOZi58FV1uKnCEAx8tPZKeGi5c2hQ6epjjzcjsdD/1fZEF5B667AM8nLe3zZWftvBxJe8Z1yoRP/w4aWW451myFViQWaKiWsERz7KAHCJEu+wAyvgqB18MOoNk76svqr71Z0whjrTF/1eEHaoictzMdao8hWYNhveaPA4Ic46rWoBTyHOHdt9p+hF1NAgMB1231232139E4RWyXUFAO8LeXbYlyw+nq+Y/ch0WP4Q5lFY0iIGSfW2D+P9xp4QHGQNr4mUsxho9BMjU0KyZ41m28IpLGtSpKysrgVmEWJVkf1yx2uaKOHVbuiFOkfTdS9MV4bSUY8x4hd0dGgdtBdMQEyaGVd8PSdLBOLOpjFdgAJJ1tZrAENG1VqbSgRdAs0cIFSPPUpjK+EC61zIG4Cb/j5LfpqO0s+abeQgAvwP3WXm9EkgcDP1UulCG74YQmXa7e+ORT3+3Vmt6lC/rY3SurFLl2HNkH1dBHhO2+XpYV/WGDDRFJ/WxI3gFdWF31sqT9n75HsozFtA5vp90ZOq3SxqtQKBgQDZDqfj6Aw5jCI+rPapmp4NISDLUHeeeKfRx/2yjmCPZ/WCnIW4R7jxyf3rvd4beNMqVHfAhdwISfug5C3n2nZJV4aMY/o52DEH38d2dYqkJX78V+Jaw0vy8DvuxGtVCB/5r3tK4zbza9g2uFPUb9/8QBo3h8KKbjs6haOxBLFqwKBgQCjAKqhTsrZwI0AR1NQ76U558CkR5NbR15pROgzXvzLwnr5L2pOhrf+IEsGOZklXgv727jc907Gp/VlBQrsFU5rPKMc091HdLV7fmsVY/CIb9P+oSGj7nZ5X6O2n3wY2nJzlnWT4+wZSLQDiThuUA+awDe1TZZ4jVX4Y9kDOLwA5wKBgHWhsLEdp8pkPIbU+9SMu80HwBsPYdtawGcrh5IapDIGLaI1BQGLPU9aNjnP88OrYfzA4mLGYmddQKPNX1d0KEwLKUVuyLwC8Pk4zI4j6SImO3JPrGPvxTS66rPBIOJbbkWCijmHWY4hmUMXO/Xdqreup3ctsYqzc8nJTzJN5pKDAoGAQxOuI81BypPjMj8nuQG1E3wcGT5fFEvtPRKfHyyyiMMSSeLKM2Ba7NerJ/eh3u+xrMYBb+TRZQyO/jAyC27FI3oDgYRp5dLQL+6Y8Gd8/xhNu9Xg+w3RcSb7Ptaoga27NXewENjVOp5hfacFMtf9Y+g/xHsWNauruhiUoC/DpfcCgYEA2KjZndyY4iKQg2ia3PrRREZukoTAiYVE36i66YVYhwnrqjP3VRwrrK8kpG/HMhcPYFEuO1d7pKLShoxn10UdDlAX1R7mkFSGS/t8KNp7LqNHaDxL0lWeUq7/WEHn7vxvlHtB3dIB+cuq5iC/VuTvnQhXPOGU/6hgJu1ImuDz5uQ=

支付寶公鑰

alipay.alipay_public_key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1j83H1RmHZeuLbYyxhWAn80GTK/963/SnGHfZAujXsB4/EWn+BqHK6zOmBwXAZAsv1231231234fFVEpwIHF7o9DdX6skYlSYv1eeq2HRfc/XZMKBg1snAXA/OBjUjTcKTeFJx75zezxgTwrHl3MSrXEr4WnGPAxu+jC9cFreeep4K25OBbsSNFdEnqaVbWmJT/U0wAAE8eOcHSk5TYgQfmvqFLuSpjOwDWF0m6/YmqagsBvtb/Y+IUyQKWi62nqJrDbuduaRiC43hUp6nU3E2VNDuxdexkuQF/cjz5l3/GEeRtFgb00RmkmjtnC+FwIDAQAB

伺服器非同步通知頁面路徑

alipay.notify_url=http://jackchen.imwork.net:27687/pay/asyncNotify

頁面跳轉同步通知頁面路徑

alipay.return_url=http://jackchen.imwork.net:27687/pay/syncNotify

簽名方式

alipay.sign_type=RSA2

字元編碼格式

alipay.charset=utf-8

支付寶閘道器

alipay.gatewayUrl=http://openapi.alipaydev.com/gateway.do

支付寶沙箱閘道器

alipay.gatewayUrl=http://openapi.alipaydev.com/gateway.do

非同步通知 對時間欄位格式化,否則非同步通知失敗

spring.mvc.date-format=yyyy-MM-dd HH:mm:ss ```

建立AlipayUtil

支付資訊VO java @Data public class PayVo { /** * 商戶訂單號,必填 */ private String out_trade_no; /** * 訂單名稱,必填 */ private String subject; /** * 付款金額,必填 */ private String total_amount; /** * 商品描述,可為空 */ private String body; } AlipayUtil 工具類 ```java @ConfigurationProperties(prefix = "alipay") @Component @Data public class AlipayUtil { / * 應用ID */ public String app_id; / * 商戶私鑰 / public String merchant_private_key; / * 支付寶公鑰 / public String alipay_public_key; / * 伺服器[非同步通知]頁面路徑 必須外網可以正常訪問 支付寶會告訴支付成功的資訊 */ public String notify_url; / * 頁面跳轉[同步通知]頁面路徑 必須外網可以正常訪問 支付成功跳轉到成功頁 / public String return_url; / * 簽名方式 / private String sign_type; / * 字元編碼格式 */ private String charset; / * 訂單超時時間 / private String timeout = "1m"; / * 支付閘道器 / public String gatewayUrl;

/**
 * 發起支付請求
 * @param vo 支付資訊
 * @return
 * @throws AlipayApiException
 */
public String pay(PayVo vo) throws AlipayApiException {
    // 根據支付寶的配置生成一個支付客戶端
    AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, app_id, merchant_private_key, "json", charset, alipay_public_key, sign_type);

    // 建立一個支付請求
    AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
    // 設定請求引數
    alipayRequest.setReturnUrl(return_url);
    alipayRequest.setNotifyUrl(notify_url);

    // 商戶訂單號,商戶網站訂單系統中唯一訂單號
    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 + "\","
            + "\"timeout_express\":\"" + timeout + "\","
            + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

    String result = alipayClient.pageExecute(alipayRequest).getBody();

    // 收到支付寶的響應,響應一個頁面,瀏覽器顯示這個頁面,就會自動到支付寶的收銀臺頁面
    System.out.println("支付寶響應:" + result);

    return result;

}

} ```

建立支付成功返回頁面

paySuccess.html ```java

Title

您已支付成功

```

非同步/同步通知引數封裝物件

java @ToString @Data public class PayAsyncVo { /** * 交易建立時間。格式為 yyyy-MM-dd HH:mm:ss */ private String gmt_create; /** * 編碼格式。如 utf-8、gbk、gb312等。 */ private String charset; /** * 交易付款時間。格式為 yyyy-MM-dd HH:mm:ss */ private String gmt_payment; /** * 通知的傳送時間。格式為 yyyy-MM-dd HH:mm:ss */ private Date notify_time; /** * 訂單標題/商品標題/交易標題/訂單關鍵字等,是請求時對應引數,會在通知中原樣傳回 */ private String subject; /** * 簽名。詳情可檢視 非同步返回結果的驗籤 */ private String sign; /** * 買家支付寶賬號 ID。以 2088 開頭的純 16 位數字 */ private String buyer_id; /** * 商品描述。該訂單的備註、描述、明細等。對應請求時的 body 引數,會在通知中原樣傳回 */ private String body; /** * 開票金額。使用者在交易中支付的可開發票的金額,單位為人民幣(元),精確到小數點後 2 位 */ private String invoice_amount; /** * 呼叫的介面版本。固定為1.0 */ private String version; /** * 通知校驗 ID */ private String notify_id; /** * 支付金額資訊。支付成功的各個渠道金額資訊。詳情可檢視下文 資金明細資訊說明 */ private String fund_bill_list; /** * 通知型別 */ private String notify_type; /** * 商家訂單號。原支付請求的商家訂單號 */ private String out_trade_no; /** * 訂單金額。本次交易支付訂單金額,單位為人民幣(元),精確到小數點後 2 位 */ private String total_amount; /** * 交易狀態。交易目前所處狀態,詳情可查看下錶 交易狀態說明 */ private String trade_status; /** * 支付寶交易號,支付寶交易憑證號 */ private String trade_no; /** * 授權方的APPID。由於本介面暫不開放第三方應用授權,因此 auth_app_id=app_id */ private String auth_app_id; /** * 實收金額。商家在交易中實際收到的款項,單位為人民幣(元),精確到小數點後 2 位 */ private String receipt_amount; /** * 使用集分寶支付金額,單位為人民幣(元),精確到小數點後 2 位 */ private String point_amount; /** * 支付寶應用的APPID。支付寶分配給開發者的應用 ID */ private String app_id; /** * 使用者在交易中支付的金額,單位為人民幣(元),精確到小數點後 2 位 */ private String buyer_pay_amount; /** * 簽名型別。簽名演算法型別,目前支援RSA2和RSA,推薦使用 RSA2 */ private String sign_type; /** * 賣家支付寶賬號 ID。以 2088 開頭的純 16 位數字 */ private String seller_id; }

API介面

```java @Controller public class TestController {

@Autowired
private AlipayUtil alipayUtil;

@ResponseBody
@RequestMapping("/test")
public String index() {
    return "Hello World";
}

/**
 * 使用者下單:支付寶支付
 * 1、讓支付頁讓瀏覽器展示
 * 2、支付成功以後,跳轉到使用者的訂單列表頁
 *
 * @param orderCode 訂單編碼
 * @return
 * @throws AlipayApiException
 */
@ResponseBody
@GetMapping(value = "/payOrder", produces = "text/html")
public String aliPayOrder(@RequestParam String orderCode) throws AlipayApiException {
    // 通過訂單編碼查詢支付資訊
    // PayVo payVo = orderService.getOrderPay(orderCode);

    System.out.println("訂單編碼:" + orderCode);
    // 構造一份訂單支付資訊
    PayVo payVo = new PayVo();
    payVo.setOut_trade_no(UUID.randomUUID().toString());
    payVo.setSubject("話費充值100元");
    payVo.setTotal_amount("99.8");
    payVo.setBody("話費充值100元,急速充值。");

    String pay = alipayUtil.pay(payVo);
    return pay;
}

@GetMapping(value = "/pay/syncNotify")
public String paySyncNotify(PayAsyncVo payasyncVo, HttpServletRequest request) {
    System.out.println("同步通知內容:" + payasyncVo);
    return "paySuccess";
}

/**
 * 支付寶的非同步通知,只要返回 success 支付寶便不再通知
 */
@PostMapping(value = "/pay/asyncNotify")
@ResponseBody
public String payAsyncNotify(PayAsyncVo asyncVo, HttpServletRequest request) throws AlipayApiException {
    // 獲取支付寶反饋資訊
    Map<String, String> params = new HashMap<>();
    Map<String, String[]> requestParams = request.getParameterMap();
    for (String name : requestParams.keySet()) {
        String[] values = requestParams.get(name);
        String valueStr = "";
        for (int i = 0; i < values.length; i++) {
            valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
        }
        // 出現亂碼時使用
        // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
        params.put(name, valueStr);
    }

    // 呼叫SDK驗證簽名
    boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayUtil.getAlipay_public_key(), alipayUtil.getCharset(), alipayUtil.getSign_type());

    if (signVerified) {
        System.out.println("簽名驗證成功...");
        // 業務處理,如修改訂單狀態
        System.out.println(asyncVo.toString());

        return "success";
    } else {
        System.out.println("簽名驗證失敗...");
        return "error";
    }
}

} ```

支付測試

統一收單下單並支付頁面介面呼叫時序圖 image.png 請求http://localhost:8080/payOrder/?orderCode=123378904789支付地址,生成如下表單指令碼 ```java 訂單編碼:123378904789 支付寶響應:

上述指令碼返回遊覽器,自動執行,生成如下頁面。 ![在這裡插入圖片描述](http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/288cefd5483e4af5ad11baf30171fc47~tplv-k3u1fbpfcp-zoom-1.image) 登入沙箱環境賬號進行支付 ![在這裡插入圖片描述](http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cdbcd41280ad436194ff4970996b3ac2~tplv-k3u1fbpfcp-zoom-1.image) 支付成功非同步回撥執行 ![在這裡插入圖片描述](http://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f4808ce63b4d460089269886feec0346~tplv-k3u1fbpfcp-zoom-1.image)java 簽名驗證成功... PayAsyncVo(gmt_create=2022-09-11 21:09:56, charset=utf-8, gmt_payment=2022-09-11 21:10:18, notify_time=Sun Sep 11 21:10:19 CST 2022, subject=話費充值100元, sign=Yty7oT1xpLQ5UwC5DKVFwMO+k2XtOBOza37itFL/R8rIjtFxDoMtP3Qxdi8r76hmLyDjBShz8IQxag6zcqvfhN3OvoyN/gYzYpKz/sqKIYgDqQJqgM4SYA1/4W7kRhG4A0yw2M9ANpm8MYq+i21lvDerQ6R2w71urn/HR7GteZLOFvniisbUu6/Dcykdb6tDgM9tsl1iqGSE/xf6kahcboTXlSdAasFAKPHmiPhjrvs7lpwoFiZZeHlDMYFUkg0hhmJVz/VT8tkVNSEfN/jXZDU+2nvJwK6tR0EkG4gpiQEa7cRP26Jjmbl/pAZ1qKqkhzxRsCa+0U2xYUMy5/r+AQ==, buyer_id=2088102177032991, body=話費充值100元,急速充值。, invoice_amount=99.80, version=1.0, notify_id=2022091100222211018032990521528764, fund_bill_list=[{"amount":"99.80","fundChannel":"ALIPAYACCOUNT"}], notify_type=trade_status_sync, out_trade_no=aec33d19-eda4-4f17-8cb5-5aa0e6129b4b, total_amount=99.80, trade_status=TRADE_SUCCESS, trade_no=2022091122001432990501977422, auth_app_id=2016092300581647, receipt_amount=99.80, point_amount=0.00, app_id=2016092300581647, buyer_pay_amount=99.80, sign_type=RSA2, seller_id=2088102176985780) ``` 等待幾秒後,返回同步通知配置地址

java 同步通知內容:PayAsyncVo(gmt_create=null, charset=utf-8, gmt_payment=null, notify_time=null, subject=null, sign=JuFKKdvhaFPJ6LAJ2BIwVLNS7xb1gZzLtg4kvs2XpuC4i/ElwxKgouyDa/OnJkxCjiO1+YkOhFkPGSNnaWbsic9vgskER5OwChbs5CXgPIZKzG1nFPHTitYHpOeC6XP7O1gzhj9Rq/W3lzYhvnhQBcea3SiF5We21icEMWvahJHp25hlbpOJVxWJOXSB1DjRlnbd30zp09aAV5o+VVDdqByPuBS3ff8owPYh0duhP0f1LEh/BHmJUpBXbeUbwgruay1Tmqzf37SXY/YQymHIIbnz0BpCJ60xj+SuXMlnTwy3LnK0xni9JK+QeHcdY5XpqdtJNl1Vy75zl6PTIgei5A==, buyer_id=null, body=null, invoice_amount=null, version=1.0, notify_id=null, fund_bill_list=null, notify_type=null, out_trade_no=aec33d19-eda4-4f17-8cb5-5aa0e6129b4b, total_amount=99.80, trade_status=null, trade_no=2022091122001432990501977422, auth_app_id=2016092300581647, receipt_amount=null, point_amount=null, app_id=2016092300581647, buyer_pay_amount=null, sign_type=RSA2, seller_id=2088102176985780) 在這裡插入圖片描述

支付查詢測試

AlipayUtil新增訂單查詢方法

```java public String payQuery(String outTradeNo) throws AlipayApiException { // 根據支付寶的配置生成一個支付客戶端 AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, app_id, merchant_private_key, "json", charset, alipay_public_key, sign_type);

    // 建立一個支付請求
    AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();

    JSONObject bizContent = new JSONObject();
    // 訂單支付時傳入的商戶訂單號,和支付寶交易號不能同時為空。trade_no,out_trade_no如果同時存在優先取trade_no
    bizContent.put("out_trade_no", outTradeNo);
    // 支付寶交易號,和商戶訂單號不能同時為空
    //bizContent.put("trade_no", "2014112611001004680073956707");
    alipayRequest.setBizContent(bizContent.toString());
    AlipayTradeQueryResponse response = alipayClient.execute(alipayRequest);
    if (response.isSuccess()) {
        System.out.println("呼叫成功");
        return response.getBody();
    } else {
        System.out.println("呼叫失敗");
        return "查詢失敗。";
    }
}

``` 訂單查詢介面

java /** * 通過商戶訂單號進行查詢支付資訊 * @param outTradeNo 商戶訂單號 * @return * @throws AlipayApiException */ @GetMapping(value = "/pay/payQuery") @ResponseBody public String payQuery(String outTradeNo) throws AlipayApiException { String pay = alipayUtil.payQuery(outTradeNo); return pay; }

發起一份訂單支付,得到商戶ID:a83cf764-f177-4f27-81f7-615bfb418d43,進入付款頁面暫定付款 在這裡插入圖片描述 訪問http://localhost:8080/pay/payQuery?outTradeNo=a83cf764-f177-4f27-81f7-615bfb418d43查詢訂單狀態

交易狀態:

WAIT_BUYER_PAY(交易建立,等待買家付款)

TRADE_CLOSED(未付款交易超時關閉,或支付完成後全額退款)

TRADE_SUCCESS(交易支付成功)

TRADE_FINISHED(交易結束,不可退款)

訂單查詢介面響應資訊如下: java {"alipay_trade_query_response":{"code":"10000","msg":"Success","buyer_logon_id":"cvj***@sandbox.com","buyer_pay_amount":"0.00","buyer_user_id":"2088102177032991","buyer_user_type":"PRIVATE","invoice_amount":"0.00","out_trade_no":"a83cf764-f177-4f27-81f7-615bfb418d43","point_amount":"0.00","receipt_amount":"0.00","total_amount":"99.80","trade_no":"2022091222001432990501977609","trade_status":"WAIT_BUYER_PAY"},"sign":"Ab5EVgiN1y+4z78gIfepK9V4ZDb03gX4IjE3Ao/O3LfIRclFVoTFbvl9MbkVvJ7jfELt/cQ3HQYs9ihxQC3n+2xz/tS0MwYVlvPIdBfu+9uP9nzjYp6Qzd1ccTag0BTCue/bASUdV3Ze4/l86Zec/FC7x30HIu2dPVY9PPK7QabXUypFLb24DUkTPUlb4xr7TSz6S6Zum1vOHabFPvSR1IgQ/ZqC5dnfmB60KclcyWAchfoBvTHJCfytnXZac8iAAfd+E2PKE2SOqpFQFquvC75/JleBsXdt0AuXMXXKDKJTq0g6qPVEOSgZQW+hnsbOaIB2A2OTxlNrvtdOBSVQ8A=="}

訂單關閉測試

AlipayUtil新增訂單關閉方法

```java public String payClose(String outTradeNo) throws AlipayApiException { // 根據支付寶的配置生成一個支付客戶端 AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, app_id, merchant_private_key, "json", charset, alipay_public_key, sign_type);

    // 建立一個支付請求
    AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();

    JSONObject bizContent = new JSONObject();
    // 該交易在支付寶系統中的交易流水號。最短 16 位,最長 64 位。和out_trade_no不能同時為空,如果同時傳了 out_trade_no和 trade_no,則以 trade_no為準。

// bizContent.put("trade_no", "2013112611001004680073956707"); // 訂單支付時傳入的商戶訂單號,和支付寶交易號不能同時為空。 trade_no,out_trade_no如果同時存在優先取trade_no bizContent.put("out_trade_no", outTradeNo); alipayRequest.setBizContent(bizContent.toString()); AlipayTradeCloseResponse response = alipayClient.execute(alipayRequest); if(response.isSuccess()){ System.out.println("呼叫成功"); return response.getBody(); } else { System.out.println("呼叫失敗"); return "訂單關閉失敗。"; } } ```

訂單關閉介面 java /** * 未支付訂單關閉 * @param outTradeNo 商戶訂單號 * @return * @throws AlipayApiException */ @GetMapping(value = "/pay/payClose") @ResponseBody public String payClose(String outTradeNo) throws AlipayApiException { String pay = alipayUtil.payClose(outTradeNo); return pay; }

訪問:http://localhost:8080/pay/payClose?outTradeNo=a83cf764-f177-4f27-81f7-615bfb418d43介面關閉訂單

訂單關閉介面響應資訊如下: java {"alipay_trade_close_response":{"code":"10000","msg":"Success","out_trade_no":"a83cf764-f177-4f27-81f7-615bfb418d43","trade_no":"2022091222001432990501977609"},"sign":"Jem6c7OOfcRHbats0Cx7nGJivIqzrnGwzAYElyay3jEVRKcd/gCYkMwpAM7axDg6PAKLRPS7yXW9GyFeuQm/vweKrEeQxZPq9GbBFLZmwJ272nj0Qxo5lkqwI7nneU1srje/HfVOF8uTiPQIr1kO8FZw0z4QD2E28PFNUG7xouVweN5+U847ha2crWoWJR/VtJRr5oR925/BMlPjOt8ih25P3Wt0SxiXnU7/iKPV7OK7NJV4zGIZ81AO1kFD+rNEWkDbbRnESPEqvTTSqbWLrAP8n1nKvCoaQRRCsyJvuCv9m6gs7AG62qZxYLca9QbiIUjHtGqMOR8g8V5Vfz8bHA=="} 再次訪問http://localhost:8080/pay/payQuery?outTradeNo=a83cf764-f177-4f27-81f7-615bfb418d43查詢訂單狀態

交易狀態:

WAIT_BUYER_PAY(交易建立,等待買家付款)

TRADE_CLOSED(未付款交易超時關閉,或支付完成後全額退款)

TRADE_SUCCESS(交易支付成功)

TRADE_FINISHED(交易結束,不可退款)

訂單查詢介面響應資訊如下: java {"alipay_trade_query_response":{"code":"10000","msg":"Success","buyer_logon_id":"cvj***@sandbox.com","buyer_pay_amount":"0.00","buyer_user_id":"2088102177032991","buyer_user_type":"PRIVATE","invoice_amount":"0.00","out_trade_no":"a83cf764-f177-4f27-81f7-615bfb418d43","point_amount":"0.00","receipt_amount":"0.00","total_amount":"99.80","trade_no":"2022091222001432990501977609","trade_status":"TRADE_CLOSED"},"sign":"Ab5EVgiN1y+4z78gIfepK9V4ZDb03gX4IjE3Ao/O3LfIRclFVoTFbvl9MbkVvJ7jfELt/cQ3HQYs9ihxQC3n+2xz/tS0MwYVlvPIdBfu+9uP9nzjYp6Qzd1ccTag0BTCue/bASUdV3Ze4/l86Zec/FC7x30HIu2dPVY9PPK7QabXUypFLb24DUkTPUlb4xr7TSz6S6Zum1vOHabFPvSR1IgQ/ZqC5dnfmB60KclcyWAchfoBvTHJCfytnXZac8iAAfd+E2PKE2SOqpFQFquvC75/JleBsXdt0AuXMXXKDKJTq0g6qPVEOSgZQW+hnsbOaIB2A2OTxlNrvtdOBSVQ8A=="}