精华内容
下载资源
问答
  • 方法wxpay用于生成预支付订单信息方法notifyWeiXinPay用于微信支付成功后的回调, 注意: 在手机端使用微信支付成功后,微信服务器会根据提供的回调地址进行回调,parameterMap.put("notify_url", wxnotify);...

    微信支付Java后台

    1.微信配置信息 global.properties

    bd7712f0781d8790211a27c288f38560.png

    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 map = weixinPrePay(trade_no,totalAmount,description,openId,request);

    SortedMap finalpackage = new TreeMap();

    //应用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 weixinPrePay(String trade_no,BigDecimal totalAmount,

    String description, String openid, HttpServletRequest request) {

    SortedMap parameterMap = new TreeMap();

    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 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 params = PayCommonUtil.doXMLParse(resultxml);

    outSteam.close();

    inStream.close();

    Map return_data = new HashMap();

    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 configMap;

    private static ConfigManager m_instance = null;

    private static Properties props = null;

    private ConfigManager() {

    m_props = new Properties();

    configMap = new HashMap();

    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 getSysConfigMsg(){

    Set keyset = m_props.keySet();

    Iterator 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 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 parameters){

    StringBuffer sb = new StringBuffer();

    sb.append("");

    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+">");

    }else {

    sb.append(""+value+""+key+">");

    }

    }

    sb.append("");

    return sb.toString();

    }

    //生成签名

    public static String createSign(String characterEncoding,SortedMap 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 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 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("");

    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 param){

    StringBuffer sb = new StringBuffer();

    sb.append("");

    for (Map.Entry entry : param.entrySet()) {

    sb.append("");

    sb.append(entry.getValue());

    sb.append(""+ entry.getKey() +">");

    }

    sb.append("");

    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包

    com.github.liyiorg

    weixin-popular

    2.8.5

    commons-httpclient

    commons-httpclient

    3.1

    org.jdom

    jdom2

    2.0.6

    以上是所有代码。不明白的留言!

    展开全文
  • 主要介绍了APP微信支付java后台_统一下单回调),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 方法wxpay用于生成预支付订单信息方法notifyWeiXinPay用于微信支付成功后的回调, 注意: 在手机端使用微信支付成功后,微信服务器会根据提供的回调地址进行回调,parameterMap.put("notify_url", wxnotify);...

    1.微信配置信息 global.properties

    73de20fff4a9f70c1925acf10d63764f.png

    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 map = weixinPrePay(trade_no,totalAmount,description,openId,request);

    SortedMap finalpackage = new TreeMap();

    //应用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 weixinPrePay(String trade_no,BigDecimal totalAmount,

    String description, String openid, HttpServletRequest request) {

    SortedMap parameterMap = new TreeMap();

    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 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 params = PayCommonUtil.doXMLParse(resultxml);

    outSteam.close();

    inStream.close();

    Map return_data = new HashMap();

    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 configMap;

    private static ConfigManager m_instance = null;

    private static Properties props = null;

    private ConfigManager() {

    m_props = new Properties();

    configMap = new HashMap();

    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 getSysConfigMsg(){

    Set keyset = m_props.keySet();

    Iterator 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 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 parameters){

    StringBuffer sb = new StringBuffer();

    sb.append("");

    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+">");

    }else {

    sb.append(""+value+""+key+">");

    }

    }

    sb.append("");

    return sb.toString();

    }

    //生成签名

    public static String createSign(String characterEncoding,SortedMap 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 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 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("");

    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 param){

    StringBuffer sb = new StringBuffer();

    sb.append("");

    for (Map.Entry entry : param.entrySet()) {

    sb.append("");

    sb.append(entry.getValue());

    sb.append(""+ entry.getKey() +">");

    }

    sb.append("");

    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包

    com.github.liyiorg

    weixin-popular

    2.8.5

    commons-httpclient

    commons-httpclient

    3.1

    org.jdom

    jdom2

    2.0.6

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

    展开全文
  • APP微信支付java后台_统一下单回调

    万次阅读 多人点赞 2018-03-24 22:23:04
    方法wxpay用于生成预支付订单信息 方法notifyWeiXinPay用于微信支付成功后的回调, 注意: 在手机端使用微信支付成功后,微信服务器会根据提供的回调地址进行回调, parameterMap.put("notify_url", ...

    微信支付Java后台

    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>
    以上是所有代码。不明白的留言!




    展开全文
  • 首先,本文参考文档: a.... Java 后端微信支付demo 引入jar包 <dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> ...

    首先,参考文档:

    【微信支付】H5支付开发文档
    Java 后端微信支付demo

    1. 引入jar包
    		<dependency>
                <groupId>com.github.wxpay</groupId>
                <artifactId>wxpay-sdk</artifactId>
                <version>0.0.3</version>
            </dependency>
    
    1. 配置申请好的AppId,MchId, Key

    这里只需要统一下单、支付回调以及查询订单,所以不需要加载证书

    import com.github.wxpay.sdk.WXPayConfig;
    
    import java.io.InputStream;
    
    /** 配置我们自己的信息  */
    
    public class WxPayConfig implements WXPayConfig {
    
    //    /** 加载证书  这里证书需要到微信商户平台进行下载*/
    //    private byte [] certData;
    //
    //    public WxPayConfig() throws  Exception{
    //        InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("../cert/pay/apiclient_cert.p12");
    //        this.certData = IOUtils.toByteArray(certStream);
    //        certStream.close();
    //    }
    
        /** 设置我们自己的appid
         * 商户号
         * 秘钥
         * */
    
        @Override
        public String getAppID() {
            return "###AppId";
        }
    
        @Override
        public String getMchID() {
            return "###MchId";	
        }
    
        @Override
        public String getKey() {
            return "###Key";
        }
    
        @Override
        public InputStream getCertStream() {
            return null;
        }
    
        @Override
        public int getHttpConnectTimeoutMs() {
            return 0;
        }
    
        @Override
        public int getHttpReadTimeoutMs() {
            return 0;
        }
    }
    
    1. 统一下单接口示例:
     	// 微信支付下单
        @PreAuthorize("@el.check('anonymous')") // 匿名访问
        @PostMapping("/prePay")
        public ResponseEntity placeOrder(HttpServletRequest request, @RequestBody Map params) throws Exception {
    
            // 保存订单并返回订单号 shopOrderDTO.getId()
    
            // 处理请求参数
            WxPayConfig wxPayConfig = new WxPayConfig();
            WXPay wxPay = new WXPay(wxPayConfig);
            String url = "###公网地址";
            String notifyUrl = url + "/payReturn";	// 微信支付回调地址,详情参考微信官方文档要求
    
            Map<String,String> data = new HashMap<>();
            data.put("out_trade_no", shopOrderDTO.getId()+"");   //订单编号
            data.put("total_fee",params.get("total_free").toString());   //金额(单位为分) int
            data.put("attach", new JSONObject().toJSONString(attach));  //附加数据:{nums:1, device_id:"0x234143", store_id:10000000}
    
            data.put("appid",wxPayConfig.getAppID());
            data.put("mch_id",wxPayConfig.getMchID());
            data.put("trade_type","MWEB");	// h5支付固定写法
            data.put("device_info","WEB"); // h5支付固定写法
            data.put("notify_url",notifyUrl);
            data.put("spbill_create_ip", IPUtil.getIPAddress(request));
            data.put("fee_type","CNY");
            data.put("body","###支付信息描述");
            data.put("nonce_str", WXPayUtil.generateNonceStr()); 
            data.put("scene_info", "###参考官方文档");
            // 生成签名
            String s = WXPayUtil.generateSignature(data, wxPayConfig.getKey());
            data.put("sign",s);
    
            // 发起下单请求
            Map<String, String> respData = wxPay.unifiedOrder(data);
    
            // 处理下单结果
            if (respData.get("return_code").equals("SUCCESS")){
                if (respData.get("result_code").equals("SUCCESS")) {
                    respData.put("out_trade_no", shopOrderDTO.getId()+"");
                    return new ResponseEntity<>(respData, HttpStatus.OK);
                } else {
                    // 下单失败的处理 如保存日志
                    throw new Exception(respData.get("err_code_des"));
                }
            } else {
            	// 下单失败的处理 如保存日志
                throw new Exception(respData.get("return_msg"));
            }
    
        }
    
    1. 支付回调接口
        // 微信支付回调
        @PreAuthorize("@el.check('anonymous')")
        @RequestMapping("/payReturn")
        public String payReturn(HttpServletRequest request, HttpServletResponse response) throws Exception {
            // logger.info("微信支付回调:");
    
            WxPayConfig wxPayConfig = new WxPayConfig();
            WXPay wxPay = new WXPay(wxPayConfig);
    
            // 接收请求参数
            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 xml = new String(outSteam.toByteArray(), "utf-8");
            // 转为Map
            Map<String, String> params = WXPayUtil.xmlToMap(xml);
            outSteam.close();
            inStream.close();
    
            // 验证签名
            if (wxPay.isResponseSignatureValid(params)) { 
    
                if (params.get("return_code").equals("FAIL")) {
    
                    shopLogService.anonymousCreate(shopLogService.getShopLog(null, null, "支付发起失败",params.get("return_msg") + "" ));
    
                } else if (params.get("return_code").equals("SUCCESS")){
    
                    if (params.get("result_code").equals("FAIL")) {
    
                        // 支付失败
    
                    } else if (params.get("result_code").equals("SUCCESS")) {
    
                        // 查询订单,将支付返回结果与订单保存信息对比
                        ShopOrderDTO orderDTO = shopOrderService.findById(Long.valueOf(params.get("out_trade_no")));	
    
    					// 判断金额、订单支付状态、支付结果
                        if (orderDTO.getAmount() == Integer.valueOf(params.get("total_fee")) && orderDTO.getState() == 1
                                && !StringUtils.isBlank(params.get("transaction_id"))) {
    
                            // 修改订单状态为已支付 省略
                            
                            return "<xml>\n" +
                                    "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                                    "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                                    "</xml>";
    
                        } else if (StringUtils.isBlank(params.get("transaction_id"))){
                            // 支付ID为空
                        } else if (orderDTO.getState() == 0){
                            // 订单状态为已支付
                        } else if (orderDTO.getAmount() != Integer.valueOf(params.get("total_fee"))){
                            // 支付金额与订单金额不相等
                        }
                    }
                }
            }
            return "";
        }
    
    
    1. 查询订单接口
        // 微信支付查询 参数是订单id
        @PreAuthorize("@el.check('anonymous')")
        @RequestMapping("/paySearch")
        public Map paySearch(String id) throws Exception {
    		
    		// 查询订单
            ShopOrderDTO orderDTO = shopOrderService.findById(Long.valueOf(id));
    
    		// 如果订单已支付且支付id不为空,可以直接返回结果
            if (orderDTO.getState() == 0 && !StringUtils.isBlank(orderDTO.getPayId())) {
                Map<String, String> result = new HashMap<>();
                result.put("return_code", "SUCCESS");
                result.put("result_code", "SUCCESS");
                result.put("trade_state", "SUCCESS");
                return result;
            } else {
            	// 处理参数
                WxPayConfig wxPayConfig = new WxPayConfig();
                WXPay wxPay = new WXPay(wxPayConfig);
                Map<String,String> data = new HashMap<>();
                data.put("out_trade_no", id);   //订单编号
                data.put("appid",wxPayConfig.getAppID());
                data.put("mch_id",wxPayConfig.getMchID());
                data.put("nonce_str", WXPayUtil.generateNonceStr()); 
                // 签名
                String s = WXPayUtil.generateSignature(data, wxPayConfig.getKey());
                data.put("sign",s);
                // 发起查询
                Map<String, String> result = wxPay.orderQuery(data);
    			
    			// 如果用户已支付
                if (result.get("return_code").equals("SUCCESS") && result.get("result_code").equals("SUCCESS") && result.get("trade_state").equals("SUCCESS")) {
                    // 修改订单支付状态和支付id
                }
                return result;
            }
        }
    
    展开全文
  • 踩坑: 微信小程序支付流程(统一下单, 支付回调)

    万次阅读 多人点赞 2018-07-30 16:15:55
    众所周知,微信小程序目前只能使用微信支付,而且微信小程序支付相对于app支付,h5支付都要简单一些,但是该支付文档对java这语言是非常不友好的,居然没有demo,网上虽说有很多博客,但是找了好多都是跑不通,乱七八糟的很...
  • 最近做微信支付,踩了一点坑。就留下代码防止各位入坑。哈不多说,上代码 service package com.sjc.wx.service; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java....
  • APP绑定微信商户平台获取商户id(mchID)、证书(商户后台下载)、支付签名密钥(商户后台设置api密钥)、退款签名密钥(商户后台设置api密钥ipv3)等 1.导入微信支付SDK <!--微信支付SDK--> <...
  • /** * @ 接收支付成功后,微信返回 * @Title: wxNotify * @Description: TODO * @return void * @date 2019年9月9日 下午4:41:15 * @author Minglij * @throws Exception */ ...
  • 这篇文章主要讨论APP掉起支付,包括统一下单,微信接口回调,以及一些注意事项 微信官方文档: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1 这里有详细的入参列表,调用地址,但是我表示,...
  • 2)java后台调用统一下单支付接口(这里会进行第一次签名),用来获取prepay_id; 3)java后台再次调用签名(这里会进行第二次签名),并返回支付需要用使用的参数; 4)小程序前端wx.requestPayment方法发起微信...
  • 调起微信支付统一下单接口的一个方法封装。需要的同学们可以参考下。 调第三方接口用到了 restTemplate , 需要先进行注入。... * @param orderCode 商品订单号(可用于支付成功回调方法的查询) ...
  • java调用微信小程序统一下单接口今天...再调用微信支付统一下单API,微信返回给我们一个prepay_id,我们封装起来一起返给前端即可,前端支付成功了,微信会发送通知给我们的回调地址,我们更新订单状态即可,大致流程...
  • 苹果支付是直接由ios客户端调起苹果支付并支付完成后,java后台提供一个支付回调接口供ios客户端进行同步回调,只需要在该接口进行进行验证苹果支付是否支付成功,跟微信支付和支付宝支付不一样,不需要统一下单接口...
  • Java微信支付-支付成功异步回调验签

    千次阅读 2019-10-12 12:08:00
    接上一篇Java微信支付-统一下单API,本篇在上篇文章的基础上讲述统一下单支付成功之后微信异步回调通知 在调用微信支付-统一下单API时,会传递notify_url这个参数给微信,这个参数是用户成功支付之后微信端会向此...
  • Java微信支付-退款成功异步回调验签

    千次阅读 2019-10-14 10:25:35
    接上一篇Java微信支付-申请退款API,本篇在上篇文章的基础上讲述调用申请退款API后退款成功之后微信异步回调通知 下文中所需配置、类都在以请查看以上链接内容。 在调用微信支付-统一下单API时,会传递notify_url...
  • 二、支付回调 1、回调方法 该链接是通过【统一下单API】中提交的参数notify_url设置,如果链接无法访问,商户将无法接收到微信通知。 参考文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&...
  • package com.pay;import java.util.Date;import java.util.Map;public class test { /** * 生成统一下单 * @throws Exception */public static void main1(String[] args) throws Exception { ...
  • 看着头疼所以我决心自己开始写Java微信支付之公众号支付,多的不说见下面源码,为了方便使用我分别用了两个Servlet,一个是统一下单UnifiedorderServlet,一个是支付回调PayCallBackServlet,你们可以自己封装。...
  • 此微信支付为微信支付JAVA 后台版本 比较简陋,包含java 后台的 统一下单回调 ,除了controller 文件外,其他的均为工具类 没有其他退款等功能
  • 官方API文档...index=1 微信小程序支付的第一步是需要获取用户的code值,根据code值换取openid和sessionkey ...1.统一下单接口 public Map createSmallPay(S
  • 微信公众号支付java版源代码 微信支付整体流程:微信授权登录商户的公众号——微信支付的公众号配置——统一下单——微信js调起支付页面——输入密码支付——支付成功,异步回调URL处理商户的相应业务
  • APP微信支付java后台_统一下单回调) 微信支付 - 异步通知并且查询支付结果 浅析微信支付支付结果通知 微信APP支付-JAVA java app微信支付 微信支付接口--支付成功的回调--超详细Demo 微信...
  • java微信小程序支付

    2020-04-27 15:04:09
    支付回调 流程很简单首先先看下官方统一下单文档: 官方文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1 官方统一下单接口,只需要我们后端调用这个接口就能完成统一下单,接下来是参数: ...
  • 首先说一下微信支付我所理解的流程吧,首先会想后端发起统一下单的请求,后台进行统一下单,加密之类的,然后将数据返回给前端,然后前端拿着数据发起支付支付成功开始回调。 这里发一下微信统一下单的api 可以...

空空如也

空空如也

1 2 3 4
收藏数 75
精华内容 30
关键字:

统一下单支付回调java

java 订阅