1.支付宝官网支付宝账单获取
对接支付宝官方文档api
https://opendocs.alipay.com/apis/api_15/alipay.data.dataservice.bill.downloadurl.query
支付宝官方提供的接口,返回的数据是对账文件的下载地址,根据官网描述,用户需要在获取到下载地址30秒内完成对账单的下载,否则会过期无效。
但在实际的业务中,需要获取到支付宝对账文件的数据,这里需要下载对账文件并进行解析。
2.对账数据解析
我这里做了一个接口,api如下:
请求地址:http://实际域名/aggpay/data/ali_DownloadBill
请求报文:
{
"tradeCode":"aliDownloadBill",
"tradeParam":{
"billtype":"trade",
"billdate":"2020-09-17"
},
"sign":"10A89A6A905327134F192BD8A23F0F1D"
}
返回报文:
{
"returnCode": "0000",
"aliBillData": [
{
"tradeNo": "2020091722001492631413739727",
"outTradeNo": "20200917100243655405",
"businessType": "交易",
"tradeName": "THESUBJECT",
"createTime": "2020-09-17 10:05:51",
"finishTime": "2020-09-17 10:06:02",
"storeNumber": "",
"storeName": "",
"operator": "",
"terminalNumber": "",
"clientAccount": "**莹(106***@qq.com)",
"orderAmount": "24.90",
"realAmount": "24.90",
"redPaperAmount": "0.00",
"jifenbaoAmount": "0.00",
"zfbDiscountAmount": "0.00",
"merchantOffersAmount": "0.00",
"couponName": "",
"merchantRedAmount": "0.00",
"cardAmount": "0.00",
"refundNo": "",
"serviceFee": "0.00",
"fenrun": "0.00",
"remark": null,
"couponWriteOffAmount": "0.00"
},
{
"tradeNo": "2020091722001492631413363129",
"outTradeNo": "20200917121605266207",
"businessType": "交易",
"tradeName": "处方缴费",
"createTime": "2020-09-17 12:16:17",
"finishTime": "2020-09-17 12:16:41",
"storeNumber": "",
"storeName": "",
"operator": "",
"terminalNumber": "",
"clientAccount": "**莹(106***@qq.com)",
"orderAmount": "0.02",
"realAmount": "0.02",
"redPaperAmount": "0.00",
"jifenbaoAmount": "0.00",
"zfbDiscountAmount": "0.00",
"merchantOffersAmount": "0.00",
"couponName": "",
"merchantRedAmount": "0.00",
"cardAmount": "0.00",
"refundNo": "",
"serviceFee": "0.00",
"fenrun": "0.00",
"remark": null,
"couponWriteOffAmount": "0.00"
}
],
"returnMsg": "对账单获取成功"
}
3.代码
接口入口
/**
* 支付宝下载对账单接口
*
* @param request
* @param response
* @throws Exception
*/
@RequestMapping(value = "/ali_DownloadBill", method = RequestMethod.POST)
public Map<String,Object> aliDownloadBill (HttpServletRequest request, HttpServletResponse response, @RequestBody JSONObject jsonparam) throws Exception {
logger.info ("----------layer downloadbill----------");
logger.info ("接收退款请求 jsonparam = " + jsonparam);
Map<String,Object> resultmap = new HashMap <> ();
Map<String,Object>tradeParamMap = (Map <String, Object>) jsonparam.get ("tradeParam");
String billtype = (String) tradeParamMap.get ("billtype");
String billdate = (String) tradeParamMap.get ("billdate");
String sign = (String) jsonparam.get ("sign");
//验证签名
Map<String,Object> signMap = new HashMap <> ();
signMap.put ("billtype",billtype);
signMap.put ("billdate",billdate);
String md5key = (String) YH_SysContants.yhConstantsmap.get ("ymfmd5key");
if (!ToolsUtil.vertifysign (signMap, sign, md5key)) {
resultmap.put ("returnCode","AAAA");
resultmap.put ("returnInfo","签名失败");
return resultmap;
}
AlipayDataDataserviceBillDownloadurlQueryResponse downloadbillresp = aliPayService.Ali_downloadbill (billtype,billdate);
logger.info ("body=" + downloadbillresp.getBody ());
if (downloadbillresp.isSuccess ()) {
logger.info ("------------------ali获取对账单成功------------------");
String bill_download_url = downloadbillresp.getBillDownloadUrl ();
//解析对账文件
List billInfos = downloadBill(bill_download_url);
logger.info ("解析后对账文件: " + billInfos);
resultmap.put ("returnCode","0000");
resultmap.put ("returnMsg","对账单获取成功");
resultmap.put ("aliBillData",billInfos);
} else {
logger.info ("------------------ali获取对账单成功------------------");
resultmap.put ("returnCode","AAAA");
resultmap.put ("returnMsg","对账单获取失败");
}
return resultmap;
}
public AlipayDataDataserviceBillDownloadurlQueryResponse Ali_downloadbill (String billtype, String billdate) throws Exception {
// TODO Auto-generated method stub
String appid = ALIPayConstants.yhConstantsmap.get ("aliappid").toString ();
AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest ();
Map<String, Object> requestmap = new HashMap<String, Object>();
requestmap.put("bill_type", billtype);
requestmap.put("bill_date", billdate);
String jsonStr = AliPayUtil.aliMapToJson(requestmap);
request.setBizContent(jsonStr);
AlipayDataDataserviceBillDownloadurlQueryResponse response = alirequest.RequestAliPayDownloadbill(request, appid);
logger.info("Ali_Downloadbill response = " + response);
return response;
}
支付宝获取对账文件
public AlipayDataDataserviceBillDownloadurlQueryResponse RequestAliPayDownloadbill(AlipayDataDataserviceBillDownloadurlQueryRequest req, String appid) {
AlipayDataDataserviceBillDownloadurlQueryResponse response = null;
AlipayClient alipayClient = new DefaultAlipayClient((String) ALIPayConstants.yhConstantsmap.get ("URL"), appid,
(String) ALIPayConstants.yhConstantsmap.get ("APP_PRIVATE_KEY"), (String) ALIPayConstants.yhConstantsmap.get ("FORMAT"),
(String) ALIPayConstants.yhConstantsmap.get ("CHARSET"),
(String) ALIPayConstants.yhConstantsmap.get ("ALIPAY_PUBLIC_KEY"), (String) ALIPayConstants.yhConstantsmap.get ("SIGNTYPE"));
try {
response = alipayClient.execute(req);
} catch (AlipayApiException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response;
}
下载并解析对账文件
/**
* 下载并解析对账文件
* @param downloadUrl
* @return
*/
public List<BillInfo> downloadBill(String downloadUrl) {
List<BillInfo> aliBillInfos = new ArrayList<>();
//Map<String,Object> aliBillInfos = new HashMap <> ();
HttpURLConnection conn = null;
ZipInputStream in = null;
BufferedReader br = null;
try {
//get请求
//URL url= new URL(null, downloadUrl, new sun.net.www.protocol.https.Handler());
URL url = new URL (downloadUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
conn.connect();
// 不解压直接读取,加上GBK解决乱码问题
in = new ZipInputStream(conn.getInputStream(), Charset.forName("GBK"));
br = new BufferedReader(new InputStreamReader(in, "GBK"));
ZipEntry zipFile;
// 循环读取zip中的cvs文件,无法使用jdk自带,因为文件名中有中文
while ((zipFile = in.getNextEntry()) != null) {
if (zipFile.isDirectory()) {
// 目录不处理
}
// 获得cvs名字,检测文件是否存在
String fileName = zipFile.getName();
logger.info("对账单解析,输出文件名称:{}", fileName);
if (!Objects.isNull(fileName) && fileName.indexOf(".") != -1 && !fileName.contains("汇总")) {
String line;
int i = 0;
// 按行读取数据
while ((line = br.readLine()) != null) {
if (!line.startsWith("#")) {
logger.info("解析数据:{}", line);
if (i > 0) {
String[] lines = line.split(",",-1);
BillInfo aliBillInfo = BillInfo.builder()
.tradeNo(lines[0].trim())
.outTradeNo(lines[1].trim())
.businessType(lines[2].trim())
.tradeName(lines[3].trim())
.createTime(lines[4].trim())
.finishTime(lines[5].trim())
.storeNumber(lines[6].trim())
.storeName(lines[7].trim())
.operator(lines[8].trim())
.terminalNumber(lines[9].trim())
.clientAccount(lines[10].trim())
.orderAmount(lines[11].trim())
.realAmount(lines[12].trim())
.redPaperAmount(lines[13].trim())
.jifenbaoAmount(lines[14].trim())
.zfbDiscountAmount(lines[15].trim())
.merchantOffersAmount(lines[16].trim())
.CouponWriteOffAmount(lines[17].trim())
.couponName(lines[18].trim())
.merchantRedAmount(lines[19].trim())
.cardAmount(lines[20].trim())
.refundNo(lines[21].trim())
.serviceFee(lines[22].trim())
.fenrun(lines[23].trim())
.build();
aliBillInfos.add(aliBillInfo);
}
i++;
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) br.close();
if (in != null) in.close();
if (conn != null) conn.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
return aliBillInfos;
}
实体类
package com.ggeit.pay.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.io.Serializable;
@Data
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
public class BillInfo implements Serializable {
private static final long serialVersionUID = -3947062662460225647L;
/**
* 支付宝交易号
*/
private String tradeNo;
/**
* 商户订单号
*/
private String outTradeNo;
/**
* 业务类型
*/
private String businessType;
/**
* 商品名称
*/
private String tradeName;
/**
* 创建时间
*/
private String createTime;
/**
* 完成时间
*/
private String finishTime;
/**
* 门店编号
*/
private String storeNumber;
/**
* 门店名称
*/
private String storeName;
/**
* 操作员
*/
private String operator;
/**
* 终端号
*/
private String terminalNumber;
/**
* 对方账户
*/
private String clientAccount;
/**
* 订单金额(元)
*/
private String orderAmount;
/**
* 商家实收(元)
*/
private String realAmount;
/**
* 支付宝红包(元)
*/
private String redPaperAmount;
/**
* 集分宝(元)
*/
private String jifenbaoAmount;
/**
* 支付宝优惠(元)
*/
private String zfbDiscountAmount;
/**
* 商家优惠(元)
*/
private String merchantOffersAmount;
/**
* 券核销金额(元)
*/
private String CouponWriteOffAmount;
/**
* 券名称
*/
private String couponName;
/**
* 商家红包消费金额(元)
*/
private String merchantRedAmount;
/**
* 卡消费金额(元)
*/
private String cardAmount;
/**
* 退款批次号/请求号
*/
private String refundNo;
/**
* 服务费(元)
*/
private String serviceFee;
/**
* 分润(元)
*/
private String fenrun;
/**
* 备注
*/
private String remark;
}