Java開(kāi)發(fā)支付寶PC支付完整版
一:準(zhǔn)備工作
1:如沒(méi)有賬號(hào)的請(qǐng)先去 支付寶商戶平臺(tái) 注冊(cè)商戶號(hào)
2:開(kāi)發(fā)前需要導(dǎo)入支付寶SDK 支付寶SDK下載鏈接 Maven依賴也在里面
3:生成支付寶密鑰、公鑰,需要用到支付寶密鑰生成工具 密鑰生成工具下載鏈接 ,密鑰用于簽名使用
4:電腦網(wǎng)站支付結(jié)果異步通知(關(guān)于支付結(jié)果異步通知后續(xù)會(huì)專門寫一個(gè)博客,需要重點(diǎn)注意)
注意:請(qǐng)先詳細(xì)查看官方文檔按步驟開(kāi)發(fā),一切以官方文檔為主 支付寶官方開(kāi)發(fā)文檔,如使用老接口請(qǐng)移步 老版即時(shí)到賬文檔
5:測(cè)試的時(shí)候一定要使用內(nèi)網(wǎng)穿透軟件,否則會(huì)報(bào)錯(cuò)
二:開(kāi)發(fā)代碼
博主使用的是沙箱環(huán)境,正式上線時(shí)請(qǐng)將環(huán)境改為正式環(huán)境
AlipayConfig:
public class AlipayConfig {
public static String APPID = "";
//用支付寶密鑰生成工具生成的私鑰
public static String RSA_PRIVATE_KEY = "";
//電腦網(wǎng)站支付結(jié)果異步通知,可以參考異步文檔,一定要是外網(wǎng)能訪問(wèn)的
public static String notify_url = "";
//電腦網(wǎng)站支付結(jié)果同步通知,用于轉(zhuǎn)跳到用戶自己的頁(yè)面,一定要是外網(wǎng)能訪問(wèn)的
public static String return_url = "";
//沙箱接口,正式上線時(shí)請(qǐng)改用正式支付接口
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 {
//生成一筆支付記錄,支付完成時(shí)將支付狀態(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請(qǐng)求形式返回的
@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);
//無(wú)論同步異步都要驗(yàn)證簽名
if(signVerified){
if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")){
//處理自己系統(tǒng)的業(yè)務(wù)邏輯,如:將支付記錄狀態(tài)改為成功,需要返回一個(gè)字符串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請(qǐng)求形式返回的
@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 "支付成功頁(yè)面";
}else {
//跳轉(zhuǎn)支付失敗界面
return "failure";
}
} catch (AlipayApiException e) {
e.printStackTrace();
}
return "success";
}
//將請(qǐng)求中的參數(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)亂碼錯(cuò)誤
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)完成!?。?/p>
三:演示結(jié)果
注意:掃碼或者登陸賬戶時(shí)如果用的是沙箱開(kāi)發(fā)環(huán)境請(qǐng)使用沙盒支付寶APP掃碼,或者使用沙盒賬戶支付,否則會(huì)彈出碼已失效錯(cuò)誤



支付成功頁(yè)面是從支付結(jié)果同步通知controller中跳轉(zhuǎn)的,后續(xù)會(huì)更新最詳細(xì)最完整的微信Navicat支付跟PayPal支付,有興趣請(qǐng)關(guān)注博主
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解java集成支付寶支付接口(JSP+支付寶20160912)
- java后臺(tái)實(shí)現(xiàn)支付寶支付接口和支付寶訂單查詢接口(前端為APP)
- Java實(shí)現(xiàn)支付寶之第三方支付寶即時(shí)到賬支付功能
- java實(shí)現(xiàn)在SSM下使用支付寶掃碼支付功能
- java后臺(tái)實(shí)現(xiàn)支付寶對(duì)賬功能的示例代碼
- Java判斷瀏覽器是微信還是支付寶
- 微信、支付寶二碼合一掃碼支付實(shí)現(xiàn)思路(java)
- java實(shí)現(xiàn)支付寶退款功能
- 支付寶APP支付(IOS手機(jī)端+java后臺(tái))版
- Java接入支付寶授權(quán)第三方登錄的完整步驟
相關(guān)文章
Java 多線程同步 鎖機(jī)制與synchronized深入解析
從尺寸上講,同步代碼塊比同步方法小。你可以把同步代碼塊看成是沒(méi)上鎖房間里的一塊用帶鎖的屏風(fēng)隔開(kāi)的空間2013-09-09
Java完全二叉樹(shù)的創(chuàng)建與四種遍歷方法分析
這篇文章主要介紹了Java完全二叉樹(shù)的創(chuàng)建與四種遍歷方法,結(jié)合實(shí)例形式分析了完全二叉樹(shù)的概念、定義及遍歷操作相關(guān)實(shí)現(xiàn)技巧,并對(duì)比分析了滿二叉樹(shù)與完全二叉樹(shù)的區(qū)別,需要的朋友可以參考下2017-11-11
使用Jenkins Pipeline自動(dòng)化構(gòu)建發(fā)布Java項(xiàng)目的方法
這篇文章主要介紹了使用Jenkins Pipeline自動(dòng)化構(gòu)建發(fā)布Java項(xiàng)目的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-04-04
SpringBoot使用異步線程池實(shí)現(xiàn)生產(chǎn)環(huán)境批量數(shù)據(jù)推送
本文主要介紹了SpringBoot使用異步線程池實(shí)現(xiàn)生產(chǎn)環(huán)境批量數(shù)據(jù)推送,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02
Java JDK動(dòng)態(tài)代理在攔截器和聲明式接口中的應(yīng)用小結(jié)
Java動(dòng)態(tài)代理技術(shù)通過(guò)反射機(jī)制在運(yùn)行時(shí)動(dòng)態(tài)生成代理類,實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象方法的攔截和增強(qiáng),本文給大家介紹Java JDK動(dòng)態(tài)代理在攔截器和聲明式接口中的應(yīng)用小結(jié),感興趣的朋友跟隨小編一起看看吧2025-01-01

