SpringBoot服务端App集成第三方微信支付(二次改动)

一、微信APP支付接入商户服务中心

申请流程指引

二 、配置相关的配置信息application.yml

#微信支付配置
#appid 公众账号ID
#mch_id 商户号
#device_info 设备号
#key 商户的key【API密匙】
#url api请求地址
#notify_url 服务器异步通知页面路径
weixinpayconfig:
   appid: wxf78654211a64d5f
   mch_id: 15215421
   device_info: WEB
   key: wuhanlogyinkeyuxian12344ngsi20
   url: https://api.mch.weixin.qq.com/pay/unifiedorder
   notify_url: http://域名/api/weixinnotifyUrl
#return_url: http://域名/weixinpay/returnUrl
   wx_package: Sign=WXPay

三、上传工具类

3.1微信支付配置文件

package io.renren.api.properties;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 微信支付配置文件
 * @author Administrator
 *
 */
@Component
@ConfigurationProperties(prefix="weixinpayconfig")
public class WeixinpayProperties {

	private String appid; // 公众账号ID
	
	private String mch_id; // 商户号
	
	private String device_info; // 设备号
	
	private String key; // 商户的key【API密匙】
	
	private String url; // api请求地址
	
	private String notify_url; // 服务器异步通知页面路径
	
	private String return_url; // 服务器同步通知页面路径
	private String wx_package;
	public String getAppid() {
		return appid;
	}

	public void setAppid(String appid) {
		this.appid = appid;
	}

	public String getMch_id() {
		return mch_id;
	}

	public void setMch_id(String mch_id) {
		this.mch_id = mch_id;
	}

	public String getDevice_info() {
		return device_info;
	}

	public void setDevice_info(String device_info) {
		this.device_info = device_info;
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getNotify_url() {
		return notify_url;
	}

	public void setNotify_url(String notify_url) {
		this.notify_url = notify_url;
	}

	public String getReturn_url() {
		return return_url;
	}

	public void setReturn_url(String return_url) {
		this.return_url = return_url;
	}

	public String getWx_package() {
		return wx_package;
	}

	public void setWx_package(String wx_package) {
		this.wx_package = wx_package;
	}
}

3.2 配置文件Unifiedorder

public class Unifiedorder {
	private String appid;
	private String mch_id;
	private String nonce_str;
	private String sign;
	private String body;
	private String out_trade_no;
	private int total_fee;
	private String spbill_create_ip;
	private String notify_url;
	private String trade_type;
	public String getAppid() {
		return appid;
	}
	public void setAppid(String appid) {
		this.appid = appid;
	}
	public String getMch_id() {
		return mch_id;
	}
	public void setMch_id(String mch_id) {
		this.mch_id = mch_id;
	}
	public String getNonce_str() {
		return nonce_str;
	}
	public void setNonce_str(String nonce_str) {
		this.nonce_str = nonce_str;
	}
	public String getSign() {
		return sign;
	}
	public void setSign(String sign) {
		this.sign = sign;
	}
	public String getBody() {
		return body;
	}
	public void setBody(String body) {
		this.body = body;
	}
	public String getOut_trade_no() {
		return out_trade_no;
	}
	public void setOut_trade_no(String out_trade_no) {
		this.out_trade_no = out_trade_no;
	}
	public int getTotal_fee() {
		return total_fee;
	}
	public void setTotal_fee(int total_fee) {
		this.total_fee = total_fee;
	}
	public String getSpbill_create_ip() {
		return spbill_create_ip;
	}
	public void setSpbill_create_ip(String spbill_create_ip) {
		this.spbill_create_ip = spbill_create_ip;
	}
	public String getNotify_url() {
		return notify_url;
	}
	public void setNotify_url(String notify_url) {
		this.notify_url = notify_url;
	}
	public String getTrade_type() {
		return trade_type;
	}
	public void setTrade_type(String trade_type) {
		this.trade_type = trade_type;
	}
}

3.3 微信支付签名

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;

/**
 * 微信支付签名
 * @author iYjrg_xiebin
 * @date 2016年10月25日下午4:47:07
 */
public class WXSignUtils {
    //http://mch.weixin.qq.com/wiki/doc/api/index.php?chapter=4_3
    //商户Key:改成公司申请的即可
    //32位密码设置地址:http://www.sexauth.com/  jdex1hvufnm1sdcb0e81t36k0d0f15nc

    private static String Key ="wuhanlongyingkejiyouxiangongsi20";

    /**
     * 微信支付签名算法sign
     * @param characterEncoding
     * @param parameters
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static String createSign(String characterEncoding,SortedMap<Object,Object> parameters){


        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            Object v = entry.getValue();
            if(null != v && !"".equals(v) 
                    && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + Key);
        System.out.println("字符串拼接后是:"+sb.toString());
        String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
        return sign;
    }

}

3.4 post提交xml格式的参数

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

import io.renren.api.properties.Unifiedorder;


/**
 * post提交xml格式的参数
 * @author iYjrg_xiebin
 * @date 2016年10月25日下午3:33:38
 */
public class HttpXmlUtils {

    /**
     * 开始post提交参数到接口
     * 并接受返回
     * @param url
     * @param xml
     * @param method
     * @param contentType
     * @return
     */
    public static String xmlHttpProxy(String url,String xml,String method,String contentType){
        InputStream is = null;
        OutputStreamWriter os = null;

        try {
            URL _url = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) _url.openConnection();
            conn.setDoInput(true);   
            conn.setDoOutput(true);   
            conn.setRequestProperty("Content-type", "text/xml");
            conn.setRequestProperty("Pragma:", "no-cache");  
            conn.setRequestProperty("Cache-Control", "no-cache");  
            conn.setRequestMethod("POST");
            os = new OutputStreamWriter(conn.getOutputStream());
            os.write(new String(xml.getBytes(contentType)));
            os.flush();

            //返回值
            is = conn.getInputStream();
            return getContent(is, "utf-8");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            try {
                if(os!=null){os.close();}
                if(is!=null){is.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 解析返回的值
     * @param is
     * @param charset
     * @return
     */
    public static String getContent(InputStream is, String charset) {
        String pageString = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        StringBuffer sb = null;
        try {
            isr = new InputStreamReader(is, charset);
            br = new BufferedReader(isr);
            sb = new StringBuffer();
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line + "\n");
            }
            pageString = sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null){
                    is.close();
                }
                if(isr!=null){
                    isr.close();
                }
                if(br!=null){
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            sb = null;
        }
        return pageString;
    }

    /**
     * 构造xml参数
     * @param xml
     * @return
     */
    public static String xmlInfo(Unifiedorder unifiedorder){
        //构造xml参数的时候,至少又是个必传参数
        /*
         * <xml>
               <appid>wx2421b1c4370ec43b</appid>
               <attach>支付测试</attach>
               <body>JSAPI支付测试</body>
               <mch_id>10000100</mch_id>
               <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
               <notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url>
               <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
               <out_trade_no>1415659990</out_trade_no>
               <spbill_create_ip>14.23.150.211</spbill_create_ip>
               <total_fee>1</total_fee>
               <trade_type>JSAPI</trade_type>
               <sign>0CB01533B8C1EF103065174F50BCA001</sign>
            </xml>
         */

        if(unifiedorder!=null){
            StringBuffer bf = new StringBuffer();
            bf.append("<xml>");

            bf.append("<appid><![CDATA[");
            bf.append(unifiedorder.getAppid());
            bf.append("]]></appid>");

            bf.append("<mch_id><![CDATA[");
            bf.append(unifiedorder.getMch_id());
            bf.append("]]></mch_id>");

            bf.append("<nonce_str><![CDATA[");
            bf.append(unifiedorder.getNonce_str());
            bf.append("]]></nonce_str>");

            bf.append("<sign><![CDATA[");
            bf.append(unifiedorder.getSign());
            bf.append("]]></sign>");

            bf.append("<body><![CDATA[");
            bf.append(unifiedorder.getBody());
            bf.append("]]></body>");

     

            bf.append("<out_trade_no><![CDATA[");
            bf.append(unifiedorder.getOut_trade_no());
            bf.append("]]></out_trade_no>");

            bf.append("<total_fee><![CDATA[");
            bf.append(unifiedorder.getTotal_fee());
            bf.append("]]></total_fee>");

            bf.append("<spbill_create_ip><![CDATA[");
            bf.append(unifiedorder.getSpbill_create_ip());
            bf.append("]]></spbill_create_ip>");

        

            bf.append("<notify_url><![CDATA[");
            bf.append(unifiedorder.getNotify_url());
            bf.append("]]></notify_url>");

            bf.append("<trade_type><![CDATA[");
            bf.append(unifiedorder.getTrade_type());
            bf.append("]]></trade_type>");


            bf.append("</xml>");
            return bf.toString();
        }

        return "";
    }




    /**
     * post请求并得到返回结果
     * @param requestUrl
     * @param requestMethod
     * @param output
     * @return
     */
    public static String httpsRequest(String requestUrl, String requestMethod, String output) {
        try{
            URL url = new URL(requestUrl);
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod(requestMethod);
            if (null != output) {
                OutputStream outputStream = connection.getOutputStream();
                outputStream.write(output.getBytes("UTF-8"));
                outputStream.close();
            }
            // 从输入流读取返回内容
            InputStream inputStream = connection.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            connection.disconnect();
            return buffer.toString();
        }catch(Exception ex){
            ex.printStackTrace();
        }

        return "";
    }

}

3.4 DOM解析

import java.io.StringReader;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource;



public class ParseXMLUtils {
   
   private static Logger log = Logger.getLogger(ParseXMLUtils.class);

   /**
    * 1、DOM解析
    */
   @SuppressWarnings("rawtypes")
public static void beginXMLParse(String xml){
      Document doc = null;
      try {
         doc = DocumentHelper.parseText(xml); // 将字符串转为XML

         Element rootElt = doc.getRootElement(); // 获取根节点smsReport

         System.out.println("根节点是:"+rootElt.getName());

         Iterator iters = rootElt.elementIterator("sendResp"); // 获取根节点下的子节点sms

         while (iters.hasNext()) {
            Element recordEle1 = (Element) iters.next();
            Iterator iter = recordEle1.elementIterator("sms");

            while (iter.hasNext()) {
               Element recordEle = (Element) iter.next();
               String phone = recordEle.elementTextTrim("phone"); // 拿到sms节点下的子节点stat值

               String smsID = recordEle.elementTextTrim("smsID"); // 拿到sms节点下的子节点stat值

               System.out.println(phone+":"+smsID);
            }
         }
      } catch (DocumentException e) {
         e.printStackTrace();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   /**
    * 2、DOM4j解析XML(支持xpath)
    * 解析的时候自动去掉CDMA
    * @param xml
    */
   public static void xpathParseXml(String xml){
      try { 
         StringReader read = new StringReader(xml);
         SAXReader saxReader = new SAXReader();
         Document doc = saxReader.read(read);
         String xpath ="/xml/appid";
         System.out.print(doc.selectSingleNode(xpath).getText());  
      } catch (DocumentException e) {
         e.printStackTrace();
      }  
   }

   /**
    * 3、JDOM解析XML
    * 解析的时候自动去掉CDMA
    * @param xml
    */
   @SuppressWarnings("unchecked")
public static UnifiedorderResult jdomParseXml(String xml){
      UnifiedorderResult unifieorderResult = new UnifiedorderResult();
      try { 
         StringReader read = new StringReader(xml);
         // 创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
         InputSource source = new InputSource(read);
         // 创建一个新的SAXBuilder
         SAXBuilder sb = new SAXBuilder();
         // 通过输入源构造一个Document
         org.jdom.Document doc;
         doc = (org.jdom.Document) sb.build(source);

         org.jdom.Element root = doc.getRootElement();// 指向根节点
         List<org.jdom.Element> list = root.getChildren();

         if(list != null && list.size() > 0){
            boolean flag1 = true;
            boolean flag2 = true;
            for (org.jdom.Element element : list) {
               log.info("key是:"+element.getName()+",值是:"+element.getText());
               
               if("return_code".equals(element.getName())){
                  if("FAIL".equals(element.getText())){
                     flag1 = false;
                  }else{
                     unifieorderResult.setReturn_code(element.getText());
                  }
               }
               
               if("return_msg".equals(element.getName())){
                  if(element.getText() != null && !"OK".equals(element.getText())){//微信支付的第一个坑,这里返回了OK,23333
                     log.error("统一下单参数有误,错误原因为:"+element.getText());
                     return null;
                  }
               }
               
               if(flag1){
                  if("appid".equals(element.getName())){
                     unifieorderResult.setAppid(element.getText());
                  }
                  if("mch_id".equals(element.getName())){
                     unifieorderResult.setMch_id(element.getText());
                  }
                  if("nonce_str".equals(element.getName())){
                     unifieorderResult.setNonce_str(element.getText());
                  }
                  if("sign".equals(element.getName())){
                     unifieorderResult.setSign(element.getText());
                  }
                  if("err_code".equals(element.getName())){
                     unifieorderResult.setErr_code(element.getText());
                  }
                  if("err_code_des".equals(element.getName())){
                     unifieorderResult.setErr_code_des(element.getText());
                  }
                  if("result_code".equals(element.getName())){
                     if("FAIL".equals(element.getText())){
                        flag2 = false;
                        log.error("统一下单业务结果有误,无法返回预支付交易会话标识");
                     }else{
                        unifieorderResult.setResult_code(element.getText());
                     }
                  }
               }
               if(flag1 && flag2 && flag2 == true){
                  if("trade_type".equals(element.getName())){
                     unifieorderResult.setTrade_type(element.getText());
                  }
                  if("prepay_id".equals(element.getName())){
                     log.info("统一下单接口成功返回预支付交易会话标识!");
                     unifieorderResult.setPrepay_id(element.getText());
                  }
               }
               
            }
            return unifieorderResult;
         }else{
            return null;
         }

      } catch (Exception e) {
         e.printStackTrace();
         return null;
      }
      
   }

   public static boolean parseInt(String key){
      if(!StringUtil.isEmpty(key)){
         if(key.equals("total_fee")||key.equals("cash_fee")||key.equals("coupon_fee")||key.equals("coupon_count")||key.equals("coupon_fee_0")){
            return true;
         }
      }

      return false;
   }


}

3.5统一下单提交给微信的参数

/**
* 统一下单提交为微信的参数
*/
public class UnifiedorderResult {
	private String return_code;
	private String return_msg;
	private String appid;
	private String mch_id;
	private String device_info;
	private String nonce_str;
	private String sign;
	private String result_code;
	private String err_code;
	private String err_code_des;
	private String trade_type;
	private String prepay_id;
	public String getAppid() {
		return appid;
	}
	public void setAppid(String appid) {
		this.appid = appid;
	}
	public String getMch_id() {
		return mch_id;
	}
	public void setMch_id(String mch_id) {
		this.mch_id = mch_id;
	}
	public String getDevice_info() {
		return device_info;
	}
	public void setDevice_info(String device_info) {
		this.device_info = device_info;
	}
	public String getNonce_str() {
		return nonce_str;
	}
	public void setNonce_str(String nonce_str) {
		this.nonce_str = nonce_str;
	}
	public String getSign() {
		return sign;
	}
	public void setSign(String sign) {
		this.sign = sign;
	}
	public String getResult_code() {
		return result_code;
	}
	public void setResult_code(String result_code) {
		this.result_code = result_code;
	}
	public String getErr_code() {
		return err_code;
	}
	public void setErr_code(String err_code) {
		this.err_code = err_code;
	}
	public String getErr_code_des() {
		return err_code_des;
	}
	public void setErr_code_des(String err_code_des) {
		this.err_code_des = err_code_des;
	}
	public String getTrade_type() {
		return trade_type;
	}
	public void setTrade_type(String trade_type) {
		this.trade_type = trade_type;
	}
	public String getPrepay_id() {
		return prepay_id;
	}
	public void setPrepay_id(String prepay_id) {
		this.prepay_id = prepay_id;
	}
	public String getReturn_code() {
		return return_code;
	}
	public void setReturn_code(String return_code) {
		this.return_code = return_code;
	}
	public String getReturn_msg() {
		return return_msg;
	}
	public void setReturn_msg(String return_msg) {
		this.return_msg = return_msg;
	}
}

应该就这么多了 如何疏忽了还有没贴的工具栏,那就只能下载我上传的工具类的(我想设置0积分 但是最低是1积分)

工具类下载地址
https://download.csdn.net/download/weixin_42694286/10930334

四、支付请求 拉取微信预付单

/**
	 * 支付请求 拉取微信预付单
	 * 
	 * @param order
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	@RequestMapping("/weixinpay")
	public R weixinpay(TpOrder order, HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 获取订单号
		String orderNo = order.getOrderSn();
		// 商品价格
		// BigDecimal goodsPrice = order.getGoodsPrice();
		// 订单总价
		BigDecimal totalAmount = order.getTotalAmount();
		double price = totalAmount.doubleValue();
		System.out.println("price:" + price);
		// 微信开放平台审核通过的应用APPID
		System.out.println("appid是:" + weixinpayProperties.getAppid());
		System.out.println("mch_id是:" + weixinpayProperties.getMch_id());
		String nonce_str = StringUtil.getRandomString(30);
		System.out.println("随机字符串是:" + nonce_str);
		String body = "测试微信支付0.01";
		String total_price = null;// 订单总金额,单位为分,详见支付金额
		/*
		 * double totalfee =0; try{
		 * totalfee=Double.parseDouble(total_price);////单位是分,即是0.01元 }catch (Exception
		 * e) { totalfee=0; }
		 */
		String spbill_create_ip; // 用户端实际ip
		int total_fee = (int) (price * 100);
		spbill_create_ip = getRemortIP(request);// "127.0.0.1";
System.out.println("spbill_create_ip===="+spbill_create_ip);
		String notify_url = weixinpayProperties.getNotify_url();
		System.out.println("notify_url是:" + notify_url);
		String trade_type = "APP";

		// 参数:开始生成签名
		SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
		parameters.put("appid", weixinpayProperties.getAppid());
		parameters.put("mch_id", weixinpayProperties.getMch_id());
		parameters.put("nonce_str", nonce_str);
		parameters.put("body", body);
		parameters.put("out_trade_no", orderNo);
		parameters.put("total_fee", total_fee);
		parameters.put("notify_url", notify_url);
		parameters.put("trade_type", trade_type);
		parameters.put("spbill_create_ip",spbill_create_ip);

		String sign = WXSignUtils.createSign("UTF-8", parameters);
		System.out.println("签名是:" + sign);

		Unifiedorder unifiedorder = new Unifiedorder();
		unifiedorder.setAppid(weixinpayProperties.getAppid());
		unifiedorder.setMch_id(weixinpayProperties.getMch_id());
		unifiedorder.setNonce_str(nonce_str);
		unifiedorder.setSign(sign);
		unifiedorder.setBody(body);
		unifiedorder.setOut_trade_no(orderNo);
		unifiedorder.setTotal_fee(total_fee);
		unifiedorder.setSpbill_create_ip(spbill_create_ip);
		unifiedorder.setNotify_url(notify_url);
		unifiedorder.setTrade_type(trade_type);

		// 构造xml参数
		String xmlInfo = HttpXmlUtils.xmlInfo(unifiedorder);
		System.out.println("xmlInfo:" + xmlInfo);

		String wxUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";

		String method = "POST";

		String weixinPost = HttpXmlUtils.httpsRequest(wxUrl, method, xmlInfo).toString();// 请求微信

		System.out.println("weixinPost:" + weixinPost);

		UnifiedorderResult unifiedorderResult = ParseXMLUtils.jdomParseXml(weixinPost);// 解析微信的反馈

		if (unifiedorderResult != null) {

			if ("SUCCESS".equals(unifiedorderResult.getReturn_code())) {
				// 开始拼接App调起微信的参数
				SortedMap<Object, Object> wxAppparameters = new TreeMap<Object, Object>();
				wxAppparameters.put("appid", unifiedorderResult.getAppid());
				wxAppparameters.put("partnerid", unifiedorderResult.getMch_id());
				wxAppparameters.put("prepayid", unifiedorderResult.getPrepay_id());
				wxAppparameters.put("package", weixinpayProperties.getWx_package());
				wxAppparameters.put("noncestr", nonce_str);
				wxAppparameters.put("timestamp", String.valueOf(new Date().getTime()).substring(0, 10));
				wxAppparameters.put("sign", WXSignUtils.createSign("UTF-8", wxAppparameters));
				return R.ok().put("wxAppparameters", wxAppparameters);
			} else {
				logger.error("错误原因为:" + unifiedorderResult.getReturn_msg());
				return R.error();
			}
		} else {
			logger.error("服务端请求微信的返回值异常。");
			return R.error();
		}

	}

五、微信支付服务器异步通知

/**
 * 微信支付服务器异步通知
 * 
 * @param request
 * @throws Exception
 */

@RequestMapping("/weixinnotifyUrl")
//@Transactional(isolation = Isolation.SERIALIZABLE)
public String notifyUrl(HttpServletRequest request) throws Exception {
	String result;//返回给微信的处理结果  
	//BigDecimal platfor = null;
	logger.info("notifyUrl");
	// 读取参数
	InputStream inputStream;
	StringBuffer sb = new StringBuffer();
	inputStream = request.getInputStream();
	String s;
	BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
	while ((s = in.readLine()) != null) {
		sb.append(s);
	}
	in.close();
	inputStream.close();

	// 解析xml成map
	Map<String, String> m = new HashMap<String, String>();
	m = XmlUtil.doXMLParse(sb.toString());

	//过滤空 设置 TreeMap
	SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
	Iterator<String> it = m.keySet().iterator();
	while (it.hasNext()) {
		String parameter = it.next();
		String parameterValue = m.get(parameter);

		String v = "";
		if (null != parameterValue) {
			v = parameterValue.trim();
		}
		logger.info("p:" + parameter + ",v:" + v);
		packageParams.put(parameter, v);
	}

	// 微信支付的API密钥
	String key = weixinpayProperties.getKey();
 
	if (isTenpaySign("UTF-8", packageParams, key)) { // 验证通过
		if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
			//这里面是你的业务逻辑处理
				 // 通知微信已经收到消息,不要再给我发消息了,否则微信会8连击调用本接口
				 result = setXML("SUCCESS", "OK"); 
				 System.out.println(result+"===1");
				return result;
			}
		}
	} else {
		result = setXML("fail","xml获取失败"); 
		System.out.println(result+"===2");
		return result; 
	}
	result = setXML("fail","xml获取失败"); 
	System.out.println(result+"===3");
	return result; 
}

public static String setXML(String return_code, String return_msg) {
    return "<xml><return_code><![CDATA[" + return_code + "]]></return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
}


/**
 * 类型转换
 * 
 * @author chenp
 * @param matrix
 * @return
 */
public static BufferedImage toBufferedImage(BitMatrix matrix) {
	int width = matrix.getWidth();
	int height = matrix.getHeight();
	BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
	for (int x = 0; x < width; x++) {
		for (int y = 0; y < height; y++) {
			image.setRGB(x, y, matrix.get(x, y) == true ? 0xff000000 : 0xFFFFFFFF);
		}
	}
	return image;
}

/**
 * 通过返回IO流获取支付地址
 * 
 * @param in
 * @return
 */
@SuppressWarnings({ "unused", "unchecked" })
private String getElementValue(InputStream in, String key) throws Exception {
	SAXReader reader = new SAXReader();
	Document document = reader.read(in);
	Element root = document.getRootElement();
	List<Element> childElements = root.elements();
	for (Element child : childElements) {
		if (key.equals(child.getName())) {
			return child.getStringValue();
		}
	}
	return null;
}

/**
 * 获取本机IP地址
 * 
 * @return IP
 */
public static String getRemortIP(HttpServletRequest request) {
	if (request.getHeader("x-forwarded-for") == null) {
		return request.getRemoteAddr();
	}
	return request.getHeader("x-forwarded-for");
}

/**
 * 微信支付签名算法sign
 */
@SuppressWarnings("unused")
private String getSign(Map<String, Object> map) {
	StringBuffer sb = new StringBuffer();
	String[] keyArr = (String[]) map.keySet().toArray(new String[map.keySet().size()]);// 获取map中的key转为array
	Arrays.sort(keyArr);// 对array排序
	for (int i = 0, size = keyArr.length; i < size; ++i) {
		if ("sign".equals(keyArr[i])) {
			continue;
		}
		sb.append(keyArr[i] + "=" + map.get(keyArr[i]) + "&");
	}
	sb.append("key=" + weixinpayProperties.getKey());
	String sign = string2MD5(sb.toString());
	return sign;
}

/***
 * MD5加码 生成32位md5码
 */
private String string2MD5(String str) {
	if (str == null || str.length() == 0) {
		return null;
	}
	char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	try {
		MessageDigest mdTemp = MessageDigest.getInstance("MD5");
		mdTemp.update(str.getBytes("UTF-8"));

		byte[] md = mdTemp.digest();
		int j = md.length;
		char buf[] = new char[j * 2];
		int k = 0;
		for (int i = 0; i < j; i++) {
			byte byte0 = md[i];
			buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
			buf[k++] = hexDigits[byte0 & 0xf];
		}
		return new String(buf).toUpperCase();
	} catch (Exception e) {
		return null;
	}
}

/**
 * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
 * 
 * @return boolean
 */
@SuppressWarnings("rawtypes")
public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams,
		String API_KEY) {
	StringBuffer sb = new StringBuffer();
	Set es = packageParams.entrySet();
	Iterator it = es.iterator();
	while (it.hasNext()) {
		Map.Entry entry = (Map.Entry) it.next();
		String k = (String) entry.getKey();
		String v = (String) entry.getValue();
		if (!"sign".equals(k) && null != v && !"".equals(v)) {
			sb.append(k + "=" + v + "&");
		}
	}
	sb.append("key=" + API_KEY);

	// 算出摘要
	String mysign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();
	String tenpaySign = ((String) packageParams.get("sign")).toLowerCase();

	return tenpaySign.equals(mysign);
}

}

六、微信官方接口文档稀巴烂 集成它的支付功能要人命

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章