PAYATHON 2026

沙箱环境下载交易账单报 UnknownHostException

支付小周

结论

UnknownHostException 表示当前网络无法通过 DNS 解析域名 dwbillcenter-2-1-1.daily.alipay.net。

这个域名包含 daily.alipay.net,通常是支付宝日常或沙箱环境使用的内部域名,不是对公网开放的账单下载域名。关闭防火墙、切换浏览器或反复重试一般解决不了这个问题。错误也与 CSV 文件、URL 参数或浏览器兼容性无关。

原因分析

Java 访问下载地址前,会先将域名解析为 IP 地址。目标域名无法通过 DNS 解析时,就会抛出:

java.net.UnknownHostException: dwbillcenter-2-1-1.daily.alipay.net

可以使用下面的命令检查 DNS 解析结果:

nslookup dwbillcenter-2-1-1.daily.alipay.net

如果结果为 NXDOMAIN、Non-existent domain 或提示找不到主机,说明请求还没有连接到账单服务器,在域名解析阶段就已经失败。

这个地址还需要注意两点:

  • daily.alipay.net 不是常规的公网生产域名;
  • URL 中含有 timestamp 和 token,通常是临时下载凭证。即使域名可以访问,链接也可能已经过期。

因此,修改浏览器设置、关闭防火墙或持续重试都不是合适的处理方式。

解决步骤

1. 不要直接使用该沙箱下载地址

不要把 daily.alipay.net 的地址写入业务代码,也不要将它作为生产环境的账单下载入口。即使该地址由沙箱接口返回,也不能说明公网客户端一定可以访问。

2. 确认沙箱是否支持账单文件下载

沙箱主要用于接口调用和交易流程联调,部分外围能力可能没有完整的公网下载链路。当前账单类型是否支持下载,应以支付宝开放平台最新的沙箱能力说明为准。

如果沙箱明确不支持账单文件下载,可以在本地准备一份结构与正式账单一致的测试文件,用来验证解压、解析、对账及异常处理逻辑。

3. 在正式环境中重新获取下载地址

进入生产联调后,应调用正式环境的账单下载接口获取新地址。以 alipay.data.dataservice.bill.downloadurl.query 为例,需要确认:

  • 使用的是生产网关;
  • 应用、商户账号和密钥均属于生产环境;
  • 对应账单日期的账单已经生成;
  • 获取地址后及时下载,不要长期保存临时 URL。

生产网关通常配置为:

https://openapi.alipay.com/gateway.do

沙箱网关通常配置为:

https://openapi.alipaydev.com/gateway.do

不要混用沙箱账号、生产网关、生产密钥或生产商户身份。

4. 沙箱持续返回内部域名时,提交平台排查

如果沙箱账单接口一直返回 daily.alipay.net 地址,应保存以下信息,并提交给支付宝开放平台技术支持排查:

  • 调用的 API 名称;
  • 请求时间;
  • app_id;
  • 账单日期和账单类型;
  • 接口响应中的 code、sub_code、msg、sub_msg;
  • 返回的下载域名;
  • 支付宝侧请求流水号或 trace 信息。

分享日志前,请删除或遮蔽 token、签名、私钥及其他敏感字段。

Java 处理示例

业务代码应分别处理“域名无法解析”和“HTTP 下载失败”,不要把 UnknownHostException 当作普通的可重试错误:

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.UnknownHostException;

public class BillDownloader {

    public static void download(String downloadUrl) throws IOException {
        URI uri = URI.create(downloadUrl);

        if (uri.getHost() == null) {
            throw new IllegalArgumentException("Invalid bill download URL");
        }

        if (uri.getHost().endsWith(".daily.alipay.net")) {
            throw new IllegalStateException(
                "The sandbox returned a non-public daily.alipay.net download URL"
            );
        }

        HttpURLConnection connection =
            (HttpURLConnection) uri.toURL().openConnection();

        connection.setRequestMethod("GET");
        connection.setConnectTimeout(10_000);
        connection.setReadTimeout(30_000);
        connection.setInstanceFollowRedirects(true);

        try {
            int status = connection.getResponseCode();
            if (status != HttpURLConnection.HTTP_OK) {
                throw new IOException("Bill download failed, HTTP status: " + status);
            }

            // 在此读取输入流并保存账单文件。
        } catch (UnknownHostException e) {
            throw new IOException(
                "Cannot resolve bill download host: " + uri.getHost(), e
            );
        } finally {
            connection.disconnect();
        }
    }
}

注意事项

  • 不要在 hosts 文件中随意为 daily.alipay.net 配置从网上找到的 IP。内部服务可能依赖专用网络、路由和鉴权,强行绑定 IP 通常没有效果,还可能造成安全风险。
  • 不要在日志、工单或公开页面中泄露完整的下载 URL。示例地址中的 token 属于敏感信息。如果链接仍然有效,建议重新获取。
  • UnknownHostException 与 HTTP 403、404、500 的含义不同。前者表示客户端没有找到目标服务器,后者表示服务器已经收到请求。
  • 下载 URL 通常有有效期。生产环境获取地址后应立即下载,链接过期后需重新调用账单下载接口。
  • 自动重试适合处理临时网络抖动。域名如果始终无法解析,继续重试没有意义,应停止重试并检查运行环境和接口返回的地址。

备注:内容仅供参考。