最近接手了一个棘手的工作:微信下载对账单。

刚接手完全懵逼,怎么和微信对接啊。然后就是百度。。

终于找到了组织:

微信支付|开发文档 :点击跳转

通过文档我们可以看到,首先是:

1.下载对账单开放接口链接:

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

关于应用场景:

商户可以通过该接口下载历史交易清单。比如掉单、系统错误等导致商户侧和微信侧数据不一致,通过对账单核对后可校正支付状态。

注意:

1、微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账单中,跟原支付单订单号一致;

2、微信在次日9点启动生成前一天的对账单,建议商户10点后再获取;

3、对账单中涉及金额的字段单位为“元”。

4、对账单接口只能下载三个月以内的账单。

2.传入的参数:

接着我们看下传入参数:

其中,微信分配的appId 和 商户号 是自己的。

还有就是需要 去商户平台查自己商户号以及key。这个key主要用在生成签名中。

看一下查詢代码:

SortedMapparameters = new TreeMap();

parameters.put("appid", ConfigUtil.APPID); // APPid

parameters.put("mch_id", ConfigUtil.MCH_ID); // 商户id

// parameters.put("device_info", "");//微信支付分配的终端设备号,填写此字段,只下载该设备号 的对账单

parameters.put("nonce_str", PayCommonUtil.CreateNoncestr());

// 下载对账单的日期,格式:20140603,当前日期前一天。

String billDate = DateUtil.date2Str(DateUtil.addDay(new Date(), -1), "yyyyMMdd");

parameters.put("bill_date", billDate);//

// bill_type:ALL返回当日所有订单信息,默认值SUCCESS返回当日成功支付的订单。REFUND,返回当日退款订单

parameters.put("bill_type", "ALL");

String sign = PayCommonUtil.createSign("utf-8", parameters);

parameters.put("sign", sign);

String reuqestXml = PayCommonUtil.getRequestXml(parameters);

String result = CommonUtil.httpsRequest(ConfigUtil.DOWNLOAD_BILL_URL, "POST", reuqestXml);

configUtil 工具类里面要配置APPID,MCH_ID,已及Key 。(注:所有的工具类我都放文章末尾链接里,自己下载即可。)我们需要在ConfigUtil工具类中配置一下:

public final static String APPID = "";//服务号的应用号

public final static String APP_SECRECT = "";//服务号的应用密码

public final static String TOKEN = "weixinCourse";//服务号的配置token

public final static String MCH_ID = "";//商户号

public final static String API_KEY = "";//API密钥

public final static String SIGN_TYPE = "MD5";//签名加密方式

public final static String CERT_PATH = "D:/apiclient_cert.p12";//微信支付证书存放路径地址

3.随机数:

我们看一下随机数的生成:

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;

}

4.关于签名:

关于签名,有三点需要注意:

①格式是:utf-8;

②签名类型:MD5以及HMAC-SHA256。默认为MD5,本例也是MD5。

③签名的生成:需要前面几个值(APPID等)以及Key:

public static String createSign(String characterEncoding,SortedMapparameters){

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);

String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();

return sign;

}

之后我们把map 变成xml格式数据:

例如这样:

wx2421b1c4370ec43b

20141110

ALL

10000100

21df7dc9cd8616b56919f20d9f679233

332F17B766FC787203EBE9D6E40457A1

代码:

public static String getRequestXml(SortedMapparameters){

StringBuffer sb = new StringBuffer();

sb.append("");

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)) {

if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)) {

sb.append(""+""+k+">");

}else {

sb.append(""+v+""+k+">");

}

}

sb.append("");

return sb.toString();

}

之后把xml传给微信对账单接口而后接口会返回值:

5.返回值解析:

关于返回值,这里我详解下:最重要一点是:成功和失败返回数据流类型不一样:成功返回文本格式,失败返回xml格式数据。

①返回失败的情况 :返回xml ,其中无数据也会返回xml 。并且格式是下图。

下面是错误码:

②成功:数据以文本方式返回。

拿微信给的成功返回数据举例:

交易时间,公众账号ID,商户号,子商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,总金额,代金券或立减优惠金额,微信退款单号,商户退款单号,退款金额,代金券或立减优惠退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率

`2014-11-1016:33:45,`wx2421b1c4370ec43b,`10000100,`0,`1000,`1001690740201411100005734289,`1415640626,`085e9858e3ba5186aafcbaed1,`MICROPAY,`SUCCESS,`CFT,`CNY,`0.01,`0.0,`0,`0,`0,`0,`,`,`被扫支付测试,`订单额外描述,`0,`0.60%

`2014-11-1016:46:14,`wx2421b1c4370ec43b,`10000100,`0,`1000,`1002780740201411100005729794,`1415635270,`085e9858e90ca40c0b5aee463,`MICROPAY,`SUCCESS,`CFT,`CNY,`0.01,`0.0,`0,`0,`0,`0,`,`,`被扫支付测试,`订单额外描述,`0,`0.60%

总交易单数,总交易额,总退款金额,总代金券或立减优惠退款金额,手续费总金额

`2,`0.02,`0.0,`0.0,`0

我们对成功的数据进行处理:

①把第一行表头去掉

代码为:

String tradeMsg = result.substring(result.indexOf("`"));

数据为:

`2014-11-1016:33:45,`wx2421b1c4370ec43b,`10000100,`0,`1000,`1001690740201411100005734289,`1415640626,`085e9858e3ba5186aafcbaed1,`MICROPAY,`SUCCESS,`CFT,`CNY,`0.01,`0.0,`0,`0,`0,`0,`,`,`被扫支付测试,`订单额外描述,`0,`0.60%

`2014-11-1016:46:14,`wx2421b1c4370ec43b,`10000100,`0,`1000,`1002780740201411100005729794,`1415635270,`085e9858e90ca40c0b5aee463,`MICROPAY,`SUCCESS,`CFT,`CNY,`0.01,`0.0,`0,`0,`0,`0,`,`,`被扫支付测试,`订单额外描述,`0,`0.60%

总交易单数,总交易额,总退款金额,总代金券或立减优惠退款金额,手续费总金额

`2,`0.02,`0.0,`0.0,`0

②去掉汇总数据,并且去掉"`"这个符号。

代码为:

String tradeInfo = tradeMsg.substring(0, tradeMsg.indexOf("总")).replace("`", "");// 去掉汇总数据,并且去掉'`'

数据为:

2014-11-1016:33:45,wx2421b1c4370ec43b,10000100,0,1000,1001690740201411100005734289,1415640626,085e9858e3ba5186aafcbaed1,MICROPAY,SUCCESS,CFT,CNY,0.01,0.0,0,0,0,0,,,被扫支付测试,订单额外描述,0,0.60%

2014-11-1016:46:14,wx2421b1c4370ec43b,10000100,0,1000,1002780740201411100005729794,1415635270,085e9858e90ca40c0b5aee463,MICROPAY,SUCCESS,CFT,CNY,0.01,0.0,0,0,0,0,,,被扫支付测试,订单额外描述,0,0.60%

可以看到和我们想要的数据已经大致一样了。

③用spilt方法拿出每一天数据放进数组里。之后再用spilt方法把数据放进二维数组里。

String[] tradeArray = tradeInfo.split("%"); // 根据%来区分

for (String tradeDetailInfo : tradeArray) {

String[] tradeDetailArray = tradeDetailInfo.split(",");

}

④最后保存下来就可以了。

PtWxTradeDetail entity = null;

entity = new PtWxTradeDetail();

entity.setId(null); // 自动生成id

entity.setTransDate(DateUtil.str2Date(tradeDetailArray[0], format));// 交易时间

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.setWxRefundNo(tradeDetailArray[14]);// 微信退款单号

entity.setBusinessRefundNo(tradeDetailArray[15]);// 商户退款单号

entity.setRefundAmount(tradeDetailArray[16]);// 退款金额

entity.setRedEnvelopesRefundAmount(tradeDetailArray[17]);// 企业红包退款金额

entity.setRefundType(tradeDetailArray[18]);// 退款类型

entity.setRefundStatus(tradeDetailArray[19]);// 退款状态

entity.setBusinessName(tradeDetailArray[20]);// 商品名称

entity.setBusinessData(tradeDetailArray[21]);// 商户数据包

entity.setFee(tradeDetailArray[22]);// 手续费

entity.setRate(tradeDetailArray[23] + "%");// 费率

entity.setCreateDate(new Date());

wxTradeDetailDao.insert(entity);

最后,微信支付工具类下载链接(百度网盘):点击下载

后记

写完这篇博文给我最大的感悟就是:一定要仔细,仔细,再仔细的看官方文档。你需要的,文档都有,除了手把手教你以外你需要的肯定都有。

java 微信 下载对账单_java下载微信对账单,实现与微信实收对账和日清日结对账...相关推荐

  1. java 微商城开发_Java网上商城系统可以开微信商城吗

    开微信商城是现在非常火的一件事,我们身边有很多人都在开微信商城.而开发微信商城吗?MCmore小麦来为你解惑. Java网购商城系统和微信商城 网上商城系统是由很多种类型的,如java网上购物系统,p ...

  2. java旧版下载地址_Java下载 - 最新版、历史版本的官方下载地址

    Java下载 - 最新版.历史版本的官方下载地址 2015-07-31·WeaponX 4114 次浏览 ## 最新版下载 ### 最新版Java下载地址 [http://www.oracle.com ...

  3. java离线安装包_java下载

    Java 是由 Sun Microsystems 在 1995 年首先发布的编程语言和计算平台.有许多应用程序和 Web 站点只有在安装 Java 后才能正常工作,而且这样的应用程序和 Web 站点日 ...

  4. java文件名的编码格式_java下载文件名乱码解决方法详解

    java下载文件名乱码的方法:(推荐:java视频教程) 每个浏览器的编码不一样,火狐采用的是base64.ie和谷歌采用的是url编码: 所以我们在设置响应头的时候Content-Type getS ...

  5. java下载网页内容_java下载网页并读取内容

    下载回来怎么也得读取内容: package com.core.crawl; import java.io.IOException; import com.util.file.Files; public ...

  6. java文件下载并添加水印_Java下载文件加文字水印(Excel、PDF、图片)

    一.导出Excel加文字水印 方法:通过实现准备一个带有水印的Excel文件,然后将数据覆盖该文件然后输出. 比如我准备了如下的一个带水印的模板,我起名为water.xlsx(网上有如何给Excel加 ...

  7. java file 下载文件_java下载文件的几种方式

    public HttpServletResponse download(String path, HttpServletResponse response) { try { // path是指欲下载的 ...

  8. java 不生成文件下载_java 下载文件时怎么避免在服务器上生成文件

    Stringpath=request.getSession().getServletContext().getRealPath("/");//服务器路径Stringname=de0 ...

  9. java 中文转码_java 下载文件中文名称转码详解

    String userAgent = request.getHeader("User-Agent").toLowerCase(); if(userAgent.contains(&q ...

最新文章

  1. linux查看某个端口是被哪个进程占用的
  2. java 排序_Java中常见的排序算法有哪些?---选择排序
  3. 基于 RocketMQ Prometheus Exporter 打造定制化 DevOps 平台
  4. 中国殡葬行业投资战略建议与前景策略分析报告2022-2028年版
  5. oracle获取当前日期的前一天,判断两个日期是否相等
  6. [Automation] 自动化测试工具和测试框架大集合
  7. python地图散点图_在地图上叠加散点图(img)
  8. elasticsearch-head 安装
  9. python sklearn 绘制决策树模型的节点图
  10. Taro button点击切换选中状态
  11. 声明 styleable 与声明 attr 的区别
  12. JSP期末考试复习习题及答案
  13. php在线拍照代码,PHP+Javascript实现在线拍照功能实例_php技巧
  14. java tfidf_Hanlp分词实例:Java实现TFIDF算法
  15. opengl+openmesh重绘rabbit
  16. 苦逼的程序员幽默之对联恶搞
  17. 模拟器链接appium
  18. java 电商项目 搜索模块,SSH电商项目实战之十:商品类基本模块的搭建
  19. 记录:捕鱼达人开发笔记
  20. html中dt标签,html中dt标签的使用方法

热门文章

  1. 第03章 成人感冒不是大事,少往急诊跑
  2. 小程序 ESLint Prettier
  3. linux系统的电脑品牌有什么,主流Linux系统品牌推介
  4. 刘强东在美国出事了,老老实实的IT男,真的是有钱就变坏吗?
  5. 连续、离散、定序、定类、有序、分类等变量区别
  6. htslib/sam.h库使用说明
  7. 通过生成指标功能从非指标数据中分析趋势
  8. c语言程序二分法求解,C语言二分法查找算法(附带源码)
  9. 平板点餐linux系统下载,基于Linux的智能点餐系统.pdf
  10. 利用feko仿真的RCS成像结果