java公众号订单查询

1、基本配置

package com.jbossjf.bootproject.common.weixin;

public class Configure {


	
	private static String appID = "2222b78a36297d4444";
	private static String secret = "3333ce6787950b8e98d6371b7777777";
	//商户号
	private static String mch_id = "7771978999";//"你的商户号";
	private static String key = "66662ac5b14cc3ad76ef9d77777777";//"你的商户的api秘钥";
	//


	public static String getSecret() {
		return secret;
	}

	public static void setSecret(String secret) {
		Configure.secret = secret;
	}

	public static String getKey() {
		return key;
	}

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

	public static String getAppID() {
		return appID;
	}

	public static void setAppID(String appID) {
		Configure.appID = appID;
	}

	public static String getMch_id() {
		return mch_id;
	}

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

}

2、帮助类

package com.jbossjf.bootproject.common.weixin;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

public class HttpRequest {
	//连接超时时间,默认10秒
    private static final int socketTimeout = 10000;

    //传输超时时间,默认30秒
    private static final int connectTimeout = 30000;
	/**
	 * post请求
	 * @throws IOException 
	 * @throws ClientProtocolException 
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyStoreException 
	 * @throws KeyManagementException 
	 * @throws UnrecoverableKeyException 
	 */
	public static String sendPost(String url, Object xmlObj) throws ClientProtocolException, IOException, UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException {
		

        
		HttpPost httpPost = new HttpPost(url);
		//解决XStream对出现双下划线的bug
        XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
        xStreamForRequestPostData.alias("xml", xmlObj.getClass());
        //将要提交给API的数据对象转换成XML格式数据Post给API
        String postDataXML = xStreamForRequestPostData.toXML(xmlObj);

        //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
        StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.setEntity(postEntity);

        //设置请求器的配置
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
        httpPost.setConfig(requestConfig);
        
        HttpClient httpClient = HttpClients.createDefault();
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "UTF-8");
        return result;
	}
	/**
	 * 自定义证书管理器,信任所有证书
	 * @author pc
	 *
	 */
	public static class MyX509TrustManager implements X509TrustManager {
		@Override
		public void checkClientTrusted(
				java.security.cert.X509Certificate[] arg0, String arg1)
				throws CertificateException {
			// TODO Auto-generated method stub
			
		}
		@Override
		public void checkServerTrusted(
				java.security.cert.X509Certificate[] arg0, String arg1)
				throws CertificateException {
			// TODO Auto-generated method stub
			
		}
		@Override
		public java.security.cert.X509Certificate[] getAcceptedIssuers() {
			// TODO Auto-generated method stub
			return null;
		}
      }
}
package com.jbossjf.bootproject.common.weixin;

import java.security.MessageDigest;

/**
 * User: rizenguo
 * Date: 2014/10/23
 * Time: 15:43
 */
public class MD5 {
    private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
            "8", "9", "a", "b", "c", "d", "e", "f"};

    /**
     * 转换字节数组为16进制字串
     * @param b 字节数组
     * @return 16进制字串
     */
    public static String byteArrayToHexString(byte[] b) {
        StringBuilder resultSb = new StringBuilder();
        for (byte aB : b) {
            resultSb.append(byteToHexString(aB));
        }
        return resultSb.toString();
    }

    /**
     * 转换byte到16进制
     * @param b 要转换的byte
     * @return 16进制格式
     */
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n = 256 + n;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    /**
     * MD5编码
     * @param origin 原始字符串
     * @return 经过MD5加密之后的结果
     */
    public static String MD5Encode(String origin) {
        String resultString = null;
        try {
            resultString = origin;
            MessageDigest md = MessageDigest.getInstance("MD5");
            resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultString;
    }

}

package com.jbossjf.bootproject.common.weixin;

public class QueryOrderRequest {
    public String getAppid() {
        return appid;
    }

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

    public String getMch_id() {
        return mch_id;
    }

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

    public String getOut_trade_no() {
        return out_trade_no;
    }

    public void setOut_trade_no(String out_trade_no) {
        this.out_trade_no = out_trade_no;
    }

    public String getNonce_str() {
        return nonce_str;
    }

    public void setNonce_str(String nonce_str) {
        this.nonce_str = nonce_str;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    // 公众账号id
    private String appid;

    // 商户号
    private String mch_id;

    // 商户订单号,32位以内,不重复
    private String out_trade_no;

    // 随机字符串,32位以内
    private String nonce_str;

    // 签名,遵循签名算法
    private String sign;
}

 

package com.jbossjf.bootproject.common.weixin;

public class QueryOrderRequestExt extends QueryOrderRequest {
    // 签名类型,默认MD5
    private String sign_type;
}


package com.jbossjf.bootproject.common.weixin;

public class QueryOrderResponse {
    public String getReturn_code() {
        return return_code;
    }

    public void setReturn_code(String return_code) {
        this.return_code = return_code;
    }

    public String getAppid() {
        return appid;
    }

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

    public String getMch_id() {
        return mch_id;
    }

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

    public String getNonce_str() {
        return nonce_str;
    }

    public void setNonce_str(String nonce_str) {
        this.nonce_str = nonce_str;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public String getResult_code() {
        return result_code;
    }

    public void setResult_code(String result_code) {
        this.result_code = result_code;
    }

    public String getOpenid() {
        return openid;
    }

    public void setOpenid(String openid) {
        this.openid = openid;
    }

    public String getTrade_type() {
        return trade_type;
    }

    public void setTrade_type(String trade_type) {
        this.trade_type = trade_type;
    }

    public String getTrade_state() {
        return trade_state;
    }

    public void setTrade_state(String trade_state) {
        this.trade_state = trade_state;
    }

    public String getBank_type() {
        return bank_type;
    }

    public void setBank_type(String bank_type) {
        this.bank_type = bank_type;
    }

    public int getTotal_fee() {
        return total_fee;
    }

    public void setTotal_fee(int total_fee) {
        this.total_fee = total_fee;
    }

    public int getCash_fee() {
        return cash_fee;
    }

    public void setCash_fee(int cash_fee) {
        this.cash_fee = cash_fee;
    }

    public String getTransaction_id() {
        return transaction_id;
    }

    public void setTransaction_id(String transaction_id) {
        this.transaction_id = transaction_id;
    }

    public String getOut_trade_no() {
        return out_trade_no;
    }

    public void setOut_trade_no(String out_trade_no) {
        this.out_trade_no = out_trade_no;
    }

    public String getTime_end() {
        return time_end;
    }

    public void setTime_end(String time_end) {
        this.time_end = time_end;
    }

    public String getTrade_state_desc() {
        return trade_state_desc;
    }

    public void setTrade_state_desc(String trade_state_desc) {
        this.trade_state_desc = trade_state_desc;
    }

    // 返回状态码,通信标识,SUCCESS/FAIL
    private String return_code;

    // 公众账号id
    private String appid;

    // 商户号
    private String mch_id;

    // 随机字符串
    private String nonce_str;

    // 签名
    private String sign;

    // 业务结果,交易标识,SUCCESS/FAIL
    private String result_code;

    // 用户标识
    private String openid;

    // 交易类型,JSAPI,NATIVE,APP
    private String trade_type;

    //        SUCCESS--支付成功
//            REFUND--转入退款
//            NOTPAY--未支付
//            CLOSED--已关闭
//            REVOKED--已撤销(刷卡支付)
//            USERPAYING--用户支付中
//            PAYERROR--支付失败(其他原因,如银行返回失败)
//            ACCEPT--已接收,等待扣款
    private String trade_state;

    // 付款银行
    private String bank_type;

    // 标价金额,单位分
    private int total_fee;

    // 现金支付金额
    private int cash_fee;

    // 微信支付订单号
    private String transaction_id;

    // 商户订单号
    private String out_trade_no;

    // 支付完成时间
    private String time_end;

    // 交易状态描述
    private String trade_state_desc;
}


package com.jbossjf.bootproject.common.weixin;

public class QueryOrderResponseExt extends QueryOrderResponse {
    // 返回信息,非空则表示返回了错误信息
    private String return_msg;

    // 错误代码
    private String err_code;

    // 错误代码描述
    private String err_code_des;

    // 设备号
    private String device_info;

    // 是否关注公众号
    private String is_subscribe;

    // 应结订单金额
    private String settlement_total_fee;

    // 标价币种
    private String fee_type;

    // 现金支付币种
    private String cash_fee_type;

    // 附加数据
    private String attach;
}

 

package com.jbossjf.bootproject.common.weixin;

import java.util.Random;

/**
 * 随机字符串生成
 * @author zuoliangzhu
 *
 */
public class RandomStringGenerator {
	/**
     * 获取一定长度的随机字符串
     * @param length 指定字符串长度
     * @return 一定长度的字符串
     */
    public static String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
}

 

package com.jbossjf.bootproject.common.weixin;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;


/**
 * 签名
 * @author zuoliangzhu
 *
 */
public class Signature {
	private static final Logger L = LoggerFactory.getLogger(Signature.class);
	/**
     * 签名算法
     * @param o 要参与签名的数据对象
     * @return 签名
     * @throws IllegalAccessException
     */
    public static String getSign(Object o) throws IllegalAccessException {
        ArrayList<String> list = new ArrayList<String>();
        Class cls = o.getClass();
        Field[] fields = cls.getDeclaredFields();
        for (Field f : fields) {
            f.setAccessible(true);
            if (f.get(o) != null && f.get(o) != "") {
            	String name = f.getName();
            	XStreamAlias anno = f.getAnnotation(XStreamAlias.class);
            	if(anno != null)
            		name = anno.value();
                list.add(name + "=" + f.get(o) + "&");
            }
        }
        int size = list.size();
        String [] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < size; i ++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + Configure.getKey();
        System.out.println("签名数据:"+result);
        result = MD5.MD5Encode(result).toUpperCase();
        return result;
    }

    public static String getSign(Map<String,Object> map){
        ArrayList<String> list = new ArrayList<String>();
        for(Map.Entry<String,Object> entry:map.entrySet()){
            if(entry.getValue()!=""){
                list.add(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        int size = list.size();
        String [] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < size; i ++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + Configure.getKey();
        //Util.log("Sign Before MD5:" + result);
        result = MD5.MD5Encode(result).toUpperCase();
        //Util.log("Sign Result:" + result);
        return result;
    }

    

}
package com.jbossjf.bootproject.common.weixin;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

public class StreamUtil {
	public static String read(InputStream is){
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			int len = 0;
			byte[] buffer = new byte[512];
			while((len = is.read(buffer)) != -1){
				baos.write(buffer, 0, len);
			}
			return new String(baos.toByteArray(), 0, baos.size(), "utf-8");
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}
}

 

package com.jbossjf.bootproject.common.weixin;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class WechatConnection {

    // 成功标志
    public static final String SUCCESS_CODE = "SUCCESS";

    /**
     * 建立微信连接,并返回结果
     *
     * @param url
     * @param info
     * @param object
     * @return
     * @throws IOException
     */
    public static Object connect(String url, String info, Class<?> object) throws IOException {
        // 建立连接
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        conn.setConnectTimeout(8000);
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);

        // 发送数据
        BufferedOutputStream bos = new BufferedOutputStream(conn.getOutputStream());
        bos.write(info.getBytes());
        bos.flush();
        bos.close();

        // 获取数据
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

        // 接收数据
        String line;
        StringBuffer str = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            str.append(line);
        }

        return WechatUtil.truncateDataFromXML(object, str.toString());
    }

}
package com.jbossjf.bootproject.common.weixin;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;
import com.thoughtworks.xstream.io.xml.XppDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cglib.beans.BeanMap;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

public class WechatUtil {

    private static Logger logger = LoggerFactory.getLogger(WechatUtil.class);

    /**
     * 数据转换为xml格式
     *
     * @param object
     * @param obj
     * @return
     */
    public static String truncateDataToXML(Class<?> object, Object obj) {
        XStream xStream = new XStream(new XppDriver(new XmlFriendlyReplacer("_-", "_")));
        xStream.alias("xml", object);

        return xStream.toXML(obj);
    }

    /**
     * 数据转换为对象
     *
     * @param object
     * @param str
     * @return
     */
    public static Object truncateDataFromXML(Class<?> object, String str) {
        XStream xStream = new XStream(new XppDriver(new XmlFriendlyReplacer("_-", "_")));
        xStream.alias("xml", object);

        return xStream.fromXML(str);
    }

    /**
     * 生成随机字符串
     *
     * @return
     */
    public static String makeNonceStr() {
        SimpleDateFormat sdf1=new SimpleDateFormat("yyyyMMddHHmmssS");
        StringBuffer str = new StringBuffer(sdf1.format(new Date()));
        str.append((new Random().nextInt(900) + 100));

        return str.toString();
    }

    /**
     * 拼接签名数据
     *
     * @return
     */
    public static String makeSign(BeanMap beanMap) {
        SortedMap<String, String> signMaps =new TreeMap();;

        for (Object key : beanMap.keySet()) {
            Object value = beanMap.get(key);

            // 排除空数据
            if (value == null) {
                continue;
            }

            signMaps.put(key + "", String.valueOf(value));
        }

        // 生成签名
        return generateSign(signMaps);

    }


    /**
     * 生成签名
     *
     * @param signMaps
     * @return
     * @throws Exception
     */
    public static String generateSign(SortedMap<String, String> signMaps) {
        StringBuffer sb = new StringBuffer();

        // 字典序
        for (Map.Entry signMap : signMaps.entrySet()) {
            String key = (String) signMap.getKey();
            String value = (String) signMap.getValue();

            // 为空不参与签名、参数名区分大小写
            if (null != value && !"".equals(value) && !"sign".equals(key) && !"key".equals(key)) {
                sb.append(key).append("=").append(value).append("&");
            }
        }

        // 拼接key
        sb.append("key=").append(Configure.getKey());

        // MD5加密
        return Objects.requireNonNull(encoderByMd5(sb.toString())).toUpperCase();
    }

    /**
     * 利用MD5进行加密
     *
     * @param str 待加密的字符串
     * @return 加密后的字符串
     */
    private static String encoderByMd5(String str) {
        // 生成一个MD5加密计算摘要
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            logger.error("MD5加密失败!", e);
        }

        if (md == null) {
            return null;
        }

        // 计算md5函数
        md.update(str.getBytes());
        // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
        // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
        return new BigInteger(1, md.digest()).toString(16);
    }

}

3、调用

package com.jbossjf.bootproject.controller;

import com.alibaba.fastjson.JSONObject;
import com.jbossjf.bootproject.common.weixin.*;
import com.jbossjf.bootproject.model.TrandeForm;
import com.jbossjf.bootproject.service.TrandeFormService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class WeixinSearchController
{

    @Autowired
    private TrandeFormService trandeFormService;
    Logger logger = LoggerFactory.getLogger(getClass());

    TrandeForm trandeForm = null;
    private String generateOrderInfo(String orderId) {
         trandeForm = trandeFormService.GetByTrandeNo(orderId);

        QueryOrderRequestExt ext = new QueryOrderRequestExt();
        ext.setAppid(Configure.getAppID());
        ext.setMch_id(Configure.getMch_id());
        ext.setOut_trade_no(trandeForm.getTradeNo());
        ext.setNonce_str(WechatUtil.makeNonceStr());

        ext.setSign(WechatUtil.makeSign(BeanMap.create(ext)));

        return WechatUtil.truncateDataToXML(QueryOrderRequestExt.class, ext);
    }
    @CrossOrigin
    @ResponseBody
    @RequestMapping(value = "/API/SearchTrandeFormByOpenID", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public Map<String, Object> SearchTrandeFormByOpenID(@RequestBody JSONObject jsonParam) {
        Map<String, Object> map = new HashMap<>();
        try{
            String openid = jsonParam.getString("openid");
            List<TrandeForm> trandeForms = trandeFormService.findByOpenid(openid);
            for(int i=0;i<trandeForms.size();i++)
            {
                getPayResult(trandeForms.get(i).getTradeNo());
            }
        }catch (Exception ex)
        {

        }
        return  null;
    }

    public Boolean getPayResult(String orderId) {
        try {
            String orderInfo = generateOrderInfo(orderId);

            QueryOrderResponseExt ext = null;
            try {
                ext = (QueryOrderResponseExt) WechatConnection.connect("https://api.mch.weixin.qq.com/pay/orderquery", orderInfo, QueryOrderResponseExt.class);
            } catch (Exception e) {
                logger.error("微信查询订单" + orderId + "失败!", e);
            }

            if (ext == null) {
                return false;
            }

            if (WechatConnection.SUCCESS_CODE.equals(ext.getResult_code())) {
                if (WechatConnection.SUCCESS_CODE.equals(ext.getResult_code()) && WechatConnection.SUCCESS_CODE.equals(ext.getTrade_state())) {
                    try {
                        // 更新订单状态
                        trandeForm.setTradeStatus("SUCCESS");
                        trandeFormService.UpdateBean(trandeForm);
                    } catch (Exception ex) {
                        return false;
                    }
                    return true;
                } else {
                    logger.error("订单" + orderId + "交易失败,交易状态:" + ext.getTrade_state());
                    return false;
                }
            } else {
                logger.error("订单" + orderId + "查询失败!");
                return false;
            }
        }catch (Exception ex)
        {
            return false;
        }
    }


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值