官方文檔:https://opendocs.alipay.com/open/270/105899
本地開發環境支付回調調試方法可以參考:https://www.cnblogs.com/pxblog/p/11623053.html
所需內容:
1、APPID(APPID) 即創建應用后生成 獲取:https://opendocs.alipay.com/open/200/105310
2、APP_PRIVATE_KEY(開發者私鑰) 獲取:https://opendocs.alipay.com/open/291/105971
3、ALIPAY_PUBLIC_KEY(支付寶公鑰) 獲取: https://opendocs.alipay.com/open/291/105971
jar包下載:https://yvioo.lanzous.com/iGR8pe3qkha
配置類
AliPayConfig.java
package com.alipay; public class AliPayConfig { /*******支付寶支付參數*********/ // 商戶appid 教程:https://opendocs.alipay.com/open/200/105310 public static String APPID = ""; // 私鑰 pkcs8格式的 由開發者自己生成 教程:https://opendocs.alipay.com/open/291/105971 public static String RSA_PRIVATE_KEY = ""; // 支付寶公鑰 由支付寶生成 教程:https://opendocs.alipay.com/open/291/105971 public static String ALIPAY_PUBLIC_KEY = ""; // 服務器異步通知路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問 public static String notify_url = "/alipay_notice"; // 頁面跳轉同步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問 商戶可以自定義同步跳轉地址 public static String return_url = "/alipay_return"; // 請求網關地址 public static String URL = "https://openapi.alipay.com/gateway.do"; // 編碼 public static String CHARSET = "UTF-8"; // 返回格式 public static String FORMAT = "json"; // 日志記錄目錄 public static String log_path = "/log"; // RSA2 public static String SIGNTYPE = "RSA2"; }
支付工具類
AliPay.java
package com.alipay; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipayTradePagePayRequest; import javax.servlet.http.HttpServletResponse; public class AliPay { /** * PC網站快速支付 * * @param response * @param orderNo 訂單號 * @param totalAmount 支付金額 */ public static void enterAlipayInPC(HttpServletResponse response, String orderNo, Double totalAmount,String returnUrl,String notifyUrl) { //獲得初始化的AlipayClient AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.URL, AliPayConfig.APPID, AliPayConfig.RSA_PRIVATE_KEY,AliPayConfig.FORMAT, AliPayConfig.CHARSET, AliPayConfig.ALIPAY_PUBLIC_KEY, AliPayConfig.SIGNTYPE); //創建API對應的request AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); //在公共參數中設置回跳地址 //同步跳轉鏈接 alipayRequest.setReturnUrl(returnUrl); //異步跳轉鏈接 alipayRequest.setNotifyUrl(notifyUrl); //填充業務數據 alipayRequest.setBizContent( "{" + " \"out_trade_no\":\""+orderNo+"\"," + " \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," + " \"total_amount\":"+totalAmount+"," + " \"subject\":\"訂單標題\"," + " \"extend_params\":{" + " \"sys_service_provider_id\":\"\"" + " }" + " }" );//填充業務參數 String form; try { //調用SDK生成表單 form = alipayClient.pageExecute(alipayRequest).getBody(); response.setContentType("text/html;charset=UTF-8"); response.getWriter().write(form);//直接將完整的表單html輸出到頁面 response.getWriter().flush(); } catch (Exception e) { e.printStackTrace(); } } }
控制器調用方法
AliPayController.java
package com.alipay; import com.alipay.api.AlipayApiException; import com.alipay.api.internal.util.AlipaySignature; import org.apache.commons.lang.StringUtils; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @Controller public class AliPayController { /** * 支付寶PC支付, * 這只是簡單的demo,需要自行完善邏輯 */ @RequestMapping(value = "/aliPCPay") public void aliPay(HttpServletResponse response) { //訂單號 String orderNo = ""; //訂單總金額,單位為元,精確到小數點后兩位,取值范圍[0.01,100000000]。 可以參考:https://www.cnblogs.com/pxblog/p/13186037.html Double totalAmount = 1.00; AliPay.enterAlipayInPC(response, orderNo, totalAmount,AliPayConfig.returnUrl,AliPayConfig.notifyUrl); } /** * 支付寶異步通知地址 * * @return * @throws IOException * @throws AlipayApiException */ @RequestMapping(value = "/alipay_notice") public String alipayNotice(HttpServletRequest request, HttpServletResponse response, ModelMap model) throws IOException, AlipayApiException { PrintWriter out = response.getWriter(); //獲取支付寶POST過來反饋信息 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] + ","; } //亂碼解決,這段代碼在出現亂碼時使用。如果mysign和sign不相等也可以使用這段代碼轉化 //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); params.put(name, valueStr); } System.out.println(new JSONObject(params)); //獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以下僅供參考)// //商戶訂單號 String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8"); //支付寶交易號 String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8"); //交易狀態 String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8"); //獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以上僅供參考)// //計算得出通知驗證結果 String sign = params.get("sign"); String content = AlipaySignature.getSignCheckContentV1(params); boolean verify_result = AlipaySignature.rsaCheck(content,sign, AliPayConfig.ALIPAY_PUBLIC_KEY, AliPayConfig.CHARSET,AliPayConfig.SIGNTYPE); Order order = orderMng.findByOrderNo(out_trade_no); //支付寶交易號 order.setTransactionId(trade_no); String result = "success"; System.out.println("訂單編號:" + order.getOrderNo()); System.out.println("驗證結果:" + verify_result); if (verify_result) { //驗證成功 //判斷支付寶是否返回付款成功狀態 if ("TRADE_SUCCESS".equalsIgnoreCase(trade_status)){ //判斷訂單狀態是否是未支付狀態 if (!order.getStatus().equals(PayEnums.PAY_SUCCESS.getCode())) { order.setStatus(PayEnums.PAY_SUCCESS.getCode()); orderMng.update(order); } System.out.println("支付成功"); } out.println(result); //請不要修改或刪除 out.flush(); out.close(); } else { //驗證失敗 order.setStatus(PayEnums.PAY_FAIL.getCode()); result = "fail"; orderMng.update(order); System.out.println("支付失敗"); out.println(result); //請不要修改或刪除 out.flush(); out.close(); } return null; } /** * 支付寶同步通知頁面請求 * * @return */ @RequestMapping(value = "/alipay_return") public String alipayReturn(HttpServletRequest request, ModelMap model) { //跳轉到支付結果頁 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] + ","; } //亂碼解決,這段代碼在出現亂碼時使用 try { valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } params.put(name, valueStr); } boolean signVerified = false; try { //調用SDK驗證簽名 String sign = params.get("sign"); String content = AlipaySignature.getSignCheckContentV1(params); signVerified = AlipaySignature.rsaCheck(content,sign, AliPayConfig.ALIPAY_PUBLIC_KEY, AliPayConfig.CHARSET,AliPayConfig.SIGNTYPE); } catch (Exception e) { e.printStackTrace(); } String out_trade_no = null; if (signVerified) { //商戶訂單號 try { out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } else { System.out.println("驗簽失敗"); } Order order = new Order();if (StringUtils.isNotBlank(out_trade_no)) { order = orderMng.findByOrderNo(out_trade_no); if (order != null) { return "成功頁面"; } } return "失敗頁面"; } @Autowired private OrderMng orderMng; }
查詢訂單支付狀態接口
官方文檔地址:https://opendocs.alipay.com/apis/api_1/alipay.trade.query/
/** * 交易查詢 * @param out_trade_no 訂單號 */ public static AlipayTradeQueryResponse query(String out_trade_no) { //獲得初始化的AlipayClient AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.URL, AliPayConfig.APPID, AliPayConfig.RSA_PRIVATE_KEY,AliPayConfig.FORMAT, AliPayConfig.CHARSET, AliPayConfig.ALIPAY_PUBLIC_KEY, AliPayConfig.SIGNTYPE); AlipayTradeQueryRequest alipayQueryRequest = new AlipayTradeQueryRequest(); String biz_content = "{\"out_trade_no\":\"" + out_trade_no + "\"}"; alipayQueryRequest.setBizContent(biz_content); AlipayTradeQueryResponse alipayQueryResponse = null; try { alipayQueryResponse = alipayClient.execute(alipayQueryRequest); if (null != alipayQueryResponse && alipayQueryResponse.isSuccess()) { if (alipayQueryResponse.getCode().equals("10000")) { if ("TRADE_SUCCESS".equalsIgnoreCase(alipayQueryResponse .getTradeStatus())) { //表示支付成功 } else if ("TRADE_CLOSED".equalsIgnoreCase(alipayQueryResponse .getTradeStatus())) { // 表示未付款關閉,或已付款的訂單全額退款后關閉 } else if ("TRADE_FINISHED".equalsIgnoreCase(alipayQueryResponse .getTradeStatus())) { // 此狀態,訂單不可退款或撤銷 } } else { // 如果請求未成功,請重試 } } } catch (AlipayApiException e) { // TODO Auto-generated catch block e.printStackTrace(); } return alipayQueryResponse; }