前言
支付寶支付—沙箱環境使用
支付寶支付-支付寶PC端掃碼支付「本文」
支付寶支付-手機瀏覽器H5支付
支付寶支付-當面付之掃碼支付javascript
PC端掃碼支付,其實就是就是 電腦網站支付,本文基於支付寶沙箱環境,不瞭解的能夠看一下上邊的連接。html
廢話很少說,直接進入主題。vue
Java支付項目實戰教程,包括支付寶,微信等支付方式,不看虧!下載運行測試Demo
官方Demo下載連接:電腦網站支付(Java)java
下載後導入 IDEA 中運行以下圖所示:express
若是在導入運行過程遇到錯誤,請參考這篇文章:IDEA中導入支付寶電腦網站支付測試Demo遇到的錯誤json
進行支付測試,注意付款要用沙箱環境提供的支付寶APK。後端
Maven項目中使用
pom.xml中引入支付寶sdk依賴api
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.1.0</version>
</dependency>
配置能夠單首創建一個類,靜態初始化參數:瀏覽器
public class AlipayConfig {
/** [沙箱環境]應用ID,您的APPID,收款帳號既是您的APPID對應支付寶帳號 **/
public static String app_id = "";
/** [沙箱環境]商戶私鑰,您的PKCS8格式RSA2私鑰 **/
public static String merchant_private_key = "";
/** [沙箱環境]支付寶公鑰,查看地址:https://openhome.alipay.com/platform/keyManage.htm 對應APPID下的支付寶公鑰。**/
public static String alipay_public_key = "";
/** [沙箱環境]服務器異步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數,必須外網能夠正常訪問 **/
public static String notify_url = "http://ngrok.sscai.club/alipay/aliPayNotify_url";
/** [沙箱環境]頁面跳轉同步通知頁面路徑 需http://格式的完整路徑,不能加?id=123這類自定義參數,必須外網能夠正常訪問 **/
public static String return_url = "http://ngrok.sscai.club/index.html#/alipay/success";
/** [沙箱環境] **/
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
}
至於接口啥的基本就是能夠參考上方運行的Demo了。服務器
簡單看看生成支付寶訂單「沒有使用開源SDK」。
@Transactional
public String alipayOrder(AlipayOrderRequest alipayOrderRequest) throws AlipayApiException {
/** 得到初始化的AlipayClient **/
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl,
AlipayConfig.app_id,
AlipayConfig.merchant_private_key,
"json",
AlipayConfig.charset,
AlipayConfig.alipay_public_key,
AlipayConfig.sign_type);
/** 設置請求參數 **/
String payType = alipayOrderRequest.getPayType();
/** page **/
AlipayTradePagePayRequest alipayPageRequest = new AlipayTradePagePayRequest();
alipayPageRequest.setReturnUrl(AlipayConfig.return_url);
alipayPageRequest.setNotifyUrl(AlipayConfig.notify_url);
/** 商戶訂單號,商戶網站訂單系統中惟一訂單號,必填 **/
String out_trade_no = alipayOrderRequest.getWidOutTradeNo();
/** 付款金額,必填 **/
String total_amount = alipayOrderRequest.getWidTotalFee();
/** 訂單名稱,必填 **/
String subject = alipayOrderRequest.getWidSubject();
/** 商品描述,可空 **/
String body = alipayOrderRequest.getWIDbody();
/** 拼接參數 **/
alipayPageRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
/** 發起請求 **/
return alipayClient.pageExecute(alipayPageRequest).getBody();
}
網站支付接口調用後返回的是一個 Form 表單,也就是 result 實際是一段 Html 代碼,而後把 result 傳給前段調用便可,下面是返回的 Form 的一個示例:
<form name="punchout_form" method="post" action="https://openapi.alipaydev.com/gateway.do?charset=UTF-8&method=alipay.trade.wap.pay&sign=xx&return_url=http%3A%2F%2Fngrok.sscai.club%2Falipay_trade_wap_pay_java_utf_8_war_exploded%2Freturn_url.jsp&notify_url=http%3A%2F%2Fngrok.sscai.club%2Falipay_trade_wap_pay_java_utf_8_war_exploded%2Fnotify_url.jsp&version=1.0&app_id=2016101700705301&sign_type=RSA2&timestamp=2020-01-08+14%3A09%3A58&alipay_sdk=alipay-sdk-java-3.3.0&format=json">
<input type="hidden" name="biz_content" value="{"body":"購買測試商品0.01元","out_trade_no":"20201814955421","product_code":"QUICK_WAP_WAY","subject":"電腦網站支付測試商品","timeout_express":"2m","total_amount":"0.01"}" />
<input type="submit" value="當即支付" style="display:none" />
</form>
怎麼調用呢?下面是一段我在vue中的測試代碼片斷,前段接收到後端返回的 Form 表單進行提交:
const div = document.createElement('div');
console.log("我是後端返回的數據:"+res.result)
div.innerHTML = res.result;
document.body.appendChild(div);
console.log("punchout_form:"+document.forms.punchout_form)
document.forms.punchout_form.submit();
支付成功後會自動重定向到配置的跳轉界面,由後端的的 return_url 參數控制。
再看看支付成功後的回調接口「沒有使用開源的SDK演示」:
public String alipaynotify(Model model, HttpServletRequest request) {
log.info("支付寶異步回調 ------------beg-----------");
String result = "fail";
/**獲取支付寶POST過來反饋信息**/
/* *
* 功能:支付寶服務器異步通知頁面
* 說明:
* 如下代碼只是爲了方便商戶測試而提供的樣例代碼,商戶能夠根據本身網站的須要,按照技術文檔編寫,並不是必定要使用該代碼。
* 該代碼僅供學習和研究支付寶接口使用,只是提供一個參考。
*/
Map<String, String> params=this.getAlipayRequest(request);
if(params == null || params.size()==0){
BufferedReader bufferReader = null;
StringBuilder sb = new StringBuilder();
try {
bufferReader = new BufferedReader(request.getReader());
String line = null;
while ((line = bufferReader.readLine()) != null) {
sb.append(new String(line.getBytes("ISO-8859-1"), "utf-8"));
}
} catch (IOException e) {
e.printStackTrace();
}
String body= null;
try {
body = URLDecoder.decode(sb.toString(),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
params=UriComponentsBuilder.newInstance().query(body).build().getQueryParams().toSingleValueMap();
}
boolean signVerified =false;
try {
signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
} catch (AlipayApiException e1) {
log.error("因爲"+e1.getErrMsg()+"返回給支付寶系統的結果result:fail");
model.addAttribute("result", "fail");
return result;
} /**調用SDK驗證簽名 **/
/**——請在這裏編寫您的程序(如下代碼僅做參考)——**/
/* 實際驗證過程建議商戶務必添加如下校驗:
一、須要驗證該通知數據中的out_trade_no是否爲商戶系統中建立的訂單號,
二、判斷total_amount是否確實爲該訂單的實際金額(即商戶訂單建立時的金額),
三、校驗通知中的seller_id(或者seller_email) 是否爲out_trade_no這筆單據的對應的操做方(有的時候,一個商戶可能有多個seller_id/seller_email)
四、驗證app_id是否爲該商戶自己。
*/
log.error("支付寶驗證簽名:---------------------------------"+signVerified);
if(signVerified) {/**驗證成功**/
/**商戶訂單號**/
/**交易狀態**/
log.info("支付寶異步回調驗籤成功!");
String trade_status = params.get("trade_status");
if("TRADE_FINISHED".equals(trade_status)){
/**判斷該筆訂單是否在商戶網站中已經作過處理**/
/**若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序**/
/**若是有作過處理,不執行商戶的業務程序**/
/**注意:**/
/**退款日期超過可退款期限後(如三個月可退款),支付寶系統發送該交易狀態通知**/
try {
/** 在這裏處理支付成功後的操做,好比修改訂單狀態等等**/
coding...
result = "success";
} catch (Exception e) {
log.error(e.getMessage());
result = "fail";
}
}else if ("TRADE_SUCCESS".equals(trade_status)){
/**判斷該筆訂單是否在商戶網站中已經作過處理**/
/**若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序**/
/**若是有作過處理,不執行商戶的業務程序**/
/**注意:**/
/**付款完成後,支付寶系統發送該交易狀態通知**/
try {
/** 在這裏處理支付成功後的操做,好比修改訂單狀態等等 **/
coding...
result = "success";
} catch (Exception e) {
log.error(e.getMessage());
result = "fail";
}
}else{
result = "fail";
}
}else {/**驗證失敗**/
result = "fail";
/**調試用,寫文本函數記錄程序運行狀況是否正常**/
/**String sWord = AlipaySignature.getSignCheckContentV1(params);**/
/**AlipayConfig.logResult(sWord);**/
log.debug("支付寶異步回調驗籤失敗");
}
log.debug("異步回調返回給支付寶系統的結果result:"+result);
model.addAttribute("result", result);
log.info("支付寶異步回調 -------------end ------------");
return result;
}
該方法返回給支付寶的 result 就 success、fail 兩個結果。
從以上看來,其實不難發現支付寶支付是很是簡單的,儘管我上邊貼了大量的代碼,其實採用開源SDK的話能夠更加縮減、美化一些。
ok,這篇文章就到這結束了,上邊並無詳細介紹接口調用、參數說明等,詳細介紹請查看官方文檔:https://docs.open.alipay.com/270/105902/
官方測試Demo下載
上方可運行的官方支付Demo:https://www.lanzous.com/i8qjxij
求關注,求推薦
博客地址:https://www.cnblogs.com/niceyoo
求關注❤️,求推薦????,若是以爲這篇文章有點東西,不妨左上角關注一下我。