JavaWeb - 小米商城 :订单支付[沙箱支付]

11 篇文章 1 订阅
6 篇文章 0 订阅

JavaWeb - 小米商城 :订单支付[沙箱支付]

1.功能描述

接上篇 JavaWeb - 小米商城:提交订单 订单创建后进入支付界面,整合支付宝沙箱支付。如 以下H5页面所示:

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

支付提示界面:

当点击提交订单, 此时将订单数据存储到数据表

在这里插入图片描述

支付宝支付:

一般的开发中使用的是沙箱做模拟支付

在这里插入图片描述

支付过程提示:

在这里插入图片描述

**使用沙箱app扫码支付成功后跳转到支付成功提示界面 **

在这里插入图片描述

我的订单列表:

支付成功可以通过点击我的订单查看订单列表

在这里插入图片描述

订单详情界面

通过点击订单列表中订单详情按钮打开该

在这里插入图片描述

2.沙箱支付功能分析

2.1 在pom文件中添加依赖

 <!--   支付宝沙箱支付的依赖     -->
    <dependency>
      <groupId>com.alipay.sdk</groupId>
      <artifactId>alipay-sdk-java</artifactId>
      <version>4.16.2.ALL</version>
    </dependency>

3.代码实现

3.1前端

3.1.1 修改链接地址
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>订单成功</title>
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="css/login2.css">
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <script type="text/javascript" src="js/includeHeader.js"></script>
    <script>
        $(document).ready(function () {//当页面加载完成执行代码
            var oid = getParams("oid");
            var money = getParams("money");
            $("#oidh4").text("订单号:" + oid);
            $("#moneyh4").text("订单总金额:" + money);
            $("#payalink").attr("href", "pay.do?action=alipay&oid=" + oid + "&omoney=" + money);
            $("#Weixinlink").attr("href", "payWeixin.do?action=alipay&oid=" + oid + "&omoney=" + money);
        });
    </script>
</head>
<body>
<div id="headtop">
</div>

<div class="container">
    <hr>
    <div class="row" style="width: 30%;margin: 0 auto;padding-top: 20px">
        <div class="panel panel-success">
            <div class="panel-heading">
                <h3 class="panel-title">订单提示</h3>
            </div>
            <div class="panel-body">
                <h3 class="text-default"><span class="glyphicon glyphicon-ok-sign"></span>&nbsp;&nbsp;&nbsp;&nbsp;订单添加成功!!
                </h3>
                <hr>
                <h4 id="oidh4"></h4>
                <h4 id="moneyh4"></h4>
                <span class="h3">立即支付</span>
                <a id="payalink" class="btn btn-warning">支付宝支付</a>&nbsp;&nbsp;&nbsp;&nbsp;
                <a id="Weixinlink" class="btn btn-success">微信支付</a>
            </div>
        </div>

    </div>

</div>
<!--网站版权部分开始-->
//......
</body>
</html>

3.2后端

3.2.1 PayServlet

在 PayServlet类中首先设置如下私有属性

APP_ID (appId,从沙箱管理页面获得) APP_PRIVATE_KEY (应用私钥,最开始在密钥工具生成而 来) ALIPAY_PUBLIC_KEY (支付宝公钥,上一步骤获得) GATEWAY_URL (支付宝网关地址,在开发 平台沙箱管理页面中获得) SIGN_TYPE (签名类型) NOTIFY_URL (异步回调地址,须是公网IP,后 面再解释) RETURN_URL (同步回调地址,可以是私网IP)

@WebServlet("/pay.do")
public class PayServlet extends BaseServlet {
    //appid
    private final String APP_ID = "2021000119697420";
    //应用私钥
    private final String APP_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQ";
    private final String CHARSET = "UTF-8";
    // 支付宝公钥
    private final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6Gamayt9Z";
    //这是沙箱接口路径,正式路径为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";

    /**
     * 支付方法
     */
    public String alipay(HttpServletRequest req, HttpServletResponse resp) {
        HttpSession session = req.getSession();
        String dona_id = req.getParameter("oid");
        String money = req.getParameter("omoney");
        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, "小米商城");
        } catch (Exception 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;
    }

    /**
     * 支付宝的异步通知路径
     */
    public String returnUrl(HttpServletRequest req, HttpServletResponse resp) {
        //接收到付款成功的提示
        System.out.println("接收到付款成功的提示");
        //修改订单的状态 为 已支付

        System.out.println("=================================同步回调=====================================");
        try {

            // 获取支付宝GET过来反馈信息
            Map<String, String> params = new HashMap<String, String>();
            Map<String, String[]> requestParams = req.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);//查看参数都有哪些
            //验证签名(支付宝公钥)
            boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE); // 调用SDK验证签名
            //验证签名通过
            // 商户订单号
            String out_trade_no = new String(req.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

            // 支付宝交易流水号
            String trade_no = new String(req.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

            // 付款金额
            float money = Float.parseFloat(new String(req.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 在这里编写自己的业务代码(对数据库进行操作)
            //在这里编写自己的业务代码(对数据库的操作)
            String oid = req.getSession().getAttribute("dona_id").toString();
            IOrderService orderService = new OrderServiceImpl();
            boolean flag = orderService.updateOrderState(OrderStatus.PAY.ordinal(),oid);
            if (flag){
                System.out.println("订单状态修改成功");
            }else {
                System.out.println("订单状态修改失败");
            }

            System.out.println("修改订单的状态 为 已支付");
            return Constants.REDIRECT + "/message.html?msg=支付成功!";
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("支付失败");
            return Constants.REDIRECT + "/error.html?msg=支付失败!";
        }
    }
}

3.2.2 编写OrderServiceImpl码
public class OrderServiceImpl implements IOrderService {
    private IOrderDao orderDao = null;
    private ICartDao cartDao = null;
    private IOrderDetailDao orderDetailDao = null;

    public OrderServiceImpl() {
        orderDao = new OrderDaoImpl();
        cartDao = new CartDaoImpl();
        orderDetailDao = new OrderDetailDaoImpl();
    }
    
    //..........

    @Override
    public boolean updateOrderState(int status,String oid) {
        return orderDao.updateOrderState(status,oid);
    }

    @Override
    public List<OrdersView> queryAllDataByUid(int uid) {
        return orderDao.queryAllDataByUid(uid);
    }
}
3.2.3 编写OrderDaoImpl代码
public class OrderDaoImpl implements IOrderDao {
    private QueryRunner queryRunner = null;

    public OrderDaoImpl() {
        queryRunner = new QueryRunner();
    }

   //......

    @Override
    public boolean updateOrderState(int status, String oid) {
        String sql = "update tb_order set status=? where id=?";
        try {
            int n = queryRunner.update(DBUtils.getConn(), sql, status, oid);
            return n >= 1 ? true : false;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    
    //......
    
}

4. 我的订单列表码实现

4.1 前端

4.1.1 修改orderList.html文件
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>订单列表</title>
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <link rel="stylesheet" type="text/css" href="css/login2.css">
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <script type="text/javascript">
        function showOrder(orderId) {
            location.href = "orderDetail.html?oid=" + orderId;
        }
        function changeStatus(orderId) {
            location.href = "order.do?action=changeStatus&oid=" + orderId;
        }

        $(document).ready(function () {
            //获取购物车的session数据显示到页面
            $.get("order.do?action=showMyOrder", "", function (result) {
                if (result.flag === true) {
                    var index = 0;
                    for (var i in result.data) {
                        index++;
                        var odhtml = '      <tr>' +
                            '<td>' + index + '</td>' +
                            '<td>' + result.data[i].oid + '</td>' +
                            '<td>' + result.data[i].totalMoney + '</td>' +
                            '<td>' +
                            '<font color="red">';
                        var 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 = "订单完成";
                        }
                        if (result.data[i].ostate === 5) {
                            statu = "未支付";
                        }
                        odhtml += statu + '</font>' +
                            ' </td>' +
                            ' <td>' + result.data[i].orderTime + '</td>' +
                            ' <td>' + result.data[i].address + '</td>' +
                            '<td>' +
                            '<button type="button" class="btn btn-danger btn-sm" οnclick="showOrder(\'' + result.data[i].oid + '\')">订单详情</button>';
                        var qrstr = "";
                        if (result.data[i].ostate === 3) {
                            qrstr = '<button type="button" class="btn btn-warning btn-sm" οnclick="changeStatus(\'' + result.data[i].oid + '\')">确认收货</button>';
                        }
                        odhtml += qrstr + '</td>' + '</tr>';
                        $("#orderBody").append(odhtml);
                        $("#utip").text( result.data[i].userName);
                    }
                }else {
                    var odhtml = '<tr><td colspan="7">当前用户没有订单数据</td></tr>'
                    $("#orderBody").append(odhtml);
                }
                $("#sizetip").append(index);
            });
        });
    </script>
    <script type="text/javascript" src="js/includeHeader.js"></script>
</head>
<body style="background-color:#f5f5f5">
<div id="headtop">
</div>
<div class="container" style="background-color: white;">
    <div class="row" style="margin-left: 40px">
        <h3>我的订单列表&nbsp;&nbsp;
            <small >温馨提示: <em id="utip"></em><font color="red" id="sizetip"></font>个订单</small></h3>
    </div>
    <div class="row" style="margin-top: 40px;">
        <div class="col-md-12">
            <table id="tb_list" class="table table-striped table-hover table-bordered table-condensed">
                <thead>
                <tr>
                    <th>序号</th>
                    <th>订单编号</th>
                    <th>总金额</th>
                    <th>订单状态</th>
                    <th>订单时间</th>
                    <th>收货地址</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody id="orderBody">
                </tbody>
            </table>
        </div>
    </div>
</div>
<!-- 底部 -->
<!--网站版权部分开始-->
//.....
</body>
</html>

4.2 后端

4.2.1 OrderServlet
@WebServlet("/order.do")
public class OrderServlet extends BaseServlet {

    private ResultData resultData = new ResultData();
		
    //....
    
    /**
     * 显示我的订单信息
     */
    public String showMyOrder(HttpServletRequest req, HttpServletResponse resp) {
        HttpSession session = req.getSession();
        System.out.println(session.getId());
        resultData.setFlag(true);
        User user = (User) session.getAttribute(Constants.LOGINUSER);
        System.err.println(user);
        if (user == null) {
            resultData.setFlag(false);
        } else {
            OrderServiceImpl orderService = new OrderServiceImpl();
            List<OrdersView> ordersViews = orderService.queryAllDataByUid(user.getId());
            if (ordersViews!=null && ordersViews.size()!=0){
                resultData.setData(ordersViews);
            }else {
                resultData.setFlag(false);
            }
        }
        String json = JSON.toJSONString(resultData);
        resp.setContentType("application/json;charset=utf-8");
        return json;
    }
}
4.2.2 OrderServiceImpl
public class OrderServiceImpl implements IOrderService {
    private IOrderDao orderDao = null;
    private ICartDao cartDao = null;
    private IOrderDetailDao orderDetailDao = null;

    public OrderServiceImpl() {
        orderDao = new OrderDaoImpl();
        cartDao = new CartDaoImpl();
        orderDetailDao = new OrderDetailDaoImpl();
    }

	//........ 
    
    @Override
    public List<OrdersView> queryAllDataByUid(int uid) {
        return orderDao.queryAllDataByUid(uid);
    }
}
4.2.3 OrderDaompl
public class OrderDaoImpl implements IOrderDao {
    private QueryRunner queryRunner = null;

    public OrderDaoImpl() {
        queryRunner = new QueryRunner();
    }

	//.......

    @Override
    public List<OrdersView> 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 telephone,a.detail as address,o.`status` as ostate,o.money as totalMoney " +
                " from tb_user u,tb_order o, tb_address a " +
                " where u.id=? and u.id=o.uid and o.aid=a.id";
        List<OrdersView> ordersViews = null;
        QueryRunner qrun = new QueryRunner(DBUtils.getDataSource());
        try {
            ordersViews = qrun.query(sql, uid, new BeanListHandler<>(OrdersView.class));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return ordersViews;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值