支付宝对账单功能开发

本文详细介绍了如何使用支付宝开放平台API获取并解析交易账单。首先,通过调用指定接口获取ZIP格式的账单下载链接;然后,不解压直接读取CSV文件内容,解析明细数据并存储到自定义账单实体中;最后,展示了账单实体的结构。整个过程实现了高效的数据处理,避免了文件保存和解压的额外步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

支付宝开放平台API

https://opendocs.alipay.com/apis/api_15/alipay.data.dataservice.bill.downloadurl.query

请求API下载账单解析

  • 支付宝下载对账单,不保存文件、不解压直接解析。
  • 该需求实现的是(trade)支付宝交易账单的业务账单。

 

流程

1 、调用支付宝接口, 获取zip账单下载地址

//从支付宝平台抽取对账单数据
    public Object checkAlipay(String qDate) throws AlipayApiException {
        BaseResult result = new BaseResult();
        //初始化支付宝客户端参数
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do", Constants.ALI_APP_ID,
                Constants.ALI_PRIVATE_KEY, "json", "utf-8",
                Constants.ALI_DEV_PLAT_PUBLIC_KEY);
        //创建API对应的request类
        AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest();
        JSONObject bizContent = new JSONObject();
        //设置业务参数
        bizContent.put("bill_type", "trade");
        bizContent.put("bill_date", qDate);
        request.setBizContent(bizContent.toString());
        //请求查询对账单下载地址接口
        AlipayDataDataserviceBillDownloadurlQueryResponse response = alipayClient.certificateExecute(request);
        //查询账单为空
        if (StringUtils.isEmpty(response.getBillDownloadUrl())) {
            result.setMessage(response.getMsg());
            result.setCode(Integer.valueOf(response.getCode()));
            return ResponseEntity.ok(result);
        }
        String urlStr = response.getBillDownloadUrl();
        log.info("==================支付宝返回文件下载地址:" + urlStr);

2、解析文件获取数据(重点)

  • 这里只解析明细数据,没有做汇总数据的解析。
  • 文件不做保存、不做解压直接解析获取数据。
//解析账单文件
    private List<AlipayBillAcount> downBill(String urlStr) {
        List<AlipayBillAcount> allBillInfos = new ArrayList<>();
        HttpURLConnection conn = null;
        ZipInputStream in = null;
        BufferedReader br = null;
        try {
            URL url = new URL(urlStr);
            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();
                log.info("对账单解析,输出文件名称:{}", fileName);
                if (!Objects.isNull(fileName) && fileName.indexOf(".") != -1 && !fileName.contains("汇总")) {
                    String line;
                    int i = 0;
                    // 按行读取数据
                    while ((line = br.readLine()) != null) {
                        if (!line.startsWith("#")) {
                            log.info("解析数据:{}", line);
                            if (i > 0) {
                                String[] lines = line.split(",", -1);
                                AlipayBillAcount alipayBillAcount = AlipayBillAcount.builder()
                                        .tradeNo(lines[0].trim())
                                        .outTradeNo(lines[1].trim())
                                        .businessType(lines[2].trim())
                                        .tradeName(lines[3].trim())
                                        .createTime(lines[4].trim())
                                        .date(lines[5].trim())
                                        .storeNumber(lines[6].trim())
                                        .storeName(lines[7].trim())
                                        .operator(lines[8].trim())
                                        .terminalNumber(lines[9].trim())
                                        .clientAccount(lines[10].trim())
                                        .orderAmount(new BigDecimal(lines[11].trim()))
                                        .realAmount(new BigDecimal(lines[12].trim()))
                                        .redPaperAmount(new BigDecimal(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(new BigDecimal(lines[22].trim()))
                                        .fenrun(lines[23].trim()).build();
                                allBillInfos.add(alipayBillAcount);
                            }
                            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 allBillInfos;
    }

 3、账单实体

@Data
@SuperBuilder
public class AlipayBillAcount {
    /**
     * 支付宝交易号
     */

    private String tradeNo;

    /**
     * 商户订单号
     */

    private String outTradeNo;

    /**
     * 业务类型
     */

    private String businessType;

    /**
     * 商品名称
     */

    private String tradeName;

    /**
     * 创建时间
     */

    private String createTime;

    /**
     * 完成时间(交易时间)
     */

    private String date;


    /**
     * 门店编号
     */

    private String storeNumber;

    /**
     * 门店名称
     */

    private String storeName;

    /**
     * 操作员
     */

    private String operator;

    /**
     * 终端号
     */

    private String terminalNumber;

    /**
     * 对方账户
     */

    private String clientAccount;

    /**
     * 订单金额(元)
     */

    private BigDecimal orderAmount;

    /**
     * 商家实收(元)
     */

    private BigDecimal realAmount;

    /**
     * 支付宝红包(元)
     */

    private BigDecimal 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 BigDecimal serviceFee;

    /**
     * 分润(元)
     */

    private String fenrun;

    /**
     * 备注
     */

    private String remark;
}

4、业务明细账单模板

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值