首页 > 编程 > Java > 正文

详解APP微信支付(java后台_统一下单和回调)

2019-11-26 09:02:04
字体:
来源:转载
供稿:网友

1.微信配置信息 global.properties

2.方法wxpay用于生成预支付订单信息

方法notifyWeiXinPay用于微信支付成功后的回调, 注意: 在手机端使用微信支付成功后,微信服务器会根据提供的回调地址进行回调, parameterMap.put("notify_url", wxnotify); (见下面代码) 

在局域网是无法进行回调的,必须将你的服务端放在公网上进行测试, 回调函数会被多次调用,如果第一次成功后,你可以将业务数据状态标志为已处理, 对于相同订单的其它回调就不需要再次处理了;

package com.main.controller; import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.math.BigDecimal;import java.util.Date;import java.util.HashMap;import java.util.Map;import java.util.SortedMap;import java.util.TreeMap; import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse; import org.jdom.JDOMException;import org.springframework.http.MediaType;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.main.model.WeiXinPrePay;import com.main.util.ConfigManager;import com.main.util.DateUtil;import com.main.util.GeneralConstant;import com.main.util.PayCommonUtil;import com.main.util.Result;import com.main.util.StringUtil; @Controller@RequestMapping("/pay")public class PayController {		  String randomString = PayCommonUtil.getRandomString(32);  //支付成功后的回调函数  public static String wxnotify = "http://com.zhuohuicalss/pay/notifyWeiXinPay";		public PayController() {		System.out.println("MainController构造函数");	}			/**   * @param totalAmount  支付金额   * @param description  描述   * @param request   * @return   */  @RequestMapping(value = "/wxpay", produces = MediaType.APPLICATION_JSON_VALUE)  @ResponseBody    public Result wxpay(HttpServletRequest request) {  	Result result = new Result();    Long userId = new Long(1);//baseController.getUserId();        BigDecimal totalAmount = new BigDecimal(request.getParameter("totalPrice"));    String trade_no = "";    String description="";		try {			trade_no = new String(request.getParameter("orderNum").getBytes("ISO-8859-1"),"UTF-8");			description = request.getParameter("description");		} catch (UnsupportedEncodingException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}    String openId = "";        Map<String, String> map = weixinPrePay(trade_no,totalAmount,description,openId,request);     SortedMap<String, Object> finalpackage = new TreeMap<String, Object>();    //应用ID    finalpackage.put("appid", ConfigManager.getInstance().getConfigItem("WXAppID")/*PayCommonUtil.APPID*/);    //商户号    finalpackage.put("partnerid", ConfigManager.getInstance().getConfigItem("MCH_ID"));    Long time = (System.currentTimeMillis() / 1000);    //时间戳    finalpackage.put("timestamp", time.toString());    //随机字符串    finalpackage.put("noncestr", map.get("nonce_str"));    //预支付交易会话ID    finalpackage.put("prepayid", map.get("prepay_id"));    //扩展字段    finalpackage.put("package", "Sign=WXPay");        WeiXinPrePay prePay = new WeiXinPrePay();    prePay.setAppId(ConfigManager.getInstance().getConfigItem("WXAppID"));    prePay.setMchId(ConfigManager.getInstance().getConfigItem("MCH_ID"));    prePay.setTimeStamp(time.toString());    prePay.setNonceStr(map.get("nonce_str"));    prePay.setPrepayId(map.get("prepay_id"));    prePay.setSignType("MD5");    prePay.setPaySign(sign);    result.setData(prePay);    result.setStateCode(GeneralConstant.SUCCESS);    result.setDesc("微信支付加载成功");        return result;  }  		/**   * 统一下单    * 应用场景:商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付。   * @param trade_no   * @param totalAmount   * @param description   * @param openid   * @param sym   * @param request   * @return   */  @SuppressWarnings("unchecked")  public Map<String, String> weixinPrePay(String trade_no,BigDecimal totalAmount,       String description, String openid, HttpServletRequest request) {     SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();     parameterMap.put("appid", ConfigManager.getInstance().getConfigItem("WXAppID")); //应用appid     parameterMap.put("mch_id", ConfigManager.getInstance().getConfigItem("MCH_ID")/*PayCommonUtil.MCH_ID*/); //商户号    //parameterMap.put("device_info", "WEB");    parameterMap.put("nonce_str", randomString);     parameterMap.put("body", description);    parameterMap.put("out_trade_no", trade_no);    parameterMap.put("fee_type", "CNY");     System.out.println("jiner");     BigDecimal total = totalAmount.multiply(new BigDecimal(100)); //接口中参数支付金额单位为【分】,参数值不能带小数,所以乘以100    java.text.DecimalFormat df=new java.text.DecimalFormat("0");     parameterMap.put("total_fee", df.format(total));     System.out.println("jiner2");     parameterMap.put("spbill_create_ip", PayCommonUtil.getRemoteHost(request));     parameterMap.put("notify_url", wxnotify);    parameterMap.put("trade_type", "APP");//"JSAPI"    //trade_type为JSAPI是 openid为必填项    //parameterMap.put("openid", openid);    System.out.println("");     String sign = PayCommonUtil.createSign("UTF-8", parameterMap);     System.out.println("jiner2");     parameterMap.put("sign", sign);     String requestXML = PayCommonUtil.getRequestXml(parameterMap);     System.out.println(requestXML);     String result = PayCommonUtil.httpsRequest(         "https://api.mch.weixin.qq.com/pay/unifiedorder", "POST",         requestXML);     System.out.println(result);     Map<String, String> map = null;     try {       map = PayCommonUtil.doXMLParse(result);     } catch (JDOMException e) {       // TODO Auto-generated catch block       e.printStackTrace();     } catch (IOException e) {       // TODO Auto-generated catch block       e.printStackTrace();     }     return map;      }       /**   * 此函数会被执行多次,如果支付状态已经修改为已支付,则下次再调的时候判断是否已经支付,如果已经支付了,则什么也执行   * @param request   * @param response   * @return   * @throws IOException   * @throws JDOMException   */  @RequestMapping(value = "notifyWeiXinPay", produces = MediaType.APPLICATION_JSON_VALUE)  // @RequestDescription("支付回调地址")  @ResponseBody  public String notifyWeiXinPay(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException {    System.out.println("微信支付回调");    InputStream inStream = request.getInputStream();    ByteArrayOutputStream outSteam = new ByteArrayOutputStream();    byte[] buffer = new byte[1024];    int len = 0;    while ((len = inStream.read(buffer)) != -1) {      outSteam.write(buffer, 0, len);    }    String resultxml = new String(outSteam.toByteArray(), "utf-8");    Map<String, String> params = PayCommonUtil.doXMLParse(resultxml);    outSteam.close();    inStream.close();            Map<String,String> return_data = new HashMap<String,String>();     if (!PayCommonUtil.isTenpaySign(params)) {      // 支付失败    	return_data.put("return_code", "FAIL");       return_data.put("return_msg", "return_code不正确");    	return StringUtil.GetMapToXML(return_data);    } else {      System.out.println("===============付款成功==============");      // ------------------------------      // 处理业务开始      // ------------------------------      // 此处处理订单状态,结合自己的订单数据完成订单状态的更新      // ------------------------------       String total_fee = params.get("total_fee");      double v = Double.valueOf(total_fee) / 100;      String out_trade_no = String.valueOf(Long.parseLong(params.get("out_trade_no").split("O")[0]));			Date accountTime = DateUtil.stringtoDate(params.get("time_end"), "yyyyMMddHHmmss");			String ordertime = DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss");			String totalAmount = String.valueOf(v);			String appId = params.get("appid");			String tradeNo = params.get("transaction_id");					return_data.put("return_code", "SUCCESS");       return_data.put("return_msg", "OK"); 			return StringUtil.GetMapToXML(return_data);    }  } }

3.用到的一些工具类

import java.io.InputStream;import java.util.*; /** * 读取配置文件的类 单例类 * @author Administrator * */public class ConfigManager {	// 属性文件命名	private Properties m_props = null;	private static Map<String,String> configMap;	private static ConfigManager m_instance = null;	private static  Properties props = null; 	private ConfigManager() {		m_props = new Properties();		configMap = new HashMap<String,String>();		try {			props = System.getProperties(); //获取系统属性			m_props.load(getInputStream());			getSysConfigMsg();					} catch (Exception e) {			e.printStackTrace();		}	}	public synchronized static ConfigManager getInstance() {		if(m_instance == null){			m_instance = new ConfigManager();		}		return m_instance;	} 	public InputStream getInputStream() {		InputStream is = null;		try {			is = getClass().getClassLoader().getResourceAsStream("global.properties");		} catch (Exception e) {			e.printStackTrace();		}		return is;	}  	public Map<String,String> getSysConfigMsg(){		Set<Object> keyset = m_props.keySet();		Iterator<Object> it = keyset.iterator();		while(it.hasNext()){			String nextkey = it.next().toString();			configMap.put(nextkey,getConfigItem(nextkey));		}		return configMap;	}		public String getConfigItem(String name) {		String val = m_props.getProperty(name).trim();		if("fileSavePath".equals(name)){			if(props.getProperty("os.name").startsWith("Windows")){				val = val.split("#")[0].toString().trim();			}else{				val = val.split("#")[1].toString().trim();			}		}				return val;			}	public Map<String,String> getConfigMap(){		return configMap;	} }
import java.text.DateFormat;import java.text.ParsePosition;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.regex.Pattern;  public class DateUtil { 	// 格式:年-月-日 小时:分钟:秒  public static final String FORMAT_ONE = "yyyy-MM-dd HH:mm:ss";   // 格式:年-月-日 小时:分钟  public static final String FORMAT_TWO = "yyyy-MM-dd HH:mm";   // 格式:年月日 小时分钟秒  public static final String FORMAT_THREE = "yyyyMMdd-HHmmss";    // 格式:年月日  public static final String FORMAT_FOUR = "yyyyMMdd";    // 格式:年-月-日  public static final String LONG_DATE_FORMAT = "yyyy-MM-dd";   // 格式:月-日  public static final String SHORT_DATE_FORMAT = "MM-dd";   // 格式:小时:分钟:秒  public static final String LONG_TIME_FORMAT = "HH:mm:ss";   //格式:年-月  public static final String MONTG_DATE_FORMAT = "yyyy-MM";   // 年的加减  public static final int SUB_YEAR = Calendar.YEAR;   // 月加减  public static final int SUB_MONTH = Calendar.MONTH;   // 天的加减  public static final int SUB_DAY = Calendar.DATE;   // 小时的加减  public static final int SUB_HOUR = Calendar.HOUR;   // 分钟的加减  public static final int SUB_MINUTE = Calendar.MINUTE;   // 秒的加减  public static final int SUB_SECOND = Calendar.SECOND;   static final String dayNames[] = { "星期日", "星期一", "星期二", "星期三", "星期四",      "星期五", "星期六" };   public DateUtil() {  }   /**   * 把符合日期格式的字符串转换为日期类型   */  public static Date stringtoDate(String dateStr, String format) {    Date d = null;    SimpleDateFormat formater = new SimpleDateFormat(format);    try {      formater.setLenient(false);      d = formater.parse(dateStr);    } catch (Exception e) {      // log.error(e);      d = null;    }    return d;  }    /**   * 把符合日期格式的字符串转换为日期类型   */  public static Date stringtoDate(String dateStr, String format,      ParsePosition pos) {    Date d = null;    SimpleDateFormat formater = new SimpleDateFormat(format);    try {      formater.setLenient(false);      d = formater.parse(dateStr, pos);    } catch (Exception e) {      d = null;    }    return d;  }   /**   * 把日期转换为字符串   */  public static String dateToString(Date date, String format) {    String result = "";    SimpleDateFormat formater = new SimpleDateFormat(format);    try {      result = formater.format(date);    } catch (Exception e) {      // log.error(e);    }    return result;  }   /**   * 获取当前时间的指定格式   */  public static String getCurrDate(String format) {    return dateToString(new Date(), format);  }   /**   *    * @Title:    dateSub   * @Date     2014-1-9 上午10:44:02   * @Description: 得到指定日期前(后)的日期   * @param:    @param dateKind 例:Calendar.DAY_OF_MONTH   * @param:    @param dateStr 指定日期   * @param:    @param amount  增加(减去)的时间量   * @param:    @return     * @return:    String     * @throws   * @author    mtf   */  public static String dateSub(int dateKind, String dateStr, int amount) {    Date date = stringtoDate(dateStr, MONTG_DATE_FORMAT);    Calendar calendar = Calendar.getInstance();    calendar.setTime(date);    calendar.add(dateKind, amount);    return dateToString(calendar.getTime(), FORMAT_ONE);  }   /**   * 昨日日期   * @return   */  public static String yearthDate(String dateStr){  	Date date = stringtoDate(dateStr, LONG_DATE_FORMAT);//取时间     Calendar calendar = Calendar.getInstance();    calendar.setTime(date);     calendar.add(calendar.DATE,-1);//把日期往后增加一天.整数往后推,负数往前移动     //date=calendar.getTime();  //这个时间就是日期往后推一天的结果     return dateToString(calendar.getTime(), LONG_DATE_FORMAT);  }    /**   * 两个日期相减   * @return 相减得到的秒数   */  public static long timeSub(String firstTime, String secTime) {    long first = stringtoDate(firstTime, FORMAT_ONE).getTime();    long second = stringtoDate(secTime, FORMAT_ONE).getTime();    return (second - first) / 1000;  }  /**   * 两个日期相减   * 参数地DATE   * second 两个日期相差的秒   * @return 相减得到的秒数    * 后面时间减去前面时间 再减去 相差秒数  如果大于0 返回 FASLE   */  public static boolean timeSub(Date firstTime, Date secTime,long secs) {    long first = firstTime.getTime();    long second = secTime.getTime();    // 判断两个时间 是否间隔那么长 secs。    return (second - first - secs) > 0 ? false:true;  }  /**   * 两个日期相减   * 参数地DATE   * @return 相减得到的秒数    * 后面时间减去前面时间 如果大于0 返回 false   */  public static boolean timeSub(Date firstTime, Date secTime) {    long first = firstTime.getTime();    long second = secTime.getTime();    return (second - first)>0?false:true;  }  /**   * 获得某月的天数   */  public static int getDaysOfMonth(String year, String month) {    int days = 0;    if (month.equals("1") || month.equals("3") || month.equals("5")        || month.equals("7") || month.equals("8") || month.equals("10")        || month.equals("12")) {      days = 31;    } else if (month.equals("4") || month.equals("6") || month.equals("9")        || month.equals("11")) {      days = 30;    } else {      if ((Integer.parseInt(year) % 4 == 0 && Integer.parseInt(year) % 100 != 0)          || Integer.parseInt(year) % 400 == 0) {        days = 29;      } else {        days = 28;      }    }     return days;  }   /**   * 获取某年某月的天数   */  public static int getDaysOfMonth(int year, int month) {    Calendar calendar = Calendar.getInstance();    calendar.set(year, month - 1, 1);    return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);  }   /**   * 获得当前日期   */  public static int getToday() {    Calendar calendar = Calendar.getInstance();    return calendar.get(Calendar.DATE);  }   /**   * 获得当前月份   */  public static int getToMonth() {    Calendar calendar = Calendar.getInstance();    return calendar.get(Calendar.MONTH) + 1;  }   /**   * 获得当前年份   */  public static int getToYear() {    Calendar calendar = Calendar.getInstance();    return calendar.get(Calendar.YEAR);  }   /**   * 返回日期的天   */  public static int getDay(Date date) {    Calendar calendar = Calendar.getInstance();    calendar.setTime(date);    return calendar.get(Calendar.DATE);  }    /**   * 返回日期的年   */  public static int getYear(Date date) {    Calendar calendar = Calendar.getInstance();    calendar.setTime(date);    return calendar.get(Calendar.YEAR);  }   /**   * 返回日期的月份,1-12   */  public static int getMonth(Date date) {    Calendar calendar = Calendar.getInstance();    calendar.setTime(date);    return calendar.get(Calendar.MONTH) + 1;  }   /**   * 计算两个日期相差的天数,如果date2 > date1 返回正数,否则返回负数   */  public static long dayDiff(Date date1, Date date2) {    return (date2.getTime() - date1.getTime()) / 86400000;  }   /**   * 比较两个日期的年差   */  public static int yearDiff(String before, String after) {    Date beforeDay = stringtoDate(before, LONG_DATE_FORMAT);    Date afterDay = stringtoDate(after, LONG_DATE_FORMAT);    return getYear(afterDay) - getYear(beforeDay);  }   /**   * 比较指定日期与当前日期的差   */  public static int yearDiffCurr(String after) {    Date beforeDay = new Date();    Date afterDay = stringtoDate(after, LONG_DATE_FORMAT);    return getYear(beforeDay) - getYear(afterDay);  }   /**   * 获取每月的第一周   */  public static int getFirstWeekdayOfMonth(int year, int month) {    Calendar c = Calendar.getInstance();    c.setFirstDayOfWeek(Calendar.SATURDAY); // 星期天为第一天    c.set(year, month - 1, 1);    return c.get(Calendar.DAY_OF_WEEK);  }    /**   * 获取每月的最后一周   */  public static int getLastWeekdayOfMonth(int year, int month) {    Calendar c = Calendar.getInstance();    c.setFirstDayOfWeek(Calendar.SATURDAY); // 星期天为第一天    c.set(year, month - 1, getDaysOfMonth(year, month));    return c.get(Calendar.DAY_OF_WEEK);  }   /**   * 获得当前日期字符串,格式"yyyy-MM-dd HH:mm:ss"   *    * @return   */  public static String getNow() {    Calendar today = Calendar.getInstance();    return dateToString(today.getTime(), FORMAT_ONE);  }      /**   * 判断日期是否有效,包括闰年的情况   *    * @param date   *     YYYY-mm-dd   * @return   */  public static boolean isDate(String date) {    StringBuffer reg = new StringBuffer(        "^((//d{2}(([02468][048])|([13579][26]))-?((((0?");    reg.append("[13578])|(1[02]))-?((0?[1-9])|([1-2][0-9])|(3[01])))");    reg.append("|(((0?[469])|(11))-?((0?[1-9])|([1-2][0-9])|(30)))|");    reg.append("(0?2-?((0?[1-9])|([1-2][0-9])))))|(//d{2}(([02468][12");    reg.append("35679])|([13579][01345789]))-?((((0?[13578])|(1[02]))");    reg.append("-?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))");    reg.append("-?((0?[1-9])|([1-2][0-9])|(30)))|(0?2-?((0?[");    reg.append("1-9])|(1[0-9])|(2[0-8]))))))");    Pattern p = Pattern.compile(reg.toString());    return p.matcher(date).matches();  }      /*****   * 时间 增加、减少 n个小时以后时间   * @param date   *     YYYY-mm-dd HH:mm:ss   * @param num>0 小时        * @param type 增加和减少标志    * **/  public static Date adjustDateByHour(Date d ,Integer num, int type) {  	Calendar Cal= Calendar.getInstance();  	 	DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 	  Cal.setTime(d);   	if(type==0){  	  Cal.add(Calendar.MINUTE,-num);  	  // System.out.println("date:"+df.format(Cal.getTime()));  		  	}else  	{  		Cal.add(Calendar.MINUTE,num);  	  //System.out.println("date:"+df.format(Cal.getTime()));  	}  	return Cal.getTime();  }  /*****   * 时间 增加、减少 n个分钟以后时间   * @param date   *     YYYY-mm-dd HH:mm:ss   * @param num>0 分钟       * @param type 增加和减少标志    * **/  public static Date adjustDateByMinutes(Date d ,Integer num, int type) {  	Calendar Cal= Calendar.getInstance();  	 	DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 	  Cal.setTime(d);   	if(type==0){  	  Cal.add(Calendar.MINUTE,-num);  	 // System.out.println("date:"+df.format(Cal.getTime()));  		  	}else  	{  		Cal.add(Calendar.MINUTE,num);  	 //  System.out.println("date:"+df.format(Cal.getTime()));  	}  	return Cal.getTime();  }    public static void main(String[] args){//  	String dateStr = DateUtil.yearthDate("2017-05-30");//  	System.out.println(dateStr);//  	long min = DateUtil.timeSub("2017-04-12 00:00:00", "2017-04-13 00:00:00")/60;//  	System.out.println(min);  	String settlementDate = DateUtil.dateToString(new Date(), "yyyy-MM-dd");  	long day = DateUtil.dayDiff(DateUtil.stringtoDate("2017-06-22", "yyyy-MM-dd"),DateUtil.stringtoDate(settlementDate, "yyyy-MM-dd"));  	if(day >= 0){  		System.out.println(day);  	}  	  	String goodsArriveTime = "2017-04-02 17:00-18:00";  	int space_index = goodsArriveTime.indexOf(" ");  	String arrive_date = goodsArriveTime.substring(0, space_index);		String arrive_time = goodsArriveTime.substring(space_index+1, goodsArriveTime.length());				System.out.println(arrive_date);		System.out.println(arrive_time);		String arrive_start_time = arrive_time.substring(0, 2);		String arrive_end_time = arrive_time.substring(6,8);  			System.out.println(arrive_start_time);		System.out.println(arrive_end_time);				String Time = DateUtil.getCurrDate("HH");		System.out.println(Time);				String Time2 = DateUtil.getCurrDate("mm");		System.out.println(Time2);  }  }
import java.security.MessageDigest; public class MD5Util {	private static String byteArrayToHexString(byte b[]) {    StringBuffer resultSb = new StringBuffer();    for (int i = 0; i < b.length; i++)      resultSb.append(byteToHexString(b[i]));     return resultSb.toString();  }   private static String byteToHexString(byte b) {    int n = b;    if (n < 0)      n += 256;    int d1 = n / 16;    int d2 = n % 16;    return hexDigits[d1] + hexDigits[d2];  }   public static String MD5Encode(String origin, String charsetname) {    String resultString = null;    try {      resultString = new String(origin);      MessageDigest md = MessageDigest.getInstance("MD5");      if (charsetname == null || "".equals(charsetname))        resultString = byteArrayToHexString(md.digest(resultString            .getBytes()));      else        resultString = byteArrayToHexString(md.digest(resultString            .getBytes(charsetname)));    } catch (Exception exception) {    }    return resultString;  }   private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",      "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; }import org.apache.http.Consts;import org.apache.http.HttpEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpPost;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.ssl.SSLContexts;import org.apache.http.util.EntityUtils;import org.jdom.Document;import org.jdom.Element;import org.jdom.JDOMException;import org.jdom.input.SAXBuilder; import javax.net.ssl.SSLContext;import javax.servlet.http.HttpServletRequest;import java.io.*;import java.net.ConnectException;import java.net.HttpURLConnection;import java.net.URL;import java.security.KeyStore;import java.util.*; public class PayCommonUtil {	 //微信参数配置   public static String API_KEY = ConfigManager.getInstance().getConfigItem("API_KEY");     //随机字符串生成   public static String getRandomString(int length) { //length表示生成字符串的长度        String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";          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<String,Object> parameters){      StringBuffer sb = new StringBuffer();      sb.append("<xml>");      Set es = parameters.entrySet();      Iterator it = es.iterator();      while(it.hasNext()) {        Map.Entry entry = (Map.Entry)it.next();        String key = (String)entry.getKey();        String value = (String)entry.getValue();        if ("attach".equalsIgnoreCase(key)||"body".equalsIgnoreCase(key)||"sign".equalsIgnoreCase(key)) {          sb.append("<"+key+">"+"<![CDATA["+value+"]]></"+key+">");        }else {          sb.append("<"+key+">"+value+"</"+key+">");        }      }      sb.append("</xml>");      return sb.toString();   }     //生成签名   public static String createSign(String characterEncoding,SortedMap<String,Object> parameters){      StringBuffer sb = new StringBuffer();      Set es = parameters.entrySet();      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=" + API_KEY);      System.out.println(sb.toString());     String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();      return sign;   }    /**   * 验证回调签名   * @return   */  public static boolean isTenpaySign(Map<String, String> map) {  	String characterEncoding="utf-8";    String charset = "utf-8";    String signFromAPIResponse = map.get("sign");    if (signFromAPIResponse == null || signFromAPIResponse.equals("")) {  	  System.out.println("API返回的数据签名数据不存在,有可能被第三方篡改!!!");   	  return false;    }    System.out.println("服务器回包里面的签名是:" + signFromAPIResponse);   //过滤空 设置 TreeMap    SortedMap<String,String> packageParams = new TreeMap();        for (String parameter : map.keySet()) {  	  String parameterValue = map.get(parameter);  	  String v = "";  	  if (null != parameterValue) {  		  v = parameterValue.trim();  	  }  	  packageParams.put(parameter, v);    }        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);       //将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较   //算出签名    String resultSign = "";    String tobesign = sb.toString();        if (null == charset || "".equals(charset)) {  	  resultSign = MD5Util.MD5Encode(tobesign, characterEncoding).toUpperCase();    }else{  	  try{  		  resultSign = MD5Util.MD5Encode(tobesign, characterEncoding).toUpperCase();  	  }catch (Exception e) {  		  resultSign = MD5Util.MD5Encode(tobesign, characterEncoding).toUpperCase();  	  }    }        String tenpaySign = ((String)packageParams.get("sign")).toUpperCase();    return tenpaySign.equals(resultSign);  }   //请求方法   public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {      try {                URL url = new URL(requestUrl);        HttpURLConnection conn = (HttpURLConnection) url.openConnection();               conn.setDoOutput(true);        conn.setDoInput(true);        conn.setUseCaches(false);        // 设置请求方式(GET/POST)        conn.setRequestMethod(requestMethod);        conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");        // 当outputStr不为null时向输出流写数据        if (null != outputStr) {          OutputStream outputStream = conn.getOutputStream();          // 注意编码格式          outputStream.write(outputStr.getBytes("UTF-8"));          outputStream.close();        }        // 从输入流读取返回内容        InputStream inputStream = conn.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;        conn.disconnect();        return buffer.toString();      } catch (ConnectException ce) {        System.out.println("连接超时:{}"+ ce);      } catch (Exception e) {        System.out.println("https请求异常:{}"+ e);      }      return null;   }      //退款的请求方法   public static String httpsRequest2(String requestUrl, String requestMethod, String outputStr) throws Exception {      KeyStore keyStore = KeyStore.getInstance("PKCS12");      StringBuilder res = new StringBuilder("");      FileInputStream instream = new FileInputStream(new File("/home/apiclient_cert.p12"));      try {        keyStore.load(instream, "".toCharArray());      } finally {        instream.close();      }       // Trust own CA and all self-signed certs      SSLContext sslcontext = SSLContexts.custom()         .loadKeyMaterial(keyStore, "1313329201".toCharArray())          .build();      // Allow TLSv1 protocol only      SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(         sslcontext,          new String[] { "TLSv1" },          null,          SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);     CloseableHttpClient httpclient = HttpClients.custom()         .setSSLSocketFactory(sslsf)          .build();      try {         HttpPost httpost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");       httpost.addHeader("Connection", "keep-alive");        httpost.addHeader("Accept", "*/*");        httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");        httpost.addHeader("Host", "api.mch.weixin.qq.com");        httpost.addHeader("X-Requested-With", "XMLHttpRequest");        httpost.addHeader("Cache-Control", "max-age=0");        httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");         StringEntity entity2 = new StringEntity(outputStr , Consts.UTF_8);        httpost.setEntity(entity2);        System.out.println("executing request" + httpost.getRequestLine());         CloseableHttpResponse response = httpclient.execute(httpost);               try {          HttpEntity entity = response.getEntity();                   System.out.println("----------------------------------------");          System.out.println(response.getStatusLine());          if (entity != null) {            System.out.println("Response content length: " + entity.getContentLength());            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));            String text = "";           res.append(text);            while ((text = bufferedReader.readLine()) != null) {              res.append(text);              System.out.println(text);            }                      }          EntityUtils.consume(entity);       } finally {          response.close();        }      } finally {        httpclient.close();      }      return res.toString();   }   //xml解析   public static Map doXMLParse(String strxml) throws JDOMException, IOException {     strxml = strxml.replaceFirst("encoding=/".*/"", "encoding=/"UTF-8/"");       if(null == strxml || "".equals(strxml)) {        return null;      }            Map m = new HashMap();            InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));      SAXBuilder builder = new SAXBuilder();     Document doc = builder.build(in);     Element root = doc.getRootElement();     List list = root.getChildren();      Iterator it = list.iterator();      while(it.hasNext()) {        Element e = (Element) it.next();       String k = e.getName();        String v = "";        List children = e.getChildren();        if(children.isEmpty()) {          v = e.getTextNormalize();        } else {          v = getChildrenText(children);        }                m.put(k, v);      }            //关闭流      in.close();            return m;   }     public static String getChildrenText(List children) {     StringBuffer sb = new StringBuffer();     if(!children.isEmpty()) {       Iterator it = children.iterator();       while(it.hasNext()) {         Element e = (Element) it.next();        String name = e.getName();         String value = e.getTextNormalize();         List list = e.getChildren();         sb.append("<" + name + ">");         if(!list.isEmpty()) {           sb.append(getChildrenText(list));         }         sb.append(value);         sb.append("</" + name + ">");       }     }          return sb.toString();  }      public static String getRemoteHost(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.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;  }}
package com.lemonjr.api.utils; import java.util.Map;import java.util.regex.Matcher;import java.util.regex.Pattern; public class StringUtil {		/**	 * 数值类型前面补零(共13位)	 * @param num	 * @return	 */	public static String supplementZeroGenerateThirteen(int num){		String str = String.format("%013d", num); 				return str;	}		/**	 * 数值类型前面补零(共16位)	 * @param num	 * @return	 */	public static String supplementZeroGenerateSixteen(int num){		String str = String.format("%016d", num); 				return str;	}	/**	 * 数值类型前面补零(共3位)	 * @param num	 * @return	 */	public static String supplementZeroGenerateThree(int num){		String str = String.format("%03d", num); 				return str;	}		/**	 * 判断字符串是不是double型	 * @param str	 * @return	 */	public static boolean isNumeric(String str){ 		 Pattern pattern = Pattern.compile("[0-9]+[.]{0,1}[0-9]*[dD]{0,1}"); 		 Matcher isNum = pattern.matcher(str);	   if( !isNum.matches() ){		  return false; 		 } 		  return true; 	}		 public static String trim(String str, boolean nullFlag){ 	  String tempStr = null;      if (str != null)     {       tempStr = str.trim();     }      if (nullFlag)     {       if ("".equals(tempStr) || "null".equals(tempStr))       {         tempStr = null;       }     }     else     {       if (tempStr == null)       {         tempStr = "";       }     }      return tempStr;  }	 public static String replace(String strSource, String strFrom, String strTo) {			if(strSource==null){				return null;			}			int i = 0;			if ((i = strSource.indexOf(strFrom, i)) >= 0) {				char[] cSrc = strSource.toCharArray();				char[] cTo = strTo.toCharArray();				int len = strFrom.length();				StringBuffer buf = new StringBuffer(cSrc.length);				buf.append(cSrc, 0, i).append(cTo);				i += len;				int j = i;				while ((i = strSource.indexOf(strFrom, i)) > 0) {					buf.append(cSrc, j, i - j).append(cTo);					i += len;					j = i;				}				buf.append(cSrc, j, cSrc.length - j);				return buf.toString();			}			return strSource;		} 		 public static String deal(String str) {			str = replace(str, "//", "////");			str = replace(str, "'", "//'");			str = replace(str, "/r", "//r");			str = replace(str, "/n", "//n");			str = replace(str, "/"", "///"");			return str;		}	 	 public static String GetMapToXML(Map<String,String> param){      StringBuffer sb = new StringBuffer();      sb.append("<xml>");      for (Map.Entry<String,String> entry : param.entrySet()) {          sb.append("<"+ entry.getKey() +">");         sb.append(entry.getValue());         sb.append("</"+ entry.getKey() +">");     }       sb.append("</xml>");      return sb.toString();    } 	 	public static void main(String[] args){		//String a = StringUtil.supplementZeroGenerateThirteen(1000);		double a = 32.;		System.out.println(StringUtil.isNumeric("32."));		System.out.println(a);	} }

4.用到的jar包

<!--微信 -->    <dependency>      <groupId>com.github.liyiorg</groupId>      <artifactId>weixin-popular</artifactId>      <version>2.8.5</version>    </dependency><!--httpclient-->    <dependency>      <groupId>commons-httpclient</groupId>      <artifactId>commons-httpclient</artifactId>      <version>3.1</version>    </dependency>    <dependency>      <groupId>org.jdom</groupId>      <artifactId>jdom2</artifactId>      <version>2.0.6</version>    </dependency>

以上所述是小编给大家介绍的APP微信支付(java后台_统一下单和回调)详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表