Java開發(fā)支付寶PC支付完整版
一:準(zhǔn)備工作
1:如沒有賬號的請先去 支付寶商戶平臺 注冊商戶號
2:開發(fā)前需要導(dǎo)入支付寶SDK 支付寶SDK下載鏈接 Maven依賴也在里面
3:生成支付寶密鑰、公鑰,需要用到支付寶密鑰生成工具 密鑰生成工具下載鏈接 ,密鑰用于簽名使用
4:電腦網(wǎng)站支付結(jié)果異步通知(關(guān)于支付結(jié)果異步通知后續(xù)會專門寫一個博客,需要重點(diǎn)注意)
注意:請先詳細(xì)查看官方文檔按步驟開發(fā),一切以官方文檔為主 支付寶官方開發(fā)文檔,如使用老接口請移步 老版即時到賬文檔
5:測試的時候一定要使用內(nèi)網(wǎng)穿透軟件,否則會報(bào)錯
二:開發(fā)代碼
博主使用的是沙箱環(huán)境,正式上線時請將環(huán)境改為正式環(huán)境
AlipayConfig:
public class AlipayConfig { public static String APPID = ""; //用支付寶密鑰生成工具生成的私鑰 public static String RSA_PRIVATE_KEY = ""; //電腦網(wǎng)站支付結(jié)果異步通知,可以參考異步文檔,一定要是外網(wǎng)能訪問的 public static String notify_url = ""; //電腦網(wǎng)站支付結(jié)果同步通知,用于轉(zhuǎn)跳到用戶自己的頁面,一定要是外網(wǎng)能訪問的 public static String return_url = ""; //沙箱接口,正式上線時請改用正式支付接口 public static String URL = "https://openapi.alipaydev.com/gateway.do"; public static String CHARSET = "UTF-8"; public static String FORMAT = "json"; //用支付寶密鑰生成工具生成的公鑰 public static String ALIPAY_PUBLIC_KEY = ""; public static String log_path = "/log"; public static String SIGNTYPE = "RSA2"; public AlipayConfig() { } }
AlipayService:
public interface AlipayService { public String toAlipay(Map<String, String> sourceMap) throws IOException; }
AlipayServiceImpl:
@Service public class AlipayServiceImpl implements AlipayService { @Override public String toAlipay(Map<String, String> sourceMap) throws IOException { AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL,AlipayConfig.APPID,AlipayConfig.RSA_PRIVATE_KEY,AlipayConfig.FORMAT,AlipayConfig.CHARSET,AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE); AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); alipayRequest.setReturnUrl(AlipayConfig.return_url); alipayRequest.setNotifyUrl(AlipayConfig.notify_url); AlipayTradeWapPayModel alipayTradeWapPayModel = new AlipayTradeWapPayModel(); alipayTradeWapPayModel.setOutTradeNo(sourceMap.get("out_trade_no")); alipayTradeWapPayModel.setProductCode("FAST_INSTANT_TRADE_PAY"); alipayTradeWapPayModel.setTotalAmount(sourceMap.get("total_amount")); alipayTradeWapPayModel.setSubject("Alipay"); alipayTradeWapPayModel.setBody(sourceMap.get("body")); alipayRequest.setBizModel(alipayTradeWapPayModel); String form=""; try { form = alipayClient.pageExecute(alipayRequest).getBody(); } catch (AlipayApiException e) { e.printStackTrace(); } return form; } }
AlipayController:
@Controller public class AlipayController { @Autowired public AlipayService alipayService; @RequestMapping("pay") public void toAlipay(HttpServletRequest httpRequest , HttpServletResponse httpResponse, String payId, String totalFee, String body) throws IOException { //生成一筆支付記錄,支付完成時將支付狀態(tài)改為成功 Map<String, String> sourceMap = new HashMap<>(); sourceMap.put("out_trade_no",payId); sourceMap.put("total_amount",totalFee); sourceMap.put("body",getUTF8XMLString(body)); String form = alipayService.toAlipay(sourceMap); httpResponse.setContentType("text/html;charset=" + AlipayConfig.CHARSET); httpResponse.getWriter().write(form); httpResponse.getWriter().flush(); httpResponse.getWriter().close(); } //注意異步返回結(jié)果通知是以post請求形式返回的 @RequestMapping("notifyUrl") public String notify_url(HttpServletRequest request){ Map<String, String> paramsMap = convertRequestParamsToMap(request); String out_trade_no= paramsMap.get("out_trade_no"); try { boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE); //無論同步異步都要驗(yàn)證簽名 if(signVerified){ if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")){ //處理自己系統(tǒng)的業(yè)務(wù)邏輯,如:將支付記錄狀態(tài)改為成功,需要返回一個字符串success告知支付寶服務(wù)器 return "success"; } else { //支付失敗不處理業(yè)務(wù)邏輯 return "failure"; } }else { //簽名驗(yàn)證失敗不處理業(yè)務(wù)邏輯 return "failure"; } } catch (AlipayApiException e) { e.printStackTrace(); return "failure"; } } //注意同步返回結(jié)果是以get請求形式返回的 @RequestMapping("returnUrl") public String return_url(HttpServletRequest request){ Map<String, String> paramsMap = convertRequestParamsToMap(request); try { boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE); if(signVerified){ //跳轉(zhuǎn)支付成功界面 return "支付成功頁面"; }else { //跳轉(zhuǎn)支付失敗界面 return "failure"; } } catch (AlipayApiException e) { e.printStackTrace(); } return "success"; } //將請求中的參數(shù)轉(zhuǎn)換為Map public static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) { Map<String, String> retMap = new HashMap(); Set<Entry<String, String[]>> entrySet = request.getParameterMap().entrySet(); Iterator var3 = entrySet.iterator(); while(true) { while(var3.hasNext()) { Entry<String, String[]> entry = (Entry)var3.next(); String name = (String)entry.getKey(); String[] values = (String[])entry.getValue(); int valLen = values.length; if(valLen == 1) { retMap.put(name, values[0]); } else if(valLen <= 1) { retMap.put(name, ""); } else { StringBuilder sb = new StringBuilder(); String[] var9 = values; int var10 = values.length; for(int var11 = 0; var11 < var10; ++var11) { String val = var9[var11]; sb.append(",").append(val); } retMap.put(name, sb.toString().substring(1)); } } return retMap; } } //將字符串轉(zhuǎn)換為UTF-8編碼以防出現(xiàn)亂碼錯誤 public static String getUTF8XMLString(String xml) { StringBuffer sb = new StringBuffer(); sb.append(xml); String xmString = ""; String xmlUTF8=""; try { xmString = new String(sb.toString().getBytes("UTF-8")); xmlUTF8 = URLEncoder.encode(xmString, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return xmlUTF8; } }
至此代碼已經(jīng)完成?。?!
三:演示結(jié)果
注意:掃碼或者登陸賬戶時如果用的是沙箱開發(fā)環(huán)境請使用沙盒支付寶APP掃碼,或者使用沙盒賬戶支付,否則會彈出碼已失效錯誤
支付成功頁面是從支付結(jié)果同步通知controller中跳轉(zhuǎn)的,后續(xù)會更新最詳細(xì)最完整的微信Navicat支付跟PayPal支付,有興趣請關(guān)注博主
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解java集成支付寶支付接口(JSP+支付寶20160912)
- java后臺實(shí)現(xiàn)支付寶支付接口和支付寶訂單查詢接口(前端為APP)
- Java實(shí)現(xiàn)支付寶之第三方支付寶即時到賬支付功能
- java實(shí)現(xiàn)在SSM下使用支付寶掃碼支付功能
- java后臺實(shí)現(xiàn)支付寶對賬功能的示例代碼
- Java判斷瀏覽器是微信還是支付寶
- 微信、支付寶二碼合一掃碼支付實(shí)現(xiàn)思路(java)
- java實(shí)現(xiàn)支付寶退款功能
- 支付寶APP支付(IOS手機(jī)端+java后臺)版
- Java接入支付寶授權(quán)第三方登錄的完整步驟
相關(guān)文章
java中request對象各種方法的使用實(shí)例分析
這篇文章主要介紹了java中request對象各種方法的使用,結(jié)合完整實(shí)例形式較為詳細(xì)的分析了request對象的功能及其常用方法的使用技巧,需要的朋友可以參考下2015-12-12SpringBoot實(shí)現(xiàn)微信及QQ綁定登錄的示例代碼
本文主要介紹了SpringBoot實(shí)現(xiàn)微信及QQ綁定登錄的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07Java使用Hutool實(shí)現(xiàn)AES、DES加密解密的方法
本篇文章主要介紹了Java使用Hutool實(shí)現(xiàn)AES、DES加密解密的方法,具有一定的參考價值,有興趣的可以了解一下2017-08-08spring boot搭建文件服務(wù)器解決同時上傳多個圖片和下載的問題
這篇文章主要介紹了spring boot搭建文件服務(wù)器解決同時上傳多個圖片和下載的問題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-11-11spring aop之@AfterReturning不生效問題及解決
這篇文章主要介紹了spring aop之@AfterReturning不生效問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05Java反射學(xué)習(xí) getClass()函數(shù)應(yīng)用
所謂反射,可以理解為在運(yùn)行時期獲取對象類型信息的操作,本文將詳細(xì)介紹,需要的朋友可以參考下2012-12-12Mybatis注解方式操作Oracle數(shù)據(jù)庫詳解
這篇文章主要介紹了Mybatis注解方式操作Oracle數(shù)據(jù)庫詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11