支付寶支付-常用支付API詳解(查詢、退款、提現等)

本文章已同步發佈到簡書 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章