1.创建微信账单实体类
publicclassPtWxTradeDetailEntity { privateStringid; privateStringtransDate;// 交易时间privateStringcommonId;// 公众账号IDprivateStringbusinessNo;// 商户号privateStringchildBusinessNo;// 子商户号privateStringequipmentNo;// 设备号privateStringwxOrderNo;// 微信订单号privateStringbusinessOrderNo;// 商户订单号privateStringuserIdentity;// 用户标识privateStringtransType;// 交易类型privateStringtransStatus;// 交易状态privateStringpaymentBank;// 付款银行privateStringcurrency;// 货币种类privateStringtotalAmount;// 总金额privateStringredEnvelopesAmount;// 企业红包金额privateStringbusinessName;// 商品名称privateStringbusinessData;// 商户数据包privateStringfee;// 手续费privateStringrate;// 费率privateStringcreateDate; //private String wxRefundNo;// 微信退款单号//private String businessRefundNo;// 商户退款单号//private String refundAmount;// 退款金额//private String redEnvelopesRefundAmount;// 企业红包退款金额//private String refundType;// 退款类型//private String refundStatus;// 退款状态publicStringgetId() { returnid; } publicvoidsetId(Stringid) { this.id=id; } publicStringgetTransDate() { returntransDate; } publicvoidsetTransDate(StringtransDate) { this.transDate=transDate; } publicStringgetCommonId() { returncommonId; } publicvoidsetCommonId(StringcommonId) { this.commonId=commonId; } publicStringgetBusinessNo() { returnbusinessNo; } publicvoidsetBusinessNo(StringbusinessNo) { this.businessNo=businessNo; } publicStringgetChildBusinessNo() { returnchildBusinessNo; } publicvoidsetChildBusinessNo(StringchildBusinessNo) { this.childBusinessNo=childBusinessNo; } publicStringgetEquipmentNo() { returnequipmentNo; } publicvoidsetEquipmentNo(StringequipmentNo) { this.equipmentNo=equipmentNo; } publicStringgetWxOrderNo() { returnwxOrderNo; } publicvoidsetWxOrderNo(StringwxOrderNo) { this.wxOrderNo=wxOrderNo; } publicStringgetBusinessOrderNo() { returnbusinessOrderNo; } publicvoidsetBusinessOrderNo(StringbusinessOrderNo) { this.businessOrderNo=businessOrderNo; } publicStringgetUserIdentity() { returnuserIdentity; } publicvoidsetUserIdentity(StringuserIdentity) { this.userIdentity=userIdentity; } publicStringgetTransType() { returntransType; } publicvoidsetTransType(StringtransType) { this.transType=transType; } publicStringgetTransStatus() { returntransStatus; } publicvoidsetTransStatus(StringtransStatus) { this.transStatus=transStatus; } publicStringgetPaymentBank() { returnpaymentBank; } publicvoidsetPaymentBank(StringpaymentBank) { this.paymentBank=paymentBank; } publicStringgetCurrency() { returncurrency; } publicvoidsetCurrency(Stringcurrency) { this.currency=currency; } publicStringgetTotalAmount() { returntotalAmount; } publicvoidsetTotalAmount(StringtotalAmount) { this.totalAmount=totalAmount; } publicStringgetRedEnvelopesAmount() { returnredEnvelopesAmount; } publicvoidsetRedEnvelopesAmount(StringredEnvelopesAmount) { this.redEnvelopesAmount=redEnvelopesAmount; } publicStringgetBusinessName() { returnbusinessName; } publicvoidsetBusinessName(StringbusinessName) { this.businessName=businessName; } publicStringgetBusinessData() { returnbusinessData; } publicvoidsetBusinessData(StringbusinessData) { this.businessData=businessData; } publicStringgetFee() { returnfee; } publicvoidsetFee(Stringfee) { this.fee=fee; } publicStringgetRate() { returnrate; } publicvoidsetRate(Stringrate) { this.rate=rate; } publicStringgetCreateDate() { returncreateDate; } publicvoidsetCreateDate(StringcreateDate) { this.createDate=createDate; } }
2.请求对账参数实体类
publicclassWXPayCheckAccountEntity { Stringappid=Constants.WXZN_WXAPP_ID; //公众账号IDStringmch_id=Constants.WXZN_WXMCH_ID;//商户号Stringnonce_str;//随机字符串Stringsign;//签名Stringbill_date;//对账单日期Stringbill_type="SUCCESS";//账单类型 否//String tar_type;//压缩账单 否publicWXPayCheckAccountEntity(Stringnonce_str, Stringbill_date,Stringsign) { this.nonce_str=nonce_str; this.sign=sign; this.bill_date=bill_date; } publicStringgetXml(){ StringsignString="<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> "; returnsignString; } publicStringgetAppid() { returnappid; } publicvoidsetAppid(Stringappid) { this.appid=appid; } publicStringgetMch_id() { returnmch_id; } publicvoidsetMch_id(Stringmch_id) { this.mch_id=mch_id; } publicStringgetNonce_str() { returnnonce_str; } publicvoidsetNonce_str(Stringnonce_str) { this.nonce_str=nonce_str; } publicStringgetSign() { returnsign; } publicvoidsetSign(Stringsign) { this.sign=sign; } publicStringgetBill_date() { returnbill_date; } publicvoidsetBill_date(Stringbill_date) { this.bill_date=bill_date; } publicStringgetBill_type() { returnbill_type; } publicvoidsetBill_type(Stringbill_type) { this.bill_type=bill_type; } publicStringtoString() { return"{"+"appid:'"+appid+'\''+", mch_id:'"+mch_id+'\''+", nonce_str:'"+nonce_str+'\''+", sign:'"+sign+'\''+", bill_date:'"+bill_date+'\''+", bill_type:'"+bill_type+'\''+'}'; } }
3.对账入库方法
/*** 微信对账入库* @throws Exception*/publicvoidqueryWxCheckMenu() throwsException { Stringurl=Constants.WX_DOWNLOADBILL; //获取昨天日期Calendarcal=Calendar.getInstance(); cal.add(Calendar.DATE, -1); Stringyesterday="20190611"; //new SimpleDateFormat( "yyyyMMdd").format(cal.getTime());//生成随机字符串Stringnonce_str=RandomStringUtils.randomAlphanumeric(10); //创建请求xmlWXPayCheckAccountEntityentit=newWXPayCheckAccountEntity(nonce_str,yesterday,null); //生成签名SortedMap<Object, Object>sortedMap=Sign.parseJSON2Map(JSONObject.parseObject(entit.toString())); StringsignString=Sign.createSign(sortedMap,null,"sign"); //加上秘钥StringstringSignTemp=MD5Utils.getMD5Upper(signString+"&key="+Constants.WXZN_WX_KEY);//注:key为商户平台设置的密钥keyentit=newWXPayCheckAccountEntity(nonce_str,yesterday,stringSignTemp); Stringresult=HttpUtil.sendDataUTF8(url,entit.getXml()); System.out.println(result); if ("1".equals(xmlToMap(result).get("return_code"))){ //把第一行表头去掉StringtradeMsg=result.substring(result.indexOf("`")); //去掉汇总数据,并且去掉"`","\r\n"这个符号。StringtradeInfo=tradeMsg.substring(0, tradeMsg.indexOf("总")).replace("`", "").replace("\r\n", "");// 去掉汇总数据,并且去掉'`'//用spilt方法拿出每一天数据放进数组里。之后再用spilt方法把数据放进二维数组里。String[] tradeArray=tradeInfo.split("%"); // 根据%来区分ArrayList<PtWxTradeDetailEntity>ptWxTradeDetailArrayList=newArrayList<>(); for (StringtradeDetailInfo : tradeArray) { String[] tradeDetailArray=tradeDetailInfo.split(","); PtWxTradeDetailEntitypayEntityList=toWxPayEntity(tradeDetailArray); ptWxTradeDetailArrayList.add(payEntityList); } for (PtWxTradeDetailEntityentity : ptWxTradeDetailArrayList) { entity.setTotalAmount(AmountUtils.changeY2F(entity.getTotalAmount())); mapper.insertCheckWeixinRecord(entity); } System.out.println(ptWxTradeDetailArrayList); }else { System.out.println("微信对账信息入库出错"); } }
4.返回微信交易实体类
/*** 返回微信交易实体类* @param tradeDetailArray* @return*/publicstaticPtWxTradeDetailEntitytoWxPayEntity(String[] tradeDetailArray){ PtWxTradeDetailEntityentity=newPtWxTradeDetailEntity(); entity.setId(null); // 自动生成identity.setTransDate(tradeDetailArray[0]);// 交易时间entity.setCommonId(tradeDetailArray[1]);// 公众账号IDentity.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]);// 退款状态returnentity; }
5.其他方法
/*** 将json对象转换为SortedMap** @param json* @return*/publicstaticSortedMap<Object, Object>parseJSON2Map(JSONObjectjson) { SortedMap<Object, Object>map=newTreeMap<Object, Object>(); // 最外层解析for (Objectk : json.keySet()) { Objectv=json.get(k); if (vinstanceofJSONArray) { ArrayListarrayList=newArrayList(); for (inti=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);}*/ } returnmap; }
/*** 按照ASCII码排序(升序)并将key加到签名前后** @param parameters* @param key* @return*/publicstaticStringcreateSign(SortedMap<Object, Object>parameters, Stringkey, Stringsign) { StringBuffersb=newStringBuffer(); Setes=parameters.entrySet(); //所有参与传参的参数按照accsii排序(升序)Iteratorit=es.iterator(); while (it.hasNext()) { Map.Entryentry= (Map.Entry) it.next(); Stringk= (String) entry.getKey(); if (sign.equals(k)) { continue; } Objectv=entry.getValue(); //空值不传递,不参与签名组串if (null!=v&&!"".equals(v)) { sb.append(k+"="+v+"&"); } } Stringresult=""; 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);returnresult; }
/*** 按照ASCII码排序(升序)并将key加到签名前后** @param parameters* @param key* @return*/publicstaticStringcreateSign(SortedMap<Object, Object>parameters, Stringkey, Stringsign) { StringBuffersb=newStringBuffer(); Setes=parameters.entrySet(); //所有参与传参的参数按照accsii排序(升序)Iteratorit=es.iterator(); while (it.hasNext()) { Map.Entryentry= (Map.Entry) it.next(); Stringk= (String) entry.getKey(); if (sign.equals(k)) { continue; } Objectv=entry.getValue(); //空值不传递,不参与签名组串if (null!=v&&!"".equals(v)) { sb.append(k+"="+v+"&"); } } Stringresult=""; 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);returnresult; }
/*** 加密之后的字符串全为大写** @param srcStr* @return* @throws NoSuchAlgorithmException* @throws NullPointerException*/publicstaticStringgetMD5Upper(StringsrcStr)throwsNoSuchAlgorithmException { Stringsign="upper"; returnprocessStr(srcStr, sign); }