前台页面发起支付请求,后台调支付宝SDK提供的API,返回一个form表单到前台,前台直接发送支付请求,唤起支付宝支付页面
- //前台发起支付请求
- submits(){
- debugger
- const options = {
- method: 'POST',
- headers: { 'content-type': 'application/x-www-form-urlencoded' },
- url:'/pictureweb/alipay/pay',
- };
- axios(options).then((res)=>{
- debugger
- this.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
params = new HashMap (); - 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
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
params = new HashMap (); - 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
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置为1
- User 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置为1
- User 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置为3
- User user = new User();
- user.setOutTradeNo(out_trade_no);
- user.setFlag(3);
- userService.updateByOutTradeNo(user);
- }
- }
支付结果 - 支付确认中。。。。
- $(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)
- }
本文为企业推广,本网站不做任何建议,仅提供参考,作为信息展示!
推荐阅读:银川热线
网友评论
请登录后进行评论|
0条评论
请文明发言,还可以输入140字
您的评论已经发表成功,请等候审核
小提示:您要为您发表的言论后果负责,请各位遵守法纪注意语言文明