品优购项目笔记(十四)

  • 订单
    • 订单三张表关系
    • 提交订单
  • 二维码
    • 介绍
    • 优势
    • 容错级别
    • qrious二维码生成插件
  • 微信支付
    • 微信支付流程
    • 项目支付流程
    • 生成支付链接
    • 查询是否支付成功

订单

订单三张表关系

提交订单

controller

@RestController
@RequestMapping("/order")
public class OrderController {@Referenceprivate OrderService orderService;@RequestMapping("/add")public Result add(@RequestBody Order order) {try {String userName = SecurityContextHolder.getContext().getAuthentication().getName();order.setUserId(userName);orderService.add(order);return new Result(true, "保存成功!");} catch (Exception e) {e.printStackTrace();return new Result(false, "保存失败!");}}
}

Service

@Service
@Transactional
public class OrderServiceImpl implements OrderService {@Autowiredprivate PayLogDao payLogDao;@Autowiredprivate OrderDao orderDao;@Autowiredprivate OrderItemDao orderItemDao;@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate IdWorker idWorker;@Overridepublic void add(Order order) {//1. 从订单对象中获取当前登录用户用户名String userId = order.getUserId();//2. 根据用户名获取购物车集合List<BuyerCart> cartList = (List<BuyerCart>) redisTemplate.boundHashOps(Constants.CART_LIST_REDIS).get(userId);List<String> orderIdList = new ArrayList();//订单ID列表double total_money = 0;//总金额 (元)//3. 遍历购物车集合if (cartList != null) {for (BuyerCart cart : cartList) {//TODO 4. 根据购物车对象保存订单数据long orderId = idWorker.nextId();System.out.println("sellerId:" + cart.getSellerId());Order tborder = new Order();//新创建订单对象tborder.setOrderId(orderId);//订单IDtborder.setUserId(order.getUserId());//用户名tborder.setPaymentType(order.getPaymentType());//支付类型tborder.setStatus("1");//状态:未付款tborder.setCreateTime(new Date());//订单创建日期tborder.setUpdateTime(new Date());//订单更新日期tborder.setReceiverAreaName(order.getReceiverAreaName());//地址tborder.setReceiverMobile(order.getReceiverMobile());//手机号tborder.setReceiver(order.getReceiver());//收货人tborder.setSourceType(order.getSourceType());//订单来源tborder.setSellerId(cart.getSellerId());//商家ID//循环购物车明细double money = 0;//5. 从购物车中获取购物项集合List<OrderItem> orderItemList = cart.getOrderItemList();//6. 遍历购物项集合if (orderItemList != null) {for (OrderItem orderItem : orderItemList) {//TODO 7. 根据购物项对象保存订单详情数据orderItem.setId(idWorker.nextId());orderItem.setOrderId(orderId);//订单IDorderItem.setSellerId(cart.getSellerId());money += orderItem.getTotalFee().doubleValue();//金额累加orderItemDao.insertSelective(orderItem);}}tborder.setPayment(new BigDecimal(money));orderDao.insertSelective(tborder);orderIdList.add(orderId + "");//添加到订单列表total_money += money;//累加到总金额}}//TODO 8. 计算总价钱保存支付日志数据if ("1".equals(order.getPaymentType())) {//如果是微信支付PayLog payLog = new PayLog();String outTradeNo = idWorker.nextId() + "";//支付订单号payLog.setOutTradeNo(outTradeNo);//支付订单号payLog.setCreateTime(new Date());//创建时间//订单号列表,逗号分隔String ids = orderIdList.toString().replace("[", "").replace("]", "").replace(" ", "");payLog.setOrderList(ids);//订单号列表,逗号分隔payLog.setPayType("1");//支付类型payLog.setTotalFee((long) (total_money * 100));//总金额(分)payLog.setTradeState("0");//支付状态payLog.setUserId(order.getUserId());//用户IDpayLogDao.insertSelective(payLog);//插入到支付日志表//TODO 9. 使用当前登录用户的用户名作为key, 支付日志对象作为value存入redis中供支付使用redisTemplate.boundHashOps("payLog").put(order.getUserId(), payLog);//放入缓存}//TODO 10. 根据当前登录用户的用户名删除购物车redisTemplate.boundHashOps(Constants.CART_LIST_REDIS).delete(order.getUserId());}
}

二维码

介绍

二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。
二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。

优势

 信息容量大, 可以容纳多达1850个大写字母或2710个数字或500多个汉字
 应用范围广, 支持文字,声音,图片,指纹等等…
 容错能力强, 即使图片出现部分破损也能使用
 成本低, 容易制作

容错级别

容错级别也就是容错率, 相当于部分二维码被遮挡仍然可以被扫描出来.
L级(低) 7%的码字可以被恢复。
M级(中) 的码字的15%可以被恢复。
Q级(四分)的码字的25%可以被恢复。
H级(高) 的码字的30%可以被恢复。

qrious二维码生成插件

这是前端的二维码生成工具

<html>
<head>
<title>二维码入门小demo</title>
</head>
<body>
<img id="qrious">
<script src="qrious.min.js"></script>
<script>var qr = new QRious({element:document.getElementById('qrious'),size:250,      level:'H',    value:'https://www.baidu.com'});
</script>
</body>
</html>

微信支付

微信支付流程

红色部分为项目需要实现的部分

项目支付流程

生成支付链接

controller

/*** 支付业务*/
@RestController
@RequestMapping("/pay")
public class PayController {@Referenceprivate OrderService orderService;@Referenceprivate PayService payService;/*** 根据支付单号和总金额调用微信统一下单接口,生成支付链接返回* @return*/@RequestMapping("/createNative")public Map createNative(){//1.获取用户名String username = SecurityContextHolder.getContext().getAuthentication().getName();//2.获取支付日志对象PayLog payLog = orderService.getPayLogByUsername(username);if (payLog!=null){//3.调用统一下单接口,生成支付链接Map map = payService.createNative(payLog.getOutTradeNo(), "1");//payLog.getTotalFee()return map;}return new HashMap();}
}

service:注意需要发送https请求,所以要用到HttpClient工具类

@Service
public class PayServiceImpl implements PayService {//公众号唯一标识@Value("${appid}")private String appid;//财付通平台商户账号@Value("${partner}")private String partner;//密钥@Value("${partnerkey}")private String partnerkey;//回调地址@Value("${notifyurl}")private String notifyurl;@Overridepublic Map createNative(String outTradeNo, String totalFee) {//1.创建参数Map<String,String> param=new HashMap();//创建参数param.put("appid", appid);//公众号param.put("mch_id", partner);//商户号param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串param.put("body", "品优购");//商品描述param.put("out_trade_no", outTradeNo);//商户订单号param.put("total_fee",totalFee);//总金额(分)param.put("spbill_create_ip", "127.0.0.1");//IPparam.put("notify_url", "http://www.itcast.cn");//回调地址(随便写)param.put("trade_type", "NATIVE");//交易类型try {//2.生成要发送的xmlString xmlParam = WXPayUtil.generateSignedXml(param, partnerkey);System.out.println(xmlParam);HttpClient client=new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");client.setHttps(true);client.setXmlParam(xmlParam);client.post();//3.获得结果String result = client.getContent();System.out.println(result);Map<String, String> resultMap = WXPayUtil.xmlToMap(result);Map<String, String> map=new HashMap<>();map.put("code_url", resultMap.get("code_url"));//支付地址map.put("total_fee", totalFee);//总金额map.put("out_trade_no",outTradeNo);//订单号return map;} catch (Exception e) {e.printStackTrace();return new HashMap<>();}}
}

HttpClient

/*** http请求客户端* * @author Administrator* */
public class HttpClient {private String url;private Map<String, String> param;private int statusCode;private String content;private String xmlParam;private boolean isHttps;public boolean isHttps() {return isHttps;}public void setHttps(boolean isHttps) {this.isHttps = isHttps;}public String getXmlParam() {return xmlParam;}public void setXmlParam(String xmlParam) {this.xmlParam = xmlParam;}public HttpClient(String url, Map<String, String> param) {this.url = url;this.param = param;}public HttpClient(String url) {this.url = url;}public void setParameter(Map<String, String> map) {param = map;}public void addParameter(String key, String value) {if (param == null)param = new HashMap<String, String>();param.put(key, value);}public void post() throws ClientProtocolException, IOException {HttpPost http = new HttpPost(url);setEntity(http);execute(http);}public void put() throws ClientProtocolException, IOException {HttpPut http = new HttpPut(url);setEntity(http);execute(http);}public void get() throws ClientProtocolException, IOException {if (param != null) {StringBuilder url = new StringBuilder(this.url);boolean isFirst = true;for (String key : param.keySet()) {if (isFirst)url.append("?");elseurl.append("&");url.append(key).append("=").append(param.get(key));}this.url = url.toString();}HttpGet http = new HttpGet(url);execute(http);}/*** set http post,put param*/private void setEntity(HttpEntityEnclosingRequestBase http) {if (param != null) {List<NameValuePair> nvps = new LinkedList<NameValuePair>();for (String key : param.keySet())nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数}if (xmlParam != null) {http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));}}private void execute(HttpUriRequest http) throws ClientProtocolException,IOException {CloseableHttpClient httpClient = null;try {if (isHttps) {SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {// 信任所有public boolean isTrusted(X509Certificate[] chain,String authType)throws CertificateException {return true;}}).build();SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();} else {httpClient = HttpClients.createDefault();}CloseableHttpResponse response = httpClient.execute(http);try {if (response != null) {if (response.getStatusLine() != null)statusCode = response.getStatusLine().getStatusCode();HttpEntity entity = response.getEntity();// 响应内容content = EntityUtils.toString(entity, Consts.UTF_8);}} finally {response.close();}} catch (Exception e) {e.printStackTrace();} finally {httpClient.close();}}public int getStatusCode() {return statusCode;}public String getContent() throws ParseException, IOException {return content;}}

查询是否支付成功

controller

/*** 调用查询订单接口,查询是否支付成功* @param out_trade_no* @return*/@RequestMapping("/queryPayStatus")public Result queryPayStatus(String out_trade_no){String username = SecurityContextHolder.getContext().getAuthentication().getName();Result result = null;int flag = 1;while (true){//1.判断支付单号为空if (out_trade_no == null){result = new Result(false,"二维码超时");break;}//2.调用查询接口Map map = payService.queryPayStatus(out_trade_no);if ("SUCCESS".equals(map.get("trade_state"))){result = new Result(true,"支付成功");//3.如果支付成功,支付日志表和订单表的支付状态改为已支付,redis的支付日志对象删除orderService.updatePayStatus(username);break;}try {Thread.sleep(3000);} catch (Exception e) {e.printStackTrace();}//如果5分钟没有支付,则支付超时if (flag > 100){result = new Result(false,"二维码超时");break;}flag++;}return result;}

service

@Overridepublic Map queryPayStatus(String out_trade_no) {Map param=new HashMap();param.put("appid", appid);//公众账号IDparam.put("mch_id", partner);//商户号param.put("out_trade_no", out_trade_no);//订单号param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串String url="https://api.mch.weixin.qq.com/pay/orderquery";try {String xmlParam = WXPayUtil.generateSignedXml(param, partnerkey);HttpClient client=new HttpClient(url);client.setHttps(true);client.setXmlParam(xmlParam);client.post();String result = client.getContent();Map<String, String> map = WXPayUtil.xmlToMap(result);System.out.println(map);return map;} catch (Exception e) {e.printStackTrace();return null;}}

品优购项目笔记(十四):微信支付相关推荐

  1. 「学习笔记」品优购项目-上(页面公共部分 )

    「学习笔记」品优购项目-上 品优购项目-上 目标 品优购项目规划 网站制作流程 品优购项目介绍 品优购项目的学习目的 开发工具以及技术栈 开发工具 技术栈 品优购项目搭建工作 创建的文件夹如下(称为项 ...

  2. b站pink老师前端课程、品优购项目(跟着练的笔记+代码)

    02.网站制作流程 1. 03.品优购项目规划 04.项目搭建 05.样式的模块化开发 06.favicon图标制作 favicon.ico一般用于作为略缩图的网站标志,它显示在浏览器的地址栏或者标签 ...

  3. 14.------------------------------------------------------------------------------【PC端品优购项目】

    文章目录 [PC端品优购项目]前端小抄(14) 电商-主页 电商-分类列表页 电商-注册页 一.品优购项目规划 1.1 网站制作流程 1.2 品优购项目整体介绍 1.3 品优购项目的学习目的 1.4 ...

  4. day18(续)PC端品优购项目

    一.品优购项目导读 网站制作流程 原型图 三.品优购项目规划 四.品优购项目搭建工作 五.样式的模块化开发 六.favicon图标制作 七.TDK三大标签ASEO优化 八.品优购首页制作 logo s ...

  5. 品优购项目的制作——知识分享

    目录 前言 一.首页 1.基本的布局 2.版心部分 3.主要内容模块 二.注册页面 三.产品列表页面 四.产品详情页面 总结 前言 品优购项目是一个需要糅杂大量HTML5+CSS3知识点的网站项目,一 ...

  6. CSS 8 品优购项目

    目录 1.品优购项目规划 1.1网站制作流程 1.2品优购项目整体介绍 1.3品优购项目的学习目的 1.4开发工具以及技术栈 小总结​ 1.5品优购项目搭建工作. 1.5.1创建文件夹 1.5.2创建 ...

  7. 品优购项目学习---基本概述(简略)

    做项目期间看不懂的可以查阅 标记有 注 的这些部分的内容 一定会有你的需要的答案哦 如果没有 那小卓这边建议 可以直接私信小卓 小卓一定尽力提供最优解释哈   等第二遍做的时候进行梳理 注:   CS ...

  8. 前端——品优购项目(html+css)

    前端--品优购项目 文章目录 前端--品优购项目 一.品优购项目规划 二.首页 公共部分(common.css) 快捷导航模块 header模块 nav导航部分 底部模块 首页专有部分(index.c ...

  9. css三角形之美与品优购项目

    CSS三角形之美 div{width: 0;height: 0;line-height:0;font-size: 0;border-top: 10px solid red;border-right:1 ...

最新文章

  1. 数据蒋堂 | 非等值分组
  2. VS2017缺少头文件的解决办法
  3. python装饰器 property_python中property和setter装饰器用法
  4. 自动化系列-pyppeteer键盘输入点击
  5. 【KMP模板】简单写个KMP~
  6. 2017.2.14-15自测(那些普及神题)
  7. 使用折半查找法查找数组中的元素
  8. 小甲鱼python飞机大战素材_用Python做飞机大战(含素材)
  9. 绝地反击:我的战胜贫困的经历01(转载、整理)
  10. 删库跑路技巧 删库跑路命令
  11. 智能人物画像综合分析系统——Day16
  12. Manifest is not valid JSON. Line: 1, column: 1 项目打包报错解决方法
  13. HTML学生个人网站作业设计——HTML+CSS+JavaScript优分期大学生分期购物商城(7页)
  14. Web前端面试题整合,持续更新【可以收藏】
  15. wifi频谱仪测试软件,使用频谱仪测试2.4G信号的测试方法,求助
  16. 机器学习入门(浅谈L1和L2正则)
  17. python中scale什么意思啊_python数字图像处理(7):图像的形变与缩放
  18. 20个国内Android平台移动应用市场
  19. 学海无涯!2021年抓住金三银四涨薪好时机,持续更新中
  20. 微信小程序获取openid中的问题

热门文章

  1. 干货|23种最好用的3D打印软件工具
  2. 晚上如何配置ubuntu,保护眼睛?黑(暗)色主题
  3. dango shell 操作crud
  4. 鲤鱼鱼竿豆荚 - 建议做出正确的选择
  5. 抖音纸短情长音乐计算机简谱,抖音纸短情长女版谁唱的 纸短情长计算器简谱完整版...
  6. ue4 培养罐液体效果
  7. 计算机怎样保存文档,【2人回答】怎么在电脑上写文档并保存?-3D溜溜网
  8. 《左手数据,右手图表》
  9. jquery UI 跟随学习笔记——拖拽(Draggable)
  10. 1383: 手机短号 (多实例)