本文章已同步發(fā)布到簡書 http://www.jianshu.com/p/b6e6291709c7
1、前言
此項(xiàng)目已開源歡迎Start、PR、發(fā)起Issues一起討論交流共同進(jìn)步
https://github.com/Javen205/IJPay
http://git.oschina.net/javen205/IJPay
前面幾篇文件詳細(xì)介紹了 支付寶提現(xiàn)、掃碼支付、條碼支付、Wap支付、App支付
其中也斷斷續(xù)續(xù)的提到了一些接口。本片文章主要是總結(jié)支付寶支付中常用的一些接口
2、常用的接口總結(jié)
這里使用表格的方式列出 官方接口列表以及詳細(xì)的參數(shù)說明
3、使用服務(wù)端SDK封裝接口
3.1 服務(wù)端SDK下載及其使用方法
參考 開放平臺服務(wù)端SDK
Maven項(xiàng)目引用JAR包可以參考 支付寶Wap支付你了解多少? 里面有詳細(xì)的介紹
重要說明
1、接口使用的編碼格式為 UTF-8
2、接口數(shù)據(jù)交互使用的是 json
3、接口加密的模式使用官方推薦的 RSA2
4、本片文章主要是介紹Java的使用方法與封裝
3.2 初始化SDK
在SDK調(diào)用前需要進(jìn)行初始化
AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
關(guān)鍵參數(shù)說明:
3.3 API接口封裝
該接口提供所有支付寶支付訂單的查詢,商戶可以通過該接口主動查詢訂單狀態(tài),完成下一步的業(yè)務(wù)邏輯。 需要調(diào)用查詢接口的情況: 當(dāng)商戶后臺、網(wǎng)絡(luò)、服務(wù)器等出現(xiàn)異常,商戶系統(tǒng)最終未接收到支付通知; 調(diào)用支付接口后,返回系統(tǒng)錯誤或未知交易狀態(tài)情況; 調(diào)用alipay.trade.pay,返回INPROCESS的狀態(tài); 調(diào)用alipay.trade.cancel之前,需確認(rèn)支付狀態(tài);
/**
* 交易查詢接口
* 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);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
當(dāng)交易發(fā)生之后一段時(shí)間內(nèi),由于買家或者賣家的原因需要退款時(shí),賣家可以通過退款接口將支付款退還給買家,支付寶將在收到退款請求并且驗(yàn)證成功之后,按照退款規(guī)則將支付款按原路退到買家賬號上。 交易超過約定時(shí)間(簽約時(shí)設(shè)置的可退款時(shí)間)的訂單無法進(jìn)行退款 支付寶退款支持單筆交易分多次退款,多次退款需要提交原支付訂單的商戶訂單號和設(shè)置不同的退款單號。一筆退款失敗后重新提交,要采用原來的退款單號??偼丝罱痤~不能超過用戶實(shí)際支付金額
/**
* 退款
* 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);
}
商戶可使用該接口查詢自已通過alipay.trade.refund提交的退款請求是否執(zhí)行成功。 該接口的返回碼10000,僅代表本次查詢操作成功,不代表退款成功。如果該接口返回了查詢數(shù)據(jù),則代表退款成功,如果沒有查詢到則代表未退款成功,可以調(diào)用退款接口進(jìn)行重試。重試時(shí)請務(wù)必保證退款請求號一致。
/**
* 退款查詢
* 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);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
收銀員使用掃碼設(shè)備讀取用戶手機(jī)支付寶“付款碼”/聲波獲取設(shè)備(如麥克風(fēng))讀取用戶手機(jī)支付寶的聲波信息后,將二維碼或條碼信息/聲波信息通過本接口上送至支付寶發(fā)起支付。
/**
* 條形碼支付、聲波支付
* 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);// 填充業(yè)務(wù)參數(shù)
request.setNotifyUrl(notifyUrl);
return alipayClient.execute(request); // 通過alipayClient調(diào)用API,獲得對應(yīng)的response類
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
收銀員通過收銀臺或商戶后臺調(diào)用支付寶接口,生成二維碼后,展示給用戶,由用戶掃描二維碼完成訂單支付。
/**
* 掃碼支付
* 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);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
支付交易返回失敗或支付系統(tǒng)超時(shí),調(diào)用該接口撤銷交易。如果此訂單用戶支付失敗,支付寶系統(tǒng)會將此訂單關(guān)閉;如果用戶支付成功,支付寶系統(tǒng)會將此訂單資金退還給用戶。 注意:只有發(fā)生支付系統(tǒng)超時(shí)或者支付結(jié)果未知時(shí)可調(diào)用撤銷,其他正常支付的單如需實(shí)現(xiàn)相同功能請調(diào)用申請退款A(yù)PI。提交支付交易后調(diào)用【查詢訂單API】,沒有明確的支付結(jié)果再調(diào)用【撤銷訂單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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
商戶通過該接口進(jìn)行交易的創(chuàng)建下單
/**
* 統(tǒng)一收單交易創(chuàng)建接口
* 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);
}
用于交易創(chuàng)建后,用戶在一定時(shí)間內(nèi)未進(jìn)行支付,可調(diào)用該接口直接將未付款的交易進(jìn)行關(guān)閉。
/**
* 關(guān)閉訂單
* 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);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
用于在線下場景交易支付后,進(jìn)行結(jié)算
/**
* 交易結(jié)算接口
* 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);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
可以參考 支付寶支付-提現(xiàn)到個(gè)人支付寶
可以參考 支付寶支付-提現(xiàn)到個(gè)人支付寶
為方便商戶快速查賬,支持商戶通過本接口獲取商戶離線賬單下載地址
/**
* 查詢對賬單下載地址
* @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、異步通知封裝
將異步通知的參數(shù)轉(zhuǎn)化為Map為驗(yàn)簽做準(zhǔn)備
/**
* 將異步通知的參數(shù)轉(zhuǎn)化為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] + ",";
}
// 亂碼解決,這段代碼在出現(xiàn)亂碼時(shí)使用。
// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
return params;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
使用AlipaySignature.rsaCheckV1(....) 接口進(jìn)行驗(yàn)證簽名
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) {// 驗(yàn)證成功
// TODO 請?jiān)谶@里加上商戶的業(yè)務(wù)邏輯程序代碼 異步通知可能出現(xiàn)訂單重復(fù)通知 需要做去重處理
System.out.println("notify_url 驗(yàn)證成功succcess");
renderText("success");
return;
} else {
System.out.println("notify_url 驗(yàn)證失敗");
// TODO
renderText("failure");
return;
}
} catch (AlipayApiException e) {
e.printStackTrace();
renderText("failure");
}
}
- 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
此項(xiàng)目已開源歡迎Start、PR、發(fā)起Issues一起討論交流共同進(jìn)步
https://github.com/Javen205/IJPay
http://git.oschina.net/javen205/IJPay
|