第三方应用如何获取服务商支付宝代付成功账单订单号
结论
第三方应用通常无法通过 alipay.trade.query,按“支付成功(代付成功)”状态批量读取服务商的支付宝账单。可以按以下流程处理:
- 服务商账号授权第三方应用访问账单数据;
- 调用
alipay.data.dataservice.bill.downloadurl.query,获取指定日期的账单下载地址; - 下载并解压账单文件;
- 根据账单中的业务类型、交易状态或备注,筛选“代付成功”记录;
- 从相应字段中提取支付宝订单号、商户订单号等数据。
“支付成功(代付成功)”可能只是支付宝账单页面上的展示文案,不一定会原样出现在下载文件中。具体如何筛选,应以实际账单的字段名称和值为准。
为什么不能直接查询
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、私钥、账单下载地址,或包含敏感信息的账单内容。 - 如果接口返回无权限、账单不存在或下载地址为空,应检查应用授权范围、账单日期、账单类型,以及服务商账号中是否确实存在相应记录。
备注:内容仅供参考。
