微信手机app支付java

java的uniapp版本的微信支付

准备工作
1.先准备企业账号,然后创建应用,如图所示
在这里插入图片描述

创建应用获取app支付
在这里插入图片描述
3.查看appid,AppSecret
在这里插入图片描述

2.根据官方文档生成公钥私钥
支付宝官方地址

先贴代码
pom文件加上

        <dependency>
            <groupId>com.github.wxpay</groupId>
            <artifactId>wxpay-sdk</artifactId>
            <version>0.0.3</version>
        </dependency>
        <!--微信 -->
        <dependency>
            <groupId>com.github.liyiorg</groupId>
            <artifactId>weixin-popular</artifactId>
            <version>2.8.5</version>
        </dependency>

这是配置文件 文件名:global.properties

WXAppID=WXAppID
MCH_ID=MCH_ID
API_KEY=API_KEY

读取配置文件

package com.yss.utlis.vx;

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

}

工具类

package com.yss.utlis.vx;

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(Map<String, String> 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("D:\\object\\apiclient_cert.p12"));
        FileInputStream instream = new FileInputStream(new File("/usr/local/project/apiclient_cert.p12"));
        try {
            keyStore.load(instream, "1603898603".toCharArray());
        } finally {
            instream.close();
        }

        // Trust own CA and all self-signed certs
        SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, "1603898603".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.yss.utlis.vx;

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" };

}


package com.yss.utlis.vx;


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);
    }

}


package com.yss.utlis.vx;

import javax.servlet.http.HttpServletRequest;

/**
 * 获取服务器IP工具类
 */
public class IpAddr {

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

}

package com.yss.utlis.vx;

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);
    }

}


这是controller接口我的是套餐支付所以传的套餐id,大家根据自己的情况传参

 package com.yss.pay.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 com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.yss.base.auth.utils.ApiResult;
import com.yss.pay.model.entity.WeiXinPrePay;
import com.yss.pay.service.WeiXinPrePayService;
import com.yss.utlis.vx.ConfigManager;
import com.yss.utlis.vx.DateUtil;
import com.yss.utlis.vx.PayCommonUtil;
import com.yss.utlis.vx.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/vx")
@Api(description = "微信支付controller")
public class VxPayController {

    @Autowired
    private WeiXinPrePayService weiXinPrePayService;

    /**
     * @param request
     * @return
     */
    @PostMapping(value = "/wxpay", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("根据套餐ID来调取微信支付")
    public ApiResult<WeiXinPrePay> wxpay(HttpServletRequest request,String cid) {
        return  new ApiResult<>(weiXinPrePayService.wxpay(request,cid));
    }
    /**
     * @param request
     * @return
     */
    @PostMapping(value = "/refund")
    @ApiOperation("根据微信订单id退款")
    public ApiResult<Boolean> refund(String cid) {
        return  new ApiResult<>(weiXinPrePayService.refund(cid));
    }





    /**
     * 此函数会被执行多次,如果支付状态已经修改为已支付,则下次再调的时候判断是否已经支付,如果已经支付了,则什么也执行
     *
     * @param request
     * @return
     * @throws IOException
     * @throws JDOMException
     */
    @PostMapping(value = "notifyWeiXinPay", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("支付回调地址")
    public String notifyWeiXinPay(HttpServletRequest request, String cid) throws IOException, JDOMException {
        return weiXinPrePayService.notifyWeiXinPay(request,cid);
    }



}

这是service代码

package com.yss.pay.service.impl;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.yss.base.auth.utils.SecurityUtils;
import com.yss.base.model.user.User;
import com.yss.base.msg.expection.BadRequestException;
import com.yss.base.service.user.UserService;
import com.yss.ope.service.UserOrderService;
import com.yss.pay.model.entity.PayVxOrder;
import com.yss.pay.model.entity.WeiXinPrePay;
import com.yss.pay.service.PayVxOrderService;
import com.yss.pay.service.WeiXinPrePayService;
import com.yss.sys.model.entity.Combo;
import com.yss.sys.service.ComboService;
import com.yss.utlis.vx.*;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

@Service
public class WeiXinPrePayServiceImpl implements WeiXinPrePayService {

    @Autowired
    private ComboService comboService;

    @Autowired
    private UserOrderService userOrderService;

    @Autowired
    private PayVxOrderService payVxOrderService;

    @Autowired
    private UserService userService;

    private String randomString = PayCommonUtil.getRandomString(32);
    //支付成功后的回调函数
    private static String wxnotify = "http://baidu.com:8888/vx/notifyWeiXinPay";


    /**
     * 购买
     *
     * @param request
     * @param cid
     * @return
     */
    @Override
    @Transactional
    public WeiXinPrePay wxpay(HttpServletRequest request, String cid) {
        //套餐
       //逻辑处理



        //==========================================================================================
        //获取价格
        BigDecimal totalAmount = new BigDecimal(combo.getPrice());
        String trade_no = "";
        String description = "";
        try {
            //根据表内id生成订单号
            trade_no = new String(payVxOrder.getId().getBytes("ISO-8859-1"), "UTF-8");
            description = "shop";
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Map<String, String> map = weixinPrePay(trade_no,totalAmount,description,request);
        Map<String, String> finalpackage = new TreeMap<String, String>();
        //应用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(map.get("sign"));
//        prePay.setPaySign((String)getSign(trade_no,totalAmount,description,map.get("api_key",request).get("sign"));

        try {
            //二次签名
            String s = WXPayUtil.generateSignature(finalpackage, ConfigManager.getInstance().getConfigItem("API_KEY"),
                    WXPayConstants.SignType.MD5);
            System.out.println(s);
            prePay.setPaySign(s);//指定签名方式为MD5!!!!!!!!!!!!!!
        } catch (Exception e) {
            e.printStackTrace();
        }

        return prePay;
    }

    @Override
    public String notifyWeiXinPay(HttpServletRequest request, String cid) 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);
        System.out.println(params+"================================================================================================================================================");
        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(params.get("out_trade_no"));
            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");

            //改变订单状态
            Boolean a = payVxOrderService.updateVxOrder(out_trade_no);

            return_data.put("return_code", "SUCCESS");
            return_data.put("return_msg", "OK");
            return StringUtil.GetMapToXML(return_data);
        }
    }

    @Override
    public Boolean refund(String cid) {

        //获取订单信息
        PayVxOrder payVxOrder = payVxOrderService.getOne(Wrappers.<PayVxOrder>lambdaQuery().eq(PayVxOrder::getId,cid).or().eq(PayVxOrder::getOutTradeNo,cid));

        Map<String, String> parameterMap = new TreeMap<String, String>();
        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("out_trade_no", payVxOrder.getId());
        parameterMap.put("out_refund_no", payVxOrder.getId());
        parameterMap.put("fee_type", "CNY");
        System.out.println("jiner");
        BigDecimal total = new BigDecimal(payVxOrder.getTotalFee()).multiply(new BigDecimal(payVxOrder.getTotalFee()));  //接口中参数支付金额单位为【分】,参数值不能带小数,所以乘以100
        DecimalFormat df = new DecimalFormat("0");
        parameterMap.put("total_fee", df.format(total));
        parameterMap.put("refund_fee", df.format(total));
        System.out.println("jiner2");
        String sign = null;
        try {
            sign = WXPayUtil.generateSignature(parameterMap, ConfigManager.getInstance().getConfigItem("API_KEY"),
                    WXPayConstants.SignType.MD5);
        } catch (Exception e) {
            e.printStackTrace();
        }
        parameterMap.put("sign", sign);//"JSAPI"
        String requestXML = PayCommonUtil.getRequestXml(parameterMap);
        String result = null;
        try {
            result = PayCommonUtil.httpsRequest2(
                    "https://api.mch.weixin.qq.com/pay/unifiedorder", "POST",
                    requestXML);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(result);
        Map<String, String> map = null;
        try {
            map = PayCommonUtil.doXMLParse(result);
            boolean equals = map.get("result_code").equals("SUCCESS");
            if (equals) {
                payVxOrderService.delete(payVxOrder);
            }
            return equals;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return false;

        /*BigDecimal totalAmount = new BigDecimal(payVxOrder.getTotalFee());
        Map<String, String> map = weixinPrePay(payVxOrder.getOutTradeNo(), totalAmount, "", null);
        try {
            boolean equals = map.get("result_code").equals("SUCCESS");
            if (equals) {
                payVxOrderService.delete(payVxOrder);
            }
            return equals;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }*/
//        return false;
    }


    private String getSign(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("sign_type", "MD5");
        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);
//        WXPayUtil.generateSignature(parameterMap,"" , WXPayConstants.SignType.HMACSHA256)
        return PayCommonUtil.createSign("UTF-8", parameterMap);
    }


    /**
     * 统一下单
     * 应用场景:商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付。
     *
     * @param trade_no
     * @param totalAmount
     * @param description
     * @param request
     * @return
     */
    @SuppressWarnings("unchecked")
    public Map<String, String> weixinPrePay(String trade_no, BigDecimal totalAmount,
                                            String description, HttpServletRequest request) {
        //调微信生成签名的参数
        Map<String, String> parameterMap = new TreeMap<String, String>();
        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("sign_type", "MD5");
        parameterMap.put("fee_type", "CNY");
        System.out.println("jiner");
        BigDecimal total = totalAmount.multiply(new BigDecimal(100));  //接口中参数支付金额单位为【分】,参数值不能带小数,所以乘以100
        DecimalFormat df = new DecimalFormat("0");
        parameterMap.put("total_fee", df.format(total));
        System.out.println("jiner2");
        if (request!=null){
            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("");
        System.out.println("jiner2");
        String sign = null;
        try {
            sign = WXPayUtil.generateSignature(parameterMap,ConfigManager.getInstance().getConfigItem("API_KEY"),
                    WXPayConstants.SignType.MD5);
        } catch (Exception e) {
            e.printStackTrace();
        }
        parameterMap.put("sign", sign);
        String requestXML = PayCommonUtil.getRequestXml(parameterMap);
        System.out.println(requestXML + "=============================2222222");
        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;
    }



}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值