文档章节

【java微信支付】微信支付之扫码支付相关代码

卯金刀GG
 卯金刀GG
发布于 2018/02/11 13:46
字数 3643
阅读 28
收藏 10

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

相对支付宝支付而言,微信支付的开发文档写的相当的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方法)

 

 

  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] 

 

  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] 

  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]

  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] 

  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] 

  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]

  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, 300, 300,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] 

  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] 

  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] 

  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] 

  1. //查询数据库中订单,首先判定订单中金额与返回的金额是否相等,不等金额被纂改  

[java] 

  1. //判定订单是否已经被支付,不可重复支付  

[java] 

  1. //正常处理相关业务逻辑  

[java] 

  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] 

  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]

  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] 

  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] 

  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] 

  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. }  




 

开发过程中借助了网络资料,欢迎大家指正。

本文转载自:http://blog.csdn.net/bjlf_1989/article/details/51829557

卯金刀GG
粉丝 26
博文 265
码字总数 72868
作品 0
昌平
程序员
私信 提问
加载中

评论(2)

-hanley
-hanley
推荐 gitee.com/payment-wechat
POS机端应用无法调用微信支付宝支付,该怎么实现订单的支付

我有一个PHP的微信公众号内的商城,主要是做加油的。现在的业务场景是这样的:车主在平台上下了订单加完油产生一个二维码,加油工拿POS机上我们自己开发的应用去扫码核销该订单,核销完以后选...

披着羊皮的狼王
2018/12/04
535
1
YunGouOS 1.0.5 版本发布,基于微信官方渠道的个人支付接口

YunGouOS 是一款开源的基于微信官方个人支付接口开发的支付SDK,主要集成微信官方扫码支付、JSAPI支付、小程序支付、订单查询、退款等相关支付接口,开发者只需要一个架包即可完成微信支付对...

YunGouOS
06/02
920
2
轻量级支付整合轻松嵌入任何系统 - pay-java-parent

轻量级支付模块集成(微信支付,友店扫码,支付宝,富友,银联, payoneer皮卡 )支付整合,app,扫码,即时到帐刷卡付条码付、支持多种支付类型多支付账户,支付与业务完全剥离,简单几行代码即可实...

egzosn
2017/02/17
15.9K
18
YunGouOS 1.0.6 版本发布,基于微信官方渠道的个人支付接口

YunGouOS 是一款开源的基于微信官方个人支付接口开发的支付SDK,支付结算由微信官方直连。主要集成微信官方扫码支付、JSAPI支付、小程序支付、订单查询、退款等相关支付接口,开发者只需要一...

YunGouOS
06/13
2.3K
10
JavaWeb项目对接微信扫码支付

项目地址:wxpay github repo 当我接到对接微信支付的开发任务时,我的第一反应是查看官方文档,但是官方文档并不是十分简洁易读(可能是我能力有限),且可能由于开发者习惯不同或业务场景不同...

可乐味儿的白衬衫
2018/05/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Xss过滤器(Java)

问题 最近旧的系统,遇到Xss安全问题。这个系统采用用的是spring mvc的maven工程。 解决 maven依赖配置 <properties><easapi.version>2.2.0.0</easapi.version></properties><dependenci......

亚林瓜子
30分钟前
2
0
Navicat 快捷键

操作 结果 ctrl+q 打开查询窗口 ctrl+/ 注释sql语句 ctrl+shift +/ 解除注释 ctrl+r 运行查询窗口的sql语句 ctrl+shift+r 只运行选中的sql语句 F6 打开一个mysql命令行窗口 ctrl+l 删除一行 ...

低至一折起
今天
7
0
Set 和 Map

Set 1:基本概念 类数组对象, 内部元素唯一 let set = new Set([1, 2, 3, 2, 1]); console.log(set); // Set(3){ 1, 2, 3 } [...set]; // [1, 2, 3] 接收数组或迭代器对象 ...

凌兮洛
今天
1
0
PyTorch入门笔记一

张量 引入pytorch,生成一个随机的5x3张量 >>> from __future__ import print_function>>> import torch>>> x = torch.rand(5, 3)>>> print(x)tensor([[0.5555, 0.7301, 0.5655],......

仪山湖
今天
5
0
OSChina 周二乱弹 —— 开发语言和语言开发的能一样么

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌:#今日歌曲推荐# 分享The Score的单曲《Revolution》 《Revolution》- The Score 手机党少年们想听歌,请使劲儿戳(这里) @批判派...

小小编辑
今天
2.8K
19

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部