支付宝手机网站支付开发详细流程
生活随笔
收集整理的這篇文章主要介紹了
支付宝手机网站支付开发详细流程
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
首先創(chuàng)建調(diào)用支付寶支付接口的配置類
public class AlipayConfig {// 商戶appidpublic static String APPID = "";// 私鑰 pkcs8格式的public static String RSA_PRIVATE_KEY = "";// 服務(wù)器異步通知頁面路徑 需http://或者h(yuǎn)ttps://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問public static String notify_url = "http://yourwebsite/alipay/notify";// 頁面跳轉(zhuǎn)同步通知頁面路徑 需http://或者h(yuǎn)ttps://格式的完整路徑,不能加?id=123這類自定義參數(shù),必須外網(wǎng)可以正常訪問 商戶可以自定義同步跳轉(zhuǎn)地址public static String return_url = "http://yourwebsite/alipay/returnurl";// 請求網(wǎng)關(guān)地址//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"; }前臺頁面發(fā)起支付請求,后臺調(diào)支付寶SDK提供的API,返回一個form表單到前臺,前臺直接發(fā)送支付請求,喚起支付寶支付頁面
//前臺發(fā)起支付請求 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(); // 執(zhí)行后會喚起支付寶})}, @PostMapping("/pay")public void pay(HttpServletRequest request, HttpServletResponse response) throws Exception {// 商戶訂單號,商戶網(wǎng)站訂單系統(tǒng)中唯一訂單號,必填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";// 銷售產(chǎn)品碼 必填String product_code = "QUICK_WAP_PAY";/**********************/// SDK 公共請求類,包含公共請求參數(shù),以及封裝了簽名與驗(yàn)簽,開發(fā)者無需關(guān)注簽名與驗(yàn)簽//調(diào)用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);// 設(shè)置異步通知地址alipay_request.setNotifyUrl(AlipayConfig.notify_url);// 設(shè)置同步地址alipay_request.setReturnUrl(AlipayConfig.return_url);// form表單生產(chǎn)String form = "";try {// 調(diào)用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配置的是支付成功后的同步回調(diào)路徑,也就是支付成功后,支付寶要訪問的你的服務(wù)器路徑,這個路徑必須是外網(wǎng)可以訪問的,這樣支付寶才能調(diào)的通??梢栽谶@個回調(diào)函數(shù)中做一些處理后跳轉(zhuǎn)到一個頁面,比如下面代碼所示,驗(yàn)證成功后,跳轉(zhuǎn)到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] + ",";}//亂碼解決,這段代碼在出現(xiàn)亂碼時使用。如果mysign和sign不相等也可以使用這段代碼轉(zhuǎn)化valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");params.put(name, valueStr);}//獲取支付寶的通知返回參數(shù),可參考技術(shù)文檔中頁面跳轉(zhuǎn)同步通知參數(shù)列表(以下僅供參考)////商戶訂單號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");//獲取支付寶的通知返回參數(shù),可參考技術(shù)文檔中頁面跳轉(zhuǎn)同步通知參數(shù)列表(以上僅供參考)////計算得出通知驗(yàn)證結(jié)果//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) {//驗(yàn)證成功////請?jiān)谶@里加上商戶的業(yè)務(wù)邏輯程序代碼//驗(yàn)證成功跳轉(zhuǎn)到前臺支付結(jié)果頁面response.sendRedirect("http://ip:port/paysuccess.html?out_trade_no="+out_trade_no);//——請根據(jù)您的業(yè)務(wù)邏輯來編寫程序(以上代碼僅作參考)——//} else {//該頁面可做頁面美工編輯response.sendRedirect("http://ip:port/payfail.html");}}在這個paysuccess.html頁面中可以每幾秒去查詢下自己的數(shù)據(jù)庫中訂單的狀態(tài),這個狀態(tài)是支付寶通過異步回調(diào)notify_url配置的路徑來修改的,當(dāng)支付寶修改了訂單狀態(tài),前臺頁面查詢到后即可跳轉(zhuǎn)到一個指定頁面,支付完成。
@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] + ",";}//亂碼解決,這段代碼在出現(xiàn)亂碼時使用。如果mysign和sign不相等也可以使用這段代碼轉(zhuǎn)化//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");params.put(name, valueStr);}//獲取支付寶的通知返回參數(shù),可參考技術(shù)文檔中頁面跳轉(zhuǎn)同步通知參數(shù)列表(以下僅供參考)////商戶訂單號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");//交易狀態(tài)String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");//獲取支付寶的通知返回參數(shù),可參考技術(shù)文檔中頁面跳轉(zhuǎn)同步通知參數(shù)列表(以上僅供參考)////計算得出通知驗(yàn)證結(jié)果//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) {//驗(yàn)證成功////請?jiān)谶@里加上商戶的業(yè)務(wù)邏輯程序代碼//——請根據(jù)您的業(yè)務(wù)邏輯來編寫程序(以下代碼僅作參考)——if (trade_status.equals("TRADE_FINISHED")) {logger.debug("========>2,交易狀態(tài)為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);//判斷該筆訂單是否在商戶網(wǎng)站中已經(jīng)做過處理//如果沒有做過處理,根據(jù)訂單號(out_trade_no)在商戶網(wǎng)站的訂單系統(tǒng)中查到該筆訂單的詳細(xì),并執(zhí)行商戶的業(yè)務(wù)程序//請務(wù)必判斷請求時的total_fee、seller_id與通知時獲取的total_fee、seller_id為一致的//如果有做過處理,不執(zhí)行商戶的業(yè)務(wù)程序//注意://如果簽約的是可退款協(xié)議,退款日期超過可退款期限后(如三個月可退款),支付寶系統(tǒng)發(fā)送該交易狀態(tài)通知//如果沒有簽約可退款協(xié)議,那么付款完成后,支付寶系統(tǒng)發(fā)送該交易狀態(tài)通知。} else if (trade_status.equals("TRADE_SUCCESS")) {logger.debug("========>2,交易狀態(tài)為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);//判斷該筆訂單是否在商戶網(wǎng)站中已經(jīng)做過處理//如果沒有做過處理,根據(jù)訂單號(out_trade_no)在商戶網(wǎng)站的訂單系統(tǒng)中查到該筆訂單的詳細(xì),并執(zhí)行商戶的業(yè)務(wù)程序//請務(wù)必判斷請求時的total_fee、seller_id與通知時獲取的total_fee、seller_id為一致的//如果有做過處理,不執(zhí)行商戶的業(yè)務(wù)程序//注意://如果簽約的是可退款協(xié)議,那么付款完成后,支付寶系統(tǒng)發(fā)送該交易狀態(tài)通知。}//——請根據(jù)您的業(yè)務(wù)邏輯來編寫程序(以上代碼僅作參考)——//} else {//驗(yàn)證失敗//驗(yàn)證失敗,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>支付結(jié)果</title><script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> </head> <body> <h1 id="result">支付確認(rèn)中。。。。 </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 + "=([^&]*)(&|$)"); //構(gòu)造一個含有目標(biāo)參數(shù)的正則表達(dá)式對象var r = window.location.search.substr(1).match(reg); //匹配目標(biāo)參數(shù)if (r != null) return unescape(r[2]); return null; //返回參數(shù)值}goForwardToIndex = function () {window.setTimeout(function () {window.location.href="./index.html"},5000)} </script> </html>分享一些技術(shù)學(xué)習(xí)視頻資料:https://pan.baidu.com/s/13dbR69NLIEyP1tQyRTl4xw
總結(jié)
以上是生活随笔為你收集整理的支付宝手机网站支付开发详细流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从wolai转移到Notion
- 下一篇: 安全生产双重预防体系建设数字化解决方案