最近在作支付寶的接口對接,以前作過一個版本,可是因爲申請了新的帳號之前舊的的接口對接就不能使用了
因此就開始對接新的版本接口對接,在這裏也記錄一下讓那些尚未對接的兄弟少走點彎路。html
https://memberprod.alipay.com/account/reg/enterpriseIndex.htmjava
去支付寶的開放平臺
https://open.alipay.com/platform/home.htm
添加應用:
https://docs.open.alipay.com/200/105310
按照這個連接的文檔一步一步操做;spring
帳號準備好以後,就能夠了解相關的接口了,以(即時到帳)支付接口爲例。json
https://docs.open.alipay.com/270/alipay.trade.page.pay/後端
https://docs.open.alipay.com/54/103419
選擇java版本api
將這個jar包上傳到私服上去。
參考這個:
http://blog.csdn.net/huchunlinnk/article/details/17789175spring-mvc
這裏的gav的寫法取決於你上傳私服的時候的填寫服務器
<dependency> <groupId>com.alipay</groupId> <artifactId>alipay-api</artifactId> <version>1.0.0</version> </dependency>
取消AlipayConfig配置文件中的部分常量
打開下載sdk應該能夠找到
mvc
將這個類中的前幾個靜態常量變成非靜態的,以即可以支持多個配置對象。app
/* * *類名:AlipayConfig *功能:基礎配置類 *詳細:設置賬戶有關信息及返回路徑 *修改日期:2017-04-05 *說明: *如下代碼只是爲了方便商戶測試而提供的樣例代碼,商戶能夠根據本身網站的須要,按照技術文檔編寫,並不是必定要使用該代碼。 *該代碼僅供學習和研究支付寶接口使用,只是提供一個參考。 */ @Data public class AlipayConfig { //↓↓↓↓↓↓↓↓↓↓請在這裏配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ // 應用ID,您的APPID,收款帳號既是您的APPID對應支付寶帳號 public String app_id = ""; // 商戶私鑰,您的PKCS8格式RSA2私鑰 public String merchant_private_key = ""; // 支付寶公鑰,查看地址:https://openhome.alipay.com/platform/keyManage.htm 對應APPID下的支付寶公鑰。 public String alipay_public_key = ""; // 服務器異步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數,必須外網能夠正常訪問 public String notify_url = ""; // 頁面跳轉同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數,必須外網能夠正常訪問 public String return_url = ""; // 簽名方式 public static String sign_type = "RSA2"; // 字符編碼格式 public static String charset = "utf-8"; // 支付寶網關 public static String gatewayUrl = "https://openapi.alipay.com/gateway.do"; //日誌路徑 public static String log_path = "C:\\"; }
後端向支付寶發起支付的請求,在這個同時須要傳遞必要參數,下面咱們就來編寫
如何向支付寶發起支付。
/** * 阿里支付控制器 * * @author WangSen(wangsenhehe@126.com) * @Date 2017年8月16日 */ @Controller @RequestMapping("/alipay") public class AliPayController { @Autowired private AlipayViewService alipayViewService; /** * 跳轉到去支付的jsp頁面 * * @param orderId 訂單號 * * @param payAccountType 支付帳號類型 * * @param model 模型 * * @throws Exception */ @RequestMapping public void gotopay(long orderId, Model model) throws Exception { alipayViewService.setGoToPayInfo(orderId, model); } }
/** * 阿里支付頁面服務類 * * @author WangSen(wangsenhehe@126.com) * @Date 2017年8月16日 */ @Service public class AlipayViewService { @Autowired private NewAlipayBusinessService newAlipayBusinessService; /** * 設置去支付信息 * * @param orderId 訂單id * @param model 模型 * @param payAccountType 支付帳號類型 * * @return 構建的字符串 */ public void setGoToPayInfo(long orderId, Model model) throws Exception { model.addAttribute("htmlStr", newAlipayBusinessService.buildPayRequest(orderId, payPrice, "報名費", "略")); } }
/** * 新的阿里支付頁面服務類 * <p> * 阿里升級接口以後使用這個服務類 * * @author WangSen(wangsenhehe@126.com) * @Date 2017年8月16日 */ @Data public class NewAlipayBusinessService { /** * 阿里的配置文件對象 */ private AlipayConfig alipayConfig; /** * 構建支付請求 * * @param orderId 訂單號 * @param payPrice 付款金額 * @param orderName 訂單名稱 * @param body 商品描述 * * @return html字符串 */ public String buildPayRequest(long orderId, long payPrice, String orderName, String body) throws Exception { //得到初始化的AlipayClient AlipayClient alipayClient = getAlipayClient(); //設置請求參數 String bizContent = getBizContent(ConvertUtil.obj2str(orderId), AmountUtils.changeF2Y(payPrice), orderName, body); return alipayClient.pageExecute(setAlipayRequestParameters(bizContent)).getBody(); } /** * 設置阿里支付請求參數 * * @param bizContent 包含關鍵參數的json字符串 * * @return AlipayTradePagePayRequest對象 */ private AlipayTradePagePayRequest setAlipayRequestParameters(String bizContent) { AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); alipayRequest.setReturnUrl(alipayConfig.getReturn_url()); alipayRequest.setNotifyUrl(alipayConfig.getNotify_url()); alipayRequest.setBizContent(bizContent); return alipayRequest; } private AlipayClient getAlipayClient() { AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, alipayConfig.getApp_id(), alipayConfig.getMerchant_private_key(), "json", AlipayConfig.charset, alipayConfig.getAlipay_public_key(), AlipayConfig.sign_type); return alipayClient; } /** * 獲取業務的關鍵內容 * * @param out_trade_no 訂單號 * @param total_amount 付款金額 * @param subject 訂單名稱 * @param body 商品描述 * * @return 拼接以後的json字符串 */ private String getBizContent(String out_trade_no, String total_amount, String subject, String body) { ExceptionUtil.checkEmpty(out_trade_no, "訂單號不能爲空"); ExceptionUtil.checkEmpty(total_amount, "價格不能爲空"); ExceptionUtil.checkEmpty(subject, "訂單名稱不能爲空"); ExceptionUtil.checkEmpty(body, "商品描述不能爲空"); StringBuffer sb = new StringBuffer(); sb.append("{"); sb.append("\"out_trade_no\":\"").append(out_trade_no).append("\","); sb.append("\"total_amount\":\"").append(total_amount).append("\","); sb.append("\"subject\":\"").append(subject).append("\","); sb.append("\"body\":\"").append(body).append("\","); sb.append("\"product_code\":\"FAST_INSTANT_TRADE_PAY\""); sb.append("}"); return sb.toString(); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd"> <!-- 數理化支付配置對象 --> <bean id="alipayConfig" class="com.we.business.pay.newalipay.config.AlipayConfig"> <property name="app_id" value="你的appId"/> <property name="merchant_private_key" value="你的私鑰"/> <property name="alipay_public_key" value="支付寶公鑰"/> <property name="notify_url" value="支付完成的異步通知地址"/> <property name="return_url" value="支付完成跳轉的地址"/> </bean> <!-- 阿里支付業務服務類 --> <bean id="newAlipayBusinessService" class="com.we.business.pay.service.NewAlipayBusinessService"> <property name="alipayConfig" ref="alipayConfig"/> </bean> </beans>
<%@page import="com.we.core.common.util.DateTimeUtil"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>支付寶即時到帳交易接口</title> </head> ${htmlStr } <body> </body> </html>
頁面訪問:localhost:8091/alipay/gotopay.json?orderId=232323
就能夠看到支付頁面了;
用戶支付完成以後支付寶會經過你配置的的notify_url的值進行回調,
我須要編寫這個邏輯,以完成整個的支付流程。
/** * 阿里支付控制器 * * @author WangSen(wangsenhehe@126.com) * @Date 2017年8月16日 */ @Controller @RequestMapping("/alipay") public class AliPayController { @Autowired private AlipayViewService alipayViewService; /** * 支付完成 */ @Void @NotSso @ResponseBody @RequestMapping public void payFinish() throws Exception { alipayViewService.payFinish(); } }
/** * 阿里支付頁面服務類 * * @author WangSen(wangsenhehe@126.com) * @Date 2017年8月16日 */ @Service public class AlipayViewService { @Autowired private NewAlipayBusinessService newAlipayBusinessService; /** * 支付完成 * * @throws IOException io異常 */ public void payFinish() throws Exception { newAlipayBusinessService.payFinish(); } }
/** * 新的阿里支付頁面服務類 * <p> * 阿里升級接口以後使用這個服務類 * * @author WangSen(wangsenhehe@126.com) * @Date 2017年8月16日 */ @Data public class NewAlipayBusinessService { /** * 阿里的配置文件對象 */ private AlipayConfig alipayConfig; /** * 支付完成 * * @throws Exception 異常對象 */ public void payFinish() throws Exception { HttpServletRequest request = MvcUtil.getRequest(); PrintWriter out = MvcUtil.getResponse().getWriter(); //獲取支付寶POST過來反饋信息 Map<String, String> params = getParames(request); if (!isSuccess(params)) { fail(out); return; } long orderId = getOrderId(params); long payPrice = getTotalFee(params); try { //編輯你支付完成以後的邏輯 success(out); } catch (Exception e) { fail(out); } } /** * 獲取訂單id * * @param params 請求參數 * @return 訂單id */ private long getOrderId(Map<String, String> params) { String order_no = params.get("out_trade_no"); return ConvertUtil.obj2long(order_no); } /** * 獲取總金額 * * @param params 請求參數 * @return 總金額 */ private long getTotalFee(Map<String, String> params) { String total_fee = params.get("total_amount"); return ConvertUtil.obj2long(AmountUtils.changeY2F(total_fee)); } /** * 校驗支付寶支付是否成功 * * @param params http請求 * @return 成功即爲真 * @throws AlipayApiException */ private boolean isSuccess(final Map<String, String> params) throws AlipayApiException { boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipay_public_key(), AlipayConfig.charset, AlipayConfig.sign_type); //調用SDK驗證簽名 if (!signVerified) { return false; } //交易狀態 String trade_status = params.get("trade_status"); if (!trade_status.equals("TRADE_FINISHED") && !trade_status.equals("TRADE_SUCCESS")) { return false; } return true; } /** * 成功 * * TODO 重構方法名 * @param out 輸出流 */ private void success(PrintWriter out) { out.println("success"); } /** * 失敗 * * TODO 重構方法名 * @param out 輸出流 */ private void fail(PrintWriter out) { out.println("fail"); } /** * 獲取參數 * * @param request HttpServletRequest對象 * * @return 返回支付寶攜帶的參數 */ private Map<String, String> getParames(HttpServletRequest request) { Map<String, String> params = new HashMap<String, String>(); @SuppressWarnings("unchecked") Map<String, String[]> requestParams = request.getParameterMap(); for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) { String name = ConvertUtil.obj2str(iter.next()); @SuppressWarnings("cast") 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; } }
https://docs.open.alipay.com/270/105902/
https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=105971&docType=1
https://docs.open.alipay.com/203/105910
https://docs.open.alipay.com/270/106759