微信支付之扫码支付相关代码(Java)(转载)

最近开发网站过程,需要引入支付过程,第三方支付中最火的莫过于支付宝支付和微信支付,下边借助微信支付官网上的文档,写一下接入微信支付之扫码支付的流程

相对支付宝支付而言,微信支付的开发文档写的相当的low,demo写的一点都不简洁,下边写一下微信扫码支付的过程,这一过程中,需要注意的所涉及的实际业务是怎样的,根据实际情况结合业务进行引入,在进入正式开发之前,要申请微信支付的相关内容按照官网的操作进行即可,审核成功后,会得到appId,商户号,商户平台登录账号和密码

登录微信支付官网

  • https://pay.weixin.qq.com,照相开发文档入口,查看扫码支付,大致了解一下扫码支付的相关信息后,进入开发流程,这是官网上的模式二的业务流程,
  • (1)商户后台系统根据用户选购的商品生成订单。

    (2)用户确认支付后调用微信支付【统一下单API】生成预支付交易;

    (3)微信支付系统收到请求后生成预支付交易单,并返回交易会话的二维码链接code_url。

    (4)商户后台系统根据返回的code_url生成二维码。

    (5)用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统。

    (6)微信支付系统收到客户端请求,验证链接有效性后发起用户支付,要求用户授权。

    (7)用户在微信客户端输入密码,确认支付后,微信客户端提交授权。

    (8)微信支付系统根据用户授权完成支付交易。

    (9)微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。

    (10)微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。

    (11)未收到支付通知的情况,商户后台系统调用【查询订单API】。

    (12)商户确认订单已支付后给用户发货。

    开发的流程,首先根据自己的业务流程,生成订单保存到数据库当中,这一过程包含了商品的信息,需要支付的钱数,商品名称等,下边开始进入统一下单的方法,

    这部分是微信统一下单入口(controller方法)

    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. /** 
    2.  * 微信扫码支付统一下单 
    3.  */  
    4. @RequestMapping(value = "/WxPayUnifiedorder", method = RequestMethod.GET)  
    5. @ResponseBody  
    6. public Object WxPayUnifiedorder(String out_trade_no) throws Exception{  
    7.     HashMap<String,Object> map = new HashMap<String,Object>();  
    8.     String codeUrl = wxPayService.weixin_pay(out_trade_no);  
    9.     map.put("codeUrl",codeUrl);       
    10.     return map;  
    11. }  
    下边是微信支付统一下单具体实现方法

    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1.     /** 
    2.      * 微信支付统一下单接口 
    3.      * @param out_trade_no 
    4.      * @return 
    5.      * @throws Exception 
    6.      */  
    7.     public String weixin_pay(String out_trade_no) throws Exception {  
    8.         // 账号信息  
    9.         String appid = PayConfigUtil.getAppid();  // appid  
    10.         //String appsecret = PayConfigUtil.APP_SECRET; // appsecret  
    11.         // 商业号  
    12.         String mch_id = PayConfigUtil.getMchid();  
    13.         // key  
    14.         String key = PayConfigUtil.getKey();   
    15.   
    16.         String currTime = PayCommonUtil.getCurrTime();  
    17.         String strTime = currTime.substring(8, currTime.length());  
    18.         String strRandom = PayCommonUtil.buildRandom(4) + "";  
    19.         //随机字符串  
    20.         String nonce_str = strTime + strRandom;  
    21.         // 价格   注意:价格的单位是分  
    22.         //String order_price = "1";   
    23.         // 商品名称  
    24.         //String body = "企嘉科技商品";     
    25.   
    26.         //查询订单数据表获取订单信息  
    27.         PayOrder payOrder = payOrderDao.get(PayOrder.class,out_trade_no);  
    28.         // 获取发起电脑 ip  
    29.         String spbill_create_ip = PayConfigUtil.getIP();  
    30.         // 回调接口   
    31.         String notify_url = PayConfigUtil.NOTIFY_URL;  
    32.         String trade_type = "NATIVE";  
    33.         String time_start =  new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());  
    34.         Calendar ca = Calendar.getInstance();  
    35.         ca.setTime(new Date());  
    36.         ca.add(Calendar.DATE, 1);           
    37.         String time_expire =  new SimpleDateFormat("yyyyMMddHHmmss").format(ca.getTime());  
    38.         SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();  
    39.         packageParams.put("appid", appid);  
    40.         packageParams.put("mch_id", mch_id);  
    41.         packageParams.put("nonce_str", nonce_str);  
    42.         packageParams.put("body",payOrder.getBody());  
    43.         packageParams.put("out_trade_no", out_trade_no);  
    44.         //packageParams.put("total_fee", "1");  
    45.         packageParams.put("total_fee", payOrder.getTotalFee());  
    46.         packageParams.put("spbill_create_ip", spbill_create_ip);  
    47.         packageParams.put("notify_url", notify_url);  
    48.         packageParams.put("trade_type", trade_type);  
    49.         packageParams.put("time_start", time_start);  
    50.         packageParams.put("time_expire", time_expire);          
    51.         String sign = PayCommonUtil.createSign("UTF-8", packageParams,key);  
    52.         packageParams.put("sign", sign);  
    53.          
    54.         String requestXML = PayCommonUtil.getRequestXml(packageParams);  
    55.         System.out.println("请求xml::::"+requestXML);  
    56.    
    57.         String resXml = HttpUtil.postData(PayConfigUtil.PAY_API, requestXML);  
    58.         System.out.println("返回xml::::"+resXml);  
    59.           
    60.         Map map = XMLUtil.doXMLParse(resXml);  
    61.         //String return_code = (String) map.get("return_code");  
    62.         //String prepay_id = (String) map.get("prepay_id");  
    63.         String urlCode = (String) map.get("code_url");   
    64.         System.out.println("打印调用统一下单接口生成二维码url:::::"+urlCode);  
    65.         return urlCode;  
    66. }  
    这一方法中,我们从工具类中获取微信官网提供的appId以及商户号,以及在商户平台上设置的支付密钥,处理一些统一下单接口需要携带的参数,回调链接(微信发起的本地调用,并返回成功或错误信息),totalFee的单位为分,官网的接口文档有说明,trade_type写死指定为NATIVE,另外的两个量time_start与time_expire是指定订单的有效期,

    可以根据的自己的业务需求具体指定时间,(此处是24小时的订单有效期),如果无需指定,直接注释掉即可,sign是签名操作,借助工具类将packageParams转化为XML借助postData方法请求微信统一下单接口

    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. public static String PAY_API = "https://api.mch.weixin.qq.com/pay/unifiedorder";  
    resXml作为调用统一下单的返回值,当然返回的也是xml文件,再借助xmlUtil将返回值转化为map,返回值中有生成二维码的code_url,接下来我们需要处理的是,解析二维码url在前端网页中生成二维码图片,在前端使用ajax调用统一下单接口方法,接收返回值code_url,接收返回值后在调用后台接口方法解析code_url

    [javascript]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. common.get("/*****/wxpay/WxPayUnifiedorder?out_trade_no="+orderId,function(data){  
    2.     var codeUrl = data.codeUrl;  
    3.     if(codeUrl!=null && codeUrl!=""){  
    4.     $("#id_wxtwoCode").attr('src',"******/wxpay/qr_codeImg?code_url="+codeUrl);  
    5.     }  
    6. });  

    html中img标签

    [html]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. <div class="weimg">  
    2.     <!-- <img src="../common/img/wei_06.png"> -->  
    3. <img id="id_wxtwoCode"src=""/>  
    4. <p>打开手机端微信<br>扫一扫继续支付</p>  
    5. </div>  

    下边是解析二维码过程

    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. /** 
    2.  * 生成二维码图片并直接以流的形式输出到页面 
    3.  * @param code_url 
    4.  * @param response 
    5.  */  
    6. @RequestMapping("qr_codeImg")  
    7. @ResponseBody  
    8. public void getQRCode(String code_url,HttpServletResponse response){  
    9.     wxPayService.encodeQrcode(code_url, response);  
    10. }  

    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. /** 
    2.  * 生成二维码图片 不存储 直接以流的形式输出到页面 
    3.  * @param content 
    4.  * @param response 
    5.  */  
    6. @SuppressWarnings({ "unchecked""rawtypes" })  
    7. public static void encodeQrcode(String content,HttpServletResponse response){  
    8.     if(content==null || "".equals(content))  
    9.         return;  
    10.    MultiFormatWriter multiFormatWriter = new MultiFormatWriter();  
    11.    Map hints = new HashMap();  
    12.    hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); //设置字符集编码类型  
    13.    BitMatrix bitMatrix = null;  
    14.    try {  
    15.        bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 300300,hints);  
    16.        BufferedImage image = toBufferedImage(bitMatrix);  
    17.        //输出二维码图片流  
    18.        try {  
    19.            ImageIO.write(image, "png", response.getOutputStream());  
    20.        } catch (IOException e) {  
    21.            // TODO Auto-generated catch block  
    22.            e.printStackTrace();  
    23.        }  
    24.    } catch (WriterException e1) {  
    25.        // TODO Auto-generated catch block  
    26.        e1.printStackTrace();  
    27.    }           
    28. }  
    这里的300,300确定了二维码图片的大小


    二维码图片生成后,接下来的流程就是扫码进行支付操作,这里还存在一个问题,需要在扫码后支付成功,需要实现页面的跳转,这一过程需要添加js的定时器,定时查看订单的支付状态是否发生了改变是否为支付成功,成功即可跳转后续流程,失败跳转失败提示

    [javascript]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. //定时器,每隔1s查询订单支付状态,订单状态改变,清除页面定时器,页面跳转  
    2. function checkOrder(orderId) {  
    3.              console.log("定时器方法"+orderId);  
    4.              common.get("/*******/order/checkOrder?out_trade_no="+orderId,function(data){  
    5.         var isorder = data.isorder;  
    6.         var paystatus = data.paystatus;  
    7.         if(isorder=="1"){  
    8.           if(paystatus=="1"){  
    9.               //支付成功跳转  
    10.               window.location.href="******/order/wxpaySuccess?out_trade_no="+orderId;  
    11.               clearInterval(time);  
    12.           }else if(paystatus=="2"){  
    13.               //支付失败  
    14.               alert("支付失败!");  
    15.               clearInterval(time);  
    16.           }  
    17.         }  
    18.     });        
    19.       }  

    isorder查看是否存在订单,存在订单时判断支付状态,进行后续流程

    支付成功后,微信服务端开始回调方法,

    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. @RequestMapping(value = "/weixinNotify", method = RequestMethod.POST)  
    2. @ResponseBody  
    3. public void weixinNotify(HttpServletRequest request,HttpServletResponse response) throws Exception{  
    4.        System.out.println("支付回调方法开始!");  
    5.     HashMap<String,Object> map = new HashMap<String,Object>();  
    6.     wxPayService.weixin_notify(request, response);  
    7.     System.out.println("支付回调方法结束!");  
    8. }  

    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. /** 
    2.  * 微信支付回调方法 
    3.  * @param request 
    4.  * @param response 
    5.  * @throws Exception 
    6.  */  
    7.    public void weixin_notify(HttpServletRequest request,HttpServletResponse response) throws Exception{  
    8.       
    9.     //读取参数  
    10.     InputStream inputStream ;  
    11.     StringBuffer sb = new StringBuffer();  
    12.     inputStream = request.getInputStream();  
    13.     String s ;  
    14.     BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));  
    15.     while ((s = in.readLine()) != null){  
    16.         sb.append(s);  
    17.     }  
    18.     in.close();  
    19.     inputStream.close();  
    20.   
    21.     //解析xml成map  
    22.     Map<String, String> m = new HashMap<String, String>();  
    23.     m = XMLUtil.doXMLParse(sb.toString());  
    24.       
    25.     //过滤空 设置 TreeMap  
    26.     SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();        
    27.     Iterator it = m.keySet().iterator();  
    28.     while (it.hasNext()) {  
    29.         String parameter = (String) it.next();  
    30.         String parameterValue = m.get(parameter);  
    31.           
    32.         String v = "";  
    33.         if(null != parameterValue) {  
    34.             v = parameterValue.trim();  
    35.         }  
    36.         packageParams.put(parameter, v);  
    37.     }  
    38.       
    39.     // 账号信息  
    40.        String key = PayConfigUtil.getKey(); // key  
    41.        String out_trade_no = (String)packageParams.get("out_trade_no");  
    42.        //logger.info(packageParams);  
    43.     //判断签名是否正确  
    44.     if(PayCommonUtil.isTenpaySign("UTF-8", packageParams,key)) {  
    45.         //------------------------------  
    46.         //处理业务开始  
    47.         //------------------------------  
    48.         String resXml = "";  
    49.         if("SUCCESS".equals((String)packageParams.get("result_code"))){  
    50.             // 这里是支付成功  
    51.             //////////执行自己的业务逻辑////////////////  
    52.             String mch_id = (String)packageParams.get("mch_id");  
    53.             String openid = (String)packageParams.get("openid");  
    54.             String is_subscribe = (String)packageParams.get("is_subscribe");  
    55.               
    56.             String bank_type = (String)packageParams.get("bank_type");  
    57.             String total_fee = (String)packageParams.get("total_fee");  
    58.             String transaction_id = (String)packageParams.get("transaction_id");  
    59.               
    60.             System.out.println("mch_id:"+mch_id);  
    61.             System.out.println("openid:"+openid);  
    62.             System.out.println("is_subscribe:"+is_subscribe);  
    63.             System.out.println("out_trade_no:"+out_trade_no);  
    64.             System.out.println("total_fee:"+total_fee);  
    65.             System.out.println("bank_type:"+bank_type);  
    66.             System.out.println("transaction_id:"+transaction_id);  
    67.               
    68.             //成功回调后需要处理预生成订单的状态和一些支付信息  
    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. //查询数据库中订单,首先判定订单中金额与返回的金额是否相等,不等金额被纂改  
    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. //判定订单是否已经被支付,不可重复支付  
    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. //正常处理相关业务逻辑  
    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1.     } else {  
    2.         System.out.println("支付失败,错误信息:" + packageParams.get("err_code")+  
    3.                             "-----订单号:::"+out_trade_no+"*******支付失败时间::::"  
    4.                 +new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));  
    5.           
    6.         String err_code = (String)packageParams.get("err_code");  
    7.   
    8.          resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"  
    9.                  + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";  
    10.     
    11.     }  
    12.     //------------------------------  
    13.     //处理业务完毕  
    14.     //------------------------------  
    15.     BufferedOutputStream out = new BufferedOutputStream(  
    16.             response.getOutputStream());  
    17.     out.write(resXml.getBytes());  
    18.     out.flush();  
    19.     out.close();  
    20. else{  
    21.     System.out.println("通知签名验证失败---时间::::"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));  
    22. }  

    至此,微信支付流程完毕

    下边是相关工具类

    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    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 com.entplus.log.entity.Log;  
    9.   
    10. public class HttpUtil {  
    11.   
    12.     //private static final Log logger = Logs.get();  
    13.     private final static int CONNECT_TIMEOUT = 5000// in milliseconds  
    14.     private final static String DEFAULT_ENCODING = "UTF-8";  
    15.       
    16.     public static String postData(String urlStr, String data){  
    17.         return postData(urlStr, data, null);  
    18.     }  
    19.       
    20.     public static String postData(String urlStr, String data, String contentType){  
    21.         BufferedReader reader = null;  
    22.         try {  
    23.             URL url = new URL(urlStr);  
    24.             URLConnection conn = url.openConnection();  
    25.             conn.setDoOutput(true);  
    26.             conn.setConnectTimeout(CONNECT_TIMEOUT);  
    27.             conn.setReadTimeout(CONNECT_TIMEOUT);  
    28.             if(contentType != null)  
    29.                 conn.setRequestProperty("content-type", contentType);  
    30.             OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);  
    31.             if(data == null)  
    32.                 data = "";  
    33.             writer.write(data);   
    34.             writer.flush();  
    35.             writer.close();    
    36.   
    37.             reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));  
    38.             StringBuilder sb = new StringBuilder();  
    39.             String line = null;  
    40.             while ((line = reader.readLine()) != null) {  
    41.                 sb.append(line);  
    42.                 sb.append("\r\n");  
    43.             }  
    44.             return sb.toString();  
    45.         } catch (IOException e) {  
    46.             //logger.error("Error connecting to " + urlStr + ": " + e.getMessage());  
    47.             System.out.println("Error connecting to " + urlStr + ": " + e.getMessage());  
    48.         } finally {  
    49.             try {  
    50.                 if (reader != null)  
    51.                     reader.close();  
    52.             } catch (IOException e) {  
    53.             }  
    54.         }  
    55.         return null;  
    56.     }  
    57. }  


    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    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.   
    122. }  


    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. package com.entplus.wxpay.util;  
    2.   
    3.   
    4. public class PayConfigUtil {  
    5. //这个就是自己要保管好的私有Key了(切记只能放在自己的后台代码里,不能放在任何可能被看到源代码的客户端程序中)  
    6.     // 每次自己Post数据给API的时候都要用这个key来对所有字段进行签名,生成的签名会放在Sign这个字段,API收到Post数据的时候也会用同样的签名算法对Post过来的数据进行签名和验证  
    7.     // 收到API的返回的时候也要用这个key来对返回的数据算下签名,跟API的Sign数据进行比较,如果值不一致,有可能数据被第三方给篡改  
    8.   
    9.     private static String key = "";  
    10.   
    11.     //微信分配的公众号ID(开通公众号之后可以获取到)  
    12.     private static String appID = "";  
    13.   
    14.     //微信支付分配的商户号ID(开通公众号的微信支付功能之后可以获取到)  
    15.     private static String mchID = "";  
    16.   
    17.   
    18.   
    19.     //机器IP  
    20.     private static String ip = "";  
    21.   
    22.     //以下是几个API的路径:  
    23.     //1)被扫支付API  
    24.     //public static String PAY_API = "https://api.mch.weixin.qq.com/pay/micropay";  
    25.     public static String PAY_API = "https://api.mch.weixin.qq.com/pay/unifiedorder";  
    26.     //2)被扫支付查询API  
    27.     public static String PAY_QUERY_API = "https://api.mch.weixin.qq.com/pay/orderquery";  
    28.   
    29.     //3)退款API  
    30.     public static String REFUND_API = "https://api.mch.weixin.qq.com/secapi/pay/refund";  
    31.   
    32.     //4)退款查询API  
    33.     public static String REFUND_QUERY_API = "https://api.mch.weixin.qq.com/pay/refundquery";  
    34.   
    35.     //5)撤销API  
    36.     public static String REVERSE_API = "https://api.mch.weixin.qq.com/secapi/pay/reverse";  
    37.   
    38.     //6)下载对账单API  
    39.     public static String DOWNLOAD_BILL_API = "https://api.mch.weixin.qq.com/pay/downloadbill";  
    40.   
    41.     //7) 统计上报API  
    42.     public static String REPORT_API = "https://api.mch.weixin.qq.com/payitil/report";  
    43.       
    44.     //回调地址  
    45.     //public static String NOTIFY_URL = ""; //测试  
    46.   
    47.   
    48.     public static String HttpsRequestClassName = "com.entplus.wxpay.util.HttpsRequest";  
    49.   
    50.     public static void setKey(String key) {  
    51.         PayConfigUtil.key = key;  
    52.     }  
    53.   
    54.     public static void setAppID(String appID) {  
    55.         PayConfigUtil.appID = appID;  
    56.     }  
    57.   
    58.     public static void setMchID(String mchID) {  
    59.         PayConfigUtil.mchID = mchID;  
    60.     }  
    61.   
    62.     public static void setIp(String ip) {  
    63.         PayConfigUtil.ip = ip;  
    64.     }  
    65.   
    66.     public static String getKey(){  
    67.         return key;  
    68.     }  
    69.       
    70.     public static String getAppid(){  
    71.         return appID;  
    72.     }  
    73.       
    74.     public static String getMchid(){  
    75.         return mchID;  
    76.     }  
    77.   
    78.   
    79.   
    80.     public static String getIP(){  
    81.         return ip;  
    82.     }  
    83.   
    84.     public static void setHttpsRequestClassName(String name){  
    85.         HttpsRequestClassName = name;  
    86.     }  
    87.   
    88. }  



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



    [java]  view plain  copy
      在CODE上查看代码片 派生到我的代码片
    1. import java.security.MessageDigest;  
    2.   
    3. public class MD5Util {  
    4.   
    5.     private static String byteArrayToHexString(byte b[]) {  
    6.         StringBuffer resultSb = new StringBuffer();  
    7.         for (int i = 0; i < b.length; i++)  
    8.             resultSb.append(byteToHexString(b[i]));  
    9.   
    10.         return resultSb.toString();  
    11.     }  
    12.   
    13.     private static String byteToHexString(byte b) {  
    14.         int n = b;  
    15.         if (n < 0)  
    16.             n += 256;  
    17.         int d1 = n / 16;  
    18.         int d2 = n % 16;  
    19.         return hexDigits[d1] + hexDigits[d2];  
    20.     }  
    21.   
    22.     public static String MD5Encode(String origin, String charsetname) {  
    23.         String resultString = null;  
    24.         try {  
    25.             resultString = new String(origin);  
    26.             MessageDigest md = MessageDigest.getInstance("MD5");  
    27.             if (charsetname == null || "".equals(charsetname))  
    28.                 resultString = byteArrayToHexString(md.digest(resultString  
    29.                         .getBytes()));  
    30.             else  
    31.                 resultString = byteArrayToHexString(md.digest(resultString  
    32.                         .getBytes(charsetname)));  
    33.         } catch (Exception exception) {  
    34.         }  
    35.         return resultString;  
    36.     }  
    37.   
    38.     private static final String hexDigits[] = { "0""1""2""3""4""5",  
    39.             "6""7""8""9""a""b""c""d""e""f" };  
    40.   
    41. }  
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值