PAYATHON 2026

第三方应用如何获取服务商支付宝代付成功账单订单号

支付小周

结论

第三方应用通常无法通过 alipay.trade.query,按“支付成功(代付成功)”状态批量读取服务商的支付宝账单。可以按以下流程处理:

  1. 服务商账号授权第三方应用访问账单数据;
  2. 调用 alipay.data.dataservice.bill.downloadurl.query,获取指定日期的账单下载地址;
  3. 下载并解压账单文件;
  4. 根据账单中的业务类型、交易状态或备注,筛选“代付成功”记录;
  5. 从相应字段中提取支付宝订单号、商户订单号等数据。

“支付成功(代付成功)”可能只是支付宝账单页面上的展示文案,不一定会原样出现在下载文件中。具体如何筛选,应以实际账单的字段名称和值为准。

为什么不能直接查询

alipay.trade.query 是单笔交易查询接口。调用时必须提供支付宝交易号 trade_no 或商户订单号 out_trade_no,不能按日期和交易状态遍历服务商账单,因此无法用它“先找出所有代付成功的订单号”。

账单下载接口只返回账单文件的下载地址,不直接返回账单明细。第三方应用仍需自行下载、解压、解析并筛选文件。

如果业务系统在发起代付时已经保存业务请求号或商户订单号,应优先通过本地订单记录建立对应关系。账单适合用于对账和补偿,不应作为唯一的实时订单查询来源。

前置条件

调用接口前,需要确认:

  • 第三方应用已经创建,并完成支付宝开放平台应用配置;
  • 服务商账号已经授权该应用;
  • 应用具有相应的账单查询权限;
  • 请求中传入服务商授权后取得的 app_auth_token;
  • 使用正确的支付宝应用私钥、应用公钥证书或支付宝公钥;
  • 已经确认目标账单对应的 bill_type。

bill_type 的可选值取决于产品、账号和接口权限。常见类型包括交易账单,但“代付”记录具体属于哪类账单,需要查看开放平台接口文档和服务商后台实际可下载的账单,不能只根据页面上的展示文案判断。

获取账单的基本流程

1. 获取服务商授权令牌

第三方应用需要通过支付宝应用授权流程,取得服务商对应的 app_auth_token。

该令牌允许第三方应用以服务商身份访问已授权的数据。不要将它与应用自身的 auth_token、用户登录令牌或其他商户的授权令牌混用。

2. 请求账单下载地址

通过以下接口查询指定日期的账单:

alipay.data.dataservice.bill.downloadurl.query

Java SDK 示例:

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

public class AlipayBillDownloader {

    public static void main(String[] args) throws Exception {
        AlipayClient alipayClient = new DefaultAlipayClient(
            "https://openapi.alipay.com/gateway.do",
            "YOUR_APP_ID",
            "YOUR_APP_PRIVATE_KEY",
            "json",
            "UTF-8",
            "ALIPAY_PUBLIC_KEY",
            "RSA2"
        );

        AlipayDataDataserviceBillDownloadurlQueryRequest request =
            new AlipayDataDataserviceBillDownloadurlQueryRequest();

        request.setBizContent("""
            {
              "bill_type": "trade",
              "bill_date": "2026-09-07"
            }
            """);

        AlipayDataDataserviceBillDownloadurlQueryResponse response =
            alipayClient.execute(request, null, "SERVICE_PROVIDER_APP_AUTH_TOKEN");

        if (!response.isSuccess()) {
            throw new IllegalStateException(
                "获取账单失败,code=" + response.getCode()
                    + ", subCode=" + response.getSubCode()
                    + ", subMsg=" + response.getSubMsg()
            );
        }

        String downloadUrl = response.getBillDownloadUrl();
        System.out.println(downloadUrl);
    }
}

示例中的 bill_type: "trade" 是常见的交易账单类型。如果目标代付记录不在这类账单中,应根据实际产品文档调整,不能直接将其固定为 trade。

沙箱环境、证书模式和不同版本 SDK 的客户端初始化方式可能有所不同,应按照项目当前使用的支付宝 SDK 进行配置。

3. 下载并解压账单

接口调用成功后,通常会返回一个临时下载地址。应用应及时下载文件,并按照响应内容处理压缩包。

下载逻辑示例:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;

public class BillFileClient {

    public static Path download(String downloadUrl, Path outputFile)
        throws Exception {

        HttpClient client = HttpClient.newHttpClient();

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(downloadUrl))
            .GET()
            .build();

        HttpResponse<byte[]> response = client.send(
            request,
            HttpResponse.BodyHandlers.ofByteArray()
        );

        if (response.statusCode() != 200) {
            throw new IllegalStateException(
                "账单下载失败,HTTP status=" + response.statusCode()
            );
        }

        Files.write(outputFile, response.body());
        return outputFile;
    }
}

下载地址通常有有效期,不适合长期保存后再使用。下载失败时,应重新调用账单接口获取新地址。

4. 解析并筛选代付成功记录

解压账单后,应先读取表头,不要依赖固定的列序号。账单类型或格式不同,包含的字段也可能不同。

可以按以下逻辑处理:

读取账单文件
  → 根据表头建立字段名和列序号的映射
  → 跳过说明行、汇总行和空行
  → 判断业务类型是否属于目标代付业务
  → 判断状态是否为成功
  → 提取支付宝订单号和商户订单号
  → 保存或返回结构化结果

返回数据可以统一整理为:

[
  {
    "alipayOrderNo": "支付宝账单中的订单号",
    "merchantOrderNo": "业务系统或商户订单号",
    "status": "SUCCESS",
    "billDate": "2026-09-07"
  }
]

其中,alipayOrderNo 和 merchantOrderNo 是应用内部定义的返回字段,并非账单文件的正式列名。解析时必须按照实际账单表头完成字段映射。

单笔订单的进一步核验

取得账单中的订单号后,如果相应支付宝产品提供单笔查询接口,可以继续调用该接口核验状态。

普通支付交易可能使用:

alipay.trade.query

示例:

import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;

AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
request.setBizContent("""
    {
      "trade_no": "ALIPAY_TRADE_NO"
    }
    """);

AlipayTradeQueryResponse response =
    alipayClient.execute(
        request,
        null,
        "SERVICE_PROVIDER_APP_AUTH_TOKEN"
    );

if (!response.isSuccess()) {
    throw new IllegalStateException(
        "交易查询失败,code=" + response.getCode()
            + ", subCode=" + response.getSubCode()
            + ", subMsg=" + response.getSubMsg()
    );
}

代付、资金转账和普通支付可能属于不同的产品体系,不一定都支持 alipay.trade.query。应根据最初使用的代付接口,确定对应的查询接口和订单号类型。

注意事项

  • 必须使用被查询服务商对应的 app_auth_token,否则可能查到错误主体的数据,或者因无权限而调用失败。
  • 账单一般按自然日生成,当日账单可能尚未生成,数据也可能还不完整。
  • 页面中的“订单号”可能是支付宝订单号、商户订单号、业务请求号或资金流水号,接入前需要明确实际要获取哪一种。
  • 不要根据页面展示状态直接硬编码解析规则。应先取得真实账单样例,确认业务类型字段、状态字段及成功状态的实际取值。
  • 账单文件可能包含标题、说明、明细和汇总等不同类型的行,解析时不能将所有行都作为交易数据处理。
  • CSV 内容可能含有逗号、引号或换行,应使用成熟的 CSV 解析库,不建议直接调用 String.split(",")。
  • 对账任务需要支持幂等处理。可以使用“账单日期 + 订单号”去重,但最终的唯一键仍应根据实际账单字段确定。
  • 不要在日志中完整输出 app_auth_token、私钥、账单下载地址,或包含敏感信息的账单内容。
  • 如果接口返回无权限、账单不存在或下载地址为空,应检查应用授权范围、账单日期、账单类型,以及服务商账号中是否确实存在相应记录。

备注:内容仅供参考。