1、概述java
在全部的電子商務網站中都提供了在線支付功能,用戶能夠將在網上選購的商品生成訂單後經過網站提供的在線支付功能進行結算。網站開發者能夠直接使用銀行提供的接口實如今線支付,也可使用第三方支付平臺來實現。使用銀行接口須要自行開發程序,而第三方支付平臺幫助網站開發者開發了這樣的程序,網站開發者只需應用該平臺提供的接口進行不多的編碼便可實現。安全
使用支付寶平臺提供的接口很是簡單,只需準備一些參數,而後調用提供的方法對這些參數進行簽名並處理,最後經過超連接傳遞處理後的數據到支付寶平臺接口便可,至於支付寶端如何與銀行進行鏈接與網站開發者已沒有關係。因此整個實現過程只需在JSP頁面中完成便可;而對於應用銀行提供的接口實現的在線支付則比較複雜,由於銀行並無提供一個完整的程序將參數進行簽名並處理,因此須要開發者自行編寫,這個過程本系統是在一個Servlet中完成的。jsp
2、支付寶接口介紹工具
經過支付寶網站註冊賬號後,會獲取相關接口、示例程序、和使用幫助文檔。在文檔中對支付寶的服務接口和通知接口進行了概述及使用接口時須要的參數進行了說明。服務接口用來接收網站開連接到支付寶進行的交易請求等,通知接口則是支付寶用來向網站發送通知信息。oop
商品可分爲實物商品和虛擬商品(如IP電話卡),支付寶也提供針對虛擬商品的在線支付示例程序,這裏主要講解的是針對實物商品的在線支付。下面對支付寶「實物商品交易服務」接口時須要的參數進行介紹。測試
表1 支付寶服務接口參數介紹網站
參數名編碼 |
值url |
說明spa |
能否爲空 |
|
協議參數 |
||||
paygateway |
https://www.alipay.com/cooperate/gateway.do? |
支付接口 |
否 |
|
service |
trade_create_by_buyer |
經過該參數肯定用戶請求的操做。表中的值表示訂單交易 |
否 |
|
partner |
從用戶賬戶內提取 |
用戶在支付寶的ID |
否 |
|
notify_url |
商戶自定義 |
接收支付寶通知的URL |
是 |
|
return_url |
商戶自定義 |
支付寶返回的URL |
是 |
|
input_charset |
默認爲GBK |
參數編碼字符集 |
是 |
|
sign |
HTTP請求中傳遞的全部參數(除sign和sign_type之外)按照參數名稱字符升序的順序拼接起來的值 |
待簽名數據 |
否 |
業務參數 |
||||
subject |
商戶自定義 |
商品名稱 |
否 |
|
body |
商戶自定義 |
商品描述 |
是 |
|
out_trade_no |
商戶自定義 |
商戶網站產生的一個惟一訂單號 |
否 |
|
price |
商品單價(訂單總價) |
商品單價(訂單總價) |
否 |
|
discount |
-10000000.00~10000000.00 |
折扣 |
是 |
|
show_url |
商戶自定義 |
商品展現網址 |
是 |
|
quantity |
大於0 |
購買數量 |
否 |
|
payment_type |
1~6的數字。1表示商品購買 |
支付類型 |
是 |
物流信息 |
||||
logistics_type |
VIRTUAL(虛擬物品);POST(平郵);EMS;EXPRESS(其餘快遞公司) |
物流類型 |
否 |
|
logistics_fee |
0.00~10000000.00,默認爲0 |
物流費用 |
否 |
|
logistics_payment |
SELLER_PAY(由賣家支付物流費用); BUYER_PAY(由買家支付物流費用) |
物流支付類型 |
否 |
|
買賣雙方信息 |
||||
seller_email |
賣家Email |
賣家在支付寶註冊的Email或ID,二者任何一個 |
否 |
3、銀行接口介紹
銀行經過接口名稱和版本號來通知用戶使用的接口,下面介紹其中一個接口的定義
參數名 |
值 |
說明 |
能否爲空 |
interfaceName |
ICBC_PERBANK_B2C |
接口名稱 |
否 |
interfaceVersion |
1.0.0.0 |
接口版本號 |
否 |
orderid |
商戶自定義 |
商戶網站產生的一個惟一訂單號 |
否 |
amount |
商戶自定義 |
訂單金額,以分爲單位,不能夠爲零,必需符合金額標準 |
否 |
curType |
001 |
支付幣種,目前工行只支持使用人民幣(001)支付 |
否 |
merID |
由商戶在工行開戶時,由工行告知商戶 |
商戶代碼 |
否 |
merAcct |
商城收費入帳帳號 |
商城帳號 |
否 |
verifyJoinFlag |
1或0 |
檢驗聯名標誌 |
否 |
notifyType |
「HS」或「AG」 |
通知類型,取值「HS」表示在交易完成後實時將通知信息發送給merURL參數指定的URL;取值「AG」表示在交易完成後不通知商戶 |
否 |
merURL |
商戶自定義 |
接收支付結果信息通知程序地址 |
是 |
resultType |
0或1 |
結果發送類型,取值「0」表示不管支付成功或者失敗,銀行都向商戶發送交易通知信息;取值「1」表示只向商戶發送交易成功的通知信息。只有通知方式爲「HS」時此值有效 |
是 |
goodsID |
商戶自定義 |
商品編號 |
是 |
表中明確指定的參數值是不可修改的,例如接口名稱和接口版本號,其餘一些參數值須要銀行提供或由提供的API接口程序本身來生成。例如訂單簽名數據參數merSignMsg,就是由商戶網站開發者根據銀行提供的指定格式和API接口程序生成的,生成merSignMsg參數的步驟以下:
(1)按照如下格式拼接各參數。
接口名稱的值+接口版本號的值+商城代碼的值+商城帳號的值+通知地址的值+結果發送類型的值+訂單號的值+訂單金額的值+支付幣種的值+通知類型的值+交易日期時間的值+校驗聯名標誌的值
(2)經過商戶證書私鑰(user.key)對編碼後的值進行簽名。
(3)對拼接後的值進行BASE64編碼。
4、應用支付寶實如今線支付
1.建立連接支付寶平臺的支付頁面
在生成了訂單編號和訂單總價格後,就可直接經過建立一個頁面完成應用支付寶實現的在線支付。在該頁面將獲取訂單編號和訂單總價格參數,並生成支付寶接口須要的其餘參數,例如支付寶合做夥伴id、支付寶安全校驗碼等,而後調用支付寶提供的方法對這些參數進行簽名並處理,最後經過圖片超連接傳遞處理後的數據。
關鍵代碼以下:
<%@ page import="com.alipay.util.*"%> <!-- 導入支付寶提供的工具類 -->
<%
//******帳戶信息*******************************************************************
String paygateway = "https://www.alipay.com/cooperate/gateway.do?"; //支付接口
String service = "trade_create_by_buyer";
String sign_type = "MD5";
String out_trade_no = request.getParameter("orderid"); //商戶網站訂單編號
String input_charset = "GBK";
String partner = ""; //支付寶合做夥伴id (帳戶內提取)
String key = ""; //支付寶安全校驗碼(帳戶內提取)
String seller_email = ""; //賣家支付寶賬戶
//******商品信息*******************************************************************
String body = "結算商品來自聚寶商城"; //商品描述
String subject = "聚寶商城提供商品"; //商品名稱
String price = request.getParameter("amount"); //訂單總價
String quantity = "1";
String show_url = "www.sina.com.cn";
String payment_type = "1";
String discount = "0";
//******如下是物流信息和支付寶通知。通常商城不須要通知,則刪除此參數(notify_url),而且在Payment.java裏面相應刪除該參數********//
String logistics_type = "EMS";
String logistics_fee = "0.01";
String logistics_payment = "SELLER_PAY";
//支付完成後跳轉返回的網址URL
String return_url = "http://localhost:8080/onLinePayfor01/alipay_return.jsp";
//接收通知的URL,須要的話可取消對該行的註釋
//String notify_url = "http://localhost:8081/jsp_shi_gbk/alipay_notify.jsp";
String ItemUrl = Payment.CreateUrl( paygateway,service,sign_type,out_trade_no,
input_charset,partner,key,seller_email,body,
subject,price,quantity,show_url,payment_type,
discount,logistics_type,logistics_fee,
logistics_payment,return_url); //若是須要接收通知的話,可傳遞notify_url參數,並在Payment.java的CreateUrl()方法的參數中加入notify_url參數。
%>
訂單號: ${param.orderid},您須要支付:¥${param.amount}<br><br>
你選擇的是經過支付寶支付平臺進行網上支付,只有在網上支付成功後,咱們纔會爲您發貨。<br>
請當即支付:<a href="<%=ItemUrl%>"><img src="images/alipay_bwrx.gif" border="0"></a>
在獲取支付寶接口的同時支付寶會提供示例程序,開發者只需修改程序中index.jsp頁面的一些參數便可使用。
2.建立支付完成後跳轉返回的頁面
由於在代碼中設置了return_url參數,因此在支付成功後,請求會從支付寶那邊轉發到return_url參數指定的頁面。在該頁面中要驗證請求是否由支付寶發起,而且驗證訂單信息的正確性,這個過程須要按照支付寶協議來操做,好在支付寶提供的示例程序中也提供了該頁面的實現。下面給出該頁的關鍵代碼:
<%@ page import="com.alipay.util.*"%> <!-- 導入支付寶提供的工具類 -->
<%
String partner = ""; //partner合做夥伴id(必須填寫)
String privateKey = ""; //partner 的對應交易安全校驗碼(必須填寫)
String alipayNotifyURL = "http://notify.alipay.com/trade/notify_query.do?partner="
+ partner+ "¬ify_id="+ request.getParameter("notify_id");
String sign=request.getParameter("sign");
//獲取支付寶ATN返回結果,「true」是正確的訂單信息,「false」 是無效的
String responseTxt = CheckURL.check(alipayNotifyURL);
Map params = new HashMap();
//得到由支付寶POST 過來的參數並設置到新的params中
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] + ",";
params.put(name, valueStr);
}
//對由支付寶POST 過來的參數(不包括sign參數)進行簽名並處理
String mysign = com.alipay.util.SignatureHelper_return.sign(params, privateKey);
//驗證處理後的數據與sign參數值是否相同,並驗證訂單信息的正確性
if (mysign.equals(request.getParameter("sign")) && responseTxt.equals("true") ){
out.println("success");
out.println(params.get("body")); //測試時候用,能夠刪除
out.println("顯示訂單信息");
out.println(responseTxt);
}
else
out.println("fail");
%>