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

    微信支付参考链接:

      (1)微信公众平台开发文档http://mp.weixin.qq.com/wiki/home/index.html

      (2)微信支付普通商户接入文档https://pay.weixin.qq.com/wiki/doc/api/index.html

      (3)接口调试工具http://mp.weixin.qq.com/debug/

      (4)开发者问答系统http://mp.weixin.qq.com/qa/home/index.html

      (5)JSSDK实例代码http://demo.open.weixin.qq.com/jssdk/js/demo.js

      (6)商户后台登陆界面https://pay.weixin.qq.com/index.php/home/login?return_url=%2F

      (7)商户平台开发文档http://pay.weixin.qq.com/wiki/doc/api/index.html

      (8)基于H5的微信支付开发详解http://daimajun.com/web/31.html

      (9)在Web应用中接入微信支付的流程http://www.cnblogs.com/alex1128/p/wxpay.html

    获取时间戳:

      var timestamp1 = Date.parse(new Date());
      var timestamp2 = (new Date()).valueOf();
      var timestamp3 = new Date().getTime();
    注:第一种获取的时间戳是把毫秒改成000显示,第二种和第三种获取了当前毫秒的时间戳。
      获取秒级别的时间戳,可以/1000。

    支付宝支付

    (1)即时支付:https://b.alipay.com/order/productDetail.htm?productId=2015110218012942

    (2)在线文档:https://doc.open.alipay.com/doc2/detail?treeId=62&articleId=103566&docType=1

    设定时间格式化函数:

    Date.prototype.format = function (format) {
        var args = {
            "M+": this.getMonth() + 1,
            "d+": this.getDate(),
            "h+": this.getHours(),
            "m+": this.getMinutes(),
            "s+": this.getSeconds(),
        };
        if (/(y+)/.test(format))
            format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var i in args) {
            var n = args[i];
            if (new RegExp("(" + i + ")").test(format))
                format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? n : ("00" + n).substr(("" + n).length));
        }
        return format;
    };

    微信支付(统一下单)

          思路:

          ①将appid、mch_id、nonce_str、body、attach、out_trade_no、total_fee、spbill_create_ip、notify_url、trade_type 这些参数以键值对的形式拼接起来用MD5进行第一次签名

         ②拼接xml:

          例如:

     <xml>
       <appid>wx2421b1c4370ec43b</appid>
       <attach>支付测试</attach>
       <body>JSAPI支付测试</body>
       <mch_id>10000100</mch_id>
       <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
       <notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url>
       <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
       <out_trade_no>1415659990</out_trade_no>
       <spbill_create_ip>14.23.150.211</spbill_create_ip>
       <total_fee>1</total_fee>
       <trade_type>JSAPI</trade_type>
       <sign>0CB01533B8C1EF103065174F50BCA001</sign>
    </xml>

    ,把这个xml 交个  "https://api.mch.weixin.qq.com/pay/unifiedorder"  在微信 生成一个预支付订单号prepay_id

       ③将 appid、partner、prepay_id、nonce_str、timestamp、partnerkey、key、package  通过键值对的形式拼接,然后MD5加密处理,和第一步加密方式一样进行第二次签名

      ④将appid、partnerid、prepayid、package、noncestr、timestamp、sign  传给 调起微信支付功能

    注:一些用到的方法

    1、MD5  将map 拼接成键值对的串,然后进行加密

    /**
         * 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
         */
        public String createSign(SortedMap<String, String> packageParams) {
            StringBuffer sb = new StringBuffer();
            Set es = packageParams.entrySet();
            Iterator it = es.iterator();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry) it.next();
                String k = (String) entry.getKey();
                String v = (String) entry.getValue();
                if (null != v && !"".equals(v) && !"sign".equals(k)
                        && !"key".equals(k)) {
                    sb.append(k + "=" + v + "&");
                }
            }
            sb.append("key=" + this.getKey());
            String sign = MD5Util.MD5Encode(sb.toString(), this.charset)
                    .toUpperCase();
            return sign;
    
        }

    2、将xml交给 "https://api.mch.weixin.qq.com/pay/unifiedorder"  解析生成 预支付订单

        如果参数提交失败,会在try里的 if 中 返回  开发的时候建议打断点,我是存session ,然后返回错误信息msg

    /**
       *description:获取预支付id
       *@param urls
       *@param xmlParam
       *@return
       * @author ex_yangxiaoyi
       * @see
       */
      public static String getPayNo(String url,String xmlParam){
          Subject currentUser = SecurityUtils.getSubject();  
          Session session = currentUser.getSession();
          
          DefaultHttpClient client = new DefaultHttpClient();
          client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
          HttpPost httpost= HttpClientConnectionManager.getPostMethod(url);
          String prepay_id = "";
         try {
             httpost.setEntity(new StringEntity(xmlParam, "UTF-8"));
             HttpResponse response = httpclient.execute(httpost);
             String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
            if(jsonStr.indexOf("FAIL")!=-1){
                session.setAttribute("error_msg", jsonStr);
                return prepay_id;
            }
            Map map = doXMLParse(jsonStr);
            prepay_id  = (String) map.get("prepay_id");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return prepay_id;
      }
     public static InputStream String2Inputstream(String str) {
           return new ByteArrayInputStream(str.getBytes());
    }

    3、xml解析

    /**
         * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
         * @param strxml
         * @return
         * @throws JDOMException
         * @throws IOException
         */
        public static Map doXMLParse(String strxml) throws Exception {
            if(null == strxml || "".equals(strxml)) {
                return null;
            }
            
            Map m = new HashMap();
            InputStream in = String2Inputstream(strxml);
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(in);
            Element root = doc.getRootElement();
            List list = root.getChildren();
            Iterator it = list.iterator();
            while(it.hasNext()) {
                Element e = (Element) it.next();
                String k = e.getName();
                String v = "";
                List children = e.getChildren();
                if(children.isEmpty()) {
                    v = e.getTextNormalize();
                } else {
                    v = getChildrenText(children);
                }
                
                m.put(k, v);
            }
            
            //关闭流
            in.close();
            
            return m;
        }
    /**
         * 获取子结点的xml
         * @param children
         * @return String
         */
        public static String getChildrenText(List children) {
            StringBuffer sb = new StringBuffer();
            if(!children.isEmpty()) {
                Iterator it = children.iterator();
                while(it.hasNext()) {
                    Element e = (Element) it.next();
                    String name = e.getName();
                    String value = e.getTextNormalize();
                    List list = e.getChildren();
                    sb.append("<" + name + ">");
                    if(!list.isEmpty()) {
                        sb.append(getChildrenText(list));
                    }
                    sb.append(value);
                    sb.append("</" + name + ">");
                }
            }
            
            return sb.toString();
        }

     4、微信回调函数

    /**
         * 微信支付 回调函数
         */
        @RequestMapping("/notify")
        @ResponseBody
        protected void notify(HttpServletRequest request,
                HttpServletResponse response) throws Exception {
            
            PageData pd=new PageData();
            logBefore(logger, "微信支付  回调函数");
            //把如下代码贴到的你的处理回调的servlet 或者.do 中即可明白回调操作
            logger.info("微信支付回调数据开始");
            //示例报文
            //String xml = "<xml><appid><![CDATA[wxb4dc385f953b356e]]></appid><bank_type><![CDATA[CCB_CREDIT]]></bank_type><cash_fee><![CDATA[1]]></cash_fee><fee_type><![CDATA[CNY]]></fee_type><is_subscribe><![CDATA[Y]]></is_subscribe><mch_id><![CDATA[1228442802]]></mch_id><nonce_str><![CDATA[1002477130]]></nonce_str><openid><![CDATA[o-HREuJzRr3moMvv990VdfnQ8x4k]]></openid><out_trade_no><![CDATA[1000000000051249]]></out_trade_no><result_code><![CDATA[SUCCESS]]></result_code><return_code><![CDATA[SUCCESS]]></return_code><sign><![CDATA[1269E03E43F2B8C388A414EDAE185CEE]]></sign><time_end><![CDATA[20150324100405]]></time_end><total_fee>1</total_fee><trade_type><![CDATA[JSAPI]]></trade_type><transaction_id><![CDATA[1009530574201503240036299496]]></transaction_id></xml>";
            String inputLine;
            String notityXml = "";
            String resXml = "";
    
            try {
                while ((inputLine = request.getReader().readLine()) != null) {
                    notityXml += inputLine;
                }
                request.getReader().close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            System.out.println("接收到的报文:" + notityXml);
            
            BufferedWriter writer = new BufferedWriter(new FileWriter(new File("c:\ResultXml.txt"),true));
             //
             writer.write(DateUtil.getTime()+notityXml+"
    ");
             writer.close();
            
            Map m = parseXmlToList2(notityXml);
            WxPayResult wpr = new WxPayResult();
            wpr.setAppid(m.get("appid").toString());
            wpr.setBankType(m.get("bank_type").toString());
            wpr.setCashFee(m.get("cash_fee").toString());
            wpr.setFeeType(m.get("fee_type").toString());
            wpr.setIsSubscribe(m.get("is_subscribe").toString());
            wpr.setMchId(m.get("mch_id").toString());
            wpr.setNonceStr(m.get("nonce_str").toString());
            wpr.setOpenid(m.get("openid").toString());
            wpr.setOutTradeNo(m.get("out_trade_no").toString());
            wpr.setResultCode(m.get("result_code").toString());
            wpr.setReturnCode(m.get("return_code").toString());
            wpr.setSign(m.get("sign").toString());
            wpr.setTimeEnd(m.get("time_end").toString());
            wpr.setTotalFee(m.get("total_fee").toString());
            wpr.setTradeType(m.get("trade_type").toString());
            wpr.setTransactionId(m.get("transaction_id").toString());
            
            if("SUCCESS".equals(wpr.getResultCode())){
                //支付成功
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                //修改订单状态
                pd.put("WX_ORDER", wpr.getOutTradeNo());
                wxPayService.editStatusByOutId(pd);
                //保存订单信息
                pd.put("WX_ORDER_ID", UuidUtil.get32UUID());//微信订单主键ID
                pd.put("OPEN_ID", wpr.getOpenid());//用户的OPEN_ID
                pd.put("MCH_ID", wpr.getMchId());//商户号
                pd.put("NONCE_STR", wpr.getNonceStr());//随机字符串
                pd.put("SIGN", wpr.getSign());//SIGN
                pd.put("CASH_FEE", wpr.getCashFee());//现金支付金额
                pd.put("TOTAL_FEE", wpr.getTotalFee());//总金额
                pd.put("BANK_TYPE", wpr.getBankType());//付款银行
                pd.put("TRADE_TYPE", wpr.getTradeType());//交易类型
                pd.put("RESULT_CODE", wpr.getResultCode());//业务结果
                pd.put("TRANSACTION_ID", wpr.getTotalFee());//微信支付订单号
                pd.put("TIME_END", wpr.getTimeEnd());//微信支付完成时间
                wxPayService.saveWxOrder(pd);
            }else{
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            }
    
            System.out.println("微信支付回调数据结束");
    
            BufferedOutputStream out = new BufferedOutputStream(
                    response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
    
        }

    解析微信通知xml

    /**
         * description: 解析微信通知xml
         * 
         * @param xml
         * @return
         * @author ex_yangxiaoyi
         * @see
         */
        @SuppressWarnings({ "unused", "rawtypes", "unchecked" })
        private static Map parseXmlToList2(String xml) {
            Map retMap = new HashMap();
            try {
                StringReader read = new StringReader(xml);
                // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
                InputSource source = new InputSource(read);
                // 创建一个新的SAXBuilder
                SAXBuilder sb = new SAXBuilder();
                // 通过输入源构造一个Document
                Document doc = (Document) sb.build(source);
                Element root = doc.getRootElement();// 指向根节点
                List<Element> es = root.getChildren();
                if (es != null && es.size() != 0) {
                    for (Element element : es) {
                        retMap.put(element.getName(), element.getValue());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return retMap;
        }
  • 相关阅读:
    微信小程序实现课程表实例
    探索Java中的网络编程技术
    Java中的Spring MVC简介笔记
    我没有想赢,我只是不想输
    下次路过,人间再无我。
    从零基础入门MySQL数据库基础课
    vue.js-详解三大流行框架VUE_快速进阶前端大咖-Vue基础
    学习网站/实用工具,收藏的快搜网站,想找什么都有!!!
    【灵魂拷问】你真的懂得Mysql的管理和使用吗?
    【领会要领】web前端-轻量级框架应用(jQuery基础)
  • 原文地址:https://www.cnblogs.com/sweetyu/p/5163091.html
Copyright © 2011-2022 走看看