本文章已同步發佈到簡書 http://www.jianshu.com/p/b6e6291709c7
1、前言
此項目已開源歡迎Start、PR、發起Issues一起討論交流共同進步
https://github.com/Javen205/IJPay
http://git.oschina.net/javen205/IJPay
前面幾篇文件詳細介紹了 支付寶提現、掃碼支付、條碼支付、Wap支付、App支付
其中也斷斷續續的提到了一些接口。本片文章主要是總結支付寶支付中常用的一些接口
2、常用的接口總結
這裏使用表格的方式列出 官方接口列表以及詳細的參數說明
API列表 | 類型 | 描述 | 使用場景 |
---|---|---|---|
alipay.trade.query | 免費 | 統一收單線下交易查詢 | 提供所有支付寶支付訂單的查詢 |
alipay.trade.refund | 免費 | 統一收單交易退款接口 | 買家或者賣家的原因需要退款時 |
alipay.trade.fastpay.refund.query | 免費 | 統一收單交易退款查詢 | 查看退款請求是否執行成功 |
alipay.trade.pay | 免費 | 統一收單交易支付接口 | 將二維碼或條碼信息/聲波信息通過本接口上送至支付寶發起支付。 |
alipay.trade.precreate | 免費 | 統一收單線下交易預創建 | 二維碼支付 |
alipay.trade.cancel | 免費 | 統一收單交易撤銷接口 | 撤銷交易 |
alipay.trade.create | 免費 | 統一收單交易創建接口 | 創建下單 |
alipay.trade.close | 免費 | 統一收單交易關閉接口 | 用於交易創建後,用戶在一定時間內未進行支付時可以通過此接口關閉訂單 |
alipay.trade.order.settle | 免費 | 統一收單交易結算接口 | 用於在線下場景交易支付後,進行結算 |
alipay.fund.trans.toaccount.transfer | 免費 | 單筆轉賬到支付寶賬戶接口 | 支付寶提現 |
alipay.fund.trans.order.query | 免費 | 查詢轉賬訂單接口 | 提現結果查詢 |
alipay.data.dataservice.bill.downloadurl.query | 免費 | 查詢對賬單下載地址 | 爲方便商戶快速查賬 |
3、使用服務端SDK封裝接口
3.1 服務端SDK下載及其使用方法
參考 開放平臺服務端SDK
Maven項目引用JAR包可以參考 支付寶Wap支付你瞭解多少? 裏面有詳細的介紹
重要說明
1、接口使用的編碼格式爲 UTF-8
2、接口數據交互使用的是 json
3、接口加密的模式使用官方推薦的 RSA2
4、本片文章主要是介紹Java的使用方法與封裝
3.2 初始化SDK
在SDK調用前需要進行初始化
AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
關鍵參數說明:
配置參數 | 示例值解釋 | 獲取方式/示例值 |
---|---|---|
URL | 支付網關(固定) | 正式環境:https://openapi.alipay.com/gateway.do 沙箱環境:https://openapi.alipaydev.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 |
3.3 API接口封裝
3.3.1 alipay.trade.query接口封裝
該接口提供所有支付寶支付訂單的查詢,商戶可以通過該接口主動查詢訂單狀態,完成下一步的業務邏輯。 需要調用查詢接口的情況: 當商戶後臺、網絡、服務器等出現異常,商戶系統最終未接收到支付通知; 調用支付接口後,返回系統錯誤或未知交易狀態情況; 調用alipay.trade.pay,返回INPROCESS的狀態; 調用alipay.trade.cancel之前,需確認支付狀態;
/**
* 交易查詢接口
* https://doc.open.alipay.com/docs/api.htm?spm=a219a.7395905.0.0.8H2JzG&docType=4&apiId=757
* @param bizContent
* @return
* @throws AlipayApiException
*/
public static boolean isTradeQuery(AlipayTradeQueryModel model) throws AlipayApiException{
AlipayTradeQueryResponse response = tradeQuery(model);
if(response.isSuccess()){
return true;
}
return false;
}
public static AlipayTradeQueryResponse tradeQuery(AlipayTradeQueryModel model) throws AlipayApiException{
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
request.setBizModel(model);
return alipayClient.execute(request);
}
3.3.2 alipay.trade.refund 接口封裝
當交易發生之後一段時間內,由於買家或者賣家的原因需要退款時,賣家可以通過退款接口將支付款退還給買家,支付寶將在收到退款請求並且驗證成功之後,按照退款規則將支付款按原路退到買家帳號上。 交易超過約定時間(簽約時設置的可退款時間)的訂單無法進行退款 支付寶退款支持單筆交易分多次退款,多次退款需要提交原支付訂單的商戶訂單號和設置不同的退款單號。一筆退款失敗後重新提交,要採用原來的退款單號。總退款金額不能超過用戶實際支付金額
/**
* 退款
* https://doc.open.alipay.com/docs/api.htm?spm=a219a.7395905.0.0.SAyEeI&docType=4&apiId=759
* @param content
* @return
* @throws AlipayApiException
*/
public static String tradeRefund(AlipayTradeRefundModel model) throws AlipayApiException{
AlipayTradeRefundResponse response = tradeRefundToResponse(model);
return response.getBody();
}
public static AlipayTradeRefundResponse tradeRefundToResponse(AlipayTradeRefundModel model) throws AlipayApiException{
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
request.setBizModel(model);
return alipayClient.execute(request);
}
3.3.3 alipay.trade.fastpay.refund.query接口封裝
商戶可使用該接口查詢自已通過alipay.trade.refund提交的退款請求是否執行成功。 該接口的返回碼10000,僅代表本次查詢操作成功,不代表退款成功。如果該接口返回了查詢數據,則代表退款成功,如果沒有查詢到則代表未退款成功,可以調用退款接口進行重試。重試時請務必保證退款請求號一致。
/**
* 退款查詢
* https://doc.open.alipay.com/docs/api.htm?spm=a219a.7629065.0.0.KQeTSa&apiId=1049&docType=4
* @param model
* @return
* @throws AlipayApiException
*/
public static String tradeRefundQuery(AlipayTradeFastpayRefundQueryModel model) throws AlipayApiException{
AlipayTradeFastpayRefundQueryResponse response = tradeRefundQueryToResponse(model);
return response.getBody();
}
public static AlipayTradeFastpayRefundQueryResponse tradeRefundQueryToResponse(AlipayTradeFastpayRefundQueryModel model) throws AlipayApiException{
AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
request.setBizModel(model);
return alipayClient.execute(request);
}
3.3.4 alipay.trade.pay接口封裝
收銀員使用掃碼設備讀取用戶手機支付寶“付款碼”/聲波獲取設備(如麥克風)讀取用戶手機支付寶的聲波信息後,將二維碼或條碼信息/聲波信息通過本接口上送至支付寶發起支付。
/**
* 條形碼支付、聲波支付
* https://doc.open.alipay.com/docs/api.htm?spm=a219a.7629065.0.0.XVqALk&apiId=850&docType=4
* @param notifyUrl
* @throws AlipayApiException
*/
public static String tradePay(AlipayTradePayModel model, String notifyUrl) throws AlipayApiException {
AlipayTradePayResponse response = tradePayToResponse(model,notifyUrl);
return response.getBody();
}
public static AlipayTradePayResponse tradePayToResponse(AlipayTradePayModel model, String notifyUrl) throws AlipayApiException{
AlipayTradePayRequest request = new AlipayTradePayRequest();
request.setBizModel(model);// 填充業務參數
request.setNotifyUrl(notifyUrl);
return alipayClient.execute(request); // 通過alipayClient調用API,獲得對應的response類
}
3.3.5 alipay.trade.precreate 接口封裝
收銀員通過收銀臺或商戶後臺調用支付寶接口,生成二維碼後,展示給用戶,由用戶掃描二維碼完成訂單支付。
/**
* 掃碼支付
* https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.i0UVZn&treeId=193&articleId=105170&docType=1#s4
* @param notifyUrl
* @return
* @throws AlipayApiException
*/
public static String tradePrecreatePay(AlipayTradePrecreateModel model, String notifyUrl) throws AlipayApiException{
AlipayTradePrecreateResponse response = tradePrecreatePayToResponse(model,notifyUrl);
return response.getBody();
}
public static AlipayTradePrecreateResponse tradePrecreatePayToResponse(AlipayTradePrecreateModel model, String notifyUrl) throws AlipayApiException{
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setBizModel(model);
request.setNotifyUrl(notifyUrl);
return alipayClient.execute(request);
}
3.3.6 alipay.trade.cancel 接口封裝
支付交易返回失敗或支付系統超時,調用該接口撤銷交易。如果此訂單用戶支付失敗,支付寶系統會將此訂單關閉;如果用戶支付成功,支付寶系統會將此訂單資金退還給用戶。 注意:只有發生支付系統超時或者支付結果未知時可調用撤銷,其他正常支付的單如需實現相同功能請調用申請退款API。提交支付交易後調用【查詢訂單API】,沒有明確的支付結果再調用【撤銷訂單API】。
/**
* 交易撤銷接口
* https://doc.open.alipay.com/docs/api.htm?spm=a219a.7395905.0.0.XInh6e&docType=4&apiId=866
* @param bizContent
* @return
* @throws AlipayApiException
*/
public static boolean isTradeCancel(AlipayTradeCancelModel model) throws AlipayApiException{
AlipayTradeCancelResponse response = tradeCancel(model);
if(response.isSuccess()){
return true;
}
return false;
}
public static AlipayTradeCancelResponse tradeCancel(AlipayTradeCancelModel model) throws AlipayApiException{
AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
request.setBizModel(model);
AlipayTradeCancelResponse response = alipayClient.execute(request);
return response;
}
3.3.7 alipay.trade.create 接口封裝
商戶通過該接口進行交易的創建下單
/**
* 統一收單交易創建接口
* https://doc.open.alipay.com/docs/api.htm?spm=a219a.7629065.0.0.21yRUe&apiId=1046&docType=4
* @param model
* @param notifyUrl
* @return
* @throws AlipayApiException
*/
public static AlipayTradeCreateResponse tradeCreate(AlipayTradeCreateModel model, String notifyUrl) throws AlipayApiException{
AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
request.setBizModel(model);
request.setNotifyUrl(notifyUrl);
return alipayClient.execute(request);
}
3.3.8 alipay.trade.close 接口封裝
用於交易創建後,用戶在一定時間內未進行支付,可調用該接口直接將未付款的交易進行關閉。
/**
* 關閉訂單
* https://doc.open.alipay.com/docs/api.htm?spm=a219a.7629065.0.0.21yRUe&apiId=1058&docType=4
* @param model
* @return
* @throws AlipayApiException
*/
public static boolean isTradeClose(AlipayTradeCloseModel model) throws AlipayApiException{
AlipayTradeCloseResponse response = tradeClose(model);
if(response.isSuccess()){
return true;
}
return false;
}
public static AlipayTradeCloseResponse tradeClose(AlipayTradeCloseModel model) throws AlipayApiException{
AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
request.setBizModel(model);
return alipayClient.execute(request);
}
3.3.9 alipay.trade.order.settle接口封裝
用於在線下場景交易支付後,進行結算
/**
* 交易結算接口
* https://doc.open.alipay.com/docs/api.htm?spm=a219a.7395905.0.0.nl0RS3&docType=4&apiId=1147
* @param bizContent
* @return
* @throws AlipayApiException
*/
public static boolean isTradeOrderSettle(AlipayTradeOrderSettleModel model) throws AlipayApiException{
AlipayTradeOrderSettleResponse response = tradeOrderSettle(model);
if(response.isSuccess()){
return true;
}
return false;
}
public static AlipayTradeOrderSettleResponse tradeOrderSettle(AlipayTradeOrderSettleModel model) throws AlipayApiException{
AlipayTradeOrderSettleRequest request = new AlipayTradeOrderSettleRequest();
request.setBizModel(model);
return alipayClient.execute(request);
}
3.3.10 alipay.fund.trans.toaccount.transfer接口封裝
可以參考 支付寶支付-提現到個人支付寶
3.3.11 alipay.fund.trans.order.query接口封裝
可以參考 支付寶支付-提現到個人支付寶
3.3.12 alipay.data.dataservice.bill.downloadurl.query 接口封裝
爲方便商戶快速查賬,支持商戶通過本接口獲取商戶離線賬單下載地址
/**
* 查詢對賬單下載地址
* @param bizContent
* @return
* @throws AlipayApiException
*/
public static String billDownloadurlQuery(AlipayDataDataserviceBillDownloadurlQueryModel model) throws AlipayApiException{
AlipayDataDataserviceBillDownloadurlQueryResponse response = billDownloadurlQueryToResponse(model);
return response.getBillDownloadUrl();
}
public static AlipayDataDataserviceBillDownloadurlQueryResponse billDownloadurlQueryToResponse (AlipayDataDataserviceBillDownloadurlQueryModel model) throws AlipayApiException{
AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
request.setBizModel(model);
return alipayClient.execute(request);
}
4、異步通知封裝
將異步通知的參數轉化爲Map爲驗籤做準備
/**
* 將異步通知的參數轉化爲Map
* @param request
* @return
*/
public static Map<String, String> toMap(HttpServletRequest request) {
System.out.println(">>>>" + request.getQueryString());
Map<String, String> params = new HashMap<String, String>();
Map<String, String[]> requestParams = request.getParameterMap();
for (Iterator<String> 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);
}
return params;
}
使用
AlipaySignature.rsaCheckV1(....)
接口進行驗證簽名
public void notify_url() {
try {
// 獲取支付寶POST過來反饋信息
Map<String, String> params = AliPayApi.toMap(getRequest());
for (Map.Entry<String, String> entry : params.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
boolean verify_result = AlipaySignature.rsaCheckV1(params, AliPayApi.ALIPAY_PUBLIC_KEY, AliPayApi.CHARSET,
AliPayApi.SIGN_TYPE);
if (verify_result) {// 驗證成功
// TODO 請在這裏加上商戶的業務邏輯程序代碼 異步通知可能出現訂單重複通知 需要做去重處理
System.out.println("notify_url 驗證成功succcess");
renderText("success");
return;
} else {
System.out.println("notify_url 驗證失敗");
// TODO
renderText("failure");
return;
}
} catch (AlipayApiException e) {
e.printStackTrace();
renderText("failure");
}
}
此項目已開源歡迎Start、PR、發起Issues一起討論交流共同進步
https://github.com/Javen205/IJPay
http://git.oschina.net/javen205/IJPay