java對(duì)接支付寶支付接口簡(jiǎn)單步驟記錄
1、登錄支付寶開(kāi)放平臺(tái),獲取支付寶對(duì)接參數(shù)
參考地址:支付寶開(kāi)放平臺(tái)
1)進(jìn)入控制臺(tái),創(chuàng)建應(yīng)用,得到應(yīng)用ID。
2)進(jìn)入應(yīng)用,開(kāi)發(fā)設(shè)置,設(shè)置接口加密方式,得到應(yīng)用私鑰、支付寶公鑰。
3)進(jìn)入應(yīng)用,產(chǎn)品綁定,綁定支付產(chǎn)品。
2、java代碼的靜態(tài)配置文件中配置支付寶對(duì)接參數(shù)以及回調(diào)地址,并讀取到代碼中
/** * 支付寶配置參數(shù) */ @Configuration public class AlipayConfig { //應(yīng)用id public static String appId; //應(yīng)用私鑰 public static String privateKey; //支付寶公鑰 public static String alipayPublicKey; //請(qǐng)求網(wǎng)關(guān)地址 public static String alipayGateway; // 異步接收地址 public static String notifyUrl; // 同步跳轉(zhuǎn)地址 public static String returnUrl; // 編碼格式 public static String input_charset_utf = "utf-8"; //編碼格式 public static String input_charset_gbk = "GBK"; // 簽名方式 public static String sign_type_md5 = "MD5"; //簽名方式 public static String sign_type_rsa2 = "RSA2"; //字符串格式 public static String format="json"; @Value("${alipay.appId}") public void setAppId(String appId) { AlipayConfig.appId = appId; } @Value("${alipay.privateKey}") public void setPrivateKey(String privateKey) { AlipayConfig.privateKey = privateKey; } @Value("${alipay.alipayPublicKey}") public void setAlipayPublicKey(String alipayPublicKey) { AlipayConfig.alipayPublicKey = alipayPublicKey; } @Value("${alipay.alipayGateway}") public void setAlipayGateway(String alipayGateway) { AlipayConfig.alipayGateway = alipayGateway; } @Value("${alipay.notifyUrl}") public void setNotifyUrl(String notifyUrl) { AlipayConfig.notifyUrl = notifyUrl; } @Value("${alipay.returnUrl}") public void setReturnUrl(String returnUrl) { AlipayConfig.returnUrl = returnUrl; } }
3、查看文檔小程序文檔 - 支付寶文檔中心,根據(jù)支付寶提供的api實(shí)現(xiàn)接口對(duì)接。
/** * 支付寶接口對(duì)接 */ public class AlipayPayUtil { /** * 發(fā)起支付請(qǐng)求 * 統(tǒng)一收單下單并支付頁(yè)面接口 * * @return */ public static AjaxResult alipayPay(String orderNum, BigDecimal price, String title){ try{ AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.alipayGateway, AlipayConfig.appId, AlipayConfig.privateKey, AlipayConfig.format, AlipayConfig.input_charset_utf, AlipayConfig.alipayPublicKey, AlipayConfig.sign_type_rsa2); AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); //異步接收地址,僅支持http/https,公網(wǎng)可訪問(wèn) request.setNotifyUrl(AlipayConfig.notifyUrl); //同步跳轉(zhuǎn)地址,僅支持http/https request.setReturnUrl(AlipayConfig.returnUrl); /******必傳參數(shù)******/ JSONObject bizContent = new JSONObject(); //商戶訂單號(hào),商家自定義,保持唯一性 bizContent.put("out_trade_no",orderNum); //支付金額,最小值0.01元 bizContent.put("total_amount", price); //訂單標(biāo)題,不可使用特殊符號(hào) bizContent.put("subject",title); //訂單描述 bizContent.put("body", title); //電腦網(wǎng)站支付場(chǎng)景固定傳值FAST_INSTANT_TRADE_PAY bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY"); request.setBizContent(bizContent.toString()); AlipayTradePagePayResponse response = alipayClient.pageExecute(request); if (response.isSuccess()) { return AjaxResult.success(response.getBody()); } else { return AjaxResult.error("調(diào)用失敗"); } }catch (Exception e){ e.printStackTrace(); return AjaxResult.error("調(diào)用失敗"); } } /** * 統(tǒng)一收單線下交易查詢接口 * @param tradeNo 支付寶交易號(hào) */ public AjaxResult alipayQuery(String tradeNo){ try{ AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.alipayGateway, AlipayConfig.appId, AlipayConfig.privateKey, AlipayConfig.format, AlipayConfig.input_charset_utf, AlipayConfig.alipayPublicKey, AlipayConfig.sign_type_rsa2); AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); JSONObject bizContent = new JSONObject(); bizContent.put("trade_no", tradeNo); request.setBizContent(bizContent.toString()); AlipayTradeQueryResponse response = alipayClient.execute(request); if(response.isSuccess()){ return AjaxResult.success(response.getBody()); } else { return AjaxResult.error("調(diào)用失敗"); } }catch (Exception e){ e.printStackTrace(); return AjaxResult.error("調(diào)用失敗"); } } /** * 統(tǒng)一收單交易關(guān)閉接口 * @param tradeNo 支付寶交易號(hào) */ public AjaxResult alipayClose(String tradeNo){ try{ AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.alipayGateway, AlipayConfig.appId, AlipayConfig.privateKey, AlipayConfig.format, AlipayConfig.input_charset_utf, AlipayConfig.alipayPublicKey, AlipayConfig.sign_type_rsa2); AlipayTradeCloseRequest request = new AlipayTradeCloseRequest(); JSONObject bizContent = new JSONObject(); bizContent.put("trade_no", tradeNo); request.setBizContent(bizContent.toString()); AlipayTradeCloseResponse response = alipayClient.execute(request); if(response.isSuccess()){ return AjaxResult.success(response.getBody()); } else { return AjaxResult.error("調(diào)用失敗"); } }catch (Exception e){ e.printStackTrace(); return AjaxResult.error("調(diào)用失敗"); } } /** * 統(tǒng)一收單交易退款請(qǐng)求 * 全額退款,out_request_no 選填。 * 部分退款,out_request_no 必傳。 * @param tradeNo 支付寶交易號(hào) */ public AjaxResult alipayRefund(String tradeNo,BigDecimal price){ try{ AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.alipayGateway, AlipayConfig.appId, AlipayConfig.privateKey, AlipayConfig.format, AlipayConfig.input_charset_utf, AlipayConfig.alipayPublicKey, AlipayConfig.sign_type_rsa2); AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); JSONObject bizContent = new JSONObject(); bizContent.put("trade_no", tradeNo); bizContent.put("refund_amount", price); bizContent.put("out_request_no", "T"+Seq.getOrderNum()); request.setBizContent(bizContent.toString()); AlipayTradeRefundResponse response = alipayClient.execute(request); if(response.isSuccess()){ return AjaxResult.success(response.getBody()); } else { return AjaxResult.error("調(diào)用失敗"); } }catch (Exception e){ e.printStackTrace(); return AjaxResult.error("調(diào)用失敗"); } } /** * 統(tǒng)一收單交易退款查詢 * @param tradeNo 支付寶交易號(hào) */ public AjaxResult alipayRefundQuery(String tradeNo){ try{ AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.alipayGateway, AlipayConfig.appId, AlipayConfig.privateKey, AlipayConfig.format, AlipayConfig.input_charset_utf, AlipayConfig.alipayPublicKey, AlipayConfig.sign_type_rsa2); AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest(); JSONObject bizContent = new JSONObject(); bizContent.put("trade_no", tradeNo); bizContent.put("out_request_no","T"+ Seq.getOrderNum()); request.setBizContent(bizContent.toString()); AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request); if(response.isSuccess()){ return AjaxResult.success(response.getBody()); } else { return AjaxResult.error("調(diào)用失敗"); } }catch (Exception e){ e.printStackTrace(); return AjaxResult.error("調(diào)用失敗"); } } }
4、回調(diào)接口處理,支付寶回調(diào)接口分為同步回調(diào)、異步回調(diào),同步接口,業(yè)務(wù)處理后,可直接跳轉(zhuǎn)至配置的網(wǎng)頁(yè),并返回處理信息
/** * 支付寶回調(diào)地址-同步通知頁(yè)面路徑 * * @return */ @RequestMapping(value = "/returnUrl") public void returnUrl(HttpServletRequest request,HttpServletResponse response) throws IOException { try { //獲取支付寶GET過(guò)來(lái)反饋信息 Map<String, String> params = new HashMap<String, String>(); Map requestParams = request.getParameterMap(); 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] + ","; } params.put(name, valueStr); } // 獲取支付寶的通知返回參數(shù) String out_trade_no = request.getParameter("out_trade_no");// 商戶訂單號(hào) String trade_no = request.getParameter("trade_no");// 支付寶交易號(hào) String seller_id=request.getParameter("seller_id");// 收款支付寶賬號(hào)對(duì)應(yīng)的支付寶唯一用戶號(hào) String total_amount=request.getParameter("total_amount");// 交易金額 log.info("returnUrl支付寶訂單交易:[商戶訂單號(hào)]"+out_trade_no+",[支付寶交易號(hào)trade_no]"+trade_no+",[收款支付寶賬號(hào)seller_id]"+seller_id+",[交易金額total_amount]"+total_amount); //調(diào)用SDK驗(yàn)證簽名 boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipayPublicKey, AlipayConfig.input_charset_utf, AlipayConfig.sign_type_rsa2); if(signVerified) { //修改訂單狀態(tài),根據(jù)商戶訂單號(hào)查詢訂單信息 response.sendRedirect(this.alerturl + "?type=ZF&status=300"); }else { log.error("驗(yàn)簽失敗,請(qǐng)聯(lián)系管理員解決"); response.sendRedirect(this.alerturl + "?type=ZF&status=303"); } } catch (Exception e) { e.printStackTrace(); log.error("訂單修改失敗,請(qǐng)聯(lián)系管理員解決"); response.sendRedirect(this.alerturl + "?type=ZF&status=304"); } } /** * 支付寶回調(diào)地址-異步通知頁(yè)面路徑 * * @return */ @PostMapping(value = "/notifyUrl") public String notifyUrl(HttpServletRequest request) { try { // 獲取支付寶GET過(guò)來(lái)反饋信息 Map<String, String> params = new HashMap<String, String>(); Map requestParams = request.getParameterMap(); 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] + ","; } params.put(name, valueStr); } // 獲取支付寶的通知返回參數(shù) String out_trade_no = request.getParameter("out_trade_no");// 商戶訂單號(hào) String trade_no = request.getParameter("trade_no");// 支付寶交易號(hào) String seller_id=request.getParameter("seller_id");// 收款支付寶賬號(hào)對(duì)應(yīng)的支付寶唯一用戶號(hào) String total_amount=request.getParameter("total_amount");// 交易金額 String trade_status = request.getParameter("trade_status");// 交易狀態(tài) log.info("notifyUrl異步回調(diào),支付寶訂單交易:[商戶訂單號(hào)]"+out_trade_no+",[支付寶交易號(hào)trade_no]"+trade_no+",[收款支付寶賬號(hào)seller_id]"+seller_id+",[交易金額total_amount]"+total_amount+",[交易狀態(tài)]"+trade_status); //調(diào)用SDK驗(yàn)證簽名 boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipayPublicKey, AlipayConfig.input_charset_utf, AlipayConfig.sign_type_rsa2); //調(diào)用SDK驗(yàn)證簽名 if(signVerified) { if(trade_status.equals("TRADE_FINISHED")||trade_status.equals("TRADE_SUCCESS")){ //根據(jù)商戶訂單號(hào)查詢訂單信息處理 return "success"; }else { return "fail"; } }else { //驗(yàn)證失敗 log.error("驗(yàn)簽失敗,請(qǐng)聯(lián)系管理員解決"); return "fail"; } } catch (Exception e) { e.printStackTrace(); log.error("訂單修改失敗,請(qǐng)聯(lián)系管理員解決"); return "fail"; } }
注意:
如果框架接口訪問(wèn)有權(quán)限限制,需要放開(kāi)支付寶異步回調(diào)地址,否則無(wú)法訪問(wèn)
總結(jié)
到此這篇關(guān)于java對(duì)接支付寶支付接口的文章就介紹到這了,更多相關(guān)java對(duì)接支付寶支付接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot加載配值文件的實(shí)現(xiàn)步驟
本文主要介紹了springboot加載配值文件的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03SpringBoot+微信小程序?qū)崿F(xiàn)文件上傳與下載功能詳解
這篇文章主要為大家介紹了SpringBoot整合微信小程序?qū)崿F(xiàn)文件上傳與下載功能,文中的實(shí)現(xiàn)步驟講解詳細(xì),快跟隨小編一起學(xué)習(xí)一下吧2022-03-03Java實(shí)現(xiàn)WebSocket四個(gè)步驟
這篇文章主要為大家介紹了Java實(shí)現(xiàn)WebSocket的方法實(shí)例,只需要簡(jiǎn)單四個(gè)步驟,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Spring FreeMarker整合Struts2過(guò)程詳解
這篇文章主要介紹了Spring FreeMarker整合Struts2過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10SpringBoot整合Redisson的步驟(單機(jī)版)
Redisson非常適用于分布式鎖,而我們的一項(xiàng)業(yè)務(wù)需要考慮分布式鎖這個(gè)應(yīng)用場(chǎng)景,于是我整合它做一個(gè)初步簡(jiǎn)單的例子(和整合redis一樣)。2021-05-05springboot如何配置嵌套map和list參數(shù)
這篇文章主要介紹了springboot如何配置嵌套map和list參數(shù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03SpringBoot整合Redis實(shí)現(xiàn)緩存分頁(yè)數(shù)據(jù)查詢功能
類似淘寶首頁(yè),這些商品是從數(shù)據(jù)庫(kù)中查出來(lái)的嗎,答案肯定不是,本文我們就通過(guò)一個(gè)案例實(shí)操一下,首頁(yè)熱點(diǎn)數(shù)據(jù)怎么放到Redis中去查詢,感興趣的同學(xué)可以參考一下2023-06-06Java中Easypoi實(shí)現(xiàn)excel多sheet表導(dǎo)入導(dǎo)出功能
這篇文章主要介紹了Java中Easypoi實(shí)現(xiàn)excel多sheet表導(dǎo)入導(dǎo)出功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01