此次电商系统项目依然采用spring boot+纯前端html+css+js开发完成,便于初学
者学习,只要你会html标签,css选择器样式,以及原生js查找元素和增加点击事件以及jquery的ajax,则此系统十分适合你学习。
可以去看我JAVA项目实战增删改查案例
可以去看我[JAVA项目实战增删改查案例]
在线体验网址清前往:http://www.liph.fun个人网站或者点击商城地址:商城地址
注意付款的时候支付宝扫码显示二维码失效,需要下载支付宝沙漏版支付宝。
不懂的参考我上一篇文章。
采用我提前搭建完成的buiness-Admin后台管理系统的商城部分代码
即可快速搭建。
还是采用spring boot架构,内置含有统一异常处理,
统一json数据响应,
统一的工具类处理,统一数据库mybaties查询,
在这里我们就不考虑技术直接分析业务结构。
(1) 用户由购物车去结算按钮 ,跳转到如下图的订单确认页面
(2) 此时后台接口查询用户购物车中所选择的待提交订单的商品清单信息以及家庭住址信息:
上述图片描述姓名12买了1件美的冰箱花费了888元。选择了一个收货地址。
(3)用户点击提交订单按钮,此时商品清单数据和收货地址数据变成了一个整体的数据。后台生成了一个订单,如下图
其中user_id代表提交订单的用户ID,order_no订单号,shipping_id地址信息,另外还有付款金额以及付款类型和付款状态。提交订单,这张表肯定是未支付订单状态。
我们看到的付款金额只是这个订单的总价钱,页面上显示的商品清单列表会插入到商品订单明细表
订单号、商品ID、商品名称、商品价格、购买数量、商品总价属性
(4)到此订单信息处理完毕已经记录在数据库里面了。
(5)由于订单号在数据库中已经产生,产生的订单号会通过ajax调用支付宝,付款接口进行付款。
(6)关于支付宝对接看上一篇文章支付宝案例测试
(7)支付宝回调结束会返回异步通知,此时2件事要处理,第一更新订单的支付方式以及付款时间和付款状态更新为已付款。
order.setPaymentTime(DateTimeUtil.strToDate(params.get("gmt_payment")));
order.setStatus(Constant.OrderStatus.YES_PAY);
orderMapper.updateByPrimaryKeySelective(order);
LOGGER.info("支付宝支付付款成功订单状态更新");
System.out.println("支付宝支付付款成功订单状态更新"+new Date());
第二步:方便以后对账,将支付宝返回的流水号以及本系统订单号,创建时间和付款用户记录到付款流水表中。
(1)由于用户购买商品支付成功数据库中已经存在订单数据,所以出现了下图的订单列表。
(2)用户点击我的订单,判断用户是否登录未登录提示用户登录,已经登录则可以调用查看订单接口,查询该用户下的所有订单。
关键代码如下
@RequestMapping("/order/createOrder")
@ResponseBody
public CommonResult<TbOrder> createOrder(HttpSession session,Integer shippingId){
TbMember tbMember= (TbMember) session.getAttribute(Constant.CURRENT_LOGIN_USER);
if(tbMember==null){
//未登录返回0 啊
return CommonResult.failed(ResultCode.UNAUTHORIZED);
}
TbOrder order=this.orderService.createOrder(tbMember.getId(),shippingId);
return CommonResult.success(order);
}
/****
* 订单支付响应支付宝页面
* @param
* @param
* @return
*/
@RequestMapping("/order/pay")
public void pay(HttpServletRequest httpRequest, HttpServletResponse httpResponse,String orderNo)throws ServletException, IOException {
String form="";
try {
form=orderService.pay(orderNo);
} catch (Exception e) {
e.printStackTrace();
}
String charset = "utf-8";
httpResponse.setContentType("text/html;charset=" + charset);
httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}
/***
* 分页查询订单列表
* @param
* @return
*/
@RequestMapping(value = "/order/orderlist",method = RequestMethod.GET)
@ResponseBody
public CommonResult<CommonPage<com.gotop.cmdb.model.OrderVo>> getorderlist(Integer page,
Integer size,
HttpSession session){
TbMember tbMember= (TbMember) session.getAttribute(Constant.CURRENT_LOGIN_USER);
if(tbMember==null){
//未登录返回0 啊
return CommonResult.failed(ResultCode.UNAUTHORIZED);
}
/***
* 分页查询
*/
List<com.gotop.cmdb.model.OrderVo> list=orderService.getorderlist(page,size,tbMember.getId());
return CommonResult.success(CommonPage.restPage(list));
}
/****
* 根据订单号查询订单详情
* @param
* @param
* @param session
* @return
*/
@RequestMapping(value = "/order/orderdetail",method = RequestMethod.GET)
@ResponseBody
public CommonResult<OrderDetailVo> queryorderdetail(HttpSession session, String orderNo){
TbMember tbMember= (TbMember) session.getAttribute(Constant.CURRENT_LOGIN_USER);
if(tbMember==null){
//未登录返回0 啊
return CommonResult.failed(ResultCode.UNAUTHORIZED);
}
/***
* 订单唯一的,只有一个订单很多个商品明细
*/
OrderDetailVo list=orderService.queryorderdetail(orderNo);
return CommonResult.success(list);
}
@RequestMapping(value = "/order/ordercancel",method = RequestMethod.GET)
@ResponseBody
public CommonResult ordercancel(HttpSession session, String orderNo){
TbMember tbMember= (TbMember) session.getAttribute(Constant.CURRENT_LOGIN_USER);
if(tbMember==null){
//未登录返回0 啊
return CommonResult.failed(ResultCode.UNAUTHORIZED);
}
/***
* 订单唯一的,只有一个订单很多个商品明细
*/
int row=orderService.ordercancel(orderNo);
return CommonResult.success(1);
}
/***
*
* 支付宝异步通知接口
* @param request
* @param response
* @throws AlipayApiException
* @throws IOException
*/
@RequestMapping("order/alipay_callback")
public void alipayCallback(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException {
LOGGER.info("#################################支付宝异步回调######################################"+new Date());
System.out.println("#################################支付宝异步回调######################################"+new Date());
// 获取支付宝POST过来反馈信息
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);
}
LOGGER.info("支付宝回调,sign:{},trade_status:{},参数:{}"+params);
System.out.println("支付宝回调,sign:{},trade_status:{},参数:{}"+params);
//非常重要,验证回调的正确性,是不是支付宝发的.并且呢还要避免重复通知.
params.remove("sign_type");
boolean signVerified = AlipaySignature.rsaCheckV1(params, configBeanProp.getAlipay_public_key(), "utf-8", configBeanProp.getSign_type()); // 调用SDK验证签名
// ——请在这里编写您的程序(以下代码仅作参考)——
/*
* 实际验证过程建议商户务必添加以下校验: 1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
* 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), 3、校验通知中的seller_id(或者seller_email)
* 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
* 4、验证app_id是否为该商户本身。
*/
if (signVerified) {// 验证成功
// 商户订单号
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");
System.out.println("商户订单号="+out_trade_no);
System.out.println("支付宝交易号="+trade_no);
System.out.println("交易状态="+trade_status);
//订单业务逻辑处理
orderService.aliCallback(params);
System.out.println("异步回调验证成功");
response.getWriter().write("success");
} else {// 验证失败
System.out.println("异步回调验证失败");
response.getWriter().write("fail");
// 调试用,写文本函数记录程序运行情况是否正常
// String sWord = AlipaySignature.getSignCheckContentV1(params);
// AlipayConfig.logResult(sWord);
}
response.getWriter().flush();
response.getWriter().close();
}
合计6个接口
代码不重要,关键只要你能通过这篇文章能学到了电商项目支付和订单模块,
所有的系统订单和支付都一样,例如保险项目、银行理财项目、等项目。也许可能他们的订单表记录的信息全面一点和记录系统日志详细一点。
经验是由一点一点积累的,思维也是由一天一天训练出来的。
持续更新分享此项目电商在线演示地址为:演示地址
源码下载