微信对账单接口的使用以及对接口数据的解析方式

最近公司在做对账单的功能,从来没做过三方接口的我荣幸承包此活大哭,千辛万苦找到https://api.mch.weixin.qq.com/pay/downloadbill这个接口,于是陷入漫长的研究与实验阶段,从网上找了很多的文章,但是并没有帮助解决问题一直显示说我的数据格式错误,我怀疑是拼接参数的时候有问题,为了方便后面有跟我遇到相同问题的同志们,我将我的经验写下来,一来帮助大家使用这个接口,而来帮助自己进行总结,一举两得。。。

第一步:自己找到接口的说明根据说明进行一步步操作,如果期间遇到问题可以查询解决。

1:

接口链接

https://api.mch.weixin.qq.com/pay/downloadbill

2:参数列表,自己找到匹配的数据进行设置。

字段名变量名必填类型示例值描述
公众账号IDappidString(32)wx8888888888888888微信分配的公众账号ID(企业号corpid即为此appId)
商户号mch_idString(32)1900000109微信支付分配的商户号
设备号device_infoString(32)013467007045764微信支付分配的终端设备号
随机字符串nonce_strString(32)5K8264ILTKCH16CQ2502SI8ZNMTM67VS随机字符串,不长于32位。推荐随机数生成算法
签名signString(32)C380BEC2BFD727A4B6845133519F3AD6签名,详见签名生成算法
对账单日期bill_dateString(8)20140603下载对账单的日期,格式:20140603
账单类型bill_typeString(8)ALL

ALL,返回当日所有订单信息,默认值

SUCCESS,返回当日成功支付的订单

REFUND,返回当日退款订单 


3:这个是文档给的参数格式,我就是在这个地方花费不少时间(这个格式需要修改一下)

<xml>
<appid>wx2421b1c4370ec43b</appid>
<bill_date>20141110</bill_date>
<bill_type>ALL</bill_type>
<mch_id>10000100</mch_id>
<nonce_str>21df7dc9cd8616b56919f20d9f679233</nonce_str>
<sign>332F17B766FC787203EBE9D6E40457A1</sign>
</xml> 

第二步:这里我直接贴连接代码,根据代码我细讲

               
SortedMap<Object, Object> parameters = new TreeMap <Object, Object>();//用来放置各个所需要的参数,自己对应寻找填写。
		parameters.put("appid", appid);//appid
		parameters.put("bill_date", today);//下载对账单的日期,格式:20140603
		// bill_type:ALL返回当日所有订单信息,默认值SUCCESS返回当日成功支付的订单。REFUND,返回当日退款订单
		parameters.put("bill_type", "ALL");
		parameters.put("mch_id", partner);
		parameters.put("nonce_str", PayCommonUtil.CreateNoncestr());//生成的随机数<span style="font-size:24px;"></span><pre name="code" class="java">这个方法PayCommonUtil.CreateNoncestr()后面贴出。
String sign = PayCommonUtil.createSign("utf-8", parameters);//签名方式parameters.put("sign", sign);String reuqestXml = PayCommonUtil.getRequestXml(parameters);//这个就是将参数拼接成xml格式,具体在代码中展示String result = CommonUtil.httpsRequest(ConfigUtil.DOWNLOAD_BILL_URL, "POST", reuqestXml);//请求方式if (result.startsWith("<xml>")) {// 查询日期为当天时,错误信息提示日期无效System.out.println("无订单");} else {String tradeInfo = tradeMsg.substring(0, tradeMsg.indexOf("总"));//这个参数是把具体的返回值给取出来,去掉了参数名和最后的统计参数和数据,方便后面解析数据使用

 
 
tradeInfo = tradeInfo.replaceAll("%", "%,");

<span style="font-size:32px;"><strong>PayCommonUtil.CreateNoncestr()方法展示:</strong></span>
<pre name="code" class="java">public static String CreateNoncestr() {
		String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		String res = "";
		for (int i = 0; i < 16; i++) {
			Random rd = new Random();
			res += chars.charAt(rd.nextInt(chars.length() - 1));
		}
		return res;
	}
 
 
<span style="font-size:32px;">PayCommonUtil.createSign("utf-8", parameters)</span><span style="font-size: 32px; font-family: Arial, Helvetica, sans-serif;">方法展示:</span>
public static String createSign(String characterEncoding, SortedMap<Object, 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=" + ConfigUtil.API_KEY);//此处的key值自己查找帐号
		String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
		return sign;
	}

PayCommonUtil.getRequestXml(parameters)方法展示:
<pre name="code" class="java">public static String getRequestXml(SortedMap<Object, Object> parameters) {
		StringBuffer sb = new StringBuffer();
		sb.append("<xml>");
		Set es = parameters.entrySet();
		Iterator it = es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			String v = (String) entry.getValue();
			if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
				<span style="color:#ff0000;">sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");//这个位置就是我说的格式,加上这块后就好用了,感谢这个方法的提供者李欣桦。</span>
			} else {
				sb.append("<" + k + ">" + v + "</" + k + ">");
			}
		}
		sb.append("</xml>");
		return sb.toString();
	}


 
 第三步:返回数据的格式解析 
 

我自己是想将返回的数据保存到数据库中的,就想将这些数据进行解析,我先寻找规律,发现在费率那个位置的%后面没有逗号,而这个位置正好是一条数据的结尾,于是我将%换成%,问题就是这样解决,代码如下:

tradeInfo = tradeInfo.replaceAll("%", "%,");//这个参数上面讲到过,是处理后的。

public void saveWeiXinRecord(String Str) {

		String[] stringbuf = null;
		stringbuf = Str.split(",");
		for (int i = 0; i < stringbuf.length; i++) {
			System.out.println(stringbuf[i]);
		}
		int num = stringbuf.length / 24;

		for (int i = 1; i <= num; i++) {
			for (int j = i * 24 - 24; j < i * 24; j++) {
				wxMXRecord wxmxRecord = new wxMXRecord();
				wxmxRecord.setPayTime(stringbuf[j]);
				j++;
				wxmxRecord.setPublicId(stringbuf[j]);
				j++;
				wxmxRecord.setBussinessno(stringbuf[j]);
				j++;
				wxmxRecord.setBussinessnox(stringbuf[j]);
				j++;
				wxmxRecord.setMachineno(stringbuf[j]);
				j++;
				wxmxRecord.setWxorderId(stringbuf[j]);
				j++;
				wxmxRecord.setShorderId(stringbuf[j]);
				j++;
				wxmxRecord.setUsertype(stringbuf[j]);
				j++;
				wxmxRecord.setTradetype(stringbuf[j]);
				j++;
				wxmxRecord.setTradestatus(stringbuf[j]);
				j++;
				wxmxRecord.setBank(stringbuf[j]);
				j++;
				wxmxRecord.setMoneytype(stringbuf[j]);
				j++;
				wxmxRecord.setTotalmoney(stringbuf[j]);
				j++;
				wxmxRecord.setRedboxnum(stringbuf[j]);
				j++;
				wxmxRecord.setBackorderno(stringbuf[j]);
				j++;
				wxmxRecord.setBusbackorderno(stringbuf[j]);
				j++;
				wxmxRecord.setBackmoneynum(stringbuf[j]);
				j++;
				wxmxRecord.setBackredboxnum(stringbuf[j]);
				j++;
				wxmxRecord.setBacktype(stringbuf[j]);
				j++;
				wxmxRecord.setBackstatus(stringbuf[j]);
				j++;
				wxmxRecord.setProductname(stringbuf[j]);
				j++;
				wxmxRecord.setDatebag(stringbuf[j]);
				j++;
				wxmxRecord.setShouxufei(stringbuf[j]);
				j++;
				wxmxRecord.setFeilv(stringbuf[j]);

				wxmxRecord.setType("微信");
				weiXinMXDao.saveOrUpdate(wxmxRecord);
			}
		}

	}
这个就是将这些个参数数据根据逗号分开,存入到数组中,然后循环设置到一个实体对象中,然后执行对象保存即可。


以上有的代码是参考网上的,我的具体思路就是这些,第一次写,有点乱,有不足之处欢迎大家提出,有一些工具代码可以从这下载。点击下载


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值