微信APP支付统一下单、加签、map转xml,java代码

前端之家收集整理的这篇文章主要介绍了微信APP支付统一下单、加签、map转xml,java代码前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

流程:前端创建订单,后端保存订单并调用微信统一下单接口,将微信返回的预支付回话标识返回给客户端。

统一下单:

1.统一下单参数设置(map)


2.将参数加签,并将sign加入到map(这里注意,key是需要自己去设置的,设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置。加签官方文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.PHP?chapter=4_3)


3.map转xml然后转string


4.请求api(注意:请求方式POST,设置编码格式UTF-8)


5.解析微信返回的xml格式数据,并根据业务需求,格式化后返回给客户端




遇到的报错:
1.APP没有支付权限或者商户号和APP_ID不符合。这里是因为你的参数不是微信APP支付需要的参数,你用了微信其他的参数,建议关注微信官方公众号:WXPayService,里面有个接入指南,按照他的流程做,一次通过。公众号支付和扫码支付流程及技术指引也有。
2.签名错误。一方面可能是你的签名过程有问题,另一方面是可能你的参数(例如KEY有问题,他也会报签名错误),遇到这个错误建议用官方提供的 加签工具 验证你的签名是否正确,如果你的结果和他的结果一样,那应该就是你的参数有问题,加签工具地址:https://pay.weixin.qq.com/wiki/tools/signverify/。
2.time_expire时间过短。过期时间应该在当前系统时间之后。


附上代码

  1. 加签
  2.  public static String getSign(Map<String,String> map){ 	
  3.     	String StringA =  util.StringUtil.formatUrlMap(map,true,true);
  4.     	String stringSignTemp = MD5.MD5Encode(StringA+"&key="+AliPayConfig.weixin_key).toUpperCase();  
  5.     	return stringSignTemp;   
  6.     }
    /**  
  7.      *  
  8.      * 方法用途: 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序),并且生成url参数串
  9.      * 实现步骤: 
  10.      * @param paraMap   要排序的Map对象  
  11.      * @param urlEncode   是否需要URLENCODE  
  12.      * @param keyToLower    是否需要将Key转换为全小写  
  13.      *            true:key转化成小写,false:不转化  
  14.      * @return  
  15.      */  
  16.     public static String formatUrlMap(Map<String,String> paraMap,boolean urlEncode,boolean keyToLower)  
  17.     {  
  18.         if(paraMap == null){  
  19.             return "";  
  20.         }  
  21.         String buff = "";  
  22.         Map<String,String> tmpMap = paraMap;  
  23.         try  
  24.         {  
  25.             List<Map.Entry<String,String>> infoIds = new ArrayList<Map.Entry<String,String>>(tmpMap.entrySet());  
  26.             // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)  
  27.             Collections.sort(infoIds,new Comparator<Map.Entry<String,String>>()  
  28.             {  
  29.                 @Override  
  30.                 public int compare(Map.Entry<String,String> o1,Map.Entry<String,String> o2)  
  31.                 {  
  32.                     return (o1.getKey()).toString().compareTo(o2.getKey());  
  33.                 }  
  34.             });  
  35.             // 构造URL 键值对的格式  
  36.             StringBuilder buf = new StringBuilder();  
  37.             for (Map.Entry<String,String> item : infoIds)  
  38.             {  
  39.                     String key = item.getKey();  
  40.                     String val = item.getValue();  
  41.                     if (urlEncode)  
  42.                     {  
    			//如果是中文,则不参与编码
  43.                        if(key.equals("package")){
  44.           		
  45.         }else if(key.equals("body")){
  46.           		
  47.         }else if(key.equals("notify_url")){
  48.           		
  49.        	}else{
  50.          val = URLEncoder.encode(val,"utf-8"); 
  51.         }
  52.                     }  
  53.                     if (keyToLower)  
  54.                     {  
  55.                         buf.append(key.toLowerCase() + "=" + val);  
  56.                     } else  
  57.                     {  
  58.                         buf.append(key + "=" + val);  
  59.                     }  
  60.                     buf.append("&");  
  61.             }  
  62.             buff = buf.toString();  
  63.             if (buff.equals("") == false)  
  64.             {  
  65.                 buff = buff.substring(0,buff.length() - 1);  
  66.             }  
  67.         } catch (Exception e)  
  68.         {  
  69.             return null;  
  70.         }  
  71.         return buff;  
  72.     }  
  73.  /**
  74.      * MD5编码
  75.      * @param origin 原始字符串
  76.      * @return 经过MD5加密之后的结果
  77.      */
  78.     public static String MD5Encode(String origin) {
  79.         String resultString = null;
  80.         try {
  81.             resultString = origin;
  82.             MessageDigest md = MessageDigest.getInstance("MD5");
  83.             resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
  84.         } catch (Exception e) {
  85.             e.printStackTrace();
  86.         }
  87.         return resultString;
  88.     }
  89.   /**
  90.      * 转换字节数组为16进制字串
  91.      * @param b 字节数组
  92.      * @return 16进制字串
  93.      */
  94.     public static String byteArrayToHexString(byte[] b) {
  95.         StringBuilder resultSb = new StringBuilder();
  96.         for (byte aB : b) {
  97.             resultSb.append(byteToHexString(aB));
  98.         }
  99.         return resultSb.toString();
  100.     }
  101.  /**
  102.      * 转换byte到16进制
  103.      * @param b 要转换的byte
  104.      * @return 16进制格式
  105.      */
  106.     private static String byteToHexString(byte b) {
  107.         int n = b;
  108.         if (n < 0) {
  109.             n = 256 + n;
  110.         }
  111.         int d1 = n / 16;
  112.         int d2 = n % 16;
  113.         return hexDigits[d1] + hexDigits[d2];
  114.     }
    ===============================================================================
    mapxml然后转string

    private static final String PREFIX_XML = "<xml>";
  115. 	private static final String SUFFIX_XML = "</xml>";
  116. 	private static final String PREFIX_CDATA = "<![CDATA[";
  117. 	private static final String SUFFIX_CDATA = "]]>";
  118. public static String xmlFormat(Map<String,String> parm,boolean isAddCDATA) {
  119. 		StringBuffer strbuff = new StringBuffer(PREFIX_XML);
  120. 		if (StringUtil.isNotEmpty(parm)) {
  121. 			for (Entry<String,String> entry : parm.entrySet()) {
  122. 				strbuff.append("<").append(entry.getKey()).append(">");
  123. 				//这里是用CDATA标签包起来,原本以为body和sign需要包起来,但是发现不需要,又懒得删了,就改成了body1,sign1
  124. 				//isNotNullOrEmptyStr是判断不为空的方法
  125. 				if("attach".equalsIgnoreCase(entry.getKey()) ||"body1".equalsIgnoreCase(entry.getKey()) ||"sign1".equalsIgnoreCase(entry.getKey()) ){
  126. 					strbuff.append(PREFIX_CDATA);
  127. 					if (StringUtil.isNotNullOrEmptyStr(entry.getValue())) {
  128. 						strbuff.append(entry.getValue());
  129. 					}
  130. 					strbuff.append(SUFFIX_CDATA);
  131. 				}else{
  132. 					if (StringUtil.isNotNullOrEmptyStr(entry.getValue())) {
  133. 						strbuff.append(entry.getValue());
  134. 					}
  135. 				}
  136. 				strbuff.append("</").append(entry.getKey()).append(">");
  137. 			}
  138. 		}
  139. 		return strbuff.append(SUFFIX_XML).toString();
  140. 	}
    ===============================================================================

    请求api(注意:请求方式POST,设置编码格式UTF-8

    public static String httpsRequest(String requestUrl,String requestMethod,String outputStr) {    
  141.       try {    
  142.           URL url = new URL(requestUrl);    
  143.           HttpURLConnection conn = (HttpURLConnection) url.openConnection();    
  144.             
  145.           conn.setDoOutput(true);    
  146.           conn.setDoInput(true);    
  147.           conn.setUseCaches(false);    
  148.           // 设置请求方式(GET/POST)    
  149.           conn.setRequestMethod(requestMethod);    
  150.           conn.setRequestProperty("content-type","application/x-www-form-urlencoded");    
  151.           // 当outputStr不为null时向输出流写数据    
  152.           if (null != outputStr) {    
  153.               OutputStream outputStream = conn.getOutputStream();    
  154.               // 注意编码格式    
  155.               outputStream.write(outputStr.getBytes("UTF-8"));    
  156.               outputStream.close();    
  157.           }    
  158.           // 从输入流读取返回内容    
  159.           InputStream inputStream = conn.getInputStream();    
  160.           InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"utf-8");    
  161.           BufferedReader bufferedReader = new BufferedReader(inputStreamReader);    
  162.           String str = null;  
  163.           StringBuffer buffer = new StringBuffer();    
  164.           while ((str = bufferedReader.readLine()) != null) {    
  165.         	 // System.out.println("bf != null");
  166.               buffer.append(str);    
  167.           }    
  168.           // 释放资源    
  169.           bufferedReader.close();    
  170.           inputStreamReader.close();    
  171.           inputStream.close();    
  172.           inputStream = null;    
  173.           conn.disconnect();    
  174.           return buffer.toString();    
  175.       } catch (ConnectException ce) {    
  176.           System.out.println("连接超时:{}"+ ce);    
  177.       } catch (Exception e) {    
  178.           System.out.println("https请求异常:{}"+ e);    
  179.       }    
  180.       return null;    
  181.     }  
    ===============================================================================
    解析微信返回的xml格式数据,并根据业务需求,格式化后返回给客户端
    import org.jdom.Document;
  182. import org.jdom.Element;
  183. import org.jdom.input.SAXBuilder;
  184. public static Map<String,String> doXMLParse(String strxml) throws Exception {    
  185.           strxml = strxml.replaceFirst("encoding=\".*\"","encoding=\"UTF-8\"");    
  186.           if(null == strxml || "".equals(strxml)) {    
  187.               return null;    
  188.           }          
  189.           Map<String,String> m = new HashMap<String,String>();     
  190.           InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));    
  191.           SAXBuilder builder = new SAXBuilder();    
  192.           Document doc = builder.build(in);    
  193.           Element root = doc.getRootElement();    
  194.           List list = root.getChildren();    
  195.           Iterator it = list.iterator();    
  196.           while(it.hasNext()) {    
  197.               Element e = (Element) it.next();    
  198.               String k = e.getName();    
  199.               String v = "";    
  200.               List children = e.getChildren();    
  201.               if(children.isEmpty()) {    
  202.                   v = e.getTextNormalize();    
  203.               } else {    
  204.                   v = getChildrenText(children);    
  205.               }      
  206.               m.put(k,v);    
  207.           }       
  208.           in.close();     
  209.           return m;    
  210.     } 
  211.     public static String getChildrenText(List children) {    
  212.         StringBuffer sb = new StringBuffer();    
  213.         if(!children.isEmpty()) {    
  214.             Iterator it = children.iterator();    
  215.             while(it.hasNext()) {    
  216.                 Element e = (Element) it.next();    
  217.                 String name = e.getName();    
  218.                 String value = e.getTextNormalize();    
  219.                 List list = e.getChildren();    
  220.                 sb.append("<" + name + ">");    
  221.                 if(!list.isEmpty()) {    
  222.                     sb.append(getChildrenText(list));    
  223.                 }    
  224.                 sb.append(value);    
  225.                 sb.append("</" + name + ">");    
  226.             }    
  227.         }     
  228.         return sb.toString();    
  229.   }
  230.    

猜你在找的XML相关文章