PAYATHON 2026

支付宝月账单下载失败,日账单可正常下载

支付老李

结论

日账单可以正常下载,但月账单返回 isp.unknown_error,一般表示支付宝生成月度账单文件时出现了异常。常见原因是当月交易数据量较大,导致月账单汇总或生成失败。

遇到这种情况,可以按天调用 AlipayDataDataserviceBillDownloadurlQueryRequest,下载该月每天的账单,再由业务系统合并。不要反复请求同一份月账单,这类错误通常无法通过网络重试解决。

原因说明

月账单不是把已有的日账单下载地址合并后直接返回。支付宝需要在服务端生成整月的账单文件。如果整月数据量较大、生成过程超时或后台任务异常,接口可能返回:

{
  "msg": "Business Failed",
  "code": "40004",
  "sub_msg": "系统异常,请稍后再试。",
  "sub_code": "isp.unknown_error"
}

isp.unknown_error 是通用的服务端异常码,仅凭这个错误码无法判断具体的内部故障。如果日账单一直可以下载,只有某个月的月账单失败,应先排查月度数据量和月账单生成问题,而不是应用密钥、签名算法或接口权限。

如果所有月份都无法下载,则需要检查 bill_date 的格式。月账单使用 yyyy-MM,日账单使用 yyyy-MM-dd。

解决步骤

1. 检查月账单日期格式

月账单请求示例:

AlipayDataDataserviceBillDownloadurlQueryRequest request =
        new AlipayDataDataserviceBillDownloadurlQueryRequest();

request.setBizContent("{"
        + "\"bill_type\":\"trade\","
        + "\"bill_date\":\"2026-08\""
        + "}");

不要把月账单日期写成当月第一天:

{
  "bill_type": "trade",
  "bill_date": "2026-08-01"
}

这种格式请求的是日账单,不是月账单。

2. 确认账单月份已经结束

如果请求的是当前月份,月账单可能还没有生成完成。可以改为下载已经结束月份的账单,当前月份的数据则直接按日获取。

3. 改为逐日下载

如果月账单持续失败,可以把目标月份拆成每天的请求:

import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;

import java.time.LocalDate;
import java.time.YearMonth;

public class AlipayDailyBillDownloader {

    public static void queryDailyBills(
            AlipayClient alipayClient,
            YearMonth month) throws Exception {

        LocalDate date = month.atDay(1);
        LocalDate endDate = month.atEndOfMonth();

        while (!date.isAfter(endDate)) {
            AlipayDataDataserviceBillDownloadurlQueryRequest request =
                    new AlipayDataDataserviceBillDownloadurlQueryRequest();

            request.setBizContent("{"
                    + "\"bill_type\":\"trade\","
                    + "\"bill_date\":\"" + date + "\""
                    + "}");

            AlipayDataDataserviceBillDownloadurlQueryResponse response =
                    alipayClient.execute(request);

            if (response.isSuccess()) {
                String downloadUrl = response.getBillDownloadUrl();
                System.out.println(date + " => " + downloadUrl);

                // 使用 downloadUrl 下载 ZIP 文件。
                // 下载完成后解压、解析,并按业务主键去重入库。
            } else {
                System.err.println(
                        date + " 下载失败:"
                                + response.getCode() + ", "
                                + response.getSubCode() + ", "
                                + response.getSubMsg()
                );
            }

            date = date.plusDays(1);
        }
    }
}

生产环境中不要直接拼接来源不可信的 JSON 内容。以上代码只用于说明如何按日遍历并调用接口。

4. 合并日账单数据

下载每天的 ZIP 文件后,可以按以下顺序处理:

  1. 解压每日账单文件。
  2. 跳过文件说明、汇总行等非明细内容。
  3. 统一字段和字符编码。
  4. 根据支付宝交易号、商户订单号等业务标识去重。
  5. 将数据合并写入数据库,或生成内部月度账单。
  6. 单独记录下载失败的日期,并进行有限次数的重试。

文件结构应以实际下载的账单内容为准,不要假定所有 bill_type 都使用完全相同的字段。

注意事项

  • bill_download_url 通常有时效限制。获取地址后应尽快下载,不要长期保存或反复使用。
  • 日账单下载成功,只能说明接口权限、签名和基础配置大体正常,不能证明月账单文件已经生成。
  • 不要无限重试 isp.unknown_error,应限制重试次数并设置退避间隔。
  • 如果某个月每天的账单都能下载,但该月的月账单一直失败,按日下载后合并通常更稳妥。
  • 如果多个数据量较小的历史月份也全部失败,需要继续核对 bill_date、bill_type、应用授权关系,以及支付宝接口返回的完整请求日志。
  • 如需支付宝协助确认内部原因,应提供应用 ID、账单类型、账单月份、请求时间和接口响应中的 trace 信息。不要在公开渠道提交应用私钥、支付宝公钥或完整签名内容。

备注:内容仅供参考。