二维码扫码支付实现方案(仅供自己参考)

    xiaoxiao2023-10-23  175

    目录

    二维码介绍

    二维码生成插件qrious

    申请微信二维码支付

    HttpClient工具类的简单使用

    生成二维码服务

    spring  mvc控制层

    页面控制层


    前言

    此篇仅供自己参考,你们看不懂的,不要浪费时间

    此篇会讲解,微信二维码的生成,以及检测支付状态,支付日志

     

     

     

    二维码介绍

     

    二维码生成插件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:'http://www.baidu.com' }); </script> </body> </html>

     

    申请微信二维码支付

    官方有文档 https://pay.weixin.qq.com/wiki/doc/api/index.html

    把他们的sdk安装到本地maven仓库

     

    HttpClient工具类的简单使用

    HttpClient通俗的讲就是模拟了浏览器的行为,如果我们需要在后端向某一地址提交数据获取结果,就可以使用HttpClient

    生成二维码服务

    @Service public class WeixinPayServiceImpl implements WeixinPayService { @Value("${appid}") private String appid; @Value("${partner}") private String partner; @Value("${partnerkey}") private String partnerkey; /** * 生成二维码 * @return */ public Map createNative(String out_trade_no,String total_fee){ //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", out_trade_no);//商户订单号 param.put("total_fee",total_fee);//总金额(分) param.put("spbill_create_ip", "127.0.0.1");//IP param.put("notify_url", "http://test.itcast.cn");//回调地址(随便写) param.put("trade_type", "NATIVE");//交易类型 try { //2.生成要发送的xml String 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", total_fee);//总金额 map.put("out_trade_no",out_trade_no);//订单号 return map; } catch (Exception e) { e.printStackTrace(); return new HashMap<>(); } } }

    spring  mvc控制层

    @RestController @RequestMapping("/pay") public class PayController { @Reference private WeixinPayService weixinPayService; /** * 生成二维码 * @return */ @RequestMapping("/createNative") public Map createNative(){ IdWorker idworker=new IdWorker(); return weixinPayService.createNative(idworker.nextId()+"","1"); } }

     

    页面控制层

    app.controller('payController' ,function($scope ,payService){ //本地生成二维码 $scope.createNative=function(){ payService.createNative().success( function(response){ $scope.money= (response.total_fee/100).toFixed(2) ; //金额 $scope.out_trade_no= response.out_trade_no;//订单号 //二维码 var qr = new QRious({ element:document.getElementById('qrious'), size:250, level:'H', value:response.code_url }); } ); } });

     

    监控支付状态

    支付成功跳转到支持成功页面,支付失败跳到失败页面

    还需要在生成二维码生成的页面控制层加入页面查询支付状态函数

    public Map queryPayStatus(String out_trade_no) { Map param=new HashMap(); param.put("appid", appid);//公众账号ID param.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; } }

    spring mvc控制层

    @RequestMapping("/queryPayStatus") public Result queryPayStatus(String out_trade_no){ Result result=null; while(true){ //调用查询接口 Map<String,String> map = weixinPayService.queryPayStatus(out_trade_no); if(map==null){//出错 result=new Result(false, "支付出错"); break; } if(map.get("trade_state").equals("SUCCESS")){//如果成功 result=new Result(true, "支付成功"); break; } try { Thread.sleep(3000);//间隔三秒 } catch (InterruptedException e) { e.printStackTrace(); } } return result; }

     

    查询时间限制

    修改查询状态代码

    @RequestMapping("/queryPayStatus") public Result queryPayStatus(String out_trade_no){ Result result=null; int x=0; while(true){ //调用查询接口 ....... try { Thread.sleep(3000);//间隔三秒 } catch (InterruptedException e) { e.printStackTrace(); } //为了不让循环无休止地运行,我们定义一个循环变量,如果这个变量超过了这个值则退出循环,设置时间为5分钟 x++; if(x>=100){ result=new Result(false, "二维码超时"); break; } } return result; }

    修改页面查询状态的控制层

     

     

    支付成功页面显示金额

    只需要利用angularJS的页面传参

     

    支付日志问题

    参考代码

    public void add(TbOrder order) { List<Cart> cartList = (List<Cart>) redisTemplate.boundHashOps("cartList").get( order.getUserId() ); List<String> orderIdList=new ArrayList();//订单ID列表 double total_money=0;//总金额 (元) for(Cart cart:cartList){ long orderId = idWorker.nextId(); ...... orderIdList.add(orderId+"");//添加到订单列表 total_money+=money;//累加到总金额 } if("1".equals(order.getPaymentType())){//如果是微信支付 TbPayLog payLog=new TbPayLog(); 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());//用户ID payLogMapper.insert(payLog);//插入到支付日志表 redisTemplate.boundHashOps("payLog").put(order.getUserId(), payLog);//放入缓存 } redisTemplate.boundHashOps("cartList").delete(order.getUserId()); } public TbPayLog searchPayLogFromRedis(String userId) { return (TbPayLog) redisTemplate.boundHashOps("payLog").get(userId); } @RequestMapping("/createNative") public Map createNative(){ //获取当前用户 String userId=SecurityContextHolder.getContext().getAuthentication().getName(); //到redis查询支付日志 TbPayLog payLog = orderService.searchPayLogFromRedis(userId); //判断支付日志存在 if(payLog!=null){ return weixinPayService.createNative(payLog.getOutTradeNo(),payLog.getTotalFee()+""); }else{ return new HashMap(); } } public void updateOrderStatus(String out_trade_no, String transaction_id) { //1.修改支付日志状态 TbPayLog payLog = payLogMapper.selectByPrimaryKey(out_trade_no); payLog.setPayTime(new Date()); payLog.setTradeState("1");//已支付 payLog.setTransactionId(transaction_id);//交易号 payLogMapper.updateByPrimaryKey(payLog); //2.修改订单状态 String orderList = payLog.getOrderList();//获取订单号列表 String[] orderIds = orderList.split(",");//获取订单号数组 for(String orderId:orderIds){ TbOrder order = orderMapper.selectByPrimaryKey( Long.parseLong(orderId) ); if(order!=null){ order.setStatus("2");//已付款 orderMapper.updateByPrimaryKey(order); } } //清除redis缓存数据 redisTemplate.boundHashOps("payLog").delete(payLog.getUserId()); }

    在微信支付接口有成功返回状态时,调用修改状态的方法

     

     

     

     

     

     

     

     

     

    最新回复(0)