• java微信扫码支付(模式二)


    微信扫码支付——模式二

      代码:

      PayCommonUtil.java  微信支付常用方法

      1 import java.text.SimpleDateFormat;
      2 import java.util.Date;
      3 import java.util.Iterator;
      4 import java.util.Map;
      5 import java.util.Set;
      6 import java.util.SortedMap;
      7 
      8 public class PayCommonUtil
      9 {
     10     /** 
     11      * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 
     12      * @return boolean 
     13      */  
     14     public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {  
     15         StringBuffer sb = new StringBuffer();  
     16         Set es = packageParams.entrySet();  
     17         Iterator it = es.iterator();  
     18         while(it.hasNext()) {  
     19             Map.Entry entry = (Map.Entry)it.next();  
     20             String k = (String)entry.getKey();  
     21             String v = (String)entry.getValue();  
     22             if(!"sign".equals(k) && null != v && !"".equals(v)) {  
     23                 sb.append(k + "=" + v + "&");  
     24             }  
     25         }  
     26           
     27         sb.append("key=" + API_KEY);  
     28           
     29         //算出摘要  
     30         String mysign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();  
     31         String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();  
     32           
     33         //System.out.println(tenpaySign + "    " + mysign);  
     34         return tenpaySign.equals(mysign);  
     35     }  
     36   
     37     /** 
     38      * @author 
     39      * @date 2016-4-22 
     40      * @Description:sign签名 
     41      * @param characterEncoding 
     42      *            编码格式 
     43      * @param parameters 
     44      *            请求参数 
     45      * @return 
     46      */  
     47     public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {  
     48         StringBuffer sb = new StringBuffer();  
     49         Set es = packageParams.entrySet();  
     50         Iterator it = es.iterator();  
     51         while (it.hasNext()) {  
     52             Map.Entry entry = (Map.Entry) it.next();  
     53             String k = (String) entry.getKey();  
     54             String v = (String) entry.getValue();  
     55             if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {  
     56                 sb.append(k + "=" + v + "&");  
     57             }  
     58         }  
     59         sb.append("key=" + API_KEY);  
     60         String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();  
     61         return sign;  
     62     }  
     63   
     64     /** 
     65      * @author 
     66      * @date 2016-4-22 
     67      * @Description:将请求参数转换为xml格式的string 
     68      * @param parameters 
     69      *            请求参数 
     70      * @return 
     71      */  
     72     public static String getRequestXml(SortedMap<Object, Object> parameters) {  
     73         StringBuffer sb = new StringBuffer();  
     74         sb.append("<xml>");  
     75         Set es = parameters.entrySet();  
     76         Iterator it = es.iterator();  
     77         while (it.hasNext()) {  
     78             Map.Entry entry = (Map.Entry) it.next();  
     79             String k = (String) entry.getKey();  
     80             String v = (String) entry.getValue();  
     81             if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {  
     82                 sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");  
     83             } else {  
     84                 sb.append("<" + k + ">" + v + "</" + k + ">");  
     85             }  
     86         }  
     87         sb.append("</xml>");  
     88         return sb.toString();  
     89     }  
     90   
     91     /** 
     92      * 取出一个指定长度大小的随机正整数. 
     93      *  
     94      * @param length 
     95      *            int 设定所取出随机数的长度。length小于11 
     96      * @return int 返回生成的随机数。 
     97      */  
     98     public static int buildRandom(int length) {  
     99         int num = 1;  
    100         double random = Math.random();  
    101         if (random < 0.1) {  
    102             random = random + 0.1;  
    103         }  
    104         for (int i = 0; i < length; i++) {  
    105             num = num * 10;  
    106         }  
    107         return (int) ((random * num));  
    108     }  
    109   
    110     /** 
    111      * 获取当前时间 yyyyMMddHHmmss 
    112      *  
    113      * @return String 
    114      */  
    115     public static String getCurrTime() {  
    116         Date now = new Date();  
    117         SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");  
    118         String s = outFormat.format(now);  
    119         return s;  
    120     }  
    121 }

      XMLUtil.java   将支付参数转换为xml格式

     1 import java.io.ByteArrayInputStream;
     2 import java.io.IOException;
     3 import java.io.InputStream;
     4 import java.util.HashMap;
     5 import java.util.Iterator;
     6 import java.util.List;
     7 import java.util.Map;
     8 
     9 import org.jdom.Document;
    10 import org.jdom.Element;
    11 import org.jdom.JDOMException;
    12 import org.jdom.input.SAXBuilder;
    13 
    14 public class XMLUtil
    15 {
    16     /** 
    17      * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。 
    18      * @param strxml 
    19      * @return 
    20      * @throws JDOMException 
    21      * @throws IOException 
    22      */  
    23     public static Map doXMLParse(String strxml) throws JDOMException, IOException {  
    24         strxml = strxml.replaceFirst("encoding=".*"", "encoding="UTF-8"");  
    25   
    26         if(null == strxml || "".equals(strxml)) {  
    27             return null;  
    28         }  
    29           
    30         Map m = new HashMap();  
    31           
    32         InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));  
    33         SAXBuilder builder = new SAXBuilder();  
    34         Document doc = builder.build(in);  
    35         Element root = doc.getRootElement();  
    36         List list = root.getChildren();  
    37         Iterator it = list.iterator();  
    38         while(it.hasNext()) {  
    39             Element e = (Element) it.next();  
    40             String k = e.getName();  
    41             String v = "";  
    42             List children = e.getChildren();  
    43             if(children.isEmpty()) {  
    44                 v = e.getTextNormalize();  
    45             } else {  
    46                 v = XMLUtil.getChildrenText(children);  
    47             }  
    48               
    49             m.put(k, v);  
    50         }  
    51           
    52         //关闭流  
    53         in.close();  
    54           
    55         return m;  
    56     }  
    57       
    58     /** 
    59      * 获取子结点的xml 
    60      * @param children 
    61      * @return String 
    62      */  
    63     public static String getChildrenText(List children) {  
    64         StringBuffer sb = new StringBuffer();  
    65         if(!children.isEmpty()) {  
    66             Iterator it = children.iterator();  
    67             while(it.hasNext()) {  
    68                 Element e = (Element) it.next();  
    69                 String name = e.getName();  
    70                 String value = e.getTextNormalize();  
    71                 List list = e.getChildren();  
    72                 sb.append("<" + name + ">");  
    73                 if(!list.isEmpty()) {  
    74                     sb.append(XMLUtil.getChildrenText(list));  
    75                 }  
    76                 sb.append(value);  
    77                 sb.append("</" + name + ">");  
    78             }  
    79         }  
    80           
    81         return sb.toString();  
    82     }  
    83 }

      HttpUtil.java  用http连接提交支付信息参数

     1 import java.io.BufferedReader;
     2 import java.io.IOException;
     3 import java.io.InputStreamReader;
     4 import java.io.OutputStreamWriter;
     5 import java.net.URL;
     6 import java.net.URLConnection;
     7 
     8 import org.apache.commons.logging.Log;
     9 import org.apache.commons.logging.LogFactory;
    10 
    11 
    12 public class HttpUtil
    13 {
    14     private static final Log logger = LogFactory.getLog("org.apache.catalina.tribes.MESSAGES" );
    15     
    16     private final static int CONNECT_TIMEOUT = 5000; // in milliseconds  
    17     
    18     private final static String DEFAULT_ENCODING = "UTF-8";  
    19       
    20     public static String postData(String urlStr, String data){  
    21         return postData(urlStr, data, null);  
    22     }  
    23       
    24     public static String postData(String urlStr, String data, String contentType){  
    25         BufferedReader reader = null;  
    26         try {  
    27             URL url = new URL(urlStr);  
    28             URLConnection conn = url.openConnection();  
    29             conn.setDoOutput(true);  
    30             conn.setConnectTimeout(CONNECT_TIMEOUT);  
    31             conn.setReadTimeout(CONNECT_TIMEOUT);  
    32             if(contentType != null)  
    33                 conn.setRequestProperty("content-type", contentType);  
    34             OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);  
    35             if(data == null)  
    36                 data = "";  
    37             writer.write(data);   
    38             writer.flush();  
    39             writer.close();    
    40   
    41             reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));  
    42             System.out.println(reader.toString());
    43             StringBuilder sb = new StringBuilder();  
    44             String line = null;  
    45             while ((line = reader.readLine()) != null) {  
    46                 sb.append(line);  
    47                 sb.append("
    ");  
    48             }  
    49             return sb.toString();  
    50         } catch (IOException e) {  
    51             logger.error("Error connecting to " + urlStr + ": " + e.getMessage());  
    52         } finally {  
    53             try {  
    54                 if (reader != null)  
    55                     reader.close();  
    56             } catch (IOException e) {  
    57             }  
    58         }  
    59         return null;  
    60     }  
    61 }

      MD5Util.java   md5加密

     1     private static String byteToHexString(byte b) {  
     2         int n = b;  
     3         if (n < 0)  
     4             n += 256;  
     5         int d1 = n / 16;  
     6         int d2 = n % 16;  
     7         return hexDigits[d1] + hexDigits[d2];  
     8     }  
     9   
    10     public static String MD5Encode(String origin, String charsetname) {  
    11         String resultString = null;  
    12         try {  
    13             resultString = new String(origin);  
    14             MessageDigest md = MessageDigest.getInstance("MD5");  
    15             if (charsetname == null || "".equals(charsetname))  
    16                 resultString = byteArrayToHexString(md.digest(resultString  
    17                         .getBytes()));  
    18             else  
    19                 resultString = byteArrayToHexString(md.digest(resultString  
    20                         .getBytes(charsetname)));  
    21         } catch (Exception exception) {  
    22         }  
    23         return resultString;  
    24     }  
    25   
    26     private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",  
    27             "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };  
    28 } 
      GetWeixinUrlUtil.java   获取订单生成的二维码URL
     1 import java.io.UnsupportedEncodingException;
     2 import java.net.URLEncoder;
     3 import java.util.Map;
     4 import java.util.SortedMap;
     5 import java.util.TreeMap;
     6 
     7 public class GetWeixinUrlUtil
     8 {
     9     //获取二维码url  
    10     public static String weixin_pay(String ip, VcWeixinPay vcWeixinPay) throws Exception {  
    11     // 账号信息  
    12         String appid = PayConfigUtil.APP_ID;  // appid  
    13         String mch_id = PayConfigUtil.MCH_ID; // 商户号  
    14         String key = PayConfigUtil.API_KEY; // key  
    15         String currTime = PayCommonUtil.getCurrTime();  
    16         String strTime = currTime.substring(8, currTime.length());  
    17         String strRandom = PayCommonUtil.buildRandom(4) + "";  
    18         String nonce_str = strTime + strRandom;          
    19         int order_price = 1; // 商品价格   注意:价格的单位是分  
    20         String body = "商品名称";   // 商品名称  
    21         String out_trade_no = PayCommonUtil.getCurrTime() + PayCommonUtil.buildRandom(4); // 商户订单号  
    22         // 获取发起电脑 ip  
    23         String spbill_create_ip = ip;  
    24         // 回调接口   
    25         String notify_url = PayConfigUtil.NOTIFY_URL;  
    26         String trade_type = "NATIVE";  //交易类型          
    27         SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();  
    28         packageParams.put("appid", appid);  
    29         packageParams.put("mch_id", mch_id);  
    30         packageParams.put("nonce_str", nonce_str);  
    31         packageParams.put("body", body);  
    32         packageParams.put("out_trade_no", out_trade_no);  
    33         packageParams.put("total_fee", String.valueOf(order_price));  
    34         packageParams.put("spbill_create_ip", spbill_create_ip);  
    35         packageParams.put("notify_url", notify_url);  
    36         packageParams.put("trade_type", trade_type);  
    37         //生成签名
    38         String sign = PayCommonUtil.createSign("UTF-8", packageParams,key);  
    39         packageParams.put("sign", sign);  
    40           
    41         String requestXML = PayCommonUtil.getRequestXml(packageParams);  
    42         System.out.println(requestXML);  
    43    
    44         String resXml = HttpUtil.postData(PayConfigUtil.UFDODER_URL, requestXML);       
    45         Map map = XMLUtil.doXMLParse(resXml);  
    48         String urlCode = (String) map.get("code_url");  
    49           
    50         return urlCode;   
    51     } 
    52     
    53     // 特殊字符处理  
    54     public static String UrlEncode(String src)  throws UnsupportedEncodingException {  
    55         return URLEncoder.encode(src, "UTF-8").replace("+", "%20");  
    56     }  
    57 }    

      PayConfigUtil.java  微信支付参数

     1 import javax.servlet.http.HttpServletRequest;
     2 
     3 public class PayConfigUtil
     4 {
     5     public static final String APP_ID = "";//微信开发平台应用ID(公众号ID)
     6     public static final String MCH_ID = "";//商户号(商户号ID)
     7     public static final String API_KEY = "";//API key(商户号里面的)
     8     public static final String CREATE_IP = "";//发起支付的ip
     9     public static final String NOTIFY_URL = "";//回调地址
    10     public static final String UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信统一下单接口
    11     public static final String APP_SECRET = "";//应用对应的凭证(在公众号里面)
    12     
    13     //获取ip
    14     public static String getIP(HttpServletRequest request)
    15     {
    16         String ip = request.getRemoteAddr();
    17         return ip;
    18     }
    19     
      支付回调方法
      1 public void weixin_notify(HttpServletRequest request,HttpServletResponse response) throws Exception
      2     {  
      3         System.out.println("调用回调方法");
      4         //读取参数  
      5         InputStream inputStream ;  
      6         StringBuffer sb = new StringBuffer();  
      7         inputStream = request.getInputStream();  
      8         String s ;  
      9         BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));  
     10         while ((s = in.readLine()) != null){  
     11             sb.append(s);  
     12         }  
     13         in.close();  
     14         inputStream.close();  
     15   
     16         //解析xml成map  
     17         Map<String, String> m = new HashMap<String, String>();  
     18         m = XMLUtil.doXMLParse(sb.toString());  
     19           
     20         //过滤空 设置 TreeMap  
     21         SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();        
     22         Iterator it = m.keySet().iterator();  
     23         while (it.hasNext()) {  
     24             String parameter = (String) it.next();  
     25             String parameterValue = m.get(parameter);  
     26               
     27             String v = "";  
     28             if(null != parameterValue) {  
     29                 v = parameterValue.trim();  
     30             }  
     31             packageParams.put(parameter, v);  
     32         }  
     33           
     34         // 账号信息  
     35         String key = PayConfigUtil.API_KEY; // key  
     36         
     37         logger.info(packageParams);  
     38         //判断签名是否正确  
     39         if(PayCommonUtil.isTenpaySign("UTF-8", packageParams,key)) {  
     40             //------------------------------  
     41             //处理业务开始  
     42             //------------------------------  
     44             String resXml = "";  
     45             if("SUCCESS".equals((String) packageParams.get("result_code"))){  
     46                 // 这里是支付成功  
     47                 //////////执行自己的业务逻辑////////////////  
     48                 String mch_id = (String) packageParams.get("mch_id");  
     49                 String openid = (String) packageParams.get("openid");  
     50                 String is_subscribe = (String) packageParams.get("is_subscribe");  
     51                 String out_trade_no = (String) packageParams.get("out_trade_no");  
     52                 String total_fee = (String) packageParams.get("total_fee"); 
     53                 String cash_fee_s = (String) packageParams.get("cash_fee");
     54                 String cash_fee = String.valueOf(Integer.parseInt(cash_fee_s) / 100);
     55                 String time_end = MctsUtils.numberDateToDate((String) packageParams.get("time_end"));
     56                 String transaction_id = (String) packageParams.get("transaction_id");
     57                     
     58                     //////////执行自己的业务逻辑(报存订单信息到数据库)////////////////  
     59                     System.out.println("支付成功 ,处理业务成功");
     60                     logger.info("支付成功");  
     61                     //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.  
     62                     resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"  
     63                             + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";  
     64                   //------------------------------  
     65                     //处理业务完毕  
     66                     //------------------------------  
                  //向微信服务器发送确认信息,若不发送,微信服务器会间隔不同的时间调用回调方法 67 BufferedOutputStream out = new BufferedOutputStream( 68 response.getOutputStream()); 69 out.write(resXml.getBytes()); 70 out.flush(); 71 out.close(); 73 System.out.println("通知微信.异步确认成功"); 74 } else { 93 logger.info("支付失败,错误信息:" + packageParams.get("err_code")); 94 resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" 95 + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> "; 96 97 BufferedOutputStream out = new BufferedOutputStream( 98 response.getOutputStream()); 99 out.write(resXml.getBytes()); 100 out.flush(); 101 out.close(); 102 System.out.println("执行回调函数失败"); 103 } 105 } else{ 106 logger.info("通知签名验证失败"); 107 } 108 }
      根据GetWeixinUrlUtil.java获取到微信支付订单信息的二维码url,下载一个解析二维码的js插件(jquery.qrcode.min.js),把获取到二维码url在前端页面用jquery.qrcode.min.js解析,就能显示二维码了。
      前端页面简略代码:
     1 <script type="text/javascript" src="js/jquery.qrcode.min.js"></script>
     2 <script language="javascript">
     3     $(function(){
     4         var codeUrl = ${erWeiMa};//erWeiMa是后端传的二维码url
     5         $("#code").qrcode({ 
     6             render: "canvas", //table方式 
     7              240, //宽度 
     8             height:240, //高度 
     9             text: codeUrl //任意内容 
    10         }); 
    11     });
    12 </script>
    13 
    14 <div id="code" style=" 240px;height: 240px;margin: 0px auto;"></div> 

      其中用到的jar包当时忘记记录了,不知道的可以根据报错信息搜下缺少的jar包。

      

  • 相关阅读:
    应用Druid监控SQL语句的执行情况
    J2EE应用监控后台执行SQL
    maven环境搭建
    【机器学习】Sklearn库主成分分析PCA降维的运用实战
    PCA降维算法
    80行Python实现-HOG梯度特征提取(转载)
    HOG特征提取算法原理(转载)
    数据预处理方法 总结
    【AI换脸】Faceswap源代码换脸软件安装指南(转)
    人工智能领域的会议和期刊(转载)
  • 原文地址:https://www.cnblogs.com/kylyww/p/7476953.html
Copyright © 2020-2023  润新知