锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

JavaWeb-仿小米商场(8) 订单支付[沙箱支付]

时间:2022-10-20 20:00:00 dyc1型气压传感器

JavaWeb-模仿小米商场(8) 订单支付[沙箱支付]

1 功能描述

接上篇 JavaWeb - 仿小米商城(7)

点击支付宝支付按钮完成相应的支付操作 沙箱支付的逻辑可以通过使用支付宝沙箱支付来模拟用户支付

参考博客:https://blog.csdn.net/hhb442/article/details/123304287

支付提示界面:点击提交页面时,将订单数据存储在数据表中

在这里插入图片描述

付款成功可以通过我的订单查看订单

2 提交订单功能分析

2.1 抽象的功能逻辑

当商品购物车点击生成订单时,首先判断用户是否登录。如果用户没有登录,用户需要先完成登录 ,然后从购物车获取用户对象session根据购物车数据创建订单对象和订单细节列表list集合

商品购物车是面向数据库中的 tb_order表和订单细节表tb_orderDetail,将数据添加到数据库中对应的表中,

建立相应的购物车 CartServlet 类、CartService 接口和实现类,CartDao 接口和实现类。

建立相应的订单 OrderServlet 类、OrderService 接口和实现类、OrderDao 接口和实现类。

订单细节对应 OrderDetailServlet 类、OrderDetailService 接口和实现类,OrderDetailDao 接口和实现类。

提示:好需要创建辅助设备vo类

显示订单列表需要一个vo类别包括订单信息、地址信息和用户信息

OrderView : oid uid orderTime userName telphon address totalMoney ostate

GoodOrdersDetailVo: pid pimg pname star pubdate, price num money

3.1 实现沙箱支付

3.1.1 修改支付宝按钮链接

3.1.2沙箱支付PayServlet代码:

 @WebServlet("/pay.do") public class PayServlet extends BaseServlet { 
             //appid     private final String APP_ID = "2021000119697423";     //使用私钥     private final String APP_PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDnSxnNeuFy7ChdPC04Ak3QfqIqyd27nAewaFc6D9dism9wfYlxKovTLQBjaqO AAwjvo/24 VvpD6Ku5Oj zG9FG0J6veR7AAMKcuaPimDWO8Yv7y1P12MBCH3cxNhikdgE5JVCVDtU/av AKVdOs4hFmyOS0httTjaoBIhKTlESLFs6d3sOeCY2bIXiV0l FRVoJHs5OkXkjALnm 1mdRycZtz8Igjf80hhfVbdnOuhbnEVUN7VoTkd43KLuirDjEx/G8CbolW1yGYhCUJs7nYxzpVlUvIeCwRS6JRFQ7N8OWR7wzsAtdVoElc05Mt1IMECTm4WFzAi x8VLwX42XAgMBAAECggEAKEAkjGK/Cy3X1GndgKq9 fOfqwyYPsbne6acz2jkVbOxuwTNv1jlHmntcF lgTIm6q2GBjQgwG33yFLeXaIgRMRiOWCfltBYLcW0PfJlbQs0CL2NTIlrcSti8dof3FChHTIqvAuz/qkm /aQFIxVRu ZYG c0AouQClPi88xlv8wtd9E5ZHk9iWwc2KEfiROk pOSkaCQxK3TV14qP/WJfMHQmySB8hHeQZ67TdOuJpdbskIDi/g0UrrzPX7DjJMdv GIggMBOQ3Jf6w/w25TYRxOuXnnYEVBJJMt5NVpE84OCr 6rHzGNp4N cubY7fSLGLN5QwCrjeRoEQlTnyIQKBgQD33XH2dHXgBF/vEboYXHzFE2fHU 5sxXHqrI5dYC7foPDcFxqC7cz4 D/MXxwATqdKyOwjbKK4i6xAaGrTBBYjW2Nu1BfBi3zLUZUF GUzLYLOhPKrGyybmO3DGHgIxlQGgCR60oKGbNxxX1MPoh4H5ogn9FQqz ANDrGeFRqccQKBgQDu4mvIj/k6LM JMouK5A60LQh4uPzfubU1YTR1M50clPcOWteI2 y d8IhzwWw1GE5UMvQ K0rjJ3Uwj6AzSeFUn9mKY07Ihz3jn/7xvMBLYw0o3uaYPpl 5c6YDWEoqNlSlIN09Bk73Q5Vgrp00PF1d H16bgyD00oZpGe0buhwKBgBHY S7E3gP bKX7QcolRrquFgftTDq60OQT/sBMf7OMlCtU4ozQ8LRws69UneCLyVICO7alSOY 8G1G14JQRgPPvc4qKXe/QoIlYrSmWSshOM0EF7EoaMLfdSdaKLKBDWXWbkoFxG5HgmwLcCCtDLqG6ADwf sBQuHN0A5Q LSRAoGBALG5dqMSqkNjz0utdS/yGBZoYqMeTdRNH8oE9bg0nDEFiwD9CNnjdTEHfEEW o7ikyrHN7vTJ1L9HPeLRGEjQMHp7KqfQ1m5OX/cXs985pH7xxHqhy0F9YUmNw7RQT/amGHld0KeUa6mj/uQTjJEYWmwgstX3 ngT9j2WgcR9GXFAoGBAIgjeJQjPbqql3grItUxM 3zPsYywR2U7HDxb/WbWDfgC FIzTUOVFg4kZmMDvkCvZVrGccY9c8ItN64JC9n5zvUpGFRihAuHOGl5VuzUfhtXsMhAyKdf6NXTdurk35ioX91oJlWN4AdxjGyOxzKr0oSTjs6km3qLjWuKb4tSae4";     private final String CHARSET = "UTF-8";     // 支付宝公钥     private final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCA8AMIIBCgKCAQEAs4aFo85tjgc0Sn/OxeHn0GeiAcxrom1MFAVgK7mTj+gXMzXk1NUg97E/a/UfhOGQ5xWxMAbMQGDKuseRycpo8KxUl6vQKFSrsPM+hM0G80YFgpIf4iaWC1qj4AsfOEBxUQBbdIlF1Ibt2dlIddqVe7Qfge+fI4rxixOhnE2yAlSZajwsHqZL6MagPSMYCnD3qZXGEZQOsH2lDqlH1aoijFI4LzqoEnL1QYBOVOKO8SIcud9f2Aw6t8I/fuBKAyDoOS7MAm8ISRxi6Lal6De95A4dvdWBBQgF9GDNH2UE0MWA0hDDDIFtpvrPMcXkN7qvRWBKqReZbSIkorDo0MM+dwIDAQAB";   //这是沙箱接口路径,正式路径为https://openapi.alipay.com/gateway.do
    private final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
    private final String FORMAT = "JSON";
    //签名方式
    private final String SIGN_TYPE = "RSA2";
    //支付宝异步通知路径,付款完毕后会异步调用本项目的方法,必须为公网地址
    // private final String NOTIFY_URL = "http://127.0.0.1/notifyUrl";
    //支付宝同步通知路径,也就是当付款完毕后跳转本项目的页面,可以不是公网地址
    private final String RETURN_URL = "http://localhost:8080/pay.do?action=returnUrl";


    /** * 支付方法 * * @param req * @param resp * @return */
    public String alipay(HttpServletRequest req, HttpServletResponse resp) { 
        
        String dona_id = req.getParameter("oid");
        HttpSession session = req.getSession();
        String money = req.getParameter("money");
        System.out.println(money);
        Float dona_money = Float.parseFloat(money);
        //把dona_id项目id 放在session中
        session.setAttribute("dona_id", dona_id);

        //生成订单号(支付宝的要求?)
        String time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String user = UUID.randomUUID().toString().replace("-", "").toUpperCase();

        String OrderNum = time + user;

        //调用封装好的方法(给支付宝接口发送请求)
        try { 
        
            return sendRequestToAlipay(OrderNum, dona_money, "xiaomi_shop");
        } catch (AlipayApiException e) { 
        
            e.printStackTrace();
        }
        return Constants.REDIRECT + "/error.html";
    }

    /* 参数1:订单号 参数2:订单金额 参数3:订单名称 */
    //支付宝官方提供的接口
    private String sendRequestToAlipay(String outTradeNo, Float totalAmount, String subject) throws AlipayApiException { 
        
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(RETURN_URL);
        //alipayRequest.setNotifyUrl(NOTIFY_URL);

        //商品描述(可空)
        String body = "小米商场模拟支付:" + subject;
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\","
                + "\"total_amount\":\"" + totalAmount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        return result;
    }

    /** * 支付宝同步通知路径 * * @param request * @param resp * @return * @throws ServletException * @throws IOException */
    public String returnUrl(HttpServletRequest request, HttpServletResponse resp) { 
        
        //接收到付款成功提示则
        System.out.println("接收到付款成功提示");
        //修改订单状态为已支付
        System.out.println("订单状态已修改");

        System.out.println("=================================同步回调=====================================");
        try { 
        
            // 获取支付宝GET过来反馈信息
            Map<String, String> params = new HashMap<String, String>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (Iterator<String> 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] + ",";
                }
                // 乱码解决,这段代码在出现乱码时使用
                // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }

            System.out.println(params);//查看参数都有哪些
            //验证签名(支付宝公钥)
            AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE); // 调用SDK验证签名
            //验证签名通过

            // 商户订单号
            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");

            // 付款金额
            float money = Float.parseFloat(new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8"));

            System.out.println("商户订单号=" + out_trade_no);
            System.out.println("支付宝交易号=" + trade_no);
            System.out.println("付款金额=" + money);

            //todo 在这里编写自己的业务代码(对数据库的操作)
            HttpSession session = request.getSession();
            String oid = (String) session.getAttribute("dona_id");
            IOrderService orderService = new OrderServiceImpl();
            boolean falg = orderService.updateOrderState(oid, OrderStatus.PAY.ordinal());

            if (falg){ 
        
                System.out.println("订单状态修改成功");

            }else{ 
        
                System.out.println("订单状态修改失败");
            }

            //跳转到提示页面(成功或者失败的提示页面)
            ///model.addAttribute("flag", 1);
            //model.addAttribute("msg", "支持");
            //修改订单状态为已支付
            System.out.println("订单状态已修改");
            return Constants.REDIRECT + "/message.html?msg=success";

        } catch (Exception e) { 
        
            e.printStackTrace();
            return Constants.REDIRECT + "/error.html?msg=fail";
        }

    }


}

点击支付跳转至支付页面, 通过手机支付宝沙箱app扫码支付

扫码支付成功后会跳转到成功页面

4 用户订单列表

4.1:用户订单列表链接修改

订单列表页面orderList.html页面ajax请求的的js代码 用于在页面加载完成时根据数据库数据渲染页面


    <script>
        //获取购物车列表
        $(document).ready(function () { 
        
            //获取session数据显示到页面
            $.get("order.do?action=showMyOrder", "", function (result) { 
        
                var index = 0;
                if (result.flag === true) { 
        //登录
                    for (var i in result.data) { 
        
                        index++;
                        var money = result.data[i].quantity * result.data[i].price;
                        var temp =
                            ' ' +
                            ' ' + index + '' +
                            ' ' + result.data[i].oid + '' +
                            ' ' + result.data[i].totalMoney + '' +
                            ' ' +
                            ' ';
                        var statu = "";
                        if (result.data[i].ostate == 0) { 
        
                            statu = "未支付"
                        }
                        if (result.data[i].ostate == 1) { 
        
                            statu = "已支付"
                        }
                        if (result.data[i].ostate == 2) { 
        
                            statu = "待发货"
                        }
                        if (result.data[i].ostate == 3) { 
        
                            statu = "待收货"
                        }
                        if (result.data[i].ostate == 4) { 
        
                            statu = "待评价"
                        }
                        temp += statu;
                        temp += ' ' +
                            ' ' +
                            ' ' + result.data[i].orderTime + '' +
                            ' ' + result.data[i].address + '' +
                            ' ' +
                            ' ';
                        var str = ' ';

                        temp += str;
                        temp +=
                            ' ' +
                            ' ' +

                            $("#orderBody").append(temp)
                        $("#utip").text(result.data[i].userName);

                    }

                } else { 
        
                    var error = "订单空空如也"
                    $("#orderBody").append(error)
                }
                $("#sizetip").text(index);
            });
        });
    </script>

4.2后端

4.2.1后端OrderServlet

在 AddressServlet类中根据购物车信息创建订单数据

 @WebServlet("/order.do")
public class OrderServlet extends BaseServlet { 
        
    private ResultData resultData = new ResultData();


/** * 显示我的订单信息 * * @param req * @param resp * @return * @throws ServletException * @throws IOException */
    public String showMyOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
        
        resultData.setData(true);
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute(Constants.LOGINUSER);
        System.err.println(user);
        if (user == null) { 
        
            resultData.setData(false);
        } else { 
        
            IOrderService orderService = new OrderServiceImpl();
            List<OrderView> olist = orderService.queryAllDataByUId(user.getId());
            if (olist != null && !olist.isEmpty()) { 
        
                resultData.setFlag(true);
                resultData.setData(olist);
            }else{ 
        
                resultData.setFlag(false);
            }
        }
        String json = JSON.toJSONString(resultData);
        resp.setContentType("application/json;charset=utf-8");
        return json;
    }
}

4.2.2 OrdarDaoImpl

订单表的dao层实现

public class OrderDaoImpl implements IOrderDao { 
        
    //.........
 /** * 通过id查询OrderView视图类得数据查询方法 * @param uid * @return */
@Override
    public List<OrderView> queryAllDataByUId(int uid) { 
        
        String sql = " select o.id as oid ,o.uid as uid,u.username as userName, o.time as orderTime, " +
                " a.phone as telphon,a.detail as address,o.status as ostate ,o.money as totalMoney from tb_user u,tb_order o,tb_address a " +
                " where o.uid=? and o.uid=u.id and o.aid=a.id; ";
        List<OrderView> query = null;
        QueryRunner run = new QueryRunner(DBUtils.getDataSource());
        try { 
        
            query = run.query(sql, uid, new BeanListHandler<>(OrderView.class));
        } catch (SQLException e) { 
        
            e.printStackTrace();
        }
        return query;
//....
    }

4.2.3 编写OrderServiceImpl代码

订单创建涉及到多张数据表,必须做事务控制:

public class OrderServiceImpl implements IOrderService { 
        
    //......
      @Override
    public List<OrderView> queryAllDataByUId(int uid) { 
        
        return  orderDao.queryAllDataByUId(uid);
    }
    
       //......
}


   e.printStackTrace();
    }
    return query;

//…
}


#### 4.2.3 编写OrderServiceImpl代码

订单创建涉及到多张数据表,必须做事务控制:

```java
public class OrderServiceImpl implements IOrderService {
    //......
      @Override
    public List queryAllDataByUId(int uid) {
        return  orderDao.queryAllDataByUId(uid);
    }
    
       //......
}


锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章