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
- Inspect the included errorBody/status code to fix the underlying request (correct URL, bill date, permissions).
- Ensure the download_url is exactly the one returned by WeChat Pay APIs (don't re-construct it).
- Retry after fixing auth (certificates, API v3 key) if the status is 401/403.
- 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
- Use download URLs exactly as returned by WeChat Pay APIs
- Validate bill dates and permissions before downloading
- Retry only on 5xx; treat 4xx as a request problem
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
- 超时时间必须大于 0,或使用 Timeout.Infinite。
- RequestAsync 签名验证失败:
- 微信请求发生错误!错误代码: ,说明:
- sendType
- WeixinPayInfoCollection尚未注册Partner:
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)