zoukankan      html  css  js  c++  java
  • 微信支付

    微信支付

    二维码

    概述

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

    QRCode使用

    下载QRCode.js

    使用

    var qrcode = new QRCode(document.getElementById("qrcode"), {
        width : 250,
        height : 250
    });
    qrcode.makeCode(response.data.code_url);
    

    微信支付

    介绍

    	微信扫码支付是商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。该模式适用于PC网站支付、实体店单品或订单支付、媒体广告支付等场景。
    

    申请步骤

    1.注册公众号(服务号-企业才能注册)
    2.认证公众号(认证费300元/年)
    3.提交资料申请微信支付

    4.开户成功,登录商户平台进行验证
    公众号/与商户号支付信息获取

    • appid
    • mch_id
    • partnerkey

    5.启用Native

    微信支付API

    支付流程

    添加pom依赖
    <dependency>
        <groupId>com.github.wxpay</groupId>
        <artifactId>wxpay-sdk</artifactId>
        <version>0.0.3</version>
    </dependency>
    
    WXPayUtil
    获取随机字符串
    	WXPayUtil.generateNonceStr()
    MAP转换为XML字符串(自动添加签名)
    	 WXPayUtil.generateSignedXml(param, partnerkey)
    XML字符串转换为MAP
    	WXPayUtil.xmlToMap(result)
    

    结算支付

    在pay.html页面当中添加vue相关JS

    <script type="text/javascript" src="plugins/vue/vuejs-2.5.16.js"></script>
    <script type="text/javascript" src="plugins/vue/axios-0.18.0.js"></script>
    <script type="text/javascript" src="plugins/vue/qs.js"></script>
    <script type="text/javascript" src="plugins/qrcode.min.js"></script>
    

    页面加载完毕后,获取支付信息

    定义属性

    
    new Vue({
        el:"#app",
        data:{
            money:0, //支付金额
            out_trade_no:'' //支付订单号
        },
        createNative: function () {
    		let _this = this;
    		axios.post("/pay/createNative.do")
    				.then(function (response) {
    					//显示订单号和金额
    					_this.money= (response.data.total_fee/100).toFixed(2);
    					_this.out_trade_no=response.data.out_trade_no;
    					console.log(response.data);
    					var qrcode = new QRCode(document.getElementById("qrcode"), {
    						width : 250,
    						height : 250
    					});
    					qrcode.makeCode(response.data.code_url);
    					_this.queryPayStatus();//调用查询支付结果
    				}).catch(function (reason) {
    					console.log(reason);
    				});
    	},
    	queryPayStatus:function(){
    		let _this = this;
    		axios.get('/pay/queryPayStatus.do?out_trade_no='+_this.out_trade_no)
    				.then(function (response) {
    					if(response.data.success){
    						location.href="paysuccess.html#?money="+_this.money;
    					}else{
    						if(response.data.message=='二维码超时'){
    							this.createNative();//重新生成二维码
    						}else{
    							location.href="payfail.html";
    						}
    					}
    				}).catch(function (reason) {
    			console.log(reason);
    		});
    	}
    });
    
    

    支付接口

    interface/PayService

        public interface PayService {
            /**
             * 获取支付信息
             * @param outTradeNo 订单号
             * @param totalFee  支付金额
             * @return   支付信息
             */
            public Map createNative(String outTradeNo, String totalFee);
        
            /**
             * 根据订单号, 查询支付状态
             * @param out_trade_no
             * @return
             */
            public Map queryPayStatus(String out_trade_no);
        }
    

    service_buyer/PayServiceImpl

    在properties/weixinpay.properties添加支付商户信息
        appid=
        partner=
        partnerkey=
        notifyurl=
    
    加载商户信息
    @Service
    public class PayServiceImpl implements PayService {
        //微信公众账号或开放平台APP的唯一标识
        @Value("${appid}")
        private String appid;
    
        //财付通平台的商户账号
        @Value("${partner}")
        private String partner;
    
        //财付通平台的商户密钥
        @Value("${partnerkey}")
        private String partnerkey;
    
        //回调地址
        @Value("${notifyurl}")
        private String notifyurl;
    }
    
    获取微信支付信息
    @Override
    public Map createNative(String outTradeNo, String totalFee) {
    ​	//1.创建参数
    ​	Map<String,String> param=new HashMap();//创建参数
    ​	param.put("appid", appid);//公众号
    ​	param.put("mch_id", partner);//商户号
    ​	param.put("body", "myxq");//商品描述
    ​	param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
    ​	param.put("out_trade_no", outTradeNo);//商户订单号
    ​	param.put("total_fee",totalFee);//总金额(分)
    ​	param.put("spbill_create_ip", "127.0.0.1");//IP
    ​	param.put("notify_url", "http://www.baidu.com");//回调地址(随便写)
    ​	param.put("trade_type", "NATIVE");//交易类型
    ​	try {
    ​		//2.生成要发送的xml , 调用微信sdk的api接口将封装的map数据自动转换成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);
    ​		//调用微信sdk的api接口将xml格式字符串自动转换成Java对象
    ​		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<>();
    ​	}
    }
    

    查询支付状态

    @Override
    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;
    ​	}
    }
    

    web_portal/PayController

    支付接口

    @RestController
    @RequestMapping("/pay")
    public class PayController {
        @Reference
        private OrderService orderService;
        @Reference
        private PayService payService;
    
        /**
        *  支付信息接口
         * 获取当前登录用户名,
         * 根据用户名获取redis中的支付日志对象,
         * 根据支付日志对象中的支付单号和总金额
         * 调用微信统一下单接口, 生成支付链接返回
         * @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");
                return map;
            }
            return new HashMap();
        }
    
        /**
         * 支付状态查询接口
         * 调用查询订单接口, 查询是否支付成功
         * @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. 判断支付单号等于null
                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;
        }
    }
    
    
  • 相关阅读:
    obj,lib,dll,exe
    .net连接access数据库 关键字引起的 语句的语法错误
    XSS攻击与防御
    location.href和location.replace和location.reload的不同(location.replace不记录历史)
    C++中头文件包含问题
    SqlServerExpress2005 自动备份
    在SQL Server 的使用过程中,发现几个很有用,但不太常用
    双机镜像
    浅谈SQL Server identity列的操作方法
    镜像三机
  • 原文地址:https://www.cnblogs.com/mumuyinxin/p/11714408.html
Copyright © 2011-2022 走看看