手機網站支付快速接入


本文檔展示了如何從零開始,使用螞蟻金服開放平台服務端SDK快速接入手機網站支付產品,完成與支付寶對接的部分。

注意: 文檔中的代碼示例和Demo是用來闡述API基本使用方法的,僅針對大眾場景。供ISV參考,特殊情況還請ISV自行擴展,確保符合自身業務需求。

支付產品全面升級,若您使用的是老接口,請移步老版本手機網站支付文檔

第一步:創建應用並獲取APPID

要在您的應用中使用支付寶開放產品的接口能力,您需要先去螞蟻金服開放平台(open.alipay.com),在管理中心中創建登記您的應用,並提交審核,審核通過后會為您生成應用唯一標識(APPID),並且可以申請開通開放產品使用權限,通過APPID您的應用才能調用開放產品的接口能力。需要詳細了解開放平台創建應用步驟請參考《開放平台應用創建指南》

第二步:配置密鑰

開發者調用接口前需要先生成RSA密鑰,RSA密鑰包含應用私鑰(APP_PRIVATE_KEY)、應用公鑰(APP_PUBLIC_KEY)。生成密鑰后在開放平台管理中心進行密鑰配置,配置完成后可以獲取支付寶公鑰(ALIPAY_PUBLIC_KEY)。詳細步驟請參考《配置應用環境》

第三步:搭建和配置開發環境

1. 下載服務端SDK

為了幫助開發者調用開放接口,我們提供了開放平台服務端SDK,包含JAVA、PHP和.NET三語言版本,封裝了簽名&驗簽、HTTP接口請求等基礎功能。請先下載對應語言版本的SDK並引入您的開發工程。

2. 接口調用配置

各語言版本服務端SDK詳細使用說明,請參考《服務端SDK使用說明

在使用SDK調用具體API前,進行初始化,代碼如下:

1
AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
配置參數 示例值解釋 獲取方式/示例值
URL 支付寶網關(固定) https://openapi.alipay.com/gateway.do
APP_ID APPID即創建應用后生成 獲取見上面創建應用並獲取APPID
APP_PRIVATE_KEY 開發者應用私鑰,由開發者自己生成 獲取見上面配置密鑰
FORMAT 參數返回格式,只支持json json(固定)
CHARSET 請求和簽名使用的字符編碼格式,支持GBK和UTF-8 開發者根據實際工程編碼配置
ALIPAY_PUBLIC_KEY 支付寶公鑰,由支付寶生成 獲取詳見上面配置密鑰
SIGN_TYPE 商戶生成簽名字符串所使用的簽名算法類型,目前支持RSA2和RSA,推薦使用RSA2 RSA2

接下來,就可以用alipayClient來調用具體的API了。alipayClient只需要初始化一次,后續調用不同的API都可以使用同一個alipayClient對象。

TIPS:手機網站支付不支持第三方授權,不能代商家發起請求。

第四步:調用接口

手機網站支付產品包含兩類API:

  • 頁面跳轉類:需要從前端頁面以Form表單的形式發起請求,瀏覽器會自動跳轉至支付寶的相關頁面(一般是收銀台或簽約頁面),用戶在該頁面完成相關業務操作后再回跳到商戶指定頁面。例如本產品中的手機網站支付接口alipay.trade.wap.pay
  • 系統調用類:直接從服務端發起HTTP請求,支付寶會同步返回請求結果。例如本產品中的交易查詢等配套API。

調用流程

調用流程

如上圖所示,用戶在商戶的H5網站下單支付后,商戶系統按照手機網站支付接口alipay.trade.wap.payAPI的參數規范生成訂單數據,然后在前端頁面通過Form表單的形式請求到支付寶。此時支付寶會自動將頁面跳轉至支付寶H5收銀台頁面,如果用戶手機上安裝了支付寶APP,則自動喚起支付寶APP。開發者需要關注安裝了支付寶和未安裝支付寶的兩種測試場景,對於在手機瀏覽器喚起H5頁面的模式下,如果安裝了支付寶卻沒有喚起,大部分原因是當前瀏覽器不在支付寶配置的白名單內,對於商戶app內嵌webview中的支付場景,建議集成支付寶App支付產品。

用戶在支付寶APP或H5收銀台完成支付后,會根據商戶在手機網站支付API中傳入的前台回跳地址return_url自動跳轉回商戶頁面,同時在URL請求中以Query String的形式附帶上支付結果參數,詳細回跳參數見“手機網站支付接口alipay.trade.wap.pay”前台回跳參數

同時,支付寶還會根據原始支付API中傳入的異步通知地址notify_url,通過POST請求的形式將支付結果作為參數通知到商戶系統,詳情見支付結果異步通知

除了正向支付流程外,支付寶也提供交易查詢、關閉、退款、退款查詢以及對賬等配套API。

特別注意:

  • 由於前台回跳的不可靠性,前台回跳只能作為商戶支付結果頁的入口,最終支付結果必須以異步通知或查詢接口返回為准,不能依賴前台回跳。
  • 商戶系統接收到異步通知以后,必須通過驗簽(驗證通知中的sign參數)來確保支付通知是由支付寶發送的。詳細驗簽規則參考異步通知驗簽
  • 接受到異步通知並驗簽通過后,一定要檢查通知內容,包括通知中的app_id, out_trade_no, total_amount是否與請求中的一致,並根據trade_status進行后續業務處理。

使用SDK快速接入

手機網站支付alipay.trade.wap.pay:
對於頁面跳轉類API,SDK不會也無法像系統調用類API一樣自動請求支付寶並獲得結果,而是在接受request請求對象后,為開發者生成前台頁面請求需要的完整form表單的html(包含自動提交腳本),商戶直接將這個表單的String輸出到http response中即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void doPost(HttpServletRequest httpRequest,
                       HttpServletResponse httpResponse) throws ServletException, IOException {
     AlipayClient alipayClient = new DefaultAlipayClient( "https://openapi.alipay.com/gateway.do" , APP_ID, APP_PRIVATE_KEY, "json" , CHARSET, ALIPAY_PUBLIC_KEY, "RSA2" ); //獲得初始化的AlipayClient
     AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest(); //創建API對應的request
     alipayRequest.setReturnUrl( "http://domain.com/CallBack/return_url.jsp" );
     alipayRequest.setNotifyUrl( "http://domain.com/CallBack/notify_url.jsp" );//在公共參數中設置回跳和通知地址
     alipayRequest.setBizContent( "{" +
         "    \"out_trade_no\":\"20150320010101002\"," +
         "    \"total_amount\":\"88.88\"," +
         "    \"subject\":\"Iphone6 16G\"," +
         "    \"seller_id\":\"2088123456789012\"," +
         "    \"product_code\":\"QUICK_WAP_PAY\"" +
         "  }" ); //填充業務參數
     String form = alipayClient.pageExecute(alipayRequest).getBody(); //調用SDK生成表單
     httpResponse.setContentType( "text/html;charset=" + AlipayServiceEnvConstants.CHARSET);
     httpResponse.getWriter().write(form); //直接將完整的表單html輸出到頁面
     httpResponse.getWriter().flush();
}

關鍵入參:

參數名稱 參數說明
out_trade_no 商戶訂單號,需要保證不重復
subject 訂單標題
seller_id 實際收款賬號,一般填寫商戶PID即可
total_amount 訂單金額

異步通知驗簽:

1
2
3
4
5
6
7
Map<String, String> paramsMap = ... //將異步通知中收到的所有參數都存放到map中
boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE) //調用SDK驗證簽名
if (signVerfied){
     // TODO 驗簽成功后,按照支付結果異步通知中的描述,對支付結果中的業務內容進行二次校驗,校驗成功后在response中返回success並繼續商戶自身業務處理,校驗失敗返回failure
} else {
     // TODO 驗簽失敗則記錄異常日志,並在response中返回failure.
}

關鍵通知參數:

參數名稱 參數說明
trade_no 支付寶28位交易號
trade_status 交易狀態
total_amount 訂單金額

交易查詢接口alipay.trade.query:

1
2
3
4
5
6
7
8
9
AlipayClient alipayClient = new DefaultAlipayClient( "https://openapi.alipay.com/gateway.do" , APP_ID, APP_PRIVATE_KEY, "json" , CHARSET, ALIPAY_PUBLIC_KEY, "RSA2" ); //獲得初始化的AlipayClient
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); //創建API對應的request類
request.setBizContent( "{" +
"    \"out_trade_no\":\"20150320010101001\"," +
"    \"trade_no\":\"2014112611001004680073956707\"" +
"  }" ); //設置業務參數
AlipayTradeQueryResponse response = alipayClient.execute(request); //通過alipayClient調用API,獲得對應的response類
System.out.print(response.getBody());
//根據response中的結果繼續業務邏輯處理

關鍵入參:

參數名稱 參數說明
out_trade_no 支付時傳入的商戶訂單號,與trade_no必填一個
trade_no 支付時返回的支付寶交易號,與out_trade_no必填一個

關鍵出參:

參數名稱 參數說明
trade_no 支付寶28位交易號
out_trade_no 支付時傳入的商戶訂單號
trade_status 交易當前狀態

交易退款接口alipay.trade.refund:

1
2
3
4
5
6
7
8
9
10
11
AlipayClient alipayClient = new DefaultAlipayClient( "https://openapi.alipay.com/gateway.do" , APP_ID, APP_PRIVATE_KEY, "json" , CHARSET, ALIPAY_PUBLIC_KEY, "RSA2" ); //獲得初始化的AlipayClient
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); //創建API對應的request類
request.setBizContent( "{" +
"    \"out_trade_no\":\"20150320010101001\"," +
"    \"trade_no\":\"2014112611001004680073956707\"," +
"    \"out_request_no\":\"1000001\"," +
"    \"refund_amount\":\"2014112611001004680073956707\"" +
"  }" ); //設置業務參數
AlipayTradeRefundResponse response = alipayClient.execute(request); //通過alipayClient調用API,獲得對應的response類
System.out.print(response.getBody());
//根據response中的結果繼續業務邏輯處理

關鍵入參:

參數名稱 參數說明
out_trade_no 支付時傳入的商戶訂單號,與trade_no必填一個
trade_no 支付時返回的支付寶交易號,與out_trade_no必填一個
out_request_no 本次退款請求流水號,部分退款時必傳
refund_amount 本次退款金額

關鍵出參:

參數名稱 參數說明
refund_fee 該筆交易已退款的總金額

查詢對賬單下載地址接口alipay.data.dataservice.bill.downloadurl.query:

1
2
3
4
5
6
7
8
9
AlipayClient alipayClient = new DefaultAlipayClient( "https://openapi.alipay.com/gateway.do" , APP_ID, APP_PRIVATE_KEY, "json" , CHARSET, ALIPAY_PUBLIC_KEY, "RSA2" ); //獲得初始化的AlipayClient
AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest(); //創建API對應的request類
request.setBizContent( "{" +
"    \"bill_type\":\"trade\"," +
"    \"bill_date\":\"2016-04-05\""
"  }" ); //設置業務參數
AlipayDataDataserviceBillDownloadurlQueryResponse response = alipayClient.execute(request);
System.out.print(response.getBody());
//根據response中的結果繼續業務邏輯處理

關鍵入參:

參數名稱 參數說明
bill_type 固定傳入trade
bill_date 需要下載的賬單日期,最晚是當期日期的前一天

關鍵出參:

參數名稱 參數說明
bill_download_url 賬單文件下載地址,30秒有效

下載賬單文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//將接口返回的對賬單下載地址傳入urlStr
//指定希望保存的文件路徑
String filePath = "/Users/fund_bill_20160405.csv" ;
URL url = null ;
HttpURLConnection httpUrlConnection = null ;
InputStream fis = null ;
FileOutputStream fos = null ;
try {
     url = new URL(urlStr);
     httpUrlConnection = (HttpURLConnection) url.openConnection();
     httpUrlConnection.setConnectTimeout( 5 * 1000 );
     httpUrlConnection.setDoInput( true );
     httpUrlConnection.setDoOutput( true );
     httpUrlConnection.setUseCaches( false );
     httpUrlConnection.setRequestMethod( "GET" );
     httpUrlConnection.setRequestProperty( "Charsert" , "UTF-8" );
     httpUrlConnection.connect();
     fis = httpUrlConnection.getInputStream();
     byte [] temp = new byte [ 1024 ];
     int b;
     fos = new FileOutputStream( new File(filePath));
     while ((b = fis.read(temp)) != - 1 ) {
         fos.write(temp, 0 , b);
         fos.flush();
     }
} catch (MalformedURLException e) {
     e.printStackTrace();
} catch (IOException e) {
     e.printStackTrace();
} finally {
     try {
         if (fis!= null ) fis.close();
         if (fos!= null ) fos.close();
         if (httpUrlConnection!= null ) httpUrlConnection.disconnect();
     } catch (IOException e) {
         e.printStackTrace();
     }
}

關於沙箱

如何接入沙箱

沙箱環境是開放平台提供給開發者調試接口的環境,具體操作步驟見 沙箱接入指南

手機網站支付沙箱接入注意點

1、手機網站支付支持沙箱接入;在沙箱調通接口后,必須在線上進行測試與驗收,所有返回碼及業務邏輯以線上為准;
2、手機網站支付只支持余額支付,不支持銀行卡、余額寶等其他支付方式;
3、支付時,請使用沙箱買家賬號支付,在登錄支付寶,輸入手機號的頁面,點擊右下角 支付寶賬戶登錄;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM