ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

402错误与prepayment credits depleted:API预付费余额耗尽的排查与恢复指南

402错误与prepayment credits depleted:API预付费余额耗尽的排查与恢复指南 如果你在终端里跑着某个 AI 开发工具或者调用云端 API突然看到一片红色报错里最核心的一句是{error:{code:402,message:Your prepayment credits are depleted.}}那大概率不是你的代码写错了而是“钱”的问题。这个报错我最近几个月已经在好几个项目里遇到过每次朋友私信过来问“为什么我的请求突然全部失败”截图里十有八九都是这一串 JSON。今天就围绕这个 402 错误、prepayment credits depleted的真实含义以及从定位到恢复再到预防的完整链路一次性说清楚。1. 402 与 “prepayment credits depleted”这个报错到底在说什么1.1 HTTP 402 在云服务里的实际语义HTTP 状态码 402 的全称是Payment Required在 RFC 9110 的标准定义里它一直是“预留”状态意思是“将来可能用于表示需要付费才能访问”。很多年它都只是个概念但最近几年随着预付费云服务、大模型 API、AI 编程助手这类按量计费产品的普及402 正在变成一种相当常见且明确的信号。为什么平台不用 401未认证或者 403禁止访问因为这两个含义都不太准确。你的 API Key 是合法有效的身份认证也通过了服务端也没有禁止你访问的权限规则只是账户里的预付费余额花完了导致服务端无法继续为你垫付计算和带宽成本。402 刚好贴合“需要付款才能继续”这个语义请求本身没问题问题在于付款条件不满足。你可以理解为自来水公司已经给你的水管开通了用水权限但你水卡里的预存水费扣光了水阀自动关闭。再拧开水龙头不会出水但也不是水管坏了。此时报的就是“余额不足”而不是“没有开户”。1.2 拆解错误 JSONcode 与 message 的线索标题里的错误体非常典型几乎可以原样作为排查的起点{ error: { code: 402, message: Your prepayment credits are depleted. } }这里有两个关键信息code: 402标准的 HTTP 状态码说明是“付款要求”层面的失败。message: Your prepayment credits are depleted.进一步告诉你是prepayment credits预付费额度/预存积分被用完了而不是账单逾期、不是银行卡扣款失败、也不是订阅过期。“prepayment credits” 在很多国外云平台和 AI 服务中是一个专门的结算概念。你在使用前先往账户里充值一笔钱平台把它换算成 credits额度之后每次 API 请求根据 token 数、模型类型、处理时长等实时扣减。当你调用请求时会先检查账户余额是否大于 0如果小于等于 0直接就抛 402。这里有一个容易忽略的细节有些平台的 subscription订阅和 prepayment credits预付费额度是两套体系。订阅解决的是“基础服务费”或“月度包”而 API 的按量消耗可能走的却是另一套“预付费余额”。这就解释了为什么有些人明明订阅还在有效期却依然收到prepayment credits depleted因为 API 消耗的部分压根不走订阅而是从一个独立的余额池里扣。与其硬记规范不如记住一条判断原则凡是看到 402 prepayment/depleted 之类的关键词优先去查“余额池”而不是先去查代码逻辑。2. 哪些场景最容易把预付费耗尽当下实际触发路径2.1 五个常见触发场景过去一年里我处理过的 402 求助大致可以归为下面五类每一类都有自己的典型特征。第一类试用期额度用完。很多平台注册后会送一笔试用 credits金额不大只够你跑一些 demo。如果你在试用期内持续做测试、批量跑数据额度可能一两天就消失。这类触发的特征是错误出现的时间点往往离注册日或创建账号日非常近而且之前一切正常突然某一次请求后就连续失败。第二类开发调试时疯狂调用。开发一个聊天机器人或者 AI Agent经常会在循环里反复调用模型接口。尤其是在写代码时没有加缓存、没有做错误重试上限一个死循环可能几分钟内就烧掉几十美元的 token。我见过最夸张的一次是同事的脚本在调试嵌套逻辑时递归调用同一个模型接口两千多次等他发现时账户余额已经变成了负数。服务端为了止损直接在后续所有请求上统一返回 402。第三类多个项目共享同一个账户额度。团队协作时大家共用一个 API Key或者同一家云厂商的多个子服务都从同一个 prepayment credits 池里扣费。某个流量比较大的项目会在你不知情时把余额消耗掉其他项目也跟着一起遭殃。这类场景的典型特征是报错不固定在某一个业务接口上而是整个账户体系下的所有请求同时失效。第四类经过中转网关网关侧的余额先耗尽。现在不少开发者会通过第三方网关或聚合平台去调用上游模型服务本地请求先到达网关再由网关转发给模型厂商。如果你在网关侧充值的余额不足网关就会直接返回一个类似格式的 402。这时你登录原始模型厂商的控制台看到的余额可能还有很多因为卡住你的是网关的账户不是上游厂商的账户。第五类自动任务在深夜/周末把余额跑光。定时任务、CI/CD 流水线、数据批处理作业通常不会有人盯着。某个批处理脚本因为数据量突然暴增在凌晨把整月预算一次性耗尽。等到你早上到公司开始正常开发时所有请求都返回 402而你根本不知道昨晚发生了什么。2.2 各个场景的特征化识别为了方便快速判断自己属于哪一种我把特征整理成一个对照表触发场景典型信号为什么容易耗尽试用额度到期注册/激活后不久出现初始赠送额度本身很小开发调试疯狂调用代码改动后突然出现无上限重试/嵌套调用多项目共享账户整个账号下所有 key 同时失败消耗集中缺少隔离网关中转余额不足原厂控制台余额正常本地区报错网关侧独立计费后台自动任务跑量非工作时间开始报错无人实时监控用量你可以先用这个表格给当前情况做一次粗定位然后再决定下一步是充电费还是去检查代码里的调用频率。3. 从报错到定位一条完整的排查链路3.1 第一步把完整报错和请求上下文留下而不是只看 message很多人一看到 402 就慌立刻把代码改成重试或者换 Key结果越弄越糟。正确的第一步是先保存完整的原始响应包括完整的响应体 JSON不要只复制 message 一行响应头尤其是x-request-id、request-id、retry-after、x-ratelimit-*这类字段请求时间、请求的模型名 / 接口路径、当时用的 API Key 前几位发起请求的客户端名称和版本比如你用一个简单的 curl 复现时可以加上-i参数把响应头打出来curl -i https://api.example.com/v1/messages \ -H x-api-key: YOUR_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: your-model-name, max_tokens: 8, messages: [{role: user, content: hi}] }正常情况下响应头里会有请求唯一 ID。这个 ID 非常重要后续联系平台客服时只需要把请求 ID 甩过去对方就能精准查到你这笔请求当时发生的扣费记录。别等到排查到一半才想起来自己没留请求 ID。3.2 第二步登录控制台确认余额和账单状态接下来打开云服务提供商的控制台找到这三个板块Billing / Cost Management账单与成本里的“余额”或“Credit Balance”Usage / Usage Logs用量日志里最近几条请求的扣费记录Payment Methods / Invoices付款方式与发票里是否有未付账单这里要特别说明一个容易踩坑的操作不要只看“总余额”还要去查看“账单周期”和“付款状态”。有些平台允许你欠费后继续用一小段时间之后再统一拦截有些平台则风控严格只要有一笔历史账单未结清哪怕你现在刚充值也会继续返回 402。当你充值后依然报错优先去查是否存在未结清的旧账单。3.3 第三步区分是平台余额不足还是网关余额不足如果你是直接接入模型厂商的原生 API那控制台看到的余额就是真相。但如果你使用的是命令行工具或第三方客户端比如 Claude Code 这类开发工具或者本地跑的一些封装框架你需要先弄清楚工具内部到底把请求发到哪个地址用的又是谁的 Key。排查方法是打开客户端的配置文件或环境变量看base_url/api_base/BASE_URL指向的是厂商官方域名还是某个第三方网关。如果是网关地址你需要去网关的控制台查余额而不是去模型厂商官网查。这一步的遗漏是很多人“明明充了值却还在 402”的最常见原因。3.4 第四步检查环境变量与本地缓存的旧 Key还有一种很隐蔽的坑你本地的环境变量里同时存在多个 Key优先级高的那个是旧 Key已经没余额了而新充值的 Key 排在后面根本没被读到。例如在.zshrc或.env文件里同时定义了export ANTHROPIC_API_KEYsk-old-key-with-zero-balance export ANTHROPIC_AUTH_TOKENsk-new-key-with-balance如果客户端内部优先读取的是旧变量名你的新 Key 就永远不会被使用。排查时用下面的命令确认当前 shell 实际加载了哪个 Keyecho $ANTHROPIC_API_KEY | head -c 10 echo $ANTHROPIC_API_KEY | wc -c只显示前几个字符避免泄露完整 Key。如果发现加载的确实是旧 Key更新配置后重新加载环境变量再测试请求。到这里你已经能区分出大概三类问题账户余额问题、网关余额问题、本地配置问题。接下来就可以进入实际的恢复操作了。4. 额度耗尽后的恢复操作从充值到切换套餐的实操4.1 按优先级执行的恢复步骤一旦确认是prepayment credits depleted恢复操作的顺序比你想象中更重要充错地方、充错计费模式都会让你白等几个小时。第一步确认计费模式再充值。打开控制台的 Billing 页面页面上通常会明确显示“Prepay / Credits”和“Subscription / Plan”两个模块。需要往Prepay / Credits里充值而不是往订阅付款里塞钱。如果你不确定看页面上的措辞带有credit、balance、prepay字样的就是预付费额度池。盲目点“升级订阅”反而可能激活一个更贵的月套餐并没有解决 API 消耗余额的问题。第二步充值金额不要只充一美元。最低充值额可能很低但我建议首充选择能覆盖“恢复测试 后续两三天开发量”的金额。原因很简单如果充值后刚跑通一个小 demo 就又余额不足你会误以为问题没解决然后陷入重复充值、重复排查的循环。先充一笔至少够 1–2 天测试量的金额能避免很多无效操作。第三步检查付款方式是否绑定成功。很多平台要求信用卡与账户实名一致如果绑卡失败充值按钮显示成功但余额并没有到账。付款方式区域一般会有“验证”/“重试”按钮。我遇到过两次充值后余额延迟到账超过 15 分钟的情况最后都是因为支付网关回调慢而充值记录本身已经生成。这时不要反复重试支付直接刷新控制台或者联系结算客服核实订单号。第四步如果经过网关去网关侧充值并检查分发关系。如果你用的是第三方网关请直接登录网关的控制台给网关账户充值。同时检查网关的项目/密钥是否已经绑定到对应的上游厂商账户。有些网关支持一个上游账户对应多个下游项目你需要把正在报错的那个 API Key 绑定到余额充足的份额上。第五步恢复后先跑“最小验证请求”。充值成功后不要直接跑原来那个大型业务脚本。先用一个极小请求验证链路已恢复curl -s https://api.example.com/v1/messages \ -H x-api-key: YOUR_API_KEY \ -H content-type: application/json \ -d { model: your-model-name, max_tokens: 1, messages: [{role: user, content: ping}] }如果这个请求返回了正常的 200 响应说明余额恢复和链路都没有问题。然后再跑你原来失败的请求观察是否还会报 402。4.2 充值后仍然报错的几个真实原因按照上面流程操作后大部分 402 都能解决。但如果你充值后过了半小时依然报错可以从下面几个方向查旧 Key 缓存残留客户端或网关可能缓存了“此 Key 余额不足”的状态需要重新生成 API Key 或等缓存过期。此时重新创建一个 Key 并替换环境变量是最快的方式。账单冻结账户存在未支付的上一周期账单需要先把欠费结清余额才会进入可用状态。企业级审核部分平台对大额充值设置了人工审核等待审核期间请求会被持续拦截。多个余额池同一个账户下面有几个子账户你充值的 A 子账户但代码调用的是 B 子账户。如果你用的是 Claude Code 这类交互式工具恢复后还需要重新登录一次让客户端重新拉取账户状态。常见的做法是执行退出登录命令然后重新走一遍登录流程再启动会话。不要图省事不重登而直接重试原来的命令因为客户端可能把“402 状态”缓存到了本地会话里。4.3 长期方案从“救火”切换到“按需切换套餐”如果你经常在开发高峰期遇到额度耗尽除了每次充值也可以考虑把部分高消耗任务切到“按量付费 订阅包”的组合模式。订阅包通常覆盖一个基础量超出部分再按 token 从 prepayment credits 里扣。这样即使当月的订阅包用完依然可以从余额池里扣只是成本单价会略高一点。对我来说这种组合方式比单独依赖一个余额池更不容易“突发爆掉”。5. 预防额度提前打光预算设置与成本控制的日常手段5.1 平台自带的预算告警与硬上限大部分云服务平台的控制台里都提供了预算告警budget alert。你可以设置一个月度/日度预算线比如“当消耗达到总余额的 50% 时给我发邮件”。更严格的平台还支持 hard limit也就是到了某个金额直接停掉所有 API 请求。手动测试时我建议开一个偏低的 hard limit比如 80%避免脚本失控时把整个余额打光。这个设置看起来很简单但关键点在于告警渠道不能只选邮件。邮件的延迟可能超过一小时等你看到警告钱可能已经烧完了。如果平台支持 Webhook 或 Slack/钉钉通知一定要把告警发到手机能第一时间看到的地方。5.2 代码层做请求级拦截估算 token 和成本光靠平台告警还是被动。更主动的做法是在自己的代码层面对大额请求进行拦截。比如你在使用大模型 API 时可以在请求发出前先估算一次 token 量当估算值超过阈值时直接拒绝调用而不是发到服务端以后才被扣钱。以下是一段非常基础但实用的伪代码可以在任何语言里快速实现function estimateTokens(text) { // 粗略估算英文约 4 字符一个 token中文约 1-2 字符一个 token return Math.ceil(text.length / 3); } function canAffordRequest(messages, maxTokens, budgetLimit) { let inputTokens messages.reduce((acc, m) acc estimateTokens(m.content), 0); let totalCost (inputTokens maxTokens) * COST_PER_TOKEN; return totalCost budgetLimit; }这个拦截器放在所有调用模型接口的公共函数入口处。当某次请求的预估成本超过单次预算线直接抛出一条业务提示而不是把请求发出去。这样即便循环逻辑写错了最多被拦截在本地方案内不会消耗远端余额池。5.3 响应缓存把重复调用从源头减掉在很多 AI 工具场景里相同的问题会被反复请求比如同事每次启动程序都发送同样的初始化消息。如果每次都走 API 计费等于同一笔钱反复扣。解决方法是引入一层响应缓存以“请求消息的哈希值 模型名”作为缓存 key在短时间内命中相同请求时直接返回缓存结果。这个策略在开发测试阶段收益非常明显。就我自己的项目经验加入缓存后日消耗量往往能下降 40% 以上。你在日常写代码时也可以这样调试 prompt 时先用固定的测试文本不要每次重新跑一段长文档开发过程中把重复的离线任务批量处理而不是一条一条实时调用。5.4 Key 拆分给不同环境设置独立余额池不要让所有项目都挤在一个账号、一个 Key、一个余额池里。比较稳妥的做法是开发环境用一个专用 Key配额设置得很低限制死在测试范围内。生产环境用另一个 Key绑定主充值账户并开启实时用量报表。一次性离线任务用单独的临时 Key任务结束后立刻废弃。这样做的好处是即便某一个开发者的脚本出问题最多把开发环境的额度耗尽不会把生产环境的余额一起拖下水。同时因为每个 Key 都有独立的用量轨迹出问题时你一眼就能看出是哪条链路在消耗大头。5.5 自动巡检脚本每天看一眼余额比等报错靠谱最后分享一个小习惯。可以写一个简单的脚本每天定时读取账户余额并判断其变动趋势。比如在 Linux 上可以用 cron 调用一个 Python 脚本import os import requests API_KEY os.environ.get(SERVICE_API_KEY) resp requests.get( https://api.example.com/v1/billing/balance, headers{x-api-key: API_KEY} ) balance resp.json()[balance] if balance 10: print(fBalance low: {balance}, please recharge) else: print(fBalance ok: {balance})把这个脚本放到 cron 里每天早上跑一次。我个人的习惯是每天 10 点检查余额并对比前一天的数值算出单日消耗速度。如果某天消耗速度突然超过前一天的 2 倍我会立刻去翻用量日志通常能提前一两天发现隐蔽的死循环或者失控任务而不是等到所有请求都开始报 402 才去抢救。预防这件事本质上是把“余额”当成一个有限的系统资源来管理和监控服务器 CPU、内存一样。你越是提前设定告警和拦截越不会被突兀的 402 打乱节奏。402 prepayment credits depleted本身并不是什么神秘故障它是一个设计得很清晰的商业信号你的服务端账户没钱了。每次我接到类似的求助排查到最后大部分都是“忘了看余额”。真正有效的抵抗手段不是记住某个平台的报错格式而是建立一套“余额可知、消耗可控、坏了可恢复”的工作习惯。下次再看到这串 JSON别急着怀疑代码先去查余额就对了。
返回列表