只涉及支付接口 其餘接口沒有使用
支付寶官方文檔:https://docs.open.alipay.com/270/105899/
支付接口文檔 https://docs.open.alipay.com/270/alipay.trade.page.pay/
建議使用沙箱環境進行測試,沙箱接入 https://docs.open.alipay.com/200/105311java
具體實現請參考文檔和官方demoweb
使用HttpServletResponse 輸出頁面,避免中文亂碼出現spring
package com.youboy.order.controller.callback; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.log4j.Logger; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.alipay.api.AlipayApiException; import com.alipay.api.internal.util.AlipaySignature; import com.youboy.alipay.constant.AlipayConfig; import com.youboy.memberService.api.IQualificationService; import com.youboy.order.api.hxpay.IBankDockingRecordsService; import com.youboy.order.api.hxpay.IBankHxAccountService; import com.youboy.order.exception.OrderWebOSException; import com.youboy.pay.api.IPayService; import com.youboy.pay.api.IPayWorker; import com.youboy.pay.dto.PayBill; import com.youboy.pay.dto.bank.BackCode; import com.youboy.pay.dto.bank.GnetOrder; import com.youboy.pay.exception.PayWebOSException; import com.youboy.pay.utils.PaySta; import com.youboy.shardSessionFilter.MemCacheManagerSpy; /** * 支付寶回調 */ @Controller @RequestMapping("/zfb/callback") public class ZfbPayBackOrderController { private final Logger logger = Logger.getLogger(ZfbPayBackOrderController.class); /** * 支付寶支付異步回調 * @param model * @param request * @param response * @param session * @throws OrderWebOSException */ @RequestMapping(value = "/payCallBack", method = RequestMethod.POST) @ResponseBody public String zfbPayCallBack(ModelMap model, HttpServletRequest request, HttpServletResponse response, HttpSession session) throws OrderWebOSException { boolean signVerified = checkRSA(request); if (!signVerified) { // 驗證失敗 logger.error("不是支付寶的合法請求!"); return "fail"; } // 驗證通知是否有效 boolean checkedTrustiness = checkedTrustiness(request); if (!checkedTrustiness) { logger.error("支付寶請求異常!"); return "fail"; } if ("TRADE_FINISHED".equals(trade_status) || "TRADE_SUCCESS".equals(trade_status)) {//TRADE_FINISHED交易成功並結束 ...... } /*else if (trade_status.equals("TRADE_SUCCESS")) { // 判斷該筆訂單是否在商戶網站中已經作過處理 // 若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序 // 若是有作過處理,不執行商戶的業務程序 // 注意: // 付款完成後,支付寶系統發送該交易狀態通知 }*/ return "fail"; } /** * 驗證是否爲支付寶的合法請求 --驗證簽名 * @param request 獲取到的請求 * @return */ private boolean checkRSA(HttpServletRequest request) { 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) { * logger.error("回調接收參數亂碼",e); * } */ params.put(name, valueStr); } logger.info("收到支付寶異步回調:"); logger.info(params.toString()); boolean signVerified = false; // 調用SDK驗證簽名 try { signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); return signVerified; } catch (AlipayApiException e) { // 調試用,寫文本函數記錄程序運行狀況是否正常 String sWord = AlipaySignature.getSignCheckContentV1(params); AlipayConfig.logResult(sWord); logger.error("支付寶回調驗證簽名異常", e); return signVerified; } } // 驗證支付 private boolean checkedTrustiness(HttpServletRequest request) { // 驗證成功 String out_trade_no = ""; String trade_status = ""; String seller_id = ""; String app_id = ""; BigDecimal total_amount; try { // 商戶訂單號 out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8"); // 支付寶交易號 // trade_no = new // String(request.getParameter("trade_no").getBytes("ISO-8859-1"), // "UTF-8"); // 交易狀態 trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8"); // 支付訂單金額 total_amount = new BigDecimal( new String(request.getParameter("buyer_pay_amount").getBytes("ISO-8859-1"), "UTF-8")); // 賣家支付寶帳號 seller_id = new String(request.getParameter("seller_id").getBytes("ISO-8859-1"), "UTF-8"); app_id = new String(request.getParameter("app_id").getBytes("ISO-8859-1"), "UTF-8"); } catch (UnsupportedEncodingException e) { logger.error("回調參數格式轉換異常(payid=" + out_trade_no + ")", e); return false; } if (!"TRADE_FINISHED".equals(trade_status) && !"TRADE_SUCCESS".equals(trade_status)) { logger.error("支付寶返回的交易狀態不正確(payid=" + out_trade_no + ")"); return false; } // 2.驗證out_trade_no是否正確 PayBill bill = new PayBill(); try { bill = payService.find(out_trade_no).get(0); } catch (PayWebOSException e) { logger.error("paybill 查詢訂單狀況異常 (payid=" + out_trade_no + ")", e); return false; } // 3.判斷totalamount if (!total_amount.equals(bill.getAmount()) ) { logger.error("支付寶返回的訂單金額不正確(payid=" + out_trade_no + ")"); return false; } // 支付狀態是否正確 if (PaySta.Success.equals(bill.getStatus())) { logger.error("訂單狀態不正確(payid=" + out_trade_no + ")"); return false; } // 判斷 seller_id if (!AlipayConfig.seller_id.equals(seller_id)) { logger.error("支付寶返回的seller_id不正確(payid=" + out_trade_no + ")"); return false; } // 5.驗證app_id if (!AlipayConfig.app_id.equals(app_id)) { logger.error("支付寶返回的app_id不正確(payid=" + out_trade_no + ")"); return false; } return true; } }