一文教你如何對接【支付寶】支付接口,網(wǎng)友:666?。?/h1>
點擊上方[全棧開發(fā)者社區(qū)]→右上角[...]→[設(shè)為星標(biāo)?]

場景
最近在做支付寶的接口對接,之前做過一個版本,但是由于申請了新的賬號以前舊的的接口對接就不能使用了
所以就開始對接新的版本接口對接,在這里也記錄一下讓那些還沒有對接的兄弟少走點彎路。
準(zhǔn)備
先申請一個企業(yè)賬戶
https://memberprod.alipay.com/account/reg/enterpriseIndex.htm
創(chuàng)建應(yīng)用
去支付寶的開放平臺
https://open.alipay.com/platform/home.htm
添加應(yīng)用:
https://docs.open.alipay.com/200/105310
按照這個鏈接的文檔一步一步操作;
賬號準(zhǔn)備好之后,就可以了解相關(guān)的接口了,以(即時到賬)支付接口為例。
閱讀接口文檔
https://docs.open.alipay.com/270/alipay.trade.page.pay/
下載SDK
https://docs.open.alipay.com/54/103419
選擇java版本
將sdk集成進(jìn)入項目中
sdk中有一個jar包

將這個jar包上傳到私服上去。
參考這個:
http://blog.csdn.net/huchunlinnk/article/details/17789175
項目引入sdk中的關(guān)鍵jar包
這里的gav的寫法取決于你上傳私服的時候的填寫

????com.alipay
????alipay-api
????1.0.0
處理AlipayConfig對象
取消AlipayConfig配置文件中的部分常量
打開下載sdk應(yīng)該可以找到

將這個類中的前幾個靜態(tài)常量變成非靜態(tài)的,以便可以支持多個配置對象。
/*?*
?*類名:AlipayConfig
?*功能:基礎(chǔ)配置類
?*詳細(xì):設(shè)置帳戶有關(guān)信息及返回路徑
?*修改日期:2017-04-05
?*說明:
?*以下代碼只是為了方便商戶測試而提供的樣例代碼,商戶可以根據(jù)自己網(wǎng)站的需要,按照技術(shù)文檔編寫,并非一定要使用該代碼。
?*該代碼僅供學(xué)習(xí)和研究支付寶接口使用,只是提供一個參考。
?*/
@Data
public?class?AlipayConfig?{
????//↓↓↓↓↓↓↓↓↓↓請在這里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
????//?應(yīng)用ID,您的APPID,收款賬號既是您的APPID對應(yīng)支付寶賬號
????public?String?app_id?=?"";
????//?商戶私鑰,您的PKCS8格式RSA2私鑰
????public?String?merchant_private_key?=?"";
????//?支付寶公鑰,查看地址:https://openhome.alipay.com/platform/keyManage.htm 對應(yīng)APPID下的支付寶公鑰。
????public?String?alipay_public_key?=?"";
????//?服務(wù)器異步通知頁面路徑??需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
????public?String?notify_url?=?"";
????//?頁面跳轉(zhuǎn)同步通知頁面路徑?需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
????public?String?return_url?=?"";
????//?簽名方式
????public?static?String?sign_type?=?"RSA2";
????//?字符編碼格式
????public?static?String?charset?=?"utf-8";
????//?支付寶網(wǎng)關(guān)
????public?static?String?gatewayUrl?=?"https://openapi.alipay.com/gateway.do";
????//日志路徑
????public?static?String?log_path?=?"C:\\";
}
編寫請求支付的接口
后端向支付寶發(fā)起支付的請求,在這個同時需要傳遞必要參數(shù),下面我們就來編寫如何向支付寶發(fā)起支付。
編寫conroller層
/**
?*?阿里支付控制器
?*
?*?@author???WangSen([email protected])
?*?@Date?????2017年8月16日??????
?*/
@Controller
@RequestMapping("/alipay")
public?class?AliPayController?{
????@Autowired
????private?AlipayViewService?alipayViewService;
????/**
?????*?跳轉(zhuǎn)到去支付的jsp頁面
?????*
?????*?@param?orderId?訂單號
?????*?
?????*?@param?payAccountType?支付賬號類型
?????*?
?????*?@param?model?模型
?????*?
?????*?@throws?Exception
????*/
????@RequestMapping
????public?void?gotopay(long?orderId,?Model?model)?throws?Exception?{
????????alipayViewService.setGoToPayInfo(orderId,?model);
????}
}
編寫viewService層
/**
?*?阿里支付頁面服務(wù)類
?*?
?*?@author???WangSen([email protected])
?*?@Date?????2017年8月16日??????
?*/
@Service
public?class?AlipayViewService?{
????@Autowired
????private?NewAlipayBusinessService?newAlipayBusinessService;
????/**
?????*?設(shè)置去支付信息
?????*?
?????*?@param?orderId?訂單id
?????*?@param?model?模型
?????*?@param?payAccountType?支付賬號類型
?????*?
?????*?@return?構(gòu)建的字符串
????*/
????public?void?setGoToPayInfo(long?orderId,?Model?model)?throws?Exception?{
????????model.addAttribute("htmlStr",?newAlipayBusinessService.buildPayRequest(orderId,?payPrice,?"報名費",?"略"));
????}
}
編寫service層
/**
?*?新的阿里支付頁面服務(wù)類
?*?
?*?阿里升級接口之后使用這個服務(wù)類
?*?
?*?@author???WangSen([email protected])
?*?@Date?????2017年8月16日??????
?*/
@Data
public?class?NewAlipayBusinessService?{
????/**
?????*?阿里的配置文件對象
?????*/
????private?AlipayConfig?alipayConfig;
????/**
?????*?構(gòu)建支付請求
?????*
?????*?@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();
????????//設(shè)置請求參數(shù)
????????String?bizContent?=?getBizContent(ConvertUtil.obj2str(orderId),?AmountUtils.changeF2Y(payPrice),?orderName,
????????????????body);
????????return?alipayClient.pageExecute(setAlipayRequestParameters(bizContent)).getBody();
????}
????/**
?????*?設(shè)置阿里支付請求參數(shù)
?????*
?????*?@param?bizContent?包含關(guān)鍵參數(shù)的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;
????}
????/**
?????*?獲取業(yè)務(wù)的關(guān)鍵內(nèi)容
?????*
?????*?@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文件配置支付對象
"1.0"?encoding="UTF-8"?>
"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">
????
????"alipayConfig"?class="com.we.business.pay.newalipay.config.AlipayConfig">
????????"app_id"?value="你的appId"/>
????????"merchant_private_key"?value="你的私鑰"/>
????????"alipay_public_key"?value="支付寶公鑰"/>
????????"notify_url"?value="支付完成的異步通知地址"/>
????????"return_url"?value="支付完成跳轉(zhuǎn)的地址"/>
????
????
????"newAlipayBusinessService"?class="com.we.business.pay.service.NewAlipayBusinessService">
????????"alipayConfig"?ref="alipayConfig"/>
????
?
編寫jsp頁面
<%@page?import="com.we.core.common.util.DateTimeUtil"%>
<%@?page?language="java"?contentType="text/html;?charset=UTF-8"?pageEncoding="UTF-8"%>
"-//W3C//DTD?HTML?4.01?Transitional//EN">
????
????????"Content-Type"?content="text/html;?charset=UTF-8">
????????支付寶即時到賬交易接口
????
????${htmlStr?}
????
????
測試
頁面訪問:
localhost:8091/alipay/gotopay.json?orderId=232323
就可以看到支付頁面了;

編寫支付的異步通知接口
用戶支付完成之后支付寶會通過你配置的的notify_url的值進(jìn)行回調(diào),
我需要編寫這個邏輯,以完成整個的支付流程。
編寫controller層
/**
?*?阿里支付控制器
?*
?*?@author???WangSen([email protected])
?*?@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();
????}
}
編寫viewService層
/**
?*?阿里支付頁面服務(wù)類
?*?
?*?@author???WangSen([email protected])
?*?@Date?????2017年8月16日??????
?*/
@Service
public?class?AlipayViewService?{
????@Autowired
????private?NewAlipayBusinessService?newAlipayBusinessService;
????/**
?????*?支付完成
?????*
?????*?@throws?IOException?io異常
????*/
????public?void?payFinish()?throws?Exception?{
????????newAlipayBusinessService.payFinish();
????}
}
編寫處理支付完成的servie
/**
?*?新的阿里支付頁面服務(wù)類
?*?
?*?阿里升級接口之后使用這個服務(wù)類
?*?
?*?@author???WangSen([email protected])
?*?@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?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?請求參數(shù)??
?????*?@return?訂單id
????*/
????private?long?getOrderId(Map?params) ?{
????????String?order_no?=?params.get("out_trade_no");
????????return?ConvertUtil.obj2long(order_no);
????}
????/**
?????*?獲取總金額
?????*
?????*?@param?params?請求參數(shù)
?????*?@return?總金額
????*/
????private?long?getTotalFee(Map?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?params) ?throws?AlipayApiException?{
????????boolean?signVerified?=?AlipaySignature.rsaCheckV1(params,?alipayConfig.getAlipay_public_key(),
????????????????AlipayConfig.charset,?AlipayConfig.sign_type);?//調(diào)用SDK驗證簽名
????????if?(!signVerified)?{
????????????return?false;
????????}
????????//交易狀態(tài)
????????String?trade_status?=?params.get("trade_status");
????????if?(!trade_status.equals("TRADE_FINISHED")?&&?!trade_status.equals("TRADE_SUCCESS"))?{
????????????return?false;
????????}
????????return?true;
????}
????/**
?????*?成功
?????*
?????*?TODO?重構(gòu)方法名
?????*?@param?out?輸出流
????*/
????private?void?success(PrintWriter?out)?{
????????out.println("success");
????}
????/**
?????*?失敗
?????*
?????*?TODO?重構(gòu)方法名
?????*?@param?out?輸出流
????*/
????private?void?fail(PrintWriter?out)?{
????????out.println("fail");
????}
????/**
?????*?獲取參數(shù)
?????*
?????*?@param?request?HttpServletRequest對象
?????*?
?????*?@return?返回支付寶攜帶的參數(shù)
????*/
????private?Map?getParames(HttpServletRequest?request)? {
????????Map?params?=?new?HashMap();
????????@SuppressWarnings("unchecked")
????????Map?requestParams?=?request.getParameterMap();
????????for?(Iterator?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?????????????????valueStr?=?(i?==?values.length?-?1)???valueStr?+?values[i]?:?valueStr?+?values[i]?+?",";
????????????}
????????????//亂碼解決,這段代碼在出現(xiàn)亂碼時使用
????????????//valueStr?=?new?String(valueStr.getBytes("ISO-8859-1"),?"utf-8");
????????????params.put(name,?valueStr);
????????}
????????return?params;
????}
}
做的過程可能用到的資源
支付接口以及異步通知接口的參數(shù)詳解:
https://docs.open.alipay.com/270/105902/
生成公鑰私鑰的步驟:
https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=105971&docType=1
服務(wù)端的sdk:
https://docs.open.alipay.com/203/105910
即時到賬新老版本接口對比:
https://docs.open.alipay.com/270/106759
覺得本文對你有幫助?請分享給更多人
關(guān)注「全棧開發(fā)者社區(qū)」加星標(biāo),提升全棧技能
本公眾號會不定期給大家發(fā)福利,包括送書、學(xué)習(xí)資源等,敬請期待吧!
如果感覺推送內(nèi)容不錯,不妨右下角點個在看轉(zhuǎn)發(fā)朋友圈或收藏,感謝支持。
好文章,留言、點贊、在看和分享一條龍吧??
瀏覽
59
點擊上方[全棧開發(fā)者社區(qū)]→右上角[...]→[設(shè)為星標(biāo)?]

場景
最近在做支付寶的接口對接,之前做過一個版本,但是由于申請了新的賬號以前舊的的接口對接就不能使用了
所以就開始對接新的版本接口對接,在這里也記錄一下讓那些還沒有對接的兄弟少走點彎路。
準(zhǔn)備
先申請一個企業(yè)賬戶
https://memberprod.alipay.com/account/reg/enterpriseIndex.htm
創(chuàng)建應(yīng)用
去支付寶的開放平臺
https://open.alipay.com/platform/home.htm
添加應(yīng)用:
https://docs.open.alipay.com/200/105310
按照這個鏈接的文檔一步一步操作;
賬號準(zhǔn)備好之后,就可以了解相關(guān)的接口了,以(即時到賬)支付接口為例。
閱讀接口文檔
https://docs.open.alipay.com/270/alipay.trade.page.pay/
下載SDK
https://docs.open.alipay.com/54/103419
選擇java版本
將sdk集成進(jìn)入項目中
sdk中有一個jar包

將這個jar包上傳到私服上去。
參考這個:
http://blog.csdn.net/huchunlinnk/article/details/17789175
項目引入sdk中的關(guān)鍵jar包
這里的gav的寫法取決于你上傳私服的時候的填寫

????com.alipay
????alipay-api
????1.0.0
處理AlipayConfig對象
取消AlipayConfig配置文件中的部分常量
打開下載sdk應(yīng)該可以找到

將這個類中的前幾個靜態(tài)常量變成非靜態(tài)的,以便可以支持多個配置對象。
/*?*
?*類名:AlipayConfig
?*功能:基礎(chǔ)配置類
?*詳細(xì):設(shè)置帳戶有關(guān)信息及返回路徑
?*修改日期:2017-04-05
?*說明:
?*以下代碼只是為了方便商戶測試而提供的樣例代碼,商戶可以根據(jù)自己網(wǎng)站的需要,按照技術(shù)文檔編寫,并非一定要使用該代碼。
?*該代碼僅供學(xué)習(xí)和研究支付寶接口使用,只是提供一個參考。
?*/
@Data
public?class?AlipayConfig?{
????//↓↓↓↓↓↓↓↓↓↓請在這里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
????//?應(yīng)用ID,您的APPID,收款賬號既是您的APPID對應(yīng)支付寶賬號
????public?String?app_id?=?"";
????//?商戶私鑰,您的PKCS8格式RSA2私鑰
????public?String?merchant_private_key?=?"";
????//?支付寶公鑰,查看地址:https://openhome.alipay.com/platform/keyManage.htm 對應(yīng)APPID下的支付寶公鑰。
????public?String?alipay_public_key?=?"";
????//?服務(wù)器異步通知頁面路徑??需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
????public?String?notify_url?=?"";
????//?頁面跳轉(zhuǎn)同步通知頁面路徑?需http://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問
????public?String?return_url?=?"";
????//?簽名方式
????public?static?String?sign_type?=?"RSA2";
????//?字符編碼格式
????public?static?String?charset?=?"utf-8";
????//?支付寶網(wǎng)關(guān)
????public?static?String?gatewayUrl?=?"https://openapi.alipay.com/gateway.do";
????//日志路徑
????public?static?String?log_path?=?"C:\\";
}
編寫請求支付的接口
后端向支付寶發(fā)起支付的請求,在這個同時需要傳遞必要參數(shù),下面我們就來編寫如何向支付寶發(fā)起支付。
編寫conroller層
/**
?*?阿里支付控制器
?*
?*?@author???WangSen([email protected])
?*?@Date?????2017年8月16日??????
?*/
@Controller
@RequestMapping("/alipay")
public?class?AliPayController?{
????@Autowired
????private?AlipayViewService?alipayViewService;
????/**
?????*?跳轉(zhuǎn)到去支付的jsp頁面
?????*
?????*?@param?orderId?訂單號
?????*?
?????*?@param?payAccountType?支付賬號類型
?????*?
?????*?@param?model?模型
?????*?
?????*?@throws?Exception
????*/
????@RequestMapping
????public?void?gotopay(long?orderId,?Model?model)?throws?Exception?{
????????alipayViewService.setGoToPayInfo(orderId,?model);
????}
}
編寫viewService層
/**
?*?阿里支付頁面服務(wù)類
?*?
?*?@author???WangSen([email protected])
?*?@Date?????2017年8月16日??????
?*/
@Service
public?class?AlipayViewService?{
????@Autowired
????private?NewAlipayBusinessService?newAlipayBusinessService;
????/**
?????*?設(shè)置去支付信息
?????*?
?????*?@param?orderId?訂單id
?????*?@param?model?模型
?????*?@param?payAccountType?支付賬號類型
?????*?
?????*?@return?構(gòu)建的字符串
????*/
????public?void?setGoToPayInfo(long?orderId,?Model?model)?throws?Exception?{
????????model.addAttribute("htmlStr",?newAlipayBusinessService.buildPayRequest(orderId,?payPrice,?"報名費",?"略"));
????}
}
編寫service層
/**
?*?新的阿里支付頁面服務(wù)類
?*?
?*?阿里升級接口之后使用這個服務(wù)類
?*?
?*?@author???WangSen([email protected])
?*?@Date?????2017年8月16日??????
?*/
@Data
public?class?NewAlipayBusinessService?{
????/**
?????*?阿里的配置文件對象
?????*/
????private?AlipayConfig?alipayConfig;
????/**
?????*?構(gòu)建支付請求
?????*
?????*?@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();
????????//設(shè)置請求參數(shù)
????????String?bizContent?=?getBizContent(ConvertUtil.obj2str(orderId),?AmountUtils.changeF2Y(payPrice),?orderName,
????????????????body);
????????return?alipayClient.pageExecute(setAlipayRequestParameters(bizContent)).getBody();
????}
????/**
?????*?設(shè)置阿里支付請求參數(shù)
?????*
?????*?@param?bizContent?包含關(guān)鍵參數(shù)的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;
????}
????/**
?????*?獲取業(yè)務(wù)的關(guān)鍵內(nèi)容
?????*
?????*?@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文件配置支付對象
"1.0"?encoding="UTF-8"?>
"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">
????
????"alipayConfig"?class="com.we.business.pay.newalipay.config.AlipayConfig">
????????"app_id"?value="你的appId"/>
????????"merchant_private_key"?value="你的私鑰"/>
????????"alipay_public_key"?value="支付寶公鑰"/>
????????"notify_url"?value="支付完成的異步通知地址"/>
????????"return_url"?value="支付完成跳轉(zhuǎn)的地址"/>
????
????
????"newAlipayBusinessService"?class="com.we.business.pay.service.NewAlipayBusinessService">
????????"alipayConfig"?ref="alipayConfig"/>
????
?
編寫jsp頁面
<%@page?import="com.we.core.common.util.DateTimeUtil"%>
<%@?page?language="java"?contentType="text/html;?charset=UTF-8"?pageEncoding="UTF-8"%>
"-//W3C//DTD?HTML?4.01?Transitional//EN">
????
????????"Content-Type"?content="text/html;?charset=UTF-8">
????????支付寶即時到賬交易接口
????
????${htmlStr?}
????
????
測試
頁面訪問:
localhost:8091/alipay/gotopay.json?orderId=232323
就可以看到支付頁面了;

編寫支付的異步通知接口
用戶支付完成之后支付寶會通過你配置的的notify_url的值進(jìn)行回調(diào),
我需要編寫這個邏輯,以完成整個的支付流程。
編寫controller層
/**
?*?阿里支付控制器
?*
?*?@author???WangSen([email protected])
?*?@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();
????}
}
編寫viewService層
/**
?*?阿里支付頁面服務(wù)類
?*?
?*?@author???WangSen([email protected])
?*?@Date?????2017年8月16日??????
?*/
@Service
public?class?AlipayViewService?{
????@Autowired
????private?NewAlipayBusinessService?newAlipayBusinessService;
????/**
?????*?支付完成
?????*
?????*?@throws?IOException?io異常
????*/
????public?void?payFinish()?throws?Exception?{
????????newAlipayBusinessService.payFinish();
????}
}
編寫處理支付完成的servie
/**
?*?新的阿里支付頁面服務(wù)類
?*?
?*?阿里升級接口之后使用這個服務(wù)類
?*?
?*?@author???WangSen([email protected])
?*?@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?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?請求參數(shù)??
?????*?@return?訂單id
????*/
????private?long?getOrderId(Map?params) ?{
????????String?order_no?=?params.get("out_trade_no");
????????return?ConvertUtil.obj2long(order_no);
????}
????/**
?????*?獲取總金額
?????*
?????*?@param?params?請求參數(shù)
?????*?@return?總金額
????*/
????private?long?getTotalFee(Map?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?params) ?throws?AlipayApiException?{
????????boolean?signVerified?=?AlipaySignature.rsaCheckV1(params,?alipayConfig.getAlipay_public_key(),
????????????????AlipayConfig.charset,?AlipayConfig.sign_type);?//調(diào)用SDK驗證簽名
????????if?(!signVerified)?{
????????????return?false;
????????}
????????//交易狀態(tài)
????????String?trade_status?=?params.get("trade_status");
????????if?(!trade_status.equals("TRADE_FINISHED")?&&?!trade_status.equals("TRADE_SUCCESS"))?{
????????????return?false;
????????}
????????return?true;
????}
????/**
?????*?成功
?????*
?????*?TODO?重構(gòu)方法名
?????*?@param?out?輸出流
????*/
????private?void?success(PrintWriter?out)?{
????????out.println("success");
????}
????/**
?????*?失敗
?????*
?????*?TODO?重構(gòu)方法名
?????*?@param?out?輸出流
????*/
????private?void?fail(PrintWriter?out)?{
????????out.println("fail");
????}
????/**
?????*?獲取參數(shù)
?????*
?????*?@param?request?HttpServletRequest對象
?????*?
?????*?@return?返回支付寶攜帶的參數(shù)
????*/
????private?Map?getParames(HttpServletRequest?request)? {
????????Map?params?=?new?HashMap();
????????@SuppressWarnings("unchecked")
????????Map?requestParams?=?request.getParameterMap();
????????for?(Iterator?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?????????????????valueStr?=?(i?==?values.length?-?1)???valueStr?+?values[i]?:?valueStr?+?values[i]?+?",";
????????????}
????????????//亂碼解決,這段代碼在出現(xiàn)亂碼時使用
????????????//valueStr?=?new?String(valueStr.getBytes("ISO-8859-1"),?"utf-8");
????????????params.put(name,?valueStr);
????????}
????????return?params;
????}
}
做的過程可能用到的資源
支付接口以及異步通知接口的參數(shù)詳解:
https://docs.open.alipay.com/270/105902/
生成公鑰私鑰的步驟:
https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=105971&docType=1
服務(wù)端的sdk:
https://docs.open.alipay.com/203/105910
即時到賬新老版本接口對比:
https://docs.open.alipay.com/270/106759
覺得本文對你有幫助?請分享給更多人
關(guān)注「全棧開發(fā)者社區(qū)」加星標(biāo),提升全棧技能
本公眾號會不定期給大家發(fā)福利,包括送書、學(xué)習(xí)資源等,敬請期待吧!
如果感覺推送內(nèi)容不錯,不妨右下角點個在看轉(zhuǎn)發(fā)朋友圈或收藏,感謝支持。
好文章,留言、點贊、在看和分享一條龍吧??
