JeffreySu/WeiXinMPSDK · error · TenpayApiRequestException

下载微信支付文件失败,HTTP ( ):

Error message

下载微信支付文件失败,HTTP {(int)response.StatusCode} ({response.ReasonPhrase}):{errorBody}

What it means

TenPayDownloadHelper.DownloadAndVerifyAsync downloads WeChat Pay files (e.g. bills, certificates). If the HTTP response is not a success status code, it reads the error body and throws TenpayApiRequestException including status code, reason phrase, and the WeChat error payload.

Solutions

  1. Inspect the included errorBody/status code to fix the underlying request (correct URL, bill date, permissions).
  2. Ensure the download_url is exactly the one returned by WeChat Pay APIs (don't re-construct it).
  3. Retry after fixing auth (certificates, API v3 key) if the status is 401/403.
  4. Handle transient 5xx with a retry with backoff.

Example fix

// before
await helper.DownloadAndVerifyAsync(badUrl, stream, "SHA1", hash, timeOut);
// after
if (!string.IsNullOrEmpty(downloadUrlFromApi))
    await helper.DownloadAndVerifyAsync(downloadUrlFromApi, stream, "SHA1", hash, timeOut);
Defensive patterns

Strategy: try-catch

Validate before calling

if (string.IsNullOrEmpty(downloadUrl) || !downloadUrl.StartsWith("https://"))
    throw new InvalidOperationException("download_url 无效");

Try / catch

try { await helper.DownloadAndVerifyAsync(url, stream, "SHA1", hash, timeOut); }
catch (TenpayApiRequestException ex)
{ logger.Error(ex, "下载失败: {0}", ex.Message); /* inspect status/errorBody */ }

Prevention

When it happens

Trigger: Calling the download API with a wrong download_url, expired/invalid bill date, insufficient permissions, or an invalid signature — any non-2xx response from the WeChat Pay file download endpoint.

Common situations: Downloading daily bills for a date with no data (HTTP 400/403/404), using a URL returned by another API incorrectly, or auth/certificate misconfiguration causing 401/403.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/e35e736e94154d17. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Helpers/TenPayDownloadHelper.cs:78

            CancellationToken cancellationToken)
        {
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            using (var response = await request.GetHttpResponseMessageAsync(
                url,
                null,
                cancellationToken,
                HttpCompletionOption.ResponseHeadersRead,
                timeOut,
                ApiRequestMethod.GET).ConfigureAwait(false))
            {
                if (!response.IsSuccessStatusCode)
                {
                    var errorBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                    throw new TenpayApiRequestException(
                        $"下载微信支付文件失败,HTTP {(int)response.StatusCode} ({response.ReasonPhrase}):{errorBody}");
                }

                if (destination.CanSeek)
                {
                    destination.SetLength(0);
                    destination.Seek(0, SeekOrigin.Begin);
                }

                using (var hashAlgorithm = CreateHashAlgorithm(hashType))
                using (var source = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                {
                    var buffer = ArrayPool<byte>.Shared.Rent(BufferSize);
                    try
                    {
                        int read;
                        while ((read = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) > 0)
                        {

View on GitHub (pinned to be573f6f94)