• 微信支付对账单下载


    以上是官网文档说明:

    下面是根据文档 梳理下思路:

    /**
    关于签名的算法,api提供的原文是:
    
    1.签名算法
    
    签名生成的通用步骤如下:
    
    第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
    
    特别注意以下重要规则:
     参数名ASCII码从小到大排序(字典序);
     如果参数的值为空不参与签名;
       参数名区分大小写;
     验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
     微信接口可能增加字段,验证签名时必须支持增加的扩展字段
    
    第二步,在stringA最后拼接上key=(API密钥的值)得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
    
    举例:
    
    假设传送的参数如下:
    
    appid: wx8888888888888888
    
    mch_id: 1900000109
    
    device_info: 013467007045764
    
    body: test
    
    nonce_str: 5K8264ILTKCH16CQ2502SI8ZNMTM67VS
    
    第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:
    
    stringA="appid=wx8888888888888888&body=test&device_info=013467007045764&mch_id=1900000109&nonce_str=5K8264ILTKCH16CQ2502SI8ZNMTM67VS";
    
    第二步:拼接API密钥:
    
    stringSignTemp="stringA&key=332F17B766FC787203EBE9D6E40457A1"
    
    sign=MD5(stringSignTemp).toUpperCase()="332F17B766FC787203EBE9D6E40457A1"
    
    */
    

     微信支付签名算法sign:

    String keywx = "9e4b63793722c61a555696be897d61f8";
    	/**
    	 * 微信支付签名算法sign
    	 * 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
                     创建签名 签名 sign 	 
    	 */
    	protected void  createSign(SortedMap<Object,Object> parameters) {
    		StringBuffer sb = new StringBuffer();
    		//parameters 参数集合值
    		Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
    		Iterator it = es.iterator();
    		while(it.hasNext()) {
    			Map.Entry entry = (Map.Entry)it.next();
    			String k = (String)entry.getKey();
    			Object v = entry.getValue();  
    			if(null != v && !"".equals(v) 
    					&& !"sign".equals(k) && !"key".equals(k)) {
    				sb.append(k + "=" + v+ "&" );
    			}
    		}
    		//key就是微信支付账户密钥
    		sb.append("key=" + keywx);
    		//sb.append("key=" + this.getKey());
    		System.out.println("字符串拼接后是:"+sb.toString());  
    		//字体编码 生成MD5的时候,需要统一编码,这里微信api要求是UTF-8
    		String enc = getCharacterEncoding(this.request, this.response);
    		//生成MD5签名验证 注意转换成大写  在此是小写
    		String sign = MD5Util.MD5Encode(sb.toString(), enc).toUpperCase();
    		
    		this.setParameter("sign", sign);
    		
    		//debug信息
    		this.setDebugInfo(sb.toString() + " => sign:" + sign);
    		return ;
    	}
    		/**
    	*设置debug信息
    	*/
    	protected void setDebugInfo(String debugInfo) {
    		this.debugInfo = debugInfo;
    	}
    	/**
    	 * 设置参数值
    	 * @param parameter 参数名称
    	 * @param parameterValue 参数值
    	 */
    	public void setParameter(String parameter, String parameterValue) {
    		String v = "";
    		if(null != parameterValue) {
    			v = parameterValue.trim();
    		}
    		this.parameters.put(parameter, v);
    	}
    	/**
    	 * 获取编码字符集
    	 * @param request
    	 * @param response
    	 * @return String
    	 */
    	public static String getCharacterEncoding(HttpServletRequest request,
    			HttpServletResponse response) {
    		
    		if(null == request || null == response) {
    			return "gbk";
    		}
    		
    		String enc = request.getCharacterEncoding();
    		if(null == enc || "".equals(enc)) {
    			enc = response.getCharacterEncoding();
    		}
    		
    		if(null == enc || "".equals(enc)) {
    			enc = "gbk";
    		}
    		
    		return enc;
    	}
    

     MD5Util方法:

    public class MD5Util {
    
    	private static String byteArrayToHexString(byte b[]) {
    		StringBuffer resultSb = new StringBuffer();
    		for (int i = 0; i < b.length; i++)
    			resultSb.append(byteToHexString(b[i]));
    
    		return resultSb.toString();
    	}
    
    	private static String byteToHexString(byte b) {
    		int n = b;
    		if (n < 0)
    			n += 256;
    		int d1 = n / 16;
    		int d2 = n % 16;
    		return hexDigits[d1] + hexDigits[d2];
    	}
    
    	public static String MD5Encode(String origin, String charsetname) {
    		String resultString = null;
    		try {
    			resultString = new String(origin);
    			MessageDigest md = MessageDigest.getInstance("MD5");
    			if (charsetname == null || "".equals(charsetname))
    				resultString = byteArrayToHexString(md.digest(resultString
    						.getBytes()));
    			else
    				resultString = byteArrayToHexString(md.digest(resultString
    						.getBytes(charsetname)));
    		} catch (Exception exception) {
    		}
    		return resultString;
    	}
    
    	private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
    			"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
    
    }
    

    参数包装成XML格式丢给微信:

     /**
         * 参数包装成XML格式丢给微信
        * */
    	public  String GetpayXmlRequest(String appid,String spid,String getNonce_str,String sign, String trans_time, String bill_type)
    	{  
    		/*
    	   <xml>
    		   <appid>wx8888888888888888</appid>
    		   <bill_date>20160426</bill_date>
    		   <bill_type>ALL</bill_type>
    		   <mch_id>1900000109</mch_id>
    		   <nonce_str>21df7dc9cd8616b56919f20d9f679233</nonce_str>
    		   <sign>E8778F1C4C953C0BF37AA45C3BC379D0</sign>
    		 </xml> 
    	  */
    		
    		       StringBuffer sb = new StringBuffer();  
    			   sb.append("<xml>");  
    			   sb.append("<appid><![CDATA[");  
    			   sb.append(appid);  
    			   sb.append("]]></appid>");  
    			
    			   sb.append("<mch_id><![CDATA[");  
    			   sb.append(spid);  
    			   sb.append("]]></mch_id>");  
    			 
    			   sb.append("<nonce_str><![CDATA[");  
    			   sb.append(getNonce_str);  
    			   sb.append("]]></nonce_str>");  
    			 
    			   sb.append("<sign><![CDATA[");  
    			   sb.append(sign);  
    			   sb.append("]]></sign>");  
    			  
    			   sb.append("<bill_date><![CDATA[");  
    			   sb.append(trans_time);  
    			   sb.append("]]></bill_date>");  
    			 
    			   sb.append("<bill_type><![CDATA[");  
    			   sb.append(bill_type);  
    			   sb.append("]]></bill_type>");  
    			 
    			   sb.append("</xml>");  
    			   return sb.toString();  
    
    		        /*
    		         
    		        sb.append("<appid>");
    		        sb.append(appid);  
    		        sb.append("</appid>");
    		        sb.append("<bill_date>");  
    		        sb.append(trans_time);  
    		        sb.append("</bill_date>");
    		        sb.append("<bill_type>");  
    		        sb.append(bill_type);  
    		        sb.append("</bill_type>");
    		        sb.append("<mch_id>");
    		        sb.append(spid);
    		        sb.append("</mch_id>");
    		        sb.append("<nonce_str>"); 
    		        sb.append(stamp);  
    		        sb.append("</nonce_str>");
    		        sb.append("<sign>"); 	
    		        sb.append(sign); 
    		        sb.append("</sign>");
    		        sb.append("</xml>");  
    		       return sb.toString();  
    		       */
    
    		    }  
    

     post发送请求数据:

    /** 请求的参数 */
    	protected SortedMap parameters;
    	
        protected HttpServletRequest request;
    	
    	protected HttpServletResponse response;
    	/** 密钥 */
    	protected String key;
    	/** debug信息 */
    	protected String debugInfo;
    	
    	/**
    	*获取密钥
    	*/
    	public String getKey() {
    		return key;
    	}
    	/**
    	*设置密钥
    	*/
    	public void setKey(String key) {
    		this.key = key;
    	}
    	
    	/**
    	 * post发送请求数据
    	 * @param urlStr
    	 */
    	public  void testPost(String urlStr) {  
    		 BufferedReader br= null;
    		 HttpURLConnection con=null;
    		 OutputStreamWriter out=null;
    		        try {  
    		            URL url = new URL(urlStr);  
    		           // URLConnection con = url.openConnection(); 
    		            con = (HttpURLConnection) url.openConnection(); 
    		         // 发送POST请求必须设置如下两行
    		            con.setDoOutput(true);  // POST方式
    		            con.setDoInput(true);
    		            con.setUseCaches(false);
    		            con.setRequestMethod("POST"); 
    		         // 设置通用的请求属性
    		            con.setRequestProperty("accept", "*/*");
    		            con.setRequestProperty("connection", "Keep-Alive");
    		            con.setRequestProperty("user-agent",
    		                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
    		            
    //		            con.setRequestProperty("Pragma:", "no-cache");  
    //		            con.setRequestProperty("Cache-Control", "no-cache");  
    //		            con.setRequestProperty("Content-Type", "text/xml");  
    		            
    		            // 输出流,写数据
    		             out = new OutputStreamWriter(con  
    		                   .getOutputStream(),"UTF-8");    
    		            
    		            
    		         // 发送请求参数
    		            String xmlInfo = GetpayXmlRequest("wx8888888888888888","1900000109","1462240367309","56B106AFDDF1802B12DF8634C2E73B92","20160623","ALL");  
    		            System.out.println("urlStr=" + urlStr);  
    		            System.out.println("xmlInfo=" + xmlInfo);  
    		           out.write(new String(xmlInfo.getBytes("UTF-8"))); 
    		        // flush输出流的缓冲
    		            out.flush();  
    		           // out.close();  
    		          //读取服务器的响应内容并显示 定义BufferedReader输入流来读取URL的响应
    		            br = new BufferedReader(new InputStreamReader(con  
    		                    .getInputStream(),"UTF-8"));  
    		           String line = "";  
    		           StringBuffer buffer = new StringBuffer();
    //		            for (line = br.readLine(); line != null; line = br.readLine()) {  
    //		               System.out.println(line);  
    //		               buffer.append(line);// 将读到的内容添加到 buffer 中
    //		               buffer.append("
    "); // 添加换行符
    //
    //		            } 
    		            while ((line = br.readLine()) != null)
    		            {   
    		            buffer.append(line); // 将读到的内容添加到 buffer 中
    		            buffer.append("
    "); // 添加换行符
    		            System.out.println(line);  
    	                }  
    		            
    		            //con.getOutputStream().close();
    		        } 
    		        catch (MalformedURLException e) 
    		        {  
    		            e.printStackTrace();  
    		        } 
    		        catch (IOException e)
    		        {  
    		            e.printStackTrace();  
    		        }  
    		        // 使用finally块来关闭输入流
    		        finally {
    		            try {
    		            	if(out!=null){
    		                    out.close();
    		                }
    
    		                if (br != null) 
    		                {
    		                	br.close();
    		                	con.disconnect();
    		                }
    		            } catch (Exception e2) {
    		                e2.printStackTrace();
    		            }
    		        }
    
    		    }  
    

     

    /**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		String url = "https://api.mch.weixin.qq.com/pay/downloadbill";  
    		 
    		  new HttpPostTest().testPost(url);  
    
    		    
    		  //微信api提供的参数   赋值
    		    String appid="wx8888888888888888"; 
    		    String spid="1900000109";//       1221024001
    		    String getNonce_str="1462240367309";//1462240367309  ibuaiVcKdpRxkhJA
    		    String trans_time="20160623";
    		    String bill_type="ALL";
    		    String sign ="";
    	         
    		   // 获取值
    	        SortedMap<Object,Object> sparameters = new TreeMap<Object,Object>();  
    	        sparameters.put("appid", appid);
    	        sparameters.put("mch_id", spid); 
    	        sparameters.put("nonce_str", getNonce_str);
    	        sparameters.put("bill_date", trans_time);  
    	        sparameters.put("bill_type", bill_type);  
    	         
    	        // new HttpPostTest().createSign(sparameters);
    	}
    

     注意 以上单元测试时要先 创建生成签名后,再把签名的值传到参数中去,然后进行httppost请求即可。

     这里商户号 一定都要改成自己申请的appid 和 mch_id 这样就会有微信返回结果数据显示了,结果实例就不在这里展现出来。

      获取到对账信息后就是后续的业务处理了,根据不同的需求进行不同的业务处理了,主要就是解析数据格式,生成文档,保存到本地以及导入到数据库的逻辑操作了。

     

  • 相关阅读:
    mysql03聚合函数
    栈、队列、循环队列、双端队列、优先级队列04
    OOAD之策略模式(1)
    jvm01:java内存区域与内存
    Python+Selenium
    Python+Selenium
    Python+Selenium
    Python+Selenium
    Python+Selenium
    Python+Selenium
  • 原文地址:https://www.cnblogs.com/Warmsunshine/p/5715088.html
Copyright © 2020-2023  润新知