1.创建微信账单实体类
public class PtWxTradeDetailEntity {
private String id;
private String transDate;// 交易时间
private String commonId;// 公众账号ID
private String businessNo;// 商户号
private String childBusinessNo;// 子商户号
private String equipmentNo;// 设备号
private String wxOrderNo;// 微信订单号
private String businessOrderNo;// 商户订单号
private String userIdentity;// 用户标识
private String transType;// 交易类型
private String transStatus;// 交易状态
private String paymentBank;// 付款银行
private String currency;// 货币种类
private String totalAmount;// 总金额
private String redEnvelopesAmount;// 企业红包金额
private String businessName;// 商品名称
private String businessData;// 商户数据包
private String fee;// 手续费
private String rate;// 费率
private String createDate;
//private String wxRefundNo;// 微信退款单号
//private String businessRefundNo;// 商户退款单号
//private String refundAmount;// 退款金额
//private String redEnvelopesRefundAmount;// 企业红包退款金额
//private String refundType;// 退款类型
//private String refundStatus;// 退款状态
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTransDate() {
return transDate;
}
public void setTransDate(String transDate) {
this.transDate = transDate;
}
public String getCommonId() {
return commonId;
}
public void setCommonId(String commonId) {
this.commonId = commonId;
}
public String getBusinessNo() {
return businessNo;
}
public void setBusinessNo(String businessNo) {
this.businessNo = businessNo;
}
public String getChildBusinessNo() {
return childBusinessNo;
}
public void setChildBusinessNo(String childBusinessNo) {
this.childBusinessNo = childBusinessNo;
}
public String getEquipmentNo() {
return equipmentNo;
}
public void setEquipmentNo(String equipmentNo) {
this.equipmentNo = equipmentNo;
}
public String getWxOrderNo() {
return wxOrderNo;
}
public void setWxOrderNo(String wxOrderNo) {
this.wxOrderNo = wxOrderNo;
}
public String getBusinessOrderNo() {
return businessOrderNo;
}
public void setBusinessOrderNo(String businessOrderNo) {
this.businessOrderNo = businessOrderNo;
}
public String getUserIdentity() {
return userIdentity;
}
public void setUserIdentity(String userIdentity) {
this.userIdentity = userIdentity;
}
public String getTransType() {
return transType;
}
public void setTransType(String transType) {
this.transType = transType;
}
public String getTransStatus() {
return transStatus;
}
public void setTransStatus(String transStatus) {
this.transStatus = transStatus;
}
public String getPaymentBank() {
return paymentBank;
}
public void setPaymentBank(String paymentBank) {
this.paymentBank = paymentBank;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public String getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(String totalAmount) {
this.totalAmount = totalAmount;
}
public String getRedEnvelopesAmount() {
return redEnvelopesAmount;
}
public void setRedEnvelopesAmount(String redEnvelopesAmount) {
this.redEnvelopesAmount = redEnvelopesAmount;
}
public String getBusinessName() {
return businessName;
}
public void setBusinessName(String businessName) {
this.businessName = businessName;
}
public String getBusinessData() {
return businessData;
}
public void setBusinessData(String businessData) {
this.businessData = businessData;
}
public String getFee() {
return fee;
}
public void setFee(String fee) {
this.fee = fee;
}
public String getRate() {
return rate;
}
public void setRate(String rate) {
this.rate = rate;
}
public String getCreateDate() {
return createDate;
}
public void setCreateDate(String createDate) {
this.createDate = createDate;
}
}
2.请求对账参数实体类
public class WXPayCheckAccountEntity {
String appid= Constants.WXZN_WXAPP_ID; //公众账号ID
String mch_id=Constants.WXZN_WXMCH_ID;//商户号
String nonce_str;//随机字符串
String sign;//签名
String bill_date;//对账单日期
String bill_type="SUCCESS";//账单类型 否
//String tar_type;//压缩账单 否
public WXPayCheckAccountEntity(String nonce_str, String bill_date,String sign) {
this.nonce_str = nonce_str;
this.sign = sign;
this.bill_date = bill_date;
}
public String getXml(){
String signString="<xml><appid>"+appid+"</appid><bill_date>"+bill_date+"</bill_date><bill_type>"+bill_type+"</bill_type><mch_id>"+mch_id+"</mch_id><nonce_str>"+nonce_str+"</nonce_str><sign>"+sign+"</sign></xml> ";
return signString;
}
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 getBill_date() {
return bill_date;
}
public void setBill_date(String bill_date) {
this.bill_date = bill_date;
}
public String getBill_type() {
return bill_type;
}
public void setBill_type(String bill_type) {
this.bill_type = bill_type;
}
@Override
public String toString() {
return "{" +
"appid:'" + appid + '\'' +
", mch_id:'" + mch_id + '\'' +
", nonce_str:'" + nonce_str + '\'' +
", sign:'" + sign + '\'' +
", bill_date:'" + bill_date + '\'' +
", bill_type:'" + bill_type + '\'' +
'}';
}
}
3.对账入库方法
/**
* 微信对账入库
* @throws Exception
*/
@Override
public void queryWxCheckMenu() throws Exception {
String url= Constants.WX_DOWNLOADBILL;
//获取昨天日期
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
String yesterday ="20190611"; //new SimpleDateFormat( "yyyyMMdd").format(cal.getTime());
//生成随机字符串
String nonce_str= RandomStringUtils.randomAlphanumeric(10);
//创建请求xml
WXPayCheckAccountEntity entit=new WXPayCheckAccountEntity(nonce_str,yesterday,null);
//生成签名
SortedMap<Object, Object> sortedMap = Sign.parseJSON2Map(JSONObject.parseObject(entit.toString()));
String signString=Sign.createSign(sortedMap,null,"sign");
//加上秘钥
String stringSignTemp= MD5Utils.getMD5Upper(signString+"&key="+ Constants.WXZN_WX_KEY);//注:key为商户平台设置的密钥key
entit=new WXPayCheckAccountEntity(nonce_str,yesterday,stringSignTemp);
String result= HttpUtil.sendDataUTF8(url,entit.getXml());
System.out.println(result);
if ("1".equals(xmlToMap(result).get("return_code"))){
//把第一行表头去掉
String tradeMsg = result.substring(result.indexOf("`"));
//去掉汇总数据,并且去掉"`","\r\n"这个符号。
String tradeInfo = tradeMsg.substring(0, tradeMsg.indexOf("总")).replace("`", "").replace("\r\n", "");// 去掉汇总数据,并且去掉'`'
//用spilt方法拿出每一天数据放进数组里。之后再用spilt方法把数据放进二维数组里。
String[] tradeArray = tradeInfo.split("%"); // 根据%来区分
ArrayList<PtWxTradeDetailEntity> ptWxTradeDetailArrayList=new ArrayList<>();
for (String tradeDetailInfo : tradeArray) {
String[] tradeDetailArray = tradeDetailInfo.split(",");
PtWxTradeDetailEntity payEntityList=toWxPayEntity(tradeDetailArray);
ptWxTradeDetailArrayList.add(payEntityList);
}
for (PtWxTradeDetailEntity entity : ptWxTradeDetailArrayList) {
entity.setTotalAmount(AmountUtils.changeY2F(entity.getTotalAmount()));
mapper.insertCheckWeixinRecord(entity);
}
System.out.println(ptWxTradeDetailArrayList);
}else {
System.out.println("微信对账信息入库出错");
}
}
4.返回微信交易实体类
/**
* 返回微信交易实体类
* @param tradeDetailArray
* @return
*/
public static PtWxTradeDetailEntity toWxPayEntity(String[] tradeDetailArray){
PtWxTradeDetailEntity entity = new PtWxTradeDetailEntity();
entity.setId(null); // 自动生成id
entity.setTransDate(tradeDetailArray[0]);// 交易时间
entity.setCommonId(tradeDetailArray[1]);// 公众账号ID
entity.setBusinessNo(tradeDetailArray[2]);// 商户号
entity.setChildBusinessNo(tradeDetailArray[3]);// 子商户号
entity.setEquipmentNo(tradeDetailArray[4]);// 设备号
entity.setWxOrderNo(tradeDetailArray[5]);// 微信订单号
entity.setBusinessOrderNo(tradeDetailArray[6]);// 商户订单号
entity.setUserIdentity(tradeDetailArray[7]);// 用户标识
entity.setTransType(tradeDetailArray[8]);// 交易类型
entity.setTransStatus(tradeDetailArray[9]);// 交易状态
entity.setPaymentBank(tradeDetailArray[10]);// 付款银行
entity.setCurrency(tradeDetailArray[11]);// 货币种类
entity.setTotalAmount(tradeDetailArray[12]);// 总金额
entity.setRedEnvelopesAmount(tradeDetailArray[13]);// 企业红包金额
entity.setBusinessName(tradeDetailArray[14]);// 商品名称
entity.setBusinessData(tradeDetailArray[15]);// 商户数据包
entity.setFee(tradeDetailArray[16]);// 手续费
entity.setRate(tradeDetailArray[17] + "%");// 费率
//entity.setWxRefundNo(tradeDetailArray[14]);// 微信退款单号
//entity.setBusinessRefundNo(tradeDetailArray[15]);// 商户退款单号
//entity.setRefundAmount(tradeDetailArray[16]);// 退款金额
//entity.setRedEnvelopesRefundAmount(tradeDetailArray[17]);// 企业红包退款金额
//entity.setRefundType(tradeDetailArray[18]);// 退款类型
//entity.setRefundStatus(tradeDetailArray[19]);// 退款状态
return entity;
}
5.其他方法
/**
* 将json对象转换为SortedMap
*
* @param json
* @return
*/
public static SortedMap<Object, Object> parseJSON2Map(JSONObject json) {
SortedMap<Object, Object> map = new TreeMap<Object, Object>();
// 最外层解析
for (Object k : json.keySet()) {
Object v = json.get(k);
if (v instanceof JSONArray) {
ArrayList arrayList = new ArrayList();
for (int i = 0; i < ((JSONArray) v).size(); i++) {
arrayList.add(((JSONArray) v).get(i));
}
map.put(k, arrayList);
} else {
map.put(k, json.get(k));
}
/*// 如果内层还是json数组的话,继续解析
if (v instanceof JSONArray) {
// JSONObject.parseArray(((JSONArray) v).toJSONString(),String.class)
List<SortedMap<Object, Object>> list = new ArrayList<SortedMap<Object, Object>>();
Iterator<Object> it = ((JSONArray) v).iterator();
while (it.hasNext()) {
System.out.println(it.next().getClass()+"+++++++++++++++++++++++++++++++++++++++++++++++++++");
logger.info("++++++++++++++++++++++++={}",it.next().getClass());
JSONObject json2 = (JSONObject) it.next();
list.add(parseJSON2Map(json2));
}
map.put(k.toString(), list);
} else if (v instanceof JSONObject) {
// 如果内层是json对象的话,继续解析
map.put(k.toString(), parseJSON2Map((JSONObject) v));
} else {
// 如果内层是普通对象的话,直接放入map中
map.put(k.toString(), v);
}*/
}
return map;
}
/**
* 按照ASCII码排序(升序)并将key加到签名前后
*
* @param parameters
* @param key
* @return
*/
public static String createSign(SortedMap<Object, Object> parameters, String key, String sign) {
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet(); //所有参与传参的参数按照accsii排序(升序)
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
if (sign.equals(k)) {
continue;
}
Object v = entry.getValue();
//空值不传递,不参与签名组串
if (null != v && !"".equals(v)) {
sb.append(k + "=" + v + "&");
}
}
String result="";
if (key!=null){
result= key + sb.toString().substring(0, sb.toString().length() - 1) + key;
}else {
result= sb.toString().substring(0, sb.toString().length() - 1);
}
//排序后的字符串
//System.out.println("待签名字符串:" + result);
return result;
}
/**
* 加密之后的字符串全为大写
*
* @param srcStr
* @return
* @throws NoSuchAlgorithmException
* @throws NullPointerException
*/
public static String getMD5Upper(String srcStr)throws NoSuchAlgorithmException {
String sign = "upper";
return processStr(srcStr, sign);
}