PAYATHON 2026

调用 alipay.open.auth.token.app 接口时返回 404

支付小周

结论

404 通常与 BizContent 里的授权参数无关,更可能是 DefaultAopClient 的网关地址配置有误。

DefaultAopClient 的第一个参数应填写支付宝开放平台的网关地址,不能填写具体 API 的方法路径。当前代码使用的是:

https://openapi.alipay.com/alipay.open.auth.token.app

这不是支付宝开放平台的标准网关路由,服务器会直接返回 HTTP 404。正确地址是:

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

AlipayOpenAuthTokenAppRequest 已经表示了 alipay.open.auth.token.app 方法。SDK 会将其作为 method 参数提交,无须再拼接到 URL 中。

正确的客户端配置

生产环境可以这样初始化:

IAopClient client = new DefaultAopClient(
    "https://openapi.alipay.com/gateway.do",
    aliPayInfo.AliPayAppId,
    aliPayInfo.AlipayMerchantPrivateKey,
    "json",
    "1.0",
    "RSA2",
    aliPayInfo.AlipayPublicKey,
    "UTF-8",
    false
);

如果使用沙箱环境,应配置对应的沙箱网关,例如:

https://openapi-sandbox.dl.alipaydev.com/gateway.do

沙箱网关、沙箱应用 ID 和沙箱密钥必须配套使用,不能与生产环境的配置混用。具体地址还需以当前支付宝开放平台文档及所用 SDK 的说明为准。

支付宝 .NET SDK 的不同版本可能提供不同的 DefaultAopClient 构造函数重载。请根据项目实际引用的 SDK 确认参数顺序,特别是以下参数:

  • serverUrl
  • appId
  • privateKey
  • format
  • version
  • signType
  • alipayPublicKey
  • charset

推荐的调用示例

可以通过对象序列化生成 BizContent,减少手工拼接 JSON 带来的转义和空值问题:

IAopClient client = new DefaultAopClient(
    "https://openapi.alipay.com/gateway.do",
    aliPayInfo.AliPayAppId,
    aliPayInfo.AlipayMerchantPrivateKey,
    "json",
    "1.0",
    "RSA2",
    aliPayInfo.AlipayPublicKey,
    "UTF-8",
    false
);

AlipayOpenAuthTokenAppRequest request =
    new AlipayOpenAuthTokenAppRequest();

if (!string.IsNullOrWhiteSpace(aliPayInfo.AppRefreshAuthToken))
{
    request.BizContent = JsonConvert.SerializeObject(new
    {
        grant_type = "refresh_token",
        refresh_token = aliPayInfo.AppRefreshAuthToken
    });
}
else
{
    request.BizContent = JsonConvert.SerializeObject(new
    {
        grant_type = "authorization_code",
        code = aliPayInfo.AppAuthCode
    });
}

AlipayOpenAuthTokenAppResponse response = client.Execute(request);

if (response == null)
{
    throw new InvalidOperationException("支付宝接口未返回有效响应。");
}

if (!response.IsError)
{
    string appAuthToken = response.AppAuthToken;
    string appRefreshToken = response.AppRefreshToken;
}
else
{
    string errorMessage =
        $"支付宝接口调用失败,Code={response.Code}," +
        $"SubCode={response.SubCode}," +
        $"Msg={response.Msg},SubMsg={response.SubMsg}";

    throw new InvalidOperationException(errorMessage);
}

示例中的 JsonConvert 来自 Newtonsoft.Json。如果项目使用 System.Text.Json,可以改为:

request.BizContent = JsonSerializer.Serialize(new
{
    grant_type = "authorization_code",
    code = aliPayInfo.AppAuthCode
});

原代码中还需要检查的问题

原来的条件判断是:

if (!string.IsNullOrEmpty(aliPayInfo.AppAuthToken))

但进入该分支后,代码实际使用的是:

aliPayInfo.AppRefreshAuthToken

刷新令牌时,应当判断 AppRefreshAuthToken:

if (!string.IsNullOrWhiteSpace(aliPayInfo.AppRefreshAuthToken))

否则可能出现 AppAuthToken 有值而 AppRefreshAuthToken 为空的情况。这个问题通常会让支付宝返回业务参数错误,而不是 HTTP 404,但同样需要修正。

授权码和刷新令牌也不能混用:

  • 首次换取应用授权令牌时,grant_type 为 authorization_code,并传入 code。
  • 刷新应用授权令牌时,grant_type 为 refresh_token,并传入 refresh_token。
  • 授权码一般有时效限制,通常不能重复使用。
  • 刷新令牌应使用接口返回的 app_refresh_token 对应值。

如何区分网关错误和业务错误

HTTP 404 表示请求没有正常进入支付宝开放平台的 API 网关处理流程,应先检查 URL、代理及网络转发配置。

网关地址修正后,如果签名、授权码或业务参数有误,通常会收到支付宝 API 的响应,其中包含:

code
msg
sub_code
sub_msg

这属于业务或签名错误,需要根据 sub_code 和 sub_msg 继续排查,而不是继续检查 HTTP 路由。

如果改为 /gateway.do 后仍返回 404,可以依次检查:

  1. 实际运行时的 serverUrl 是否被配置文件或环境变量覆盖。
  2. 反向代理、网关或抓包代理是否改写了请求地址。
  3. 生产环境与沙箱环境是否混用。
  4. SDK 版本对应的 DefaultAopClient 构造函数参数顺序是否正确。
  5. 请求日志中的最终 URL 是否确实指向 /gateway.do。
  6. 是否绕过 SDK 手工拼接了 API 方法路径。

本次需要修改的是网关地址:将具体接口路径替换为统一网关地址,再由 SDK 通过 AlipayOpenAuthTokenAppRequest 提交 alipay.open.auth.token.app 方法。

备注:内容仅供参考。