微信对账单--每日定时任务获取昨日微信支付账单

首先设置任务自动执行时间

//每日十点开始执行获取昨日账单任务
@Scheduled(cron = "0 0 10 * * ?")
public void task() throws Exception{
	// 获取昨日日期
	LocalDate today = LocalDate.now();
	LocalDate yesterday = today.minusDays(1);
	String taskDate = formatter.format(yesterday);
	// 获取昨日微信支付账单
	boolean taskStatus = this.wxpayBillsTask(task.getTaskID(), yesterday);
}

对多个公众号进行统一管理,一次性获取全部对账单

/*
 * 获取昨日微信支付账单
 * 1.查询微信公众号号配置
 * 2.分别获取支付账单请求,并保存请求记录
 * 3.解析微信返回账单数据,并保存到数据库
 * 4.更新任务进程的微信商户账单采集状态
 */
protected boolean wxpayBillsTask(int taskID, LocalDate yesterday) throws Exception{
	String bill_date = dateFormatter.format(yesterday);
	String taskDate = formatter.format(yesterday);
	logger.debug("wxpayBillsTask {}|{}", taskID, bill_date);

	// 查询微信公众号配置信息
	List<WeixinAccount> accounts = commonRepository.queryAllWeixinAccounts();

	CollectLogs log = null;
	Boolean bRet = false;
	for (WeixinAccount account : accounts) {
		if (StringUtils.isEmpty(account.getWeixinAppID()) || StringUtils.isEmpty(account.getWeixinMchID())) {
			continue;
		}
		//日志记录
		log = new CollectLogs(taskID, "开启微信支付账单信息任务" + taskID + account.getOfficialAccount() + "采集");
		commonRepository.saveCollectLogs(log);

		// 向微信发送获取账单请求
		Map<String, String> param = new HashMap<String, String>();
		param.put("appid", account.getWeixinAppID());// 公众账户ID
		param.put("mch_id", account.getWeixinMchID());// 商户号
		param.put("nonce_str", WeixinUtil.create_nonce_str());// 随机字符串
		param.put("bill_date", bill_date);// 对账单日期
		param.put("bill_type", "ALL");// 账单类型(非必填)
		param = WeixinUtil.getSign(param, account.getWeixinMchSecret());

		String sign = param.get("sign");
		param.remove("sign");

		String reuqestXml = WeixinUtil.MapToXml(param);
		reuqestXml = reuqestXml.replace("", "" + sign + "");
		String billStr = WeixinUtil.post(DOWNLOAD_BILL_URL, reuqestXml);
		logger.debug("wxpayBillsTask create order result {}", billStr);

		// 保存请求记录
		ThirdRequest requestLog = new ThirdRequest(taskID, BILL_THIRD_WXPAY, 
				account.getWeixinAppID(), param.toString(), billStr);
		//数据FAIL,结束
		if(billStr.indexOf("`")<0) {				
			Map<String, String> mapXmlResult = WeixinUtil.doXMLParse(billStr);
			if("FAIL".equals(mapXmlResult.get("return_code"))){
				requestLog.setThirdStatus(1);
			}
			logger.debug("wxpayBillsTask doXMLParse convert XML to Map {}", mapXmlResult);
			commonRepository.saveThirdRequest(requestLog);
			
			log = new CollectLogs(taskID, "微信支付账单信息任务" + taskID + account.getOfficialAccount() + "FAIL结束");
			commonRepository.saveCollectLogs(log);
			continue;
		}
		requestLog.setThirdStatus(10);
		commonRepository.saveThirdRequest(requestLog);
			
		// 解析数据
		// 获取表头和汇总以外的其他内容:交易记录
		String dataMsg = billStr.substring(billStr.indexOf("`"));
		String dataContent = dataMsg.substring(0,dataMsg.indexOf("总")).replaceFirst(taskDate,"").replaceAll("`","");
		String[] tradeStrs = dataContent.split(taskDate);
		logger.debug("wxpayBillsTask split size {}", tradeStrs.length);
		for (String trade : tradeStrs) {
			logger.debug("wxpayBillsTask tradeStrs trade {}", trade);
			String[] order = trade.split(",");
			ThirdBills billTrade = new ThirdBills();
			billTrade.setTaskID(taskID);
			billTrade.setThirdType(BILL_THIRD_WXPAY);
			billTrade.setThirdAppID(account.getWeixinAppID());
			billTrade.setThirdMchID(order[2]);
			billTrade.setTradeNo(order[6]);
			billTrade.setTradeTime(taskDate+order[0]);
			billTrade.setTradeStatus(order[9]);
			billTrade.setTradeCurrency(order[11]);
			billTrade.setTradeTotal(order[24]);
			billTrade.setTradeFee(order[22]);
			billTrade.setTradeRefund(order[16]);
			billTrade.setRefundStatus(order[19]);
			bRet = collectRepository.saveThirdBills(billTrade);
			if(!bRet) {
				log = new CollectLogs(taskID, "保存任务"+taskID+"账单数据[商户订单号]: " + order[6] +" 失败");
				commonRepository.saveCollectLogs(log);
			}
		}
		
		log = new CollectLogs(taskID, "微信支付账单信息任务" + taskID + account.getOfficialAccount() + "完成结束");
		commonRepository.saveCollectLogs(log);
	}
	//结束微信账单信息采集任务
	return bRet;
}

总结:
需要看清接口传递的参数,其中向微信发送获取账单请求时,签名sign的获取是难点,以及获取数据之后的解析也是需要注意的,当有账单数据时,返回的是文本表格数据;否则,返回xml格式的数据,所以需要分两种情况去处理。

你可能感兴趣的:(java)