java 服务端对接微信支付 Demo

服务端代码:

package com.wlsq.kso.web;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.cxf.common.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wlsq.kso.annotation.MethodAction;
import com.wlsq.kso.entity.ResultObject;
import com.wlsq.kso.service.AccountWalletService;
import com.wlsq.kso.util.HttpUtil;
import com.wlsq.kso.util.MyMd5Util;
import com.wlsq.kso.util.XmltoJsonUtil;

/**
 * 微信支付接口Controller
 * 
 * @author zzg
 * @date 2017-02-18
 */

@Controller
@RequestMapping(value = "/WeiXinPay")
public class AccountWeiXinController {
	private static final Logger LOG = LoggerFactory
			.getLogger(AccountWeiXinController.class);
	
	@Autowired
	private AccountWalletService accountWalletService;

	// 微信统一下单接口路径
	private static final String UNIFORMORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";

	// 微信商户号:*****
	private static final String MCHID = "********";
	// 微信回调地址
	private static final String NOTIFYURL = "*********";
	// 微信交易类型
	private static final String TRADETYPE = "APP";
	//微信APIKEY
    private static final String APIKEY ="************";

	/**
	 * 微信统一下单
	 * 
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	@MethodAction(optionDescription = "微信统一下单", methodName = "/WeiXinPay/uniformorder")
	@RequestMapping(value = "/uniformorder", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
	@ResponseBody
	public String uniformorder(HttpServletRequest request) throws UnsupportedEncodingException {
		ResultObject result = new ResultObject();// 返回数据结果集合
		request.setCharacterEncoding("UTF-8");  
	    
		try {
			//APP ID
			String appid = request.getParameter("appid") == null ? null
					: request.getParameter("appid").trim().toUpperCase();
			// 用户访问令牌
			String accessToken = request.getParameter("accessToken") == null ? null
					: request.getParameter("accessToken").trim();
			// 订单编号
			String orderNum = request.getParameter("orderNum") == null ? null
					: request.getParameter("orderNum").trim();// 订单编号
			// 消费金额
			String money = request.getParameter("money") == null ? null
					: request.getParameter("money").trim();// 消费金额
			// 消费主题
			String subject = request.getParameter("subject") == null ? null
					: request.getParameter("subject").trim();// 消费主体
			
			if(StringUtils.isEmpty(appid)){
				result.setMsg("参数:appid 为空");
				result.setResultCode("-1");
				return JSON.toJSONString(result);
			}
			if(StringUtils.isEmpty(accessToken)){
				result.setMsg("参数:accessToken 为空");
				result.setResultCode("-1");
				return JSON.toJSONString(result);
			}
			
			if(StringUtils.isEmpty(orderNum)){
				result.setMsg("参数:orderNum 为空");
				result.setResultCode("-1");
				return JSON.toJSONString(result);
			}
			if(StringUtils.isEmpty(money)){
				result.setMsg("参数:money 为空");
				result.setResultCode("-1");
				return JSON.toJSONString(result);
			}
			if(StringUtils.isEmpty(subject)){
				result.setMsg("参数:subject 为空");
				result.setResultCode("-1");
				return JSON.toJSONString(result);
			}

			SortedMap<Object,Object> parame = new TreeMap<Object,Object>();
			parame.put("appid", *********");
			parame.put("mch_id", MCHID);// 商家账号。
			String randomStr = getRandomString(18).toUpperCase();
			parame.put("nonce_str", randomStr);// 随机字符串			
			parame.put("body", subject);// 商品描述
			parame.put("out_trade_no", orderNum);// 商户订单编号
			   //支付金额

			parame.put("total_fee", BigDecimal.valueOf(Long.parseLong(money)).multiply(new BigDecimal(100)).toString());// 消费金额
			String ip = getIpAddr(request);
			if (StringUtils.isEmpty(ip)) {
				parame.put("spbill_create_ip", "127.0.0.1");// 消费IP地址
			} else {
				parame.put("spbill_create_ip", ip);// 消费IP地址
			}
			parame.put("notify_url", NOTIFYURL);// 回调地址
			parame.put("trade_type", TRADETYPE);// 交易类型APP
			String sign =createSign(parame); 
			parame.put("sign", sign);// 数字签证
			
			String xml = getRequestXML(parame);	

			String content = HttpUtil.sendPost(UNIFORMORDER, xml);	
			System.out.println(content);
			JSONObject jsonObject = JSONObject.parseObject(XmltoJsonUtil.xml2JSON(content)) ;  
			JSONObject result_xml = jsonObject.getJSONObject("xml");
			JSONArray result_code =  result_xml.getJSONArray("result_code");			
			String code = (String)result_code.get(0);
			
			List<String> data = new ArrayList<String>();			
			if(code.equalsIgnoreCase("FAIL")){
				result.setMsg("微信统一订单下单失败");
				result.setResultCode("-1");
				result.setData(data);
			}else if(code.equalsIgnoreCase("SUCCESS")){
				JSONArray prepay_id = result_xml.getJSONArray("prepay_id");				
				String prepayId = (String)prepay_id.get(0);
				data.add(prepayId);
				result.setMsg("微信统一订单下单成功");
				result.setResultCode("1");
				result.setData(data);
			}			
			return JSON.toJSONString(result);
		
		} catch (Exception e) {
			result.setMsg(e.getMessage());
			result.setResultCode("-1");
			return JSON.toJSONString(result);
		}		

	}
	
	/**
	 * 微信订单回调接口
	 * 
	 * @return
	 */
	@MethodAction(optionDescription = "微信回掉接口", methodName = "/WeiXinPay/notify")
	@RequestMapping(value = "/notify", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
	@ResponseBody
	public void notify(HttpServletRequest request,HttpServletResponse response){
		ResultObject result = new ResultObject();// 返回数据结果集合
		try{
			request.setCharacterEncoding("UTF-8");  
		    response.setCharacterEncoding("UTF-8");  
		    response.setContentType("text/html;charset=UTF-8");  
		    response.setHeader("Access-Control-Allow-Origin", "*");   
		    InputStream in=request.getInputStream();  
		    ByteArrayOutputStream out=new ByteArrayOutputStream();  
		    byte[] buffer =new byte[1024];  
		    int len=0;  
		    while((len=in.read(buffer))!=-1){  
		        out.write(buffer, 0, len);  
		    }  
		    out.close();  
		    in.close();  
		    String content=new String(out.toByteArray(),"utf-8");//xml数据  
		    
		    JSONObject jsonObject = JSONObject.parseObject(XmltoJsonUtil.xml2JSON(content)) ;  
			JSONObject result_xml = jsonObject.getJSONObject("xml");
			JSONArray result_code =  result_xml.getJSONArray("result_code");
			String code = (String)result_code.get(0);
			
			if(code.equalsIgnoreCase("FAIL")){
				result.setMsg("微信统一订单下单失败");
				result.setResultCode("-1");				
			
				response.getWriter().write(setXml("SUCCESS", "OK"));
				
				
			}else if(code.equalsIgnoreCase("SUCCESS")){
				result.setMsg("微信统一订单下单成功");
				result.setResultCode("1");	
				
				JSONArray out_trade_no = result_xml.getJSONArray("out_trade_no");//订单编号
				Map<String,Object> map = new HashMap<String,Object>();
				map.put("orderNum", (String)out_trade_no.get(0));
				map.put("consumState", 1);
				accountWalletService.updateAccountOrderState(map);
				
				response.getWriter().write(setXml("SUCCESS", "OK"));
				
			}			
			
		   
		}catch(Exception e){
			result.setMsg(e.getMessage());
			result.setResultCode("-1");
			return;
		}
		
	}
	

	// 返回用IP地址
	public String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader(" x-forwarded-for ");
		if (ip == null || ip.length() == 0 || " unknown ".equalsIgnoreCase(ip)) {
			ip = request.getHeader(" Proxy-Client-IP ");
		}
		if (ip == null || ip.length() == 0 || " unknown ".equalsIgnoreCase(ip)) {
			ip = request.getHeader(" WL-Proxy-Client-IP ");
		}
		if (ip == null || ip.length() == 0 || " unknown ".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	// 随机字符串生成
	public static String getRandomString(int length) { // length表示生成字符串的长度
		String base = "abcdefghijklmnopqrstuvwxyz0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}
	
	
	//拼接xml 请求路径
	public static String getRequestXML(SortedMap<Object, Object> parame){
		StringBuffer buffer = new StringBuffer();
		buffer.append("<xml>");
		Set set = parame.entrySet();
		Iterator iterator = set.iterator();
		while(iterator.hasNext()){
			Map.Entry entry = (Map.Entry) iterator.next();
			String key = (String)entry.getKey();
			String value = (String)entry.getValue();
			//过滤相关字段sign
			if("sign".equalsIgnoreCase(key)){
				buffer.append("<"+key+">"+"<![CDATA["+value+"]]>"+"</"+key+">");
			}else{
				buffer.append("<"+key+">"+value+"</"+key+">");
			}			
		}
		buffer.append("</xml>");
		return buffer.toString();
	}
	
	//创建md5 数字签证
	public static String createSign(SortedMap<Object, Object> parame){
		StringBuffer buffer = new StringBuffer();
		Set set = parame.entrySet();
		Iterator iterator = set.iterator();
		while(iterator.hasNext()){
			Map.Entry entry = (Map.Entry) iterator.next();
			String key = (String)entry.getKey();
			Object value = (String)entry.getValue();
			if(null != value && !"".equals(value) && !"sign".equals(key) && !"key".equals(key)){
				buffer.append(key+"="+value+"&");
			}			
		}
		buffer.append("key="+APIKEY);
		String sign =MyMd5Util.md5(buffer.toString()).toUpperCase(); 
		System.out.println("签名参数:"+sign);
		return sign;
	}
	
	//返回微信服务
	 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>";  
	}  
	
	//模拟微信回调接口
	 public static String callbakcXml(String orderNum){
		 return "<xml><appid><![CDATA[wx2421b1c4370ec43b]]></appid><attach><![CDATA[支付测试]]></attach><bank_type><![CDATA[CFT]]></bank_type><fee_type><![CDATA[CNY]]></fee_type> <is_subscribe><![CDATA[Y]]></is_subscribe><mch_id><![CDATA[10000100]]></mch_id><nonce_str><![CDATA[5d2b6c2a8db53831f7eda20af46e531c]]></nonce_str><openid><![CDATA[oUpF8uMEb4qRXf22hE3X68TekukE]]></openid> <out_trade_no><![CDATA["+orderNum+"]]></out_trade_no>  <result_code><![CDATA[SUCCESS]]></result_code> <return_code><![CDATA[SUCCESS]]></return_code><sign><![CDATA[B552ED6B279343CB493C5DD0D78AB241]]></sign><sub_mch_id><![CDATA[10000100]]></sub_mch_id> <time_end><![CDATA[20140903131540]]></time_end><total_fee>1</total_fee><trade_type><![CDATA[JSAPI]]></trade_type><transaction_id><![CDATA[1004400740201409030005092168]]></transaction_id></xml>";
	 }
	
	
	public static void main(String[] args) throws Exception{
		String str = HttpUtil.sendPost("http://localhost:8080/WlsqWS/WeiXinPay/notify", callbakcXml("a313a907f72f4f70b53a46b9773a9d42"));
		System.out.println("result :"+str);
//		SortedMap<Object,Object> parame = new TreeMap<Object,Object>();
//		parame.put("appid", "wxdf26629c37f5b7c1");
//		parame.put("mch_id", MCHID);
//		String randomStr = getRandomString(18).toUpperCase();
//		parame.put("nonce_str", randomStr);
//		String subject = "余额充值";
//		parame.put("body", subject);
//		String orderNum = "3a6154e2a662407c8223971284c372a7";
//		parame.put("out_trade_no", orderNum);
//		String money ="1";
//		parame.put("total_fee", money);
//		String ip ="127.0.0.1";
//		parame.put("spbill_create_ip", ip);
//		parame.put("notify_url", NOTIFYURL);
//		parame.put("trade_type", TRADETYPE);
//		String sign =createSign(parame); 
//		parame.put("sign", sign);// 数字签证
//		
//		String xml = getRequestXML(parame);		
//
//		String content = HttpUtil.sendPost(UNIFORMORDER, xml);
//		
//		//成功代码
//		String result = XmltoJsonUtil.xml2JSON(content);		
//		JSONObject jsonObject = JSONObject.parseObject(result) ;  
//		JSONObject results = jsonObject.getJSONObject("xml");
//		JSONArray array =  results.getJSONArray("result_code");
//		String code = (String)array.get(0);
//		System.out.println(results.toString());
//		System.out.println(code);
		
		//失败代码
//		String result = XmltoJsonUtil.xml2JSON(content);		
//		JSONObject jsonObject = JSONObject.parseObject(result) ; 
//		System.out.println(jsonObject.toString());
	}

}


java 工具类:

HttpUtil 类

package com.wlsq.kso.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;

public class HttpUtil
{
  public static final String POST = "POST";
  public static final String GET = "GET";

  public static String post(String uriString, Map<String, String> params)
    throws Exception
  {
    URL url = new URL(uriString);
    HttpURLConnection con = (HttpURLConnection)url.openConnection();
    con.setDoOutput(true);
    con.setDoInput(true);
    con.setRequestMethod(RequstMethod.POST.value());
    con.setRequestProperty(" Content-Type ", 
      " application/x-www-form-urlencoded ");
    con.setUseCaches(false);
    con.setInstanceFollowRedirects(true);

    if (params != null) {
      StringBuffer sb = new StringBuffer();
      String data = null;
      byte[] b = null;

      for (String key : params.keySet()) {
        sb.append(key).append('=').append((String)params.get(key)).append('&');
      }
      data = sb.substring(0, sb.length() - 1);
      b = data.getBytes("UTF-8");

      OutputStream out = con.getOutputStream();
      out.write(b);
      out.flush();
      out.close();
    }

    InputStream in = con.getInputStream();
    String responseBody = FileUtil.readAll(in);

    return responseBody;
  }

  public static String post(String uriString, Map<String, String> params, String authorization)
    throws Exception
  {
    URL url = new URL(uriString);
    HttpURLConnection con = (HttpURLConnection)url.openConnection();
    con.setDoOutput(true);
    con.setDoInput(true);
    con.setRequestMethod(RequstMethod.POST.value());
    con.setRequestProperty("Content-Type", "application/json");
    con.setRequestProperty("Authorization", authorization);
    con.setUseCaches(false);
    con.setInstanceFollowRedirects(true);

    if (params != null) {
      StringBuffer sb = new StringBuffer();
      String data = null;
      byte[] b = null;

      for (String key : params.keySet()) {
        sb.append(key).append('=').append((String)params.get(key)).append('&');
      }
      data = sb.substring(0, sb.length() - 1);
      b = data.getBytes("UTF-8");

      OutputStream out = con.getOutputStream();
      out.write(b);
      out.flush();
      out.close();
    }

    InputStream in = con.getInputStream();
    String responseBody = FileUtil.readAll(in);

    return responseBody;
  }

  public static String jpost(String uriString, Map<String, String> params)
    throws Exception
  {
    URL url = new URL(uriString);
    HttpURLConnection con = (HttpURLConnection)url.openConnection();
    con.setDoOutput(true);
    con.setDoInput(true);
    con.setRequestMethod(RequstMethod.POST.value());
    con.setRequestProperty("Content-Type", "application/json");
    con.setUseCaches(false);
    con.setInstanceFollowRedirects(true);

    if (params != null) {
      StringBuffer sb = new StringBuffer();
      String data = null;
      byte[] b = null;

      for (String key : params.keySet()) {
        sb.append(key).append('=').append((String)params.get(key)).append('&');
      }
      data = sb.substring(0, sb.length() - 1);
      b = data.getBytes("UTF-8");

      OutputStream out = con.getOutputStream();
      out.write(b);
      out.flush();
      out.close();
    }

    InputStream in = con.getInputStream();
    String responseBody = FileUtil.readAll(in);

    return responseBody;
  }

  public static String sendGet(String url, String param)
  {
    String result = "";
    BufferedReader in = null;
    try {
      String urlNameString = url + "?" + param;
      URL realUrl = new URL(urlNameString);

      URLConnection connection = realUrl.openConnection();

      connection.setRequestProperty("accept", "*/*");
      connection.setRequestProperty("Content-Type", "application/json");
      connection.setRequestProperty("connection", "Keep-Alive");
      connection.setRequestProperty("user-agent", 
        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");

      connection.connect();

      Map map = connection.getHeaderFields();

//      for (String key : map.keySet()) {
//        System.out.println(key + "--->" + map.get(key));
//      }

      in = new BufferedReader(new InputStreamReader(
        connection.getInputStream(), "utf-8"));
      String line;
      while ((line = in.readLine()) != null)
      {
        //String line;
        result = result + line;
      }
    } catch (Exception e) {
      System.out.println("����GET��������쳣��" + e);
      e.printStackTrace();
      try
      {
        if (in != null)
          in.close();
      }
      catch (Exception e2) {
        e2.printStackTrace();
      }
    }
    finally
    {
      try
      {
        if (in != null)
          in.close();
      }
      catch (Exception e2) {
        e2.printStackTrace();
      }
    }
    return result;
  }

  public static String sendPost(String url, String param)
  {
    PrintWriter out = null;
    BufferedReader in = null;
    String result = "";
    try {
      URL realUrl = new URL(url);

      URLConnection conn = realUrl.openConnection();

      conn.setRequestProperty("Content-Type", "application/xml");

      conn.setDoOutput(true);
      conn.setDoInput(true);

      out = new PrintWriter(conn.getOutputStream());

      out.print(param);

      out.flush();

      in = new BufferedReader(
        new InputStreamReader(conn.getInputStream()));
      String line;
      while ((line = in.readLine()) != null)
      {
        //String line;
        result = result + line;
      }
    } catch (Exception e) {
      System.out.println("���� POST ��������쳣��" + e);
      e.printStackTrace();
      try
      {
        if (out != null) {
          out.close();
        }
        if (in != null)
          in.close();
      }
      catch (IOException ex)
      {
        ex.printStackTrace();
      }
    }
    finally
    {
      try
      {
        if (out != null) {
          out.close();
        }
        if (in != null)
          in.close();
      }
      catch (IOException ex)
      {
        ex.printStackTrace();
      }
    }
    return result;
  }

  public static enum RequstMethod
  {
    GET("GET"), POST("POST");

    private String value;

    private RequstMethod(String value) {
      this.value = value;
    }

    public String value() {
      return this.value;
    }
  }
}


XmltoJsonUtil 类

package com.wlsq.kso.util;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.jdom.Document;  
import org.jdom.Element;  
import org.jdom.input.SAXBuilder;  

import com.alibaba.fastjson.JSONObject;

public class XmltoJsonUtil {
	public static  String xml2JSON(String xml) {  
        JSONObject obj = new JSONObject();  
        try {  
            InputStream is = new ByteArrayInputStream(xml.getBytes("utf-8"));  
            SAXBuilder sb = new SAXBuilder();  
            Document doc = sb.build(is);  
            Element root = doc.getRootElement();  
            obj.put(root.getName(), iterateElement(root));  
            return obj.toString();  
        } catch (Exception e) {  
            e.printStackTrace();  
            return null;  
        }  
    } 
	
	 private static Map  iterateElement(Element element) {  
	        List jiedian = element.getChildren();  
	        Element et = null;  
	        Map obj = new HashMap();  
	        List list = null;  
	        for (int i = 0; i < jiedian.size(); i++) {  
	            list = new LinkedList();  
	            et = (Element) jiedian.get(i);  
	            if (et.getTextTrim().equals("")) {  
	                if (et.getChildren().size() == 0)  
	                    continue;  
	                if (obj.containsKey(et.getName())) {  
	                    list = (List) obj.get(et.getName());  
	                }  
	                list.add(iterateElement(et));  
	                obj.put(et.getName(), list);  
	            } else {  
	                if (obj.containsKey(et.getName())) {  
	                    list = (List) obj.get(et.getName());  
	                }  
	                list.add(et.getTextTrim());  
	                obj.put(et.getName(), list);  
	            }  
	        }  
	        return obj;  
	    }  
	 
	 

}


MyMd5Util 类

package com.wlsq.kso.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @author fengcai ouyang
 * @version V1.0
 * @Description:
 * @date 2016/7/23 18:48
 * @Update by: ${todo}
 */
public class MyMd5Util {
    private static MessageDigest sMd5MessageDigest;
    private static StringBuilder sStringBuilder;

    private MyMd5Util() {
    }

    public static String md5(String s) {
        sMd5MessageDigest.reset();
        sMd5MessageDigest.update(s.getBytes());
        byte[] digest = sMd5MessageDigest.digest();
        sStringBuilder.setLength(0);

        for (int i = 0; i < digest.length; ++i) {
            int b = digest[i] & 255;
            if (b < 16) {
                sStringBuilder.append('0');
            }

            sStringBuilder.append(Integer.toHexString(b));
        }

        return sStringBuilder.toString().toUpperCase();
    }

    static {
        try {
            sMd5MessageDigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException var1) {

        }

        sStringBuilder = new StringBuilder();
    }
}



评论 48
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值