1、創建連接的公鑰私鑰
支付寶對接時需要有相應的密鑰、網關、APPID,第一步就是獲取這些數據:
在支付寶【開發者服務中心】(https://openhome.alipay.com/platform/developerIndex.htm)網頁中進行創建(測試時使用沙箱創建就好)
使用這個需要先入駐平台,很簡單,如下操作即可:
人后進去后在控制台頁面中渣都到【沙箱測試】
進入沙箱后操作步驟如下:
然后進入支付寶密鑰生成器下載頁面下載即可:
下載下來后點擊運行安裝得到如下的一個應用:
點擊進入並登錄(注意,在【支付寶開發者服務中心】網頁中登陸的支付寶賬號必須和在此登陸的支付寶賬號必須是同一個):
然后獲取密鑰:
將密鑰什么的都保存下來,如果沒保存也不用擔心,本地會自動保你保存一份在你本地,如下所示:
然后將生成的公鑰放到【開發者服務中心】的沙箱設置中,如下:
如此,第一步的操作算是完成!
2、導入jar包、編寫代碼
導入jar包如下(僅展示的時支付寶所用到的,其他的基礎jar包自行安裝,畢竟每個框架用的東西都有些微不同,就不再一一列舉):
<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java --> <dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>4.10.111.ALL</version> </dependency>
Java代碼:
/**
* @Author qtl
* @Description payTest
* @Date 16:36 2020/10/23
* @Param []
* @return void
**/
@PostMapping("payTest")
public void aliPay(){
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipaydev.com/gateway.do",
"2016102700768586",
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC++ZvFC+XrvFxWoiaRSgqlwhe9o4rsN1IsdoGQBjY935X5Ms46I2dqgK8xZysc+ck/X3W+Sy6I4nLp3igGtUmzqMv+51eJZE1uuj+PBS76jsGyEePXKSYAf8CtJTl/vaRR82NMriVe1WcnvjD/WC1UuCaB1j5evOPSBLAzapzLlryOIAkMB/7+H0x+2BzfMAewPIRDXNUelSEYrAq9OJNKFrJxJn9b85masIfP5nOi3KwIZQKdDRVMlO3+bebZxyorZ1iANs5PyRGOAO3XkVjeywG09LOtzB/9ZNpmehG0/Tyc5XS6qTXctwQq2eHYvrdDitryZ3C42JKy7w3l89oNAgMBAAECggEAC1XhixajtRRfHr1NML6GV0RoCFeWvWKjPARkuFnGCnIlAr+jQgwr7URqIbKP+o5RBbPy1zK7NmDKlVscYRmNoF5ajWzJ41vSxMnFUAXsve6PTLSHI5RLryfmFeDpws1M3Zhmwnxrt29PSiqd2eov9qFfl8FRvmnT0/l3Q/YGDIdxtaNWVbBmYCmn7BSUV9y+TdYkzc4ufHWMGz8zD6YEs161TROHKX6fb8owrA5DWtyhPYES7NUkpJHMhP/ktumI5DF/dNBdpPjvJCqkLR6kAYxNXYQletpxhGdVYd+/98DYHzsPZ2FKMr0v/QmpZPCbkVMPV3KBsepX7a7h1ktk+QKBgQDfi5c7l7otGCO99vG8ZlphI5gvW/f3qALJHjVk+090lpGtPigfbcqDZ2zjZKuVK8DMCwLKO/n9AOo4nym/tA+4LNGY3/mHn/ddEvUxtrEY6mgSE4dLPU8Tp6rQulgVqqLK7QspleTle8BrrFBeTgf6d8hH2kUTw+JCzTB+jaEVjwKBgQDas35oCiuYNkS7TIGo9x4peQBKpBJSCTGQ6tivC/D+fqW/2ZHF3j+p+1m5VIekWNZfhTHBiGyhdkhRKDjaOn7+UZx78/YKL3O4nrqienSCzhCdHfi6PbA5SwJxTyKFe+M0epnCGUUyf817he5OU/W/9ZLibW8FqlTTQIItmxrgowKBgQCVZp20Xjs3WCLLGveEioNs2HUlcbnP8qGp+F6HFs6LhPXnats15hKqr7y+XNGv6IX52IIM1vjEdpATN4yXaqf21z1dhpMmaWrQ8ZKdnxPNKxxSuGp7hoYLBMvMpD2qfVg/dx02tc887/AyBf/QhyYd52AbZW01QH0/WBNJAS7fUQKBgQDWjne5zBh+yObfNaySvnV5zHrrv1E16E0XVj7kZHu2wTsNH37ytxqQQcYBmxtDseAGcB6jNpsUQH2sGSDFf9Ps3tX9iRbdYTZPbnG9SxOY7F7CNZA57qE/ZAZucWt1t1fsuUa1dKM9asKFp5xmfdo/y8WhnCjqTvPPGJ9d7KgOrwKBgFCXt4er4QqCe9gDPiVvdKWhkWwciq6nixoa/ypUNzSVcPNVEnnZJqCYms2qn1jx2qm81RFQIp/pm1KukDvUBH+u4Ev45ysXGsszRyZ9vH3acK95nIO8GpbXhoDlVibHqk9Pe7eApmCynblmyyURxZ3ijeXV6n5MdsnhIFnjxx6k",
"json",
"utf-8",
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvvmbxQvl67xcVqImkUoKpcIXvaOK7DdSLHaBkAY2Pd+V+TLOOiNnaoCvMWcrHPnJP191vksuiOJy6d4oBrVJs6jL/udXiWRNbro/jwUu+o7BshHj1ykmAH/ArSU5f72kUfNjTK4lXtVnJ74w/1gtVLgmgdY+Xrzj0gSwM2qcy5a8jiAJDAf+/h9Mftgc3zAHsDyEQ1zVHpUhGKwKvTiTShaycSZ/W/OZmrCHz+ZzotysCGUCnQ0VTJTt/m3m2ccqK2dYgDbOT8kRjgDt15FY3ssBtPSzrcwf/WTaZnoRtP08nOV0uqk13LcEKtnh2L63Q4ra8mdwuNiSsu8N5fPaDQIDAQAB",
"RSA2");
//實例化客戶端
//實例化具體API對應的request類,類名稱和接口名稱對應,當前調用接口名稱:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已經封裝掉了公共參數,這里只需要傳入業務參數。以下方法為sdk的model入參方式(model和biz_content同時存在的情況下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("我是測試數據");
model.setSubject("購買手機");//展示在支付寶付款界面上的訂單信息
model.setOutTradeNo((Long.valueOf(String.valueOf((new Date()).getTime()))).toString());
model.setTimeoutExpress("3m");
model.setTotalAmount("0.01");
model.setProductCode("001-ProductCode");
request.setBizModel(model);
request.setNotifyUrl("http://xxx:8080/pay/aliPayCallback");
try {
//這里和普通的接口調用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
System.out.println("發起支付 - 生成前端喚起支付寶命令串!");
System.out.println(response.getBody());//就是orderString 可以直接給客戶端請求,無需再做處理。
} catch (AlipayApiException e) {
e.printStackTrace();
}
}
測試步驟中需要下載兩個東西,第一個是【客戶端調試】,另一個是【沙箱版支付寶】(因為是通過沙箱測試,正式的支付寶APP網關和沙箱的APP網關等均不同);
【客戶端調試】APP下載地址:https://alipaybbs.oss-cn-hangzhou.aliyuncs.com/1807/thread/60_191_eb31b639a0caf31.zip
【沙箱版支付寶】下載地址:https://sandbox.alipaydev.com/user/downloadApp.htm
下載完成后進行安裝,手機上顯示圖標如下:
需要有一點要注意,這個支付寶只具有極個別的功能,而且登陸的賬號必須要用他們提供的,賬號信息:https://openhome.alipay.com/platform/appDaily.htm?tab=account
拿到賬號后進行登錄,然后准備開始測試:
- 第一步:將代碼運行起來並調用代碼的接口生成使前端喚起手機上的支付寶軟件的命令;
- 第二步:將命令放到【客戶端調試】APP的沙盒模式中;
- 第三步:運行結果
到此支付過程完畢了,如果是將沙箱的切換到正式的支付的話,只需要更換代碼中的網關、APPID、公鑰、私鑰即可;
這個沒有什么好講的,主要就這么點東西:
/** * @Author qtl * @Description 支付寶 - 支付結果回調返回 * @Date 16:53 2020/10/23 * @Param [request] * @return boolean **/ @PostMapping("/aliPayCallback") public void aliPayCallback(HttpServletRequest request){ logger.info("服務端驗證異步通知信息參數");
// 需要注意的是這個公鑰是支付寶公鑰(沙箱測試環境獲取支付寶公鑰的地方請看下方截圖,正式企業開發),並不是上面的公鑰,需要特別注意!!!!!!!!!!! String alipaypublicKey = "xxxxxxxxx"; String charset = "utf-8"; // 獲取支付寶POST過來反饋信息 Map<String,String> params = new HashMap<String,String>(); Map requestParams = request.getParameterMap(); for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { String name = (String)iter.next(); String[] values = (String[])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); } String paramsJson = JSON.toJSONString(params); logger.info("支付寶回調,{}", paramsJson); // 切記alipaypublickey是支付寶的公鑰,請去open.alipay.com對應應用下查看。 // boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type) boolean flag = false; try { flag = AlipaySignature.rsaCheckV1(params, alipaypublicKey, charset, "RSA2" ); if(flag){ // 檢測是否是真實數據 // 在此地處行數據持久化,支付寶返回的具體數據打印上文中處理好的paramsJson對象即可看到; }else{ logger.info("返回數據存在風險,非合法的支付寶返回值!"); } } catch (AlipayApiException e) { e.printStackTrace(); } System.out.println(flag); }
另外,代碼中的paramsJson對象中的數據包含有商戶訂單號、支付寶支付訂單號、商品信息、支付金額、發票金額等,需要注意的是沒有商戶真正收到的金額信息(扣除手續費后的金額);
沙箱測試模式中支付寶公鑰獲取方式:
企業正式開發(網頁&移動開發) 支付寶公鑰獲取是在應用信息中可以獲取:
整個支付流程已經完畢!
pass: 后來發現,超時后的訂單支付寶並未回調並返回結果,也就是說只有用戶支付成功后才會回調返回結果,因此,在支付狀態存在【待支付、已支付、取消支付】三種狀態時,就需要對未支付的訂單進行處理,我的解決辦法是使用定時器,根據訂單超時時間來設定定時器執行頻率和更新訂單支付狀態數據獲取的時間范圍(例如:我設定的訂單超時時間是3分鍾超時,那我就在定時器中定為每五分鍾執行一次更新支付狀態的操作,操作中被更新的支付狀態的訂單時間取值范圍定在據當前時間的15分鍾前到4分鍾前的數據)即可;