支付寶APP支付、退款、查詢訂單


最近在搞支付這塊,總算告一段落了,來記錄一下,以后找不迷路,在此也希望幫到一些同學,

其實支付寶的技術客服還挺好的,你可以找他們要示例,不像wx......就太......。

需要准備的東西如下:

appid、應用私鑰、應用公鑰證書、支付寶公鑰證書、支付寶根證書

 

依賴

 <!-- alipay-->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <!--<version>3.7.26.ALL</version>-->
        </dependency>

 

下面就粘下重要的代碼

這里說明下,下面這些api都是以證書的方式請求的。如果你平台上是設置秘鑰形式的。可以去掉證書。

APP支付

    /** * 支付寶APP支付 * * @param aliPayParam 支付寶參數類 * @return
     */ @Override public String aliPayAPPToPay(AliPayParam aliPayParam) { try { //設置支付寶請求
            CertAlipayRequest certAlipayRequest = setUpAliPayAsk(); AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); // 實例化具體API對應的request類,類名稱和接口名稱對應,當前調用接口名稱:alipay.trade.app.pay(app 支付接口)
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest(); // 設置業務參數
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); // 商戶訂單號,商戶自定義,需保證在商戶端不重復,如:20200612000001
            String outTradeNo = String.valueOf(snowflake.nextId()); model.setOutTradeNo(outTradeNo); //訂單標題
 model.setSubject(aliPayParam.getSubject()); // 銷售產品碼,固定值 QUICK_MSECURITY_PAY
 model.setProductCode(AliPayConfig.product_code_app); // 訂單金額,精確到小數點后兩位 **/
 model.setTotalAmount(aliPayParam.getTotalAmount().toString()); // 訂單描述
 model.setBody(aliPayParam.getBody()); // 業務擴展參數 //ExtendParams extendParams = new ExtendParams(); // 系統商編號,填寫服務商的PID用於獲取返佣,返佣參數傳值前提:傳值賬號需要簽約返佣協議,用於isv商戶。 //extendParams.setSysServiceProviderId("2088511****07846"); // 花唄分期參數傳值前提:必須有該接口花唄收款准入條件,且需簽約花唄分期 // 指定可選期數,只支持3/6/12期,還款期數越長手續費越高 // extendParams.setHbFqNum("3"); // 指定花唄分期手續費承擔方式,手續費可以由用戶全承擔(該值為0),也可以商戶全承擔(該值為100),但不可以共同承擔,即不可取0和100外的其他值。 **/ //extendParams.setHbFqSellerPercent("0"); //model.setExtendParams(extendParams); // 將業務參數至request中
 request.setBizModel(model); // 異步通知地址,以http或者https開頭的,商戶外網可以post訪問的異步地址,用於接收支付寶返回的支付結果,如果未收到該通知可參考該文檔進行確認:https://opensupport.alipay.com/support/helpcenter/193/201602475759
            request.setNotifyUrl(AliPayConfig.notify_url + AliPayConfig.AliPay_APP_PAY_Callback); //第三方調用(服務商模式),傳值app_auth_token后,會收款至授權token對應商家賬號,如何獲傳值app_auth_token請參考文檔:https://opensupport.alipay.com/support/helpcenter/79/201602494631
            //request.putOtherTextParam("app_auth_token", "傳入獲取到的app_auth_token值");
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request); if (response.isSuccess()) { return response.getBody(); } else { return response.getSubMsg(); } } catch (AlipayApiException e) { e.printStackTrace(); return e.getMessage(); } }

不需要處理,返回一段字符給前端喚醒收銀台頁面就ok。

參考:https://opendocs.alipay.com/apis/api_1/alipay.trade.app.pay

 

查詢支付寶訂單

/** * 查詢支付寶訂單 * * @param aliPayParam 支付寶參數類 * @return
     */ @Override public AlipayTradeQueryResponse queryAliPayOrder(AliPayParam aliPayParam) { try { //設置支付寶請求
            CertAlipayRequest certAlipayRequest = setUpAliPayAsk(); AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); JSONObject bizContent = new JSONObject(); if (StringUtils.isNotEmpty(aliPayParam.getOutTradeNo())) { bizContent.put("out_trade_no", aliPayParam.getOutTradeNo()); } if (StringUtils.isNotEmpty(aliPayParam.getTradeNo())) { bizContent.put("trade_no", aliPayParam.getTradeNo()); } request.setBizContent(bizContent.toString()); AlipayTradeQueryResponse response = alipayClient.certificateExecute(request); if (response.isSuccess()) { System.out.println("調用成功"); return response; } else { System.out.println("調用失敗"); } } catch (AlipayApiException e) { e.printStackTrace(); } throw new CustomException("系統繁忙,請稍后重試"); }

 

支付寶退款

 /** * 支付寶退款 * * @param payRefund 支付寶退款參數類 * @return
     */ @Override public AlipayTradeRefundResponse aliPayRefund(AliPayRefundParam payRefund) { //設置支付寶請求
        CertAlipayRequest certAlipayRequest = setUpAliPayAsk(); try { AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); // 實例化具體API對應的request類,類名稱和接口名稱對應,當前調用接口名稱:alipay.trade.refund(統一收單交易退款接口)
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); // 設置業務參數
            AlipayTradeRefundModel model = new AlipayTradeRefundModel(); // 支付接口傳入的商戶訂單號。如:2020061601290011200000140004
 model.setOutTradeNo(payRefund.getOutTradeNo()); // 退款金額,退款總金額不能大於該筆訂單支付最大金額 **/
 model.setRefundAmount(payRefund.getRefundAmount().toString()); // 異步通知/查詢接口返回的支付寶交易號,如:2020061622001473951448314322
 model.setTradeNo(payRefund.getTradeNo()); //隨機數 不是全額退款,部分退款必須使用該參數,同一個訂單,不同的out_request_no代表部分退款 //String outRequestNo = RandomStringUtils.randomAlphanumeric(13); // 如需部分退款,則此參數必傳,且每次請求不能重復,如:202006230001
 model.setOutRequestNo(payRefund.getRefundNo()); model.setRefundReason(payRefund.getRefundReason()); request.setBizModel(model); //第三方調用(服務商模式),傳值app_auth_token后,會收款至授權token對應商家賬號,如何獲傳值app_auth_token請參考文檔:https://opensupport.alipay.com/support/helpcenter/79/201602494631
            //request.putOtherTextParam("app_auth_token", "傳入獲取到的app_auth_token值"); // 通過alipayClient調用API,獲得對應的response類
            AlipayTradeRefundResponse response = alipayClient.certificateExecute(request); // 獲取接口調用結果,如果調用失敗,可根據返回錯誤信息到該文檔尋找排查方案:https://opensupport.alipay.com/support/helpcenter/101
            return response; } catch (AlipayApiException e) { e.printStackTrace(); } throw new CustomException("系統繁忙,請稍后重試"); }

參考:https://opendocs.alipay.com/apis/028pxn

 

查詢支付寶退款訂單

 /** * 查詢支付寶退款訂單 * * @param payRefund 支付寶退款參數類 * @return
     */ @Override public AlipayTradeFastpayRefundQueryResponse aliPayRefundQuery(AliPayRefundParam payRefund) { try { //設置支付寶請求
            CertAlipayRequest certAlipayRequest = setUpAliPayAsk(); AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest); AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest(); com.alibaba.fastjson.JSONObject bizContent = new com.alibaba.fastjson.JSONObject(); if (StringUtils.isNotEmpty(payRefund.getOutTradeNo())) { bizContent.put("outTrade_no", payRefund.getOutTradeNo()); } if (StringUtils.isNotEmpty(payRefund.getTradeNo())) { bizContent.put("trade_no", payRefund.getTradeNo()); } if (StringUtils.isNotEmpty(payRefund.getRefundNo())){ bizContent.put("out_request_no", payRefund.getRefundNo()); } request.setBizContent(bizContent.toString()); AlipayTradeFastpayRefundQueryResponse response = alipayClient.certificateExecute(request); if (response.isSuccess()) { return response; } else { System.out.println("查訂單失敗"); } } catch (AlipayApiException e) { e.printStackTrace(); } throw new CustomException("系統繁忙,請稍后重試"); }

參考:https://opendocs.alipay.com/apis/028xqc

 

封裝支付寶請求

/** * 設置支付寶請求 * * @return
     */
    public CertAlipayRequest setUpAliPayAsk() { // 初始化
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest(); // 支付寶網關
 certAlipayRequest.setServerUrl(AliPayConfig.SERVER_URL); // 應用id
 certAlipayRequest.setAppId(AliPayConfig.APP_ID); // 應用私鑰
 certAlipayRequest.setPrivateKey(AliPayConfig.APP_PRIVATE_KEY); try { // 應用公鑰證書路徑,下載后保存位置的絕對路徑
 certAlipayRequest.setCertPath(String.valueOf(ResourceUtils.getFile(AliPayConfig.APPLICATION_PUBLIC_KEY_CERT))); // 支付寶公鑰證書路徑,下載后保存位置的絕對路徑
 certAlipayRequest.setAlipayPublicCertPath(String.valueOf(ResourceUtils.getFile(AliPayConfig.AliPay_PUBLIC_CERT))); // 支付寶根證書路徑,下載后保存位置的絕對路徑
 certAlipayRequest.setRootCertPath(String.valueOf(ResourceUtils.getFile(AliPayConfig.ROOT_CERT_PATH))); } catch (FileNotFoundException e) { e.printStackTrace(); } // 設置簽名類型
 certAlipayRequest.setSignType(AliPayConfig.sign_type); // 設置請求格式,固定值json
 certAlipayRequest.setFormat(AliPayConfig.FORMAT); // 設置編碼格式
 certAlipayRequest.setCharset(AliPayConfig.charset); return certAlipayRequest; }

 

回調通知(支付寶的支付回調通知與退款的回調通知是一塊的)

因此我們需要根據返回的字段值做判斷

 

 

 回調通知

   /** * 支付寶支付、退款成功回調 * * @param request HttpServlet 請求 */ @Override public Integer aliPayNotify(HttpServletRequest request) { //獲取支付寶POST過來反饋信息
        Map<String, String> params = new HashMap<String, String>(); Map requestParams = request.getParameterMap(); log.info("requestParams: {}", requestParams); 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] + ","; } //亂碼解決,這段代碼在出現亂碼時使用。 //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
 params.put(name, valueStr); } // 商戶訂單號 //String out_trade_no = request.getParameter("out_trade_no"); // 訂單內容 //String orderContent = request.getParameter("body"); // 交易狀態 支付成功:TRADE_SUCCESS, 交易關閉:TRADE_CLOSED, 交易完成:TRADE_FINISHED
        String tradeStatus = request.getParameter("trade_status"); //簽名驗證(對支付寶返回的數據驗證,確定是支付寶返回的)
        try { //調用SDK驗證簽名
            boolean signVerified = AlipaySignature.rsaCheckV1(params, AliPayConfig.AliPay_PUBLIC_KEY, AliPayConfig.charset, AliPayConfig.sign_type); //驗證簽約是否成功
            if (signVerified) { log.info("驗簽成功"); log.info("交易狀態: {}", tradeStatus); if (tradeStatus.equals("TRADE_SUCCESS")) { System.out.println("交易狀態為TRADE_SUCCESS"); } //支付寶交易號
                String tradeNo = params.get("trade_no"); log.info("tradeNo: {}", tradeNo); //系統訂單編號
                String outTradeNo = params.get("out_trade_no"); log.info("outTradeNo: {}", outTradeNo); //商戶業務號 這里作為退款單號
                String outBizNo = params.get("out_biz_no"); //退款總金額
                String refundFee = params.get("refund_fee"); //交易退款時間
                String gmtRefund = params.get("gmt_refund"); if (StringUtils.isNotEmpty(refundFee) && StringUtils.isNotEmpty(gmtRefund)) { System.out.println("退款成功回調通知"); } else { System.out.println("支付成功回調通知"); } } else { log.info("數字簽名驗證失敗: {}", "500"); } } catch (Exception e) { e.printStackTrace(); log.info("異常狀態: {} ", e.getMessage()); } return Constants.SUCCESS; }

參考:https://opendocs.alipay.com/open/204/105301

 

如有哪里寫的不好的還請多多包涵,有問題請下方留言哦


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM