品优购项目笔记(十四):微信支付
品优购项目笔记(十四)
- 订单
- 订单三张表关系
- 提交订单
- 二维码
- 介绍
- 优势
- 容错级别
- 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;}}
品优购项目笔记(十四):微信支付相关推荐
- 「学习笔记」品优购项目-上(页面公共部分 )
「学习笔记」品优购项目-上 品优购项目-上 目标 品优购项目规划 网站制作流程 品优购项目介绍 品优购项目的学习目的 开发工具以及技术栈 开发工具 技术栈 品优购项目搭建工作 创建的文件夹如下(称为项 ...
- b站pink老师前端课程、品优购项目(跟着练的笔记+代码)
02.网站制作流程 1. 03.品优购项目规划 04.项目搭建 05.样式的模块化开发 06.favicon图标制作 favicon.ico一般用于作为略缩图的网站标志,它显示在浏览器的地址栏或者标签 ...
- 14.------------------------------------------------------------------------------【PC端品优购项目】
文章目录 [PC端品优购项目]前端小抄(14) 电商-主页 电商-分类列表页 电商-注册页 一.品优购项目规划 1.1 网站制作流程 1.2 品优购项目整体介绍 1.3 品优购项目的学习目的 1.4 ...
- day18(续)PC端品优购项目
一.品优购项目导读 网站制作流程 原型图 三.品优购项目规划 四.品优购项目搭建工作 五.样式的模块化开发 六.favicon图标制作 七.TDK三大标签ASEO优化 八.品优购首页制作 logo s ...
- 品优购项目的制作——知识分享
目录 前言 一.首页 1.基本的布局 2.版心部分 3.主要内容模块 二.注册页面 三.产品列表页面 四.产品详情页面 总结 前言 品优购项目是一个需要糅杂大量HTML5+CSS3知识点的网站项目,一 ...
- CSS 8 品优购项目
目录 1.品优购项目规划 1.1网站制作流程 1.2品优购项目整体介绍 1.3品优购项目的学习目的 1.4开发工具以及技术栈 小总结 1.5品优购项目搭建工作. 1.5.1创建文件夹 1.5.2创建 ...
- 品优购项目学习---基本概述(简略)
做项目期间看不懂的可以查阅 标记有 注 的这些部分的内容 一定会有你的需要的答案哦 如果没有 那小卓这边建议 可以直接私信小卓 小卓一定尽力提供最优解释哈 等第二遍做的时候进行梳理 注: CS ...
- 前端——品优购项目(html+css)
前端--品优购项目 文章目录 前端--品优购项目 一.品优购项目规划 二.首页 公共部分(common.css) 快捷导航模块 header模块 nav导航部分 底部模块 首页专有部分(index.c ...
- css三角形之美与品优购项目
CSS三角形之美 div{width: 0;height: 0;line-height:0;font-size: 0;border-top: 10px solid red;border-right:1 ...
最新文章
- 数据蒋堂 | 非等值分组
- VS2017缺少头文件的解决办法
- python装饰器 property_python中property和setter装饰器用法
- 自动化系列-pyppeteer键盘输入点击
- 【KMP模板】简单写个KMP~
- 2017.2.14-15自测(那些普及神题)
- 使用折半查找法查找数组中的元素
- 小甲鱼python飞机大战素材_用Python做飞机大战(含素材)
- 绝地反击:我的战胜贫困的经历01(转载、整理)
- 删库跑路技巧 删库跑路命令
- 智能人物画像综合分析系统——Day16
- Manifest is not valid JSON. Line: 1, column: 1 项目打包报错解决方法
- HTML学生个人网站作业设计——HTML+CSS+JavaScript优分期大学生分期购物商城(7页)
- Web前端面试题整合,持续更新【可以收藏】
- wifi频谱仪测试软件,使用频谱仪测试2.4G信号的测试方法,求助
- 机器学习入门(浅谈L1和L2正则)
- python中scale什么意思啊_python数字图像处理(7):图像的形变与缩放
- 20个国内Android平台移动应用市场
- 学海无涯!2021年抓住金三银四涨薪好时机,持续更新中
- 微信小程序获取openid中的问题