> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 错误代码

> Dodo Payments API 和业务逻辑错误代码参考，按类别分组，包括触发条件、消息和解决方法。

## 概述

Dodo Payments API 使用标准 HTTP 状态代码和自定义错误代码来指示 API 请求的成功或失败。当发生错误时，API 会返回适当的 HTTP 状态代码和包含错误详细信息的 JSON 响应。

每个错误响应包括：

* 指示错误一般类别的 HTTP 状态代码
* 识别错误确切性质的特定错误代码
* 解释出错原因的人类可读错误消息
* 适用时关于错误的附加详细信息

理解这些错误代码及其含义对于以下方面至关重要：

* 调试集成问题
* 在您的应用程序中实现适当的错误处理
* 向最终用户提供有意义的反馈
* 维护强大的支付处理系统

这是 **API 和业务逻辑** 错误。对于失败支付时返回的 **卡拒绝原因**（如 `INSUFFICIENT_FUNDS` 或 `CARD_DECLINED`），请参阅 [交易失败](/api-reference/transaction-failures) 参考。

## 标准 API 错误代码

| HTTP 状态 | 名称      | 描述               |
| ------- | ------- | ---------------- |
| **400** | 错误请求    | 请求格式错误或包含无效参数    |
| **401** | 未授权     | 认证失败或 API 密钥无效   |
| **403** | 禁止      | API 密钥无权限访问请求的资源 |
| **404** | 未找到     | 请求的资源不存在         |
| **405** | 方法不允许   | 此端点不支持 HTTP 方法   |
| **409** | 冲突      | 请求与资源的当前状态冲突     |
| **422** | 无法处理的实体 | 请求格式正确但包含语义错误    |
| **429** | 请求过多    | 超出速率限制           |
| **500** | 内部服务器错误 | 服务器发生意外错误        |
| **502** | 错误网关    | 服务器从上游服务器收到无效响应  |
| **503** | 服务不可用   | 服务暂时不可用          |
| **504** | 网关超时    | 服务器在等待上游响应时超时    |

## 错误响应格式

当发生错误时，API 返回具有以下结构的 JSON 响应：

```json theme={null}
{
  "code": "UNSUPPORTED_COUNTRY",
  "message": "Country AI currently not supported"
}
```

## 错误代码参考

下面的错误代码按与 API 的相关领域分组。每个条目列出了触发条件和 API 返回的消息。

### 认证与账户

* `UNAUTHORIZED`
  * **触发条件：** 无 API 密钥或无效令牌/范围
  * **消息：** 您无权限执行此操作

* `MERCHANT_NOT_LIVE`
  * **触发条件：** 业务仍处于测试/沙盒模式
  * **消息：** 商家未上线

### 支付与结账

* `CHECKOUT_SESSION_CONSUMED`
  * **触发条件：** 结账会话已生成付款
  * **消息：** 结账会话已经被使用

* `NO_ELIGIBLE_PAYMENT_METHODS`
  * **触发条件：** 过滤后没有剩余
  * **消息：** 未找到合适的付款方式

* `PAYMENT_NOT_SUCCEEDED`
  * **触发条件：** 尝试退款/处理不成功的付款
  * **消息：** 提供的付款未成功

* `PREVIOUS_PAYMENT_PENDING`
  * **触发条件：** 尝试在之前的付款处于非终端状态时创建收费
  * **消息：** 无法创建新收费，因为之前的付款尚未成功

* `UNSUCCESSFUL_PAYMENT_ID`
  * **触发条件：** 付款 ID 引用不成功的付款
  * **消息：** 付款 ID 状态不成功。

### 连接器与 BYOP

这些错误与商家自有的支付连接器（自带处理器）有关。

* `BYOP_CONNECTOR_DISABLED`
  * **触发条件：** 更新通过已禁用的 BYOP 连接器路由的订阅上的支付方式
  * **消息：** 订阅通过商家自有（BYOP）连接器路由，该连接器当前已禁用

* `BYOP_CUSTOM_INVOICE_ADDRESS_MISSING`
  * **触发条件：** 商家路由（BYOP）的支付缺少所需的自定义发票地址
  * **消息：** 当支付通过商家的连接器路由时，需要 BYOP 自定义发票地址

* `CONNECTOR_LABEL_ALREADY_EXISTS`
  * **触发条件：** 创建已存在标签的连接器
  * **消息：** 带此标签的连接器已存在。请选择不同的标签。

### 退款

* `EXISTING_REFUND_REQUEST_PROCESSING`
  * **触发条件：** 之前的退款请求仍在处理
  * **消息：** 状态为“Pending”的退款请求仍在处理中

* `LINE_ITEM_FULLY_REFUNDED`
  * **触发条件：** 尝试对已全额退款的订单项进行退款
  * **消息：** 订单项 {id} 已被全额退款，无法进一步退款。

* `LINE_ITEM_NOT_FOUND`
  * **触发条件：** 项目 ID 不在所引用的付款中
  * **消息：** 付款中未找到订单项 {id}

* `LINE_ITEM_PRORATED`
  * **触发条件：** 尝试对按比例分配的订单进行退款或更新
  * **消息：** 订单项 {id} 无法退款，因为它是按比例分配的

* `LINE_ITEM_REFUND_AMOUNT_TOO_HIGH`
  * **触发条件：** 退款金额 > 支付金额（含税）
  * **消息：** 订单项 {id} 请求的退款金额含税为 {amount}，超过支付金额 {amount}

* `LINE_ITEM_REFUND_AMOUNT_TOO_LOW`
  * **触发条件：** 退款金额低于最低阈值
  * **消息：** 订单项 {id} 请求的退款金额为 {amount}，过低

* `NOTHING_TO_REFUND`
  * **触发条件：** 无可退款金额；所有正数订单项已全额退款
  * **消息：** 无可退款金额。所有正数订单项已被全额退款。

* `PARTIAL_REFUND_NOT_ALLOWED`
  * **触发条件：** 尝试对仅支持全额退款的支付方式进行部分退款
  * **消息：** 此付款方式不允许部分退款

* `PAYMENT_ALREADY_REFUNDED`
  * **触发条件：** 重复退款
  * **消息：** 此付款已被退款

* `PAYMENT_HAS_BEEN_REFUNDED`
  * **触发条件：** 付款已全额退款
  * **消息：** 付款 ID 已被全额退款。

* `REFUND_AMOUNT_EXCEEDS_PAID_AMOUNT`
  * **触发条件：** 汇总退款金额 > 支付金额
  * **消息：** 计算的退款金额大于支付金额

* `REFUND_WINDOW_EXPIRED`
  * **触发条件：** 超出允许的退款时间窗口
  * **消息：** 付款创建 {days} 天后无法发起退款。联系 [support@dodopayments.com](mailto:support@dodopayments.com)。

* `ZERO_AMOUNT_PAYMENT_REFUND_NOT_ALLOWED`
  * **触发条件：** 尝试对0金额付款进行退款
  * **消息：** 无法对金额为零的付款进行退款

### 订阅与附加项

* `ADDONS_IN_USAGE_BASED_BILLING_NOT_SUPPORTED`
  * **触发条件：** 尝试将附加项添加到基于使用量计费的订阅
  * **消息：** 基于使用量计费的订阅不支持附加项

* `ADDONS_NOT_ALLOWED_FOR_ON_DEMAND`
  * **触发条件：** 尝试将附加项添加到按需订阅
  * **消息：** 按需订阅不允许附加项

* `CANCEL_SCHEDULED_PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED`
  * **触发条件：** 客户门户尝试取消已安排的计划更改，而业务已禁用该操作
  * **消息：** 客户门户里的取消已安排计划变更被禁用。

* `CHARGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION`
  * **触发条件：** 尝试收费安排取消的订阅
  * **消息：** 订阅已安排取消

* `CUSTOMER_HAS_EXISTING_SUBSCRIPTION`
  * **触发条件：** 为已经有订阅的客户创建订阅，而不允许每个客户有多个订阅
  * **消息：** 客户 {id} 已有现有订阅。要允许每个客户有多个订阅，请更改业务设置

* `DO_NOT_BILL_NOT_ALLOWED_IN_CUSTOMER_PORTAL`
  * **触发条件：** 用户门户计划更改中使用了 `do_not_bill` 分摊模式
  * **消息：** 用户门户中不允许使用 do\_not\_bill 分摊模式

* `DUPLICATE_ADDON_IDS_IN_REQUEST`
  * **触发条件：** 请求中出现多个相同的 `addon_id`
  * **消息：** 不允许重复的附加项 ID

* `INACTIVE_SUBSCRIPTION_PLAN_CHANGE_NOT_SUPPORTED`
  * **触发条件：** 对非活动订阅进行计划更改
  * **消息：** 不支持对非活动订阅进行更改计划

* `INVALID_PRORATION_MODE_WITH_NEXT_BILLING_DATE`
  * **触发条件：** 非 `full_immediately` 分摊模式与 `effective_at: next_billing_date` 一起使用
  * **消息：** 只有 full\_immediately 分摊模式可以与 effective\_at: next\_billing\_date 一起使用

* `MISSING_ADDON_IDS`
  * **触发条件：** `addon_id` 列表为空或包含未知 ID
  * **消息：** 一个或多个产品 ID 不存在: {id}

* `ON_DEMAND_PLAN_CHANGE_NOT_SUPPORTED`
  * **触发条件：** 不允许按需计划兑换
  * **消息：** 不支持对按需订阅的更改计划

* `ON_DEMAND_USAGE_BASED_BILLING_NOT_SUPPORTED`
  * **触发条件：** 尝试使用按需与基于使用量计费
  * **消息：** 按需订阅不支持基于使用量的计费

* `ONE_TIME_PRODUCTS_NOT_ALLOWED_FOR_ON_DEMAND`
  * **触发条件：** 添加一次性产品到按需订阅
  * **消息：** 按需订阅不允许一次性产品

* `PENDING_PLAN_CHANGE_EXISTS`
  * **触发条件：** 新计划变更请求，而之前的请求仍待付款
  * **消息：** 此订阅已有待处理的计划更改。请等待当前付款完成。

* `PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED`
  * **触发条件：** 通过客户门户进行计划更改，而业务已禁用它
  * **消息：** 客户门户的订阅计划更改被禁用。

* `PLAN_CHANGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION`
  * **触发条件：** 尝试对安排取消的订阅进行计划更改
  * **消息：** 订阅已安排取消

* `SCHEDULE_PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED`
  * **触发条件：** 通过客户门户安排计划更改，而业务已禁用
  * **消息：** 此业务的计划更改安排被禁用。

* `SCHEDULED_PLAN_CHANGE_EXISTS`
  * **触发条件：** 创建已存在的计划更改安排
  * **消息：** 此订阅已存在计划更改安排。请取消现有的计划更改安排后再创建新的计划更改安排。

* `SCHEDULED_PLAN_CHANGE_NOT_FOUND`
  * **触发条件：** 引用或取消不存在的计划更改安排
  * **消息：** 此订阅没有找到计划更改安排。

* `SUBSCRIPTION_EXPIRED`
  * **触发条件：** 超过 `ends_at` 结算
  * **消息：** 订阅已过期，无法创建新收费

* `SUBSCRIPTION_INACTIVE`
  * **触发条件：** 状态 ≠ `ACTIVE`
  * **消息：** 订阅未激活

* `SUBSCRIPTION_NOT_ON_DEMAND`
  * **触发条件：** 应为按需，但为固定间隔
  * **消息：** 订阅已经不是按需的

* `SUBSCRIPTION_PAYMENT_RETRY_LIMIT_EXCEEDED`
  * **触发条件：** 订阅支付重试超过最大尝试次数
  * **消息：** 此订阅超过了10次的最大重试次数

### 产品、购物车与品牌

* `BRAND_MISMATCH`
  * **触发条件：** 购物车中的物品属于不同的品牌
  * **消息：** 产品购物车中的所有物品应属于同一品牌

* `BRAND_NOT_ENABLED`
  * **触发条件：** 品牌被禁用或未激活
  * **消息：** 提供的品牌未启用

* `BRAND_SUBMISSION_NOT_ENABLED`
  * **触发条件：** 品牌验证重新提交功能未启用
  * **消息：** 品牌验证重新提交未启用

* `FILE_IN_USE`
  * **触发条件：** 删除仍由活动许可授予引用的数字产品文件（传递 `?force=true` 以覆盖）
  * **消息：** 数字文件被活动许可授予引用

* `INVALID_SUGGESTED_PRICE`
  * **触发条件：** PWYW 价格 \< 允许的最低价格
  * **消息：** 建议价格不能低于最低价格。如果按需付款，以最低可接受金额为准

* `LOCALIZED_PRICE_ALREADY_EXISTS`
  * **触发条件：** 已为该产品和国家/货币创建了本地化价格
  * **消息：** 已为该产品和国家/货币创建本地化价格

* `LOCALIZED_PRICE_DUPLICATES_BASE`
  * **触发条件：** 本地化价格重复产品的基础货币/国家
  * **消息：** 本地化价格重复产品的基础货币/国家

* `LOCALIZED_PRICE_SHAPE_MISMATCH`
  * **触发条件：** 本地化价格形状与产品的 `pricing_mode` 不符
  * **消息：** 本地化价格形状与产品的 pricing\_mode 不符

* `MISSING_PRODUCT_INFORMATION`
  * **触发条件：** 产品存在但缺少必要信息
  * **消息：** 产品 {id} 存在但其他必要信息缺失或无效

* `PAY_AS_YOU_WANT_AMOUNT_REQUIRED`
  * **触发条件：** PWYW 产品缺少价格
  * **消息：** 按需付款的产品金额为必需项

* `PRODUCT_CART_EMTPY`
  * **触发条件：** 提交空购物车
  * **消息：** product\_cart 为空（错误代码故意拼写为 `EMTPY` 以匹配 API 返回的确切值）

* `PRODUCT_COLLECTION_IS_DELETED`
  * **触发条件：** 操作已删除的产品集合
  * **消息：** *无消息*

* `PRODUCT_COLLECTION_MUST_HAVE_PRODUCTS`
  * **触发条件：** 从集合中移除最后一个产品（或有产品的最后一组）
  * **消息：** 不能删除集合中的最后一个产品。请存档集合。

* `PRODUCT_IS_DELETED`
  * **触发条件：** 产品软删除
  * **消息：** *无消息*

* `PRODUCT_PRICING_MODE_REQUIRED`
  * **触发条件：** 添加本地化价格之前，产品的 `pricing_mode` 尚未设置
  * **消息：** 在添加本地化价格之前，必须先设置产品定价模式

* `SLUG_ALREADY_TAKEN`
  * **触发条件：** 请求的产品简短网址已被占用
  * **消息：** Slug 已被占用

* `UNABLE_TO_EDIT_PRIMARY_BRAND`
  * **触发条件：** 尝试通过常规 API 更新主要品牌
  * **消息：** 主要品牌不能通过此 API 端点更新。

### 折扣

* `DISCOUNT_ALREADY_USED_ON_SUBSCRIPTION`
  * **触发条件：** 重新应用已在此订阅中使用的折扣
  * **消息：** 此折扣已在该订阅中使用

* `DISCOUNT_CODE_ALREADY_EXISTS`
  * **触发条件：** 创建重复的折扣代码
  * **消息：** 折扣代码已存在

* `DISCOUNT_CODE_EXPIRED`
  * **触发条件：** 折扣代码在其 `expires_at` 日期之后
  * **消息：** 折扣代码已过期

* `DISCOUNT_CODE_USAGE_LIMIT_EXCEEDED`
  * **触发条件：** 折扣超过 `usage_limit` 限制再次使用
  * **消息：** 使用限制不能低于使用的次数/折扣代码达到使用限制

* `DISCOUNT_NOT_APPLICABLE_TO_NEW_PRODUCT`
  * **触发条件：** 更改到现有折扣不适用的产品
  * **消息：** 新计划产品无折扣适用

* `DISCOUNT_NOT_AVAILABLE_FOR_ON_DEMAND`
  * **触发条件：** 代码应用于按需订阅
  * **消息：** 按需订阅不可用折扣优惠券

* `DISCOUNT_NOT_AVAILABLE_FOR_PRODUCT`
  * **触发条件：** 代码应用于无关的产品
  * **消息：** 此产品不可用折扣优惠券

* `INVALID_DISCOUNT_CODE`
  * **触发条件：** 代码不存在/不适用
  * **消息：** 无效折扣代码/折扣代码不能应用于购物车中的任何产品

* `INVALID_PERCENTAGE`
  * **触发条件：** 百分比金额 > 100%（或 10,000 个基点）
  * **消息：** 百分率金额不能超过10000/折扣代码金额不能超过100%

* `UNSUPPORTED_DISCOUNT_TYPE`
  * **触发条件：** 平额折扣等尚未上线
  * **消息：** 暂时仅支持百分比折扣代码

### 许可证密钥

* `ACTIVATION_LIMIT_LESS_THAN_CURRENT_AMOUNT`
  * **触发条件：** 许可证密钥激活: 新限额 \< 现有实例数量
  * **消息：** 新激活限额不能低于当前实例数量

* `INACTIVE_LICENSE_KEY`
  * **触发条件：** 密钥状态 ≠ `ACTIVE`
  * **消息：** 许可证密钥未激活

* `LICENSE_KEY_LIMIT_REACHED`
  * **触发条件：** 激活次数 = 限额
  * **消息：** 许可证密钥激活限额已达

* `LICENSE_KEY_NOT_FOUND`
  * **触发条件：** 实例 ID 或密钥 ID 无效
  * **消息：** 找不到许可证密钥实例或该许可证密钥不属于该实例

* `NO_EXPIRY_ON_SUBSCRIPTION_LICENSE_KEYS`
  * **触发条件：** 尝试为基于订阅的密钥设置到期日期
  * **消息：** 无法为基于订阅的许可证密钥设置到期日期

### 基于使用量计费与计量器

* `DUPLICATE_METER_IDS_IN_REQUEST`
  * **触发条件：** 请求中多次出现相同的计量器 ID
  * **消息：** 不允许重复的计量器 ID

* `INVALID_QUANTITY`
  * **触发条件：** 为基于使用量计价指定无效数量
  * **消息：** 基于使用量计价产品只允许 1 数量

* `METER_IS_DELETED`
  * **触发条件：** 尝试使用已删除的计量器
  * **消息：** 该计量器已经被删除

* `MISSING_METER_IDS`
  * **触发条件：** 计量器 ID 列表为空或包含无效 ID
  * **消息：** 一个或多个计量器 ID 不存在: {id}

### 基于信用的计费

* `CREDIT_ENTITLEMENT_IS_DELETED`
  * **触发条件：** 操作已删除的信用授权
  * **消息：** 信用授权已经被删除

* `CREDIT_ENTITLEMENT_NAME_ALREADY_EXISTS`
  * **触发条件：** 创建名称已存在的信用授权
  * **消息：** 已存在具有此名称的信用授权

* `OVERAGE_LIMIT_EXCEEDED`
  * **触发条件：** 使用或信用扣减将超过配置的超支限额
  * **消息：** 超支限额已过

### 钱包

* `INSUFFICIENT_WALLET_FUNDS`
  * **触发条件：** 钱包余额 \< 借记金额
  * **消息：** 钱包余额不足

* `NEGATIVE_BALANCE_ADJUSTMENT`
  * **触发条件：** 试图使钱包余额为负
  * **消息：** 不允许钱包余额为负

### 货币、税收与地区

* `EXCHANGE_RATE_NOT_FOUND`
  * **触发条件：** 没有 `from → to` 货币对的汇率
  * **消息：** 找不到从货币到货币的汇率

* `INVALID_TAX_ID`
  * **触发条件：** VAT/GST/TIN 验证失败
  * **消息：** 税号无效

* `REQUEST_AMOUNT_BELOW_MINIMUM`
  * **触发条件：** 金额 \< 产品最低金额
  * **消息：** 金额不能低于产品所指定的最低金额

* `TOTAL_PAYMENT_AMOUNT_BELOW_MINIMUM_AMOUNT`
  * **触发条件：** 购物车总计 \< 网关最低金额
  * **消息：** 需要最低金额 {display_str} 才可处理付款

* `UNSUPPORTED_BILLING_CURRENCY`
  * **触发条件：** 订阅仅限 USD
  * **消息：** 订阅不支持非 USD 计费货币

* `UNSUPPORTED_COUNTRY`
  * **触发条件：** 地区尚未支持
  * **消息：** 目前不支持国家 {country_name}

* `UNSUPPORTED_CURRENCY`
  * **触发条件：** 产品或附加项货币无效
  * **消息：** 当前不支持该货币/目前只支持 USD 和 INR 产品/仅支持 USD 和 INR 附加价格/只能请求 USD 或 INR 作为计费货币/货币不支持/印度卡订阅的意外货币

* `UNSUPPORTED_TAX_CATEGORY`
  * **触发条件：** 税务类别字符串不在枚举中
  * **消息：** 类别 {category} 目前不支持

### 验证与请求

* `DUPLICATE_LINE_ITEMS_IN_REQUEST`
  * **触发条件：** 相同的 `item_id` 在 `items[]` 中出现两次
  * **消息：** 在项目数组中指定的项目 ID 重复

* `INVALID_QUERY_PARAMS`
  * **触发条件：** 互斥/格式错误的查询参数
  * **消息：** 查询参数应仅包含时间范围或（开始，结束）

* `INVALID_REQUEST_BODY`
  * **触发条件：** 格式错误的 JSON 或模式违反
  * **消息：** 请求主体无效。请检查请求头和对象。

* `INVALID_REQUEST_PARAMETERS`
  * **触发条件：** 语义错误（例如，过往的日期）
  * **消息：** 不能将下次计费日期更改为过去时间

* `MAXIMUM_KEYS_REACHED`
  * **触发条件：** 元数据/自定义字段超过 50 对
  * **消息：** 超过 50 个键值对

### 常规与系统

* `INTEGER_CONVERSION_FAILURE`
  * **触发条件：** 任何整型 ↔ 字符串/小数转换失败服务器端
  * **消息：** 整数转换失败

* `INTERNAL_SERVER_ERROR`
  * **触发条件：** 未捕获异常；您应记录服务器端的详细信息
  * **消息：** *无公开消息（通用500）*

* `NOT_FOUND`
  * **触发条件：** 任何丢失资源的通用404
  * **消息：** 找不到项目 *(或更具体的)*

* `TOO_MANY_REQUESTS`
  * **触发条件：** 429 速率限制
  * **消息：** *无消息*

* `UNSUPPORTED_ACTION`
  * **触发条件：** 不支持资源类型操作
  * **消息：** 不支持基于使用量的订阅更改计划

## 最佳实践

1. 始终在应用程序中优雅地处理错误
2. 实现适当的错误日志记录
3. 为最终用户使用适当的错误消息
4. 为瞬时错误实施重试逻辑
5. 对于未解决的问题请联系支持

## 支持

有关错误代码或集成问题的更多帮助，请联系 [support@dodopayments.com](mailto:support@dodopayments.com)。
