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

    微信支付分很多种,其中微信H5支付是给在手机浏览器上使用,在手机上发起付款,自动跳转到微信并付款

    微信支付开发文档:https://pay.weixin.qq.com/wiki/doc/api/index.html

    微信H5支付文档:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_1

    微信统一下单接口:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_1

    微信H5支付流程:

    1、用户在商户侧完成下单,使用微信支付进行支付

    2、由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB

    3、统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名“mweb_url”),商户通过mweb_url调起微信支付中间页

    4、中间页进行H5权限的校验,安全性检查(此处常见错误请见下文)

    5、如支付成功,商户后台会接收到微信侧的异步通知

    6、用户在微信支付收银台完成支付或取消支付,返回商户页面(默认为返回支付发起页面)

    7、商户在展示页面,引导用户主动发起支付结果的查询

    8,9、商户后台判断是否接到收微信侧的支付结果通知,如没有,后台调用我们的订单查询接口确认订单状态

    10、展示最终的订单支付结果给用户

    支付部分代码:

       /**
         * 微信H5支付2号方案
         */
        @RequestMapping("/wapPay")
        @ResponseBody
        public net.sf.json.JSONObject pay(HttpServletRequest  request, HttpServletResponse response, Integer userid, Double money, Integer num)
                throws ServletException, IOException {
    
            request.setCharacterEncoding("UTF-8");
            net.sf.json.JSONObject json = new net.sf.json.JSONObject();
    
            String ip = null;
    
            //以下代码为获取请求的公网IP
            //X-Forwarded-For:Squid 服务代理
            String ipAddresses = request.getHeader("X-Forwarded-For");
    
            if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
                //Proxy-Client-IP:apache 服务代理
                ipAddresses = request.getHeader("Proxy-Client-IP");
            }
    
            if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
                //WL-Proxy-Client-IP:weblogic 服务代理
                ipAddresses = request.getHeader("WL-Proxy-Client-IP");
            }
    
            if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
                //HTTP_CLIENT_IP:有些代理服务器
                ipAddresses = request.getHeader("HTTP_CLIENT_IP");
            }
    
            if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
                //X-Real-IP:nginx服务代理
                ipAddresses = request.getHeader("X-Real-IP");
            }
    
            //有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
            if (ipAddresses != null && ipAddresses.length() != 0) {
                ip = ipAddresses.split(",")[0];
            }
    
            //还是不能获取到,最后再通过request.getRemoteAddr();获取
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
                ip = request.getRemoteAddr();
            }
            if (StrKit.isBlank(ip)) {
                ip = "127.0.0.1";
            }
    
            int intMoney =(int)(money * 100);
            //商户相关资料
            String appid = "***";//公众号appid
            String appsecret = "***";//公众号秘钥
            String partner = "***";//商户号
            String partnerkey = "***";//商户API秘钥
    
            //用于获取随机数
            String currTime = TenpayUtil.getCurrTime();//获取当前时间
            String strTime = currTime.substring(8, currTime.length());//8位日期
            String strRandom = TenpayUtil.buildRandom(4) + "";//四位随机数
            String strReq = strTime + strRandom;//10位序列号,可以自行调整
    
            String orderNo=appid+userid+ Sha1Util.getTimeStamp();//随机生成了一个订单号
    
            //商户号
            String mch_id = partner;
    
            //设备号   非必输
            String device_info="WEB";
    
            //随机数
            String nonce_str = strReq;
    
            //商品描述
            String body = "号码筛选充值";
    
            //附加数据
            String attach = "shengyu";
    
            //商户订单号
            String out_trade_no = orderNo;
    
            //总金额以分为单位,不带小数点
            int total_fee = intMoney;
    
    //        String spbill_create_ip = request.getRemoteAddr();
            String spbill_create_ip = ip;
    
            String trade_type = "MWEB";//H5支付方式
    
            SortedMap<String, String> packageParams = new TreeMap<String, String>();
            packageParams.put("appid", appid);
            packageParams.put("mch_id", mch_id);
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("body", body);
            packageParams.put("attach", attach);
            packageParams.put("out_trade_no", out_trade_no);
            packageParams.put("total_fee", String.valueOf((intMoney)));
            packageParams.put("spbill_create_ip", spbill_create_ip);
            packageParams.put("notify_url", notify_url);
            packageParams.put("trade_type", trade_type);
            RequestHandler reqHandler = new RequestHandler(request, response);
            reqHandler.init(appid, appsecret, partnerkey);
    
            //获取签名
            String sign = reqHandler.createSign(packageParams);
    
            String xml="<xml>"+
                    "<appid>"+appid+"</appid>"+
                    "<mch_id>"+mch_id+"</mch_id>"+
                    "<nonce_str>"+nonce_str+"</nonce_str>"+
                    "<sign>"+sign+"</sign>"+
                    "<body>"+body+"</body>"+
                    "<attach>"+attach+"</attach>"+
                    "<out_trade_no>"+out_trade_no+"</out_trade_no>"+
                    "<total_fee>"+total_fee+"</total_fee>"+
                    "<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
                    "<notify_url>"+notify_url+"</notify_url>"+
                    "<out_trade_no>"+ orderNo+"</out_trade_no>"+
                    "<trade_type>"+trade_type+"</trade_type>"+
                    "</xml>";
    
            String allParameters = "";//没用
            try {
                allParameters =  reqHandler.genPackage(packageParams);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            //请求微信统一下单接口,成功后返回预支付交易会话标识prepay_id
            String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
            String prepay_id = "";
            String mweb_url="";
            try {
                Map<String ,String> returnmap= new GetWxOrderno().getPayNo(createOrderURL, xml);
                prepay_id=returnmap.get("prepay_id");
                mweb_url=returnmap.get("mweb_url");
                if(prepay_id.equals("")){
                    json.put("msg","统一支付接口获取预支付订单出错");
                    return json;
                }
                //这里可以放增加订单信息
    
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
    
            //生成H5调起微信支付API相关参数(前端页面js的配置参数)
            SortedMap<String, String> finalpackage = new TreeMap<String, String>();
            String timestamp = Sha1Util.getTimeStamp();//当前时间的时间戳
            String packages = "prepay_id="+prepay_id;;//订单详情扩展字符串
            finalpackage.put("appId", appid);//公众号appid
            finalpackage.put("timeStamp", timestamp);
            finalpackage.put("nonceStr", strReq); //随机数
            finalpackage.put("package", packages);
            finalpackage.put("signType", "MD5");//签名方式
            String finalsign = reqHandler.createSign(finalpackage);//签名
    
            String returnurl_1="";
            try {
                returnurl_1=returnurl;
                // 将普通字符创转换成application/x-www-from-urlencoded字符串
                returnurl_1 = URLEncoder.encode(returnurl, "GBK"); 
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            json.put("appId", appid);
            json.put("timeStamp", timestamp);
            json.put("nonceStr", strReq);
            json.put("packages", packages);
            json.put("sign", finalsign);
            json.put("mweb_url", mweb_url+"&redirect_url="+returnurl);//+"&redirect_url=wap%2frechargeSuccess.html"
            return json;
        }
    
        /**
         * 支付完成的回调,修改订单状态等
         * @return
         */
        @ResponseBody
        @RequestMapping("/trueOrder")
        public String notify(HttpServletRequest request, HttpServletResponse response)
                throws Exception {
    
            BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
    
            StringBuilder jsonStr = sb;
            Map<String, Object> dataMap = new HashMap<String, Object>();
    
            Map map = doXMLParse(jsonStr.toString());
            String out_trade_no  = (String) map.get("out_trade_no");//获取订单号
            //下面是根据订单号修改订单状态、账户余额等
    
            //返回,如果不加可能会请求多次
            return  "<xml>" +
                    "<return_code><![CDATA[SUCCESS]]></return_code>" +
                    "<return_msg><![CDATA[支付成功]]></return_msg>" +
                    "</xml>";
        }
  • 相关阅读:
    java内联函数
    jvm垃圾回收
    jvm内存管理
    java进程和线程的区别
    jvm
    简单易学的SSM(Spring+SpringMVC+MyBatis)整合
    Spring之声明式事务
    SpringMVC知识点小结
    Servlet之文件的上传与下载
    java使用字节流和字符流实现文件复制
  • 原文地址:https://www.cnblogs.com/jiangwz/p/9088367.html
Copyright © 2011-2022 走看看