支付宝手机网站支付开发详细流程
生活随笔
收集整理的這篇文章主要介紹了
支付宝手机网站支付开发详细流程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
首先創建調用支付寶支付接口的配置類
public class AlipayConfig {// 商戶appidpublic static String APPID = "";// 私鑰 pkcs8格式的public static String RSA_PRIVATE_KEY = "";// 服務器異步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問public static String notify_url = "http://yourwebsite/alipay/notify";// 頁面跳轉同步通知頁面路徑 需http://或者https://格式的完整路徑,不能加?id=123這類自定義參數,必須外網可以正常訪問 商戶可以自定義同步跳轉地址public static String return_url = "http://yourwebsite/alipay/returnurl";// 請求網關地址//public static String URL = "https://openapi.alipay.com/gateway.do";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 = "/paylog";// RSA2public static String SIGNTYPE = "RSA2"; }前臺頁面發起支付請求,后臺調支付寶SDK提供的API,返回一個form表單到前臺,前臺直接發送支付請求,喚起支付寶支付頁面
//前臺發起支付請求 submits(){debuggerconst options = {method: 'POST',headers: { 'content-type': 'application/x-www-form-urlencoded' },url:'/pictureweb/alipay/pay',};axios(options).then((res)=>{debuggerthis.showSubmitPage = false;const form = res.data;const div = document.createElement('div');div.id = 'alipay';div.innerHTML = form;document.body.appendChild(div);document.querySelector('#alipay').children[0].submit(); // 執行后會喚起支付寶})}, @PostMapping("/pay")public void pay(HttpServletRequest request, HttpServletResponse response) throws Exception {// 商戶訂單號,商戶網站訂單系統中唯一訂單號,必填String out_trade_no = UUID.randomUUID().toString();logger.debug("========>1,生成的out_trade_no為"+out_trade_no+"<===========");//user表增加訂單號String userName = (String) request.getAttribute("userName");User user = new User();user.setUserName(userName);user.setOutTradeNo(out_trade_no);user.setFlag(0);userService.updateByUserName(user);// 訂單名稱,必填String subject = "測試";// 付款金額,必填String total_amount = "1";// 商品描述,可空String body = "測試";// 超時時間 可空String timeout_express = "2m";// 銷售產品碼 必填String product_code = "QUICK_WAP_PAY";/**********************/// SDK 公共請求類,包含公共請求參數,以及封裝了簽名與驗簽,開發者無需關注簽名與驗簽//調用RSA簽名方式AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();// 封裝請求支付信息AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();model.setOutTradeNo(out_trade_no);model.setSubject(subject);model.setTotalAmount(total_amount);model.setBody(body);model.setTimeoutExpress(timeout_express);model.setProductCode(product_code);alipay_request.setBizModel(model);// 設置異步通知地址alipay_request.setNotifyUrl(AlipayConfig.notify_url);// 設置同步地址alipay_request.setReturnUrl(AlipayConfig.return_url);// form表單生產String form = "";try {// 調用SDK生成表單form = client.pageExecute(alipay_request).getBody();response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);response.getWriter().write(form);//直接將完整的表單html輸出到頁面response.getWriter().flush();response.getWriter().close();} catch (AlipayApiException e) {e.printStackTrace();}}?
return_url配置的是支付成功后的同步回調路徑,也就是支付成功后,支付寶要訪問的你的服務器路徑,這個路徑必須是外網可以訪問的,這樣支付寶才能調的通。可以在這個回調函數中做一些處理后跳轉到一個頁面,比如下面代碼所示,驗證成功后,跳轉到paysuccess.html頁面。
@GetMapping("/returnurl")public void returnUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {//獲取支付寶GET過來反饋信息Map<String, String> params = new HashMap<String, String>();Map requestParams = request.getParameterMap();for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {String name = (String) iter.next();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] + ",";}//亂碼解決,這段代碼在出現亂碼時使用。如果mysign和sign不相等也可以使用這段代碼轉化valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");params.put(name, valueStr);}//獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以下僅供參考)////商戶訂單號String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");//支付寶交易號String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");//獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以上僅供參考)////計算得出通知驗證結果//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");if (verify_result) {//驗證成功////請在這里加上商戶的業務邏輯程序代碼//驗證成功跳轉到前臺支付結果頁面response.sendRedirect("http://ip:port/paysuccess.html?out_trade_no="+out_trade_no);//——請根據您的業務邏輯來編寫程序(以上代碼僅作參考)——//} else {//該頁面可做頁面美工編輯response.sendRedirect("http://ip:port/payfail.html");}}在這個paysuccess.html頁面中可以每幾秒去查詢下自己的數據庫中訂單的狀態,這個狀態是支付寶通過異步回調notify_url配置的路徑來修改的,當支付寶修改了訂單狀態,前臺頁面查詢到后即可跳轉到一個指定頁面,支付完成。
@PostMapping("/notify")public void notify(HttpServletRequest request, HttpServletResponse response) throws Exception {//獲取支付寶POST過來反饋信息Map<String, String> params = new HashMap<String, String>();Map requestParams = request.getParameterMap();for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {String name = (String) iter.next();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] + ",";}//亂碼解決,這段代碼在出現亂碼時使用。如果mysign和sign不相等也可以使用這段代碼轉化//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");params.put(name, valueStr);}//獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以下僅供參考)////商戶訂單號String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");//支付寶交易號String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");//交易狀態String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");//獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以上僅供參考)////計算得出通知驗證結果//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");if (verify_result) {//驗證成功////請在這里加上商戶的業務邏輯程序代碼//——請根據您的業務邏輯來編寫程序(以下代碼僅作參考)——if (trade_status.equals("TRADE_FINISHED")) {logger.debug("========>2,交易狀態為TRADE_FINISHED,out_trade_no為"+out_trade_no+"<===========");//支付成功,user表flag置為1User user = new User();user.setOutTradeNo(out_trade_no);user.setFlag(1);userService.updateByOutTradeNo(user);//判斷該筆訂單是否在商戶網站中已經做過處理//如果沒有做過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,并執行商戶的業務程序//請務必判斷請求時的total_fee、seller_id與通知時獲取的total_fee、seller_id為一致的//如果有做過處理,不執行商戶的業務程序//注意://如果簽約的是可退款協議,退款日期超過可退款期限后(如三個月可退款),支付寶系統發送該交易狀態通知//如果沒有簽約可退款協議,那么付款完成后,支付寶系統發送該交易狀態通知。} else if (trade_status.equals("TRADE_SUCCESS")) {logger.debug("========>2,交易狀態為TRADE_SUCCESS,out_trade_no為"+out_trade_no+"<===========");//支付成功,user表flag置為1User user = new User();user.setOutTradeNo(out_trade_no);user.setFlag(1);userService.updateByOutTradeNo(user);//判斷該筆訂單是否在商戶網站中已經做過處理//如果沒有做過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,并執行商戶的業務程序//請務必判斷請求時的total_fee、seller_id與通知時獲取的total_fee、seller_id為一致的//如果有做過處理,不執行商戶的業務程序//注意://如果簽約的是可退款協議,那么付款完成后,支付寶系統發送該交易狀態通知。}//——請根據您的業務邏輯來編寫程序(以上代碼僅作參考)——//} else {//驗證失敗//驗證失敗,user表flag置為3User user = new User();user.setOutTradeNo(out_trade_no);user.setFlag(3);userService.updateByOutTradeNo(user);}} <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>支付結果</title><script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> </head> <body> <h1 id="result">支付確認中。。。。 </h1> </body> <script>$(function () {let out_trade_no = getUrlParam("out_trade_no")window.setInterval(function () {$.ajax({url: "/pictureweb/user/queryFlag",type: 'GET',async: false,cache: false,data:{outTradeNo:out_trade_no},contentType:"application/x-www-form-urlencoded",dataType: 'json',timeout: 60000,success: function (responseObj) {if(responseObj.code=="1"){$("#result").text("");$("#result").text("支付成功,5秒后跳回首頁");sessionStorage.setItem("ifPayed","已支付");goForwardToIndex();}},error: function (errMsg) {$("#result").text("支付失敗");goForwardToIndex();}});}, 5000)})getUrlParam = function (name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //構造一個含有目標參數的正則表達式對象var r = window.location.search.substr(1).match(reg); //匹配目標參數if (r != null) return unescape(r[2]); return null; //返回參數值}goForwardToIndex = function () {window.setTimeout(function () {window.location.href="./index.html"},5000)} </script> </html>分享一些技術學習視頻資料:https://pan.baidu.com/s/13dbR69NLIEyP1tQyRTl4xw
總結
以上是生活随笔為你收集整理的支付宝手机网站支付开发详细流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从wolai转移到Notion
- 下一篇: 六、Java中常用的API(通过包进行分