最近關注項目中在線支付,因此看一下文檔,在線支付應用開發:java
基本全部的在線支付均採用如下方式:apache
客戶點擊結賬時將關於訂單的信息和貨幣信息,相應的信息URL,通過md5或其餘方式發送(可能Socket和Http或Https)支付平臺(塊錢,paypal或支付寶等),支付平臺處理完畢時根據相應URL,返回相關的信息(付款信息,訂單信息,驗證信息).安全
在實際操做Money的問題人們一貫關注他的安全性等問題,同時本人習慣在經過http方式訪問非外網時採用Commons-httpclient的post發送實現,簡單方便,因此採用此種實現:具體看如下API和原代碼:app
網銀在線支付API接口:dom
商戶>>>>>>網銀在線支付:ide
<form method=post action="https://pay.chinaebank.cn/select_bank">函數
<input type=hidden name=v_mid value="1001"> 商戶編號post
<input type=hidden name=v_oid value="19990720-1001-000001234"> 訂單編號加密
<input type=hidden name=v_amount value="13.45"> 訂單總金額url
<input type=hidden name=v_moneytype value="0"> 幣種
<input type=hidden name=v_url value="http://domain/program">
支付動做完成後返回到該url,支付結果以POST方式發送
<input type=hidden name=v_md5info value="1630DC083D70A1E8AF60F49C143A7B95"> 訂單MD5校驗碼
<input type="hidden" name="remark1 " value="">備註字段1
<input type="hidden" name="remark2" value="">備註字段2
<input type=hidden name=v_rcvname value="張三"> 收貨人姓名
<input type=hidden name=v_rcvaddr value="北京海淀"> 收貨人地址
<input type=hidden name=v_rcvtel value="68475566"> 收貨人電話
<input type=hidden name=v_rcvpost value="100036"> 收貨人郵編
<input type=hidden name=v_orderstatus value="0"> 商品信息
<input type=hidden name=v_ordername value="李四"> 定貨人姓名
<input type=hidden name= v_orderemail value="test@test.com"> 定貨人郵件
<input type=submit value="網銀在線支付">
</form>
MD5校驗串生成方法:當消費者在商戶端生成最終訂單的時候,將訂單中的v_amount v_moneytype v_oid v_mid v_url key六個參數的value值拼成一個無間隔的字符串(順序不要改變)。參數key是商戶的MD5密鑰(該密匙可在登錄商戶管理界面後自行更改。)
網銀在線支付>>>商戶
支付完成後頁面轉到商戶,從網銀在線支付返回的消息格式爲:
<form method=get action="v_url" target=_self> <input type="hidden" name="v_oid" value=""> <input type="hidden" name="v_pstatus" value=""> <input type="hidden" name="v_pstring" value=""> <input type="hidden" name="v_pmode" value=""> <input type="hidden" name="v_md5str" value=""> <input type="hidden" name="v_amount" value=""> <input type="hidden" name="v_moneytype" value=""> <input type="hidden" name="remark1 " value=""> <input type="hidden" name="remark2" value=""> </form> |
該消息格式詳細解釋以下:v_url是該筆訂單提交時參數v_url 的值,即網銀返回到商戶的接口地址。
變量名稱 |
變量命名 |
返回值說明 |
|
訂單編號 |
v_oid |
商戶發送的v_oid定單編號。 |
|
支付狀態 |
v_pstatus |
20(表示支付成功) 30(表示支付失敗) |
|
支付結果信息 |
v_pstring |
支付完成 支付完成 |
|
支付方式 |
v_pmode |
支付銀行,例如工商銀行 |
|
訂單MD5校驗碼 |
v_md5str |
該參數的MD5字符串的順序爲:v_oid,v_pstatus,v_amount,v_moneytype,key MD5字符串示例: 20050320-1001-0000012342012.340key 用MD5函數加密上述字符串後獲得的值若是和v_md5str值相等即代表返回的信息沒有被纂改 |
|
訂單總金額 |
v_amount |
訂單實際支付金額 |
|
幣種 |
v_moneytype |
訂單實際支付幣種 |
|
備註字段1 |
remark1 |
|
|
備註字段2 |
remark2 |
|
表3
package cn.com.vnvtrip.china.pay.proxy;
import static cn.com.vnvtrip.china.pay.commons.ChinaPayConstants.CHINABANK_NOTIFY_URL_HTTP;
import static cn.com.vnvtrip.china.pay.commons.ChinaPayConstants.CHINABANK_PAY_HTTPS;
import static cn.com.vnvtrip.china.pay.commons.ChinaPayConstants.CHINABANK_PAY_MD5_KEY;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.codec.digest.DigestUtils;
import cn.com.vnvtrip.china.pay.commons.Env;
import cn.com.vnvtrip.china.pay.commons.HTTPClient;
/**
*
* 網銀接口服務的代理
*
* @author longgangbai
*
*/
public class ChinaPayProxy {
/**
* 在下訂單時採用的的Md5加密的信息: MD5校驗串生成方法:當消費者在商戶端生成最終訂單的時候, 將訂單中的v_amount
* v_moneytype v_oid v_mid v_url key六個參數的value值拼成一個無間隔的字符串(順序不要改變)。
* 參數key是商戶的MD5密鑰(該密匙可在登錄商戶管理界面後自行更改。)
*
* @param v_amount
* @param v_moneytype
* @param v_oid
* @param v_mid
* @param v_url
* @param key
* @return
*/
private static String getMd5Sign(String v_amount, String v_moneytype,
String v_oid, String v_mid, String v_url, String key) {
StringBuffer sb = new StringBuffer();
sb.append(v_amount);
sb.append(v_moneytype);
sb.append(v_oid);
sb.append(v_mid);
sb.append(v_url);
sb.append(key);
byte[] bytes = DigestUtils.md5(sb.toString());
String md5info = new String(bytes).toUpperCase();
return md5info;
}
/**
* 調用支付網關接口網址 銀行結賬的接口代理 (本人習慣採用Commons-httpclient實現)
* 用途:用來接受商戶發給網銀在線服務支付的訂單信息
*
* @param v_mid
* 商戶編號(非空)
* @param v_oid
* 訂單編號(非空)(格式:訂單生成日期(yyyymmdd)-商戶編號-商戶流水號)字段不可超過64位
* @param v_amount
* 訂單總金額 (非空)
* @param v_moneytype
* 貨幣類型 (非空) 0:RMB 1美圓
* @param v_url
* (非空) 支付的動做完成時返回的該url,支付結果以post方式發送
* @param v_md5info
* 訂單md5校驗碼
* @param remark1
* 備註字段1(可選字段)
* @param remark2
* 備註字段2 (可選字段)
* @param v_vmd
* yyyymmdd 備註字段2 (不可爲空字段)
* @param v_rcvname
* 收貨人姓名 (自定義非網銀必須字段)
* @param v_rcvaddr
* 收貨人地址(自定義非網銀必須字段)
* @param v_rcvtel
* 收貨人電話(自定義非網銀必須字段)
* @param v_rcpost
* 收貨人郵編(自定義非網銀必須字段)
* @param v_orderstatus
* 商品信息(自定義非網銀必須字段)
* @param v_ordername
* 定貨人姓名(自定義非網銀必須字段)
* @param v_orderemail
* 定貨人郵件(自定義非網銀必須字段)
* @return
*/
public static boolean chinaBankPayCheck(String v_mid, String v_oid,
String v_amount, String v_moneytype, String v_url, String remark1,
String remark2, String v_rcvname, String v_rcvaddr,
String v_rcvtel, String v_rcpost, String v_orderstatus,
String v_ordername, String v_orderemail) {
Properties p = Env.getEnv().getProperties();
String md5key = p.getProperty(CHINABANK_PAY_MD5_KEY);
String v_md5info = getMd5Sign(v_amount, v_moneytype, v_oid, v_mid,
v_url, md5key);
Map<String, String> paramMaps = new HashMap<String, String>();
paramMaps.put("v_mid", v_mid);
paramMaps.put("v_oid", v_oid);
paramMaps.put("v_amount", v_amount);
paramMaps.put("v_moneytype", v_moneytype);
paramMaps.put("v_url", p.getProperty(CHINABANK_NOTIFY_URL_HTTP));
paramMaps.put("v_md5info", v_md5info);
paramMaps.put("remark1", remark1);
paramMaps.put("remark2", remark2);
paramMaps.put("v_rcvname", v_rcvname);
paramMaps.put("v_rcvaddr", v_rcvaddr);
paramMaps.put("v_rcvtel", v_rcvtel);
paramMaps.put("v_rcpost", v_rcpost);
paramMaps.put("v_orderstatus", v_orderstatus);
paramMaps.put("v_ordername", v_ordername);
paramMaps.put("v_orderemail", v_orderemail);
return HTTPClient.executeHttp(CHINABANK_PAY_HTTPS, paramMaps, null);
}
/**
* result爲支付完畢接受的結果的map 校驗檢測在網銀支付數據是否被攔截的
*
* @param v_oid
* 獲取結果中的訂單編號
* @param v_pstatus
* 獲取訂單的支付狀態
* @param v_pstring
* 支付的結果
* @param v_amount
* 實際支付的金額
* @param v_moneytype
* 實際支付的幣種
* @param v_md5str
* 獲取訂單校驗的MD5驗證
* @return
*/
public static boolean checkPayOff(String v_oid, String v_pstatus,
String v_pstring, String v_amount, String v_moneytype,
String v_md5str) {
Properties p = Env.getEnv().getProperties();
String md5key = p.getProperty(CHINABANK_PAY_MD5_KEY);
String checkmd5 = getCheckMd5(v_oid, v_pstatus, v_amount, v_moneytype,
md5key);
if (checkmd5.equals(v_md5str)) {
return true;
}
return false;
}