{"record":{"id":"e35e736e94154d17","repo":"JeffreySu/WeiXinMPSDK","slug":"http-int-response-statuscode-response-reasonphrase-errorbody","errorCode":null,"errorMessage":"下载微信支付文件失败，HTTP {(int)response.StatusCode} ({response.ReasonPhrase})：{errorBody}","messagePattern":"下载微信支付文件失败，HTTP (.+?) \\((.+?)\\)：(.+?)","errorType":"http","errorClass":"TenpayApiRequestException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Helpers/TenPayDownloadHelper.cs","lineNumber":78,"sourceCode":"            CancellationToken cancellationToken)\n        {\n            if (destination == null)\n            {\n                throw new ArgumentNullException(nameof(destination));\n            }\n\n            using (var response = await request.GetHttpResponseMessageAsync(\n                url,\n                null,\n                cancellationToken,\n                HttpCompletionOption.ResponseHeadersRead,\n                timeOut,\n                ApiRequestMethod.GET).ConfigureAwait(false))\n            {\n                if (!response.IsSuccessStatusCode)\n                {\n                    var errorBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);\n                    throw new TenpayApiRequestException(\n                        $\"下载微信支付文件失败，HTTP {(int)response.StatusCode} ({response.ReasonPhrase})：{errorBody}\");\n                }\n\n                if (destination.CanSeek)\n                {\n                    destination.SetLength(0);\n                    destination.Seek(0, SeekOrigin.Begin);\n                }\n\n                using (var hashAlgorithm = CreateHashAlgorithm(hashType))\n                using (var source = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))\n                {\n                    var buffer = ArrayPool<byte>.Shared.Rent(BufferSize);\n                    try\n                    {\n                        int read;\n                        while ((read = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) > 0)\n                        {","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Helpers/TenPayDownloadHelper.cs#L60-L96","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait helper.DownloadAndVerifyAsync(badUrl, stream, \"SHA1\", hash, timeOut);\n// after\nif (!string.IsNullOrEmpty(downloadUrlFromApi))\n    await helper.DownloadAndVerifyAsync(downloadUrlFromApi, stream, \"SHA1\", hash, timeOut);","handlingStrategy":"try-catch","validationCode":"if (string.IsNullOrEmpty(downloadUrl) || !downloadUrl.StartsWith(\"https://\"))\n    throw new InvalidOperationException(\"download_url 无效\");","typeGuard":null,"tryCatchPattern":"try { await helper.DownloadAndVerifyAsync(url, stream, \"SHA1\", hash, timeOut); }\ncatch (TenpayApiRequestException ex)\n{ logger.Error(ex, \"下载失败: {0}\", ex.Message); /* inspect status/errorBody */ }","preventionTips":["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"],"tags":["http","wechat-pay","download","api"],"backgroundTag":"http-error-response","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}