概述
当请求失败时,Dodo Payments API 会返回 HTTP 状态码和一个说明错误的 JSON 正文。使用此页面查找错误原因及其解决方法。 每个错误响应都包含:- 一个用于表示错误大致类别的 HTTP 状态码。
- 一个用于标识确切错误的
code,例如UNSUPPORTED_COUNTRY。 - 一个以通俗语言解释错误的
message。例如,对于内部服务器错误,message可能是null。
code(而不是 message)分支处理错误。根据错误原因,同一个代码可能返回多条消息。
使用这些错误代码来:
- 调试集成问题。
- 在应用中正确处理错误。
- 向客户显示有意义的反馈。
- 确保支付处理可靠。
这些是 API 和业务逻辑 错误。对于失败支付返回的 卡片拒付原因(例如
INSUFFICIENT_FUNDS 或 CARD_DECLINED),请参阅 Transaction Failures 参考文档。标准 API 错误代码
API 使用以下 HTTP 状态码表示错误:错误响应格式
错误响应正文包含两个字段:code 和 message:
错误代码参考
以下错误代码按其涉及的 API 区域分组。每个条目列出触发错误的条件以及 API 返回的消息。{id} 等占位符表示由 API 填充的值。
身份验证与账户
-
UNAUTHORIZED- 触发条件: 请求没有 API 密钥、API 密钥无效(HTTP 401),或 API 密钥缺少该操作所需的角色(HTTP 403)
- 消息: 您无权执行此操作
-
MERCHANT_NOT_LIVE- 触发条件: 对尚未启用实时支付的业务发起实时模式请求(HTTP 403)。这包括仅使用过测试模式的业务,以及由于 验证 尚未完成而尚未启用实时支付的业务。测试模式请求不受影响。
- 消息: 商户尚未启用实时支付
-
BUSINESS_ARCHIVED- 触发条件: 面向客户的请求针对已归档业务(HTTP 403)。这包括结账、支付链接、店面、Customer Portal 和许可证密钥激活。
- 消息: 此业务已归档,不再接受请求
支付与结账
-
CHECKOUT_SESSION_CONSUMED- 触发条件: 结账会话已经生成支付(HTTP 403)。请改为创建新的结账会话。
- 消息: 使用给定结账会话的支付已生成。
-
MANUAL_RETRY_ALREADY_PAID- 触发条件: 对已成功支付的续订发票执行 手动重试。再次发送会导致向客户重复扣款。
- 消息: 此发票的支付已成功
-
MANUAL_RETRY_HARD_DECLINE- 触发条件: 手动重试时,发票的最新失败属于硬拒付,或没有已分类的错误代码。再次使用同一张卡扣款无法成功,请改为更新支付方式。
- 消息: 此发票的最后一次失败是硬拒付,因此重试无法成功 (或) 此发票的最后一次失败无法分类,因此无法重试
-
MANUAL_RETRY_IN_FLIGHT- 触发条件: 手动重试时,发票上的支付处于
processing状态,或尚无记录状态。请等待该支付的结果,而不要再次发送。 - 消息: 此发票的支付仍在处理中
- 触发条件: 手动重试时,发票上的支付处于
-
MANUAL_RETRY_LIMIT_REACHED- 触发条件: 发票的 3 次发送机会均已用尽,或冷却时间尚未结束时执行手动重试(HTTP 429)。第二次发送需在第一次发送后等待 1 小时,第三次发送需在第二次发送后等待 3 小时。正文仅包含
code和message。要查找下次允许发送的时间,请从GET /payments/{payment_id}/retry读取retry_available_at。 - 消息: 此发票的所有手动重试次数均已用尽 (或) 此发票暂时无法立即重试
- 触发条件: 发票的 3 次发送机会均已用尽,或冷却时间尚未结束时执行手动重试(HTTP 429)。第二次发送需在第一次发送后等待 1 小时,第三次发送需在第二次发送后等待 3 小时。正文仅包含
-
NO_ELIGIBLE_PAYMENT_METHODS- 触发条件: 过滤后没有可用于支付的支付方式(HTTP 422)
- 消息: 未找到符合条件的支付方式
-
PAYMENT_NOT_PERMITTED- 触发条件: 位于商户 阻止列表 中的客户发起结账或支付尝试(HTTP 403)。代码和消息会刻意省略具体原因。
- 消息: 此支付无法处理。
-
PAYMENT_NOT_RETRYABLE- 触发条件: 对不适用手动重试的支付执行手动重试。支付没有发票、发票不是未结的订阅续订发票、发票上的支付尚未失败、订阅未配置周期性计费(例如按需订阅),或客户位于阻止列表中。
- 消息: 根据原因而异,例如:只能重试订阅续订支付
-
PAYMENT_NOT_SUCCEEDED- 触发条件: 尝试退款或处理尚未成功的支付
- 消息: 提供的支付尚未成功
-
PREVIOUS_PAYMENT_PENDING- 触发条件: 上一次支付处于非终止状态时尝试创建扣款。当发票上的最新支付既不是
failed,也不在处理中时执行 手动重试 也会返回此错误,例如requires_customer_action或cancelled。 - 消息: 上一次支付尚未成功,无法创建新的扣款 (或) 此发票最近一次支付尚未失败
- 触发条件: 上一次支付处于非终止状态时尝试创建扣款。当发票上的最新支付既不是
-
UNSUCCESSFUL_PAYMENT_ID- 触发条件: 支付 ID 指向尚未成功的支付
- 消息: Payment ID 的状态不成功。
连接器与 BYOP
这些错误与商户自有支付连接器(Bring Your Own Processor,或 BYOP)有关。-
BYOP_CONNECTOR_DISABLED- 触发条件: 更新通过已禁用 BYOP 连接器路由的订阅的支付方式。Dodo Payments 不会回退到自己的连接器,因此请先重新启用该连接器。
- 消息: 此订阅通过商户自有的 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- 触发条件: 支付已全额退款
- 消息: Payment ID 已全额退款。
-
REFUND_AMOUNT_EXCEEDS_PAID_AMOUNT- 触发条件: 总退款金额高于已支付金额
- 消息: 计算出的退款金额大于已支付金额
-
REFUND_WINDOW_EXPIRED- 触发条件: 在允许的退款期限之外请求退款
- 消息: 支付创建
{days}天后无法发起退款。请联系 support@dodopayments.com。
-
ZERO_AMOUNT_PAYMENT_REFUND_NOT_ALLOWED- 触发条件: 尝试退还金额为零的支付
- 消息: 无法退还货币金额为零的支付
订阅与附加项
-
ADDONS_IN_USAGE_BASED_BILLING_NOT_SUPPORTED- 触发条件: 尝试向基于用量计费的订阅添加附加项
- 消息: 基于用量计费不支持订阅中的附加项
-
ADDONS_NOT_ALLOWED_FOR_ON_DEMAND- 触发条件: 尝试向按需订阅添加附加项
- 消息: 按需订阅不允许附加项
-
CANCEL_SCHEDULED_PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED- 触发条件: Customer Portal 尝试取消计划中的套餐变更,但业务已禁用此操作
- 消息: Customer Portal 已禁用取消计划中的套餐变更。
-
CHARGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION- 触发条件: 尝试向计划取消的订阅收费
- 消息: 订阅已计划取消
-
CUSTOMER_HAS_EXISTING_SUBSCRIPTION- 触发条件: 为已有订阅的客户创建订阅,而业务不允许每位客户拥有多个订阅
- 消息: 客户
{id}已有订阅。如需允许每位客户拥有多个订阅,请更改业务设置
-
DO_NOT_BILL_NOT_ALLOWED_IN_CUSTOMER_PORTAL- 触发条件: Customer Portal 套餐变更使用
do_not_bill按比例计费模式 - 消息: Customer Portal 不允许使用 do_not_bill 按比例计费模式
- 触发条件: Customer Portal 套餐变更使用
-
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搭配使用 - 消息: effective_at: next_billing_date 仅允许使用 full_immediately 按比例计费模式
- 触发条件: 将除
-
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- 触发条件: 通过 Customer Portal 进行套餐变更,但业务已禁用此功能
- 消息: Customer Portal 的订阅套餐变更已禁用。
-
PLAN_CHANGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION- 触发条件: 对计划取消的订阅进行套餐变更
- 消息: 订阅已计划取消
-
SCHEDULE_PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED- 触发条件: 通过 Customer Portal 安排套餐变更,但业务已禁用此功能
- 消息: 此业务已禁用安排套餐变更。
-
SCHEDULED_PLAN_CHANGE_EXISTS- 触发条件: 创建计划中的套餐变更,但已有一个计划中的变更
- 消息: 此订阅已有计划中的套餐变更。请先取消现有的计划变更,再创建新的变更。
-
SCHEDULED_PLAN_CHANGE_NOT_FOUND- 触发条件: 引用或取消不存在的计划中的套餐变更
- 消息: 未找到此订阅的计划中的套餐变更。
-
SUBSCRIPTION_EXPIRED- 触发条件: 在订阅的
expires_at日期之后为其计费 - 消息: 订阅已过期,无法创建新的扣款
- 触发条件: 在订阅的
-
SUBSCRIPTION_HAS_NO_PAYMENT_METHOD- 触发条件: 对没有已保存支付方式以进行非现场扣款的订阅执行手动重试
- 消息: 此订阅没有已保存的支付方式可用于扣款
-
SUBSCRIPTION_INACTIVE- 触发条件: 订阅状态不是
active - 消息: 订阅未处于活跃状态 (或) 此订阅不是实时订阅,因此无法安排取消
- 触发条件: 订阅状态不是
-
SUBSCRIPTION_NOT_ON_DEMAND- 触发条件: 对按固定周期计费的订阅执行按需操作
- 消息: 订阅已不是按需订阅
-
SUBSCRIPTION_PAYMENT_RETRY_LIMIT_EXCEEDED- 触发条件: 订阅支付重试次数超过最大尝试次数
- 消息: 此订阅已超过 10 次的最大重试限制
客户与阻止列表
-
CUSTOMER_ALREADY_BLOCKED- 触发条件: 阻止已在 阻止列表 中且没有剩余实时订阅需要取消的客户(HTTP 409)
- 消息: 此客户已在阻止列表中
-
PORTAL_ACTION_NOT_PERMITTED- 触发条件: 被阻止的客户调用 Customer Portal 写入路由:取消、暂停、恢复、更改套餐或更新支付方式(HTTP 403)。读取路由仍然开放。代码和消息会刻意省略具体原因。
- 消息: 此操作不可用。
产品、购物车与品牌
-
BRAND_ALREADY_ARCHIVED- 触发条件: 归档已归档的品牌
- 消息: 品牌已归档
-
BRAND_ARCHIVED- 触发条件: 更新已归档的品牌、提交品牌进行验证,或将新产品、产品集合或订阅关联到该品牌
- 消息: 品牌已归档 (或) 品牌已归档,无法更新 (或) 品牌已归档,无法提交验证
-
BRAND_ARCHIVE_TARGET_REQUIRED- 触发条件: 归档仍包含产品、实时订阅或产品集合且没有
move_products_to目标的品牌 - 消息: 品牌有
{count}个产品。请将 move_products_to 设置为目标品牌,以重新关联这些产品。如果阻止归档的是实时订阅或产品集合,消息会改为说明相应内容。
- 触发条件: 归档仍包含产品、实时订阅或产品集合且没有
-
BRAND_MISMATCH- 触发条件: 购物车商品属于不同品牌
- 消息: 产品购物车中的所有商品都应属于同一品牌
-
BRAND_NOT_ENABLED- 触发条件: 品牌已禁用或不活跃
- 消息: 提供的品牌未启用
-
BRAND_SUBMISSION_NOT_ENABLED- 触发条件: 品牌重新提交验证功能未启用
- 消息:
Brand verificatin resubmission is not enabled(按 API 返回的原文拼写)
-
CANNOT_ARCHIVE_PRIMARY_BRAND- 触发条件: 归档主品牌,其品牌 ID 就是业务 ID
- 消息: 无法归档主品牌
-
FILE_IN_USE- 触发条件: 删除仍被活跃权益授予记录引用的数字产品文件
- 消息: 数字文件仍被活跃授予记录引用
-
INVALID_BRAND_ARCHIVE_TARGET- 触发条件:
move_products_to指向正在归档的品牌、已归档品牌或其他业务的品牌 - 消息: move_products_to 必须是此业务中未归档的品牌 (或) move_products_to 不能是正在归档的品牌
- 触发条件:
-
INVALID_SUGGESTED_PRICE- 触发条件: Pay What You Want 建议价格低于最低价格
- 消息: 建议价格不能低于最低价格。对于 pay what you want,价格会被视为可接受的最低金额
-
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- 触发条件: Pay What You Want 产品缺少金额
- 消息: pay as you want 产品必须提供金额
-
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之前添加本地化价格 - 消息: 添加本地化价格前必须设置产品的 pricing_mode
- 触发条件: 在设置产品的
-
SLUG_ALREADY_TAKEN- 触发条件: 请求的产品 slug 或短 URL 已被使用
- 消息: 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 - 消息: 使用限制不能小于 times_used (或) 折扣代码已达到使用限制
- 注意: 终止性错误。代码已耗尽,请勿重试。
- 触发条件: 折扣代码的使用次数已达到
-
DISCOUNT_CONCURRENT_REDEMPTION- 触发条件: 同一代码的另一次兑换持有使用限制锁的时间过长(HTTP 503)
- 消息: 折扣正在被并发兑换;请重试
- 注意: 暂时性错误。代码可能仍有可用次数,因此可以安全重试。不要向客户显示为代码已耗尽。
-
DISCOUNT_CURRENCY_OPTION_INVALID- 触发条件: 创建或更新时
currency_options无效 - 消息: 固定金额折扣至少需要一个可解析默认值的货币选项 (或) 不允许重复的货币选项 (或) 只能将一个货币选项标记为默认选项
- 触发条件: 创建或更新时
-
DISCOUNT_CUSTOMER_NOT_ELIGIBLE- 触发条件: 客户不符合代码的
customer_eligibility(first_time、existing,或不在specific代码的允许列表中) - 消息: 客户不符合此折扣代码的使用条件
- 触发条件: 客户不符合代码的
-
DISCOUNT_MINIMUM_SUBTOTAL_NOT_MET- 触发条件: 购物车小计低于为结账货币配置的
minimum_subtotal - 消息: 购物车小计低于折扣要求的最低小计
- 触发条件: 购物车小计低于为结账货币配置的
-
DISCOUNT_NOT_YET_ACTIVE- 触发条件: 在代码的
starts_at日期之前使用代码 - 消息: 折扣代码尚未生效(starts_at 位于未来)
- 触发条件: 在代码的
-
DISCOUNT_PER_CUSTOMER_USAGE_LIMIT_EXCEEDED- 触发条件: 客户已兑换代码
per_customer_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- 触发条件: 使用了不受支持的折扣类型。
percentage和flat均受支持;不支持按单位金额折扣。 - 消息: 仅支持百分比和固定金额折扣代码 (或) 目前仅支持百分比折扣代码
- 触发条件: 使用了不受支持的折扣类型。
许可证密钥
-
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 的数量
- 消息: 基于用量定价的产品只能使用数量 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- 触发条件: 不存在该货币对的汇率
- 消息: 未找到将
{currency}转换为{currency}的汇率
-
INVALID_TAX_ID- 触发条件: VAT、GST 或 TIN 验证失败
- 消息: 税号无效
-
REQUEST_AMOUNT_BELOW_MINIMUM- 触发条件: 金额低于产品设置的最低金额
- 消息: 金额不能低于产品指定的最低金额
-
TOTAL_PAYMENT_AMOUNT_BELOW_MINIMUM_AMOUNT- 触发条件: 购物车合计低于处理支付所需的最低金额
- 消息: 处理支付至少需要
{display_str}
-
UNSUPPORTED_BILLING_CURRENCY- 触发条件: 请求的计费货币不支持此订阅
- 消息: 订阅不支持非 USD 计费货币
-
UNSUPPORTED_COUNTRY- 触发条件: 不支持该国家/地区
- 消息: 当前不支持国家/地区
{country_name}
-
UNSUPPORTED_CURRENCY- 触发条件: 产品或附加项货币不是 Dodo Payments 可用于扣款的货币。基础价格可以使用任何可扣款货币设置,因此此错误通常表示货币代码无效或不受支持。
- 消息: 当前不支持此货币 (或) 目前仅支持 USD 和 INR 产品 (或) 附加项价格目前仅支持 USD 和 INR (或) billing_currency 只能请求 USD 或 INR (或) 不支持的货币 (或) 印度卡订阅使用了意外货币
-
UNSUPPORTED_TAX_CATEGORY- 触发条件: 税务类别不是受支持的值
- 消息: 当前不支持类别
{category}
验证与请求
-
DUPLICATE_LINE_ITEMS_IN_REQUEST- 触发条件: 同一个
item_id在items[]中出现多次 - 消息: items 数组中指定了重复的 item_ids
- 触发条件: 同一个
-
INVALID_QUERY_PARAMS- 触发条件: 查询参数互斥或格式错误
- 消息: 查询参数只能包含 time_frame,或包含 (start, end) (或) 范围的开始时间不能晚于结束时间
-
INVALID_REQUEST_BODY- 触发条件: JSON 格式错误或违反架构
- 消息: 请求正文无效。请检查请求标头和对象。
-
INVALID_REQUEST_PARAMETERS- 触发条件: 参数值格式有效但语义无效,例如过去的日期
- 消息: 无法将 next_billing_date 更改为过去的时间
-
MAXIMUM_KEYS_REACHED- 触发条件: Metadata 或自定义字段超过 50 个键值对
- 消息: 超过 50 个键值对
常规与系统
-
INTEGER_CONVERSION_FAILURE- 触发条件: 服务器端在整数与字符串或小数之间转换失败,例如购物车总额过大而无法处理
- 消息: 整数转换失败 (或) 购物车总额过大,无法处理。请减少数量,或选择其他计费货币。
-
INTERNAL_SERVER_ERROR- 触发条件: 意外的服务器错误。请在本地记录请求详情。
- 消息: 无公开消息(通用 500,
message通常为null)
-
NOT_FOUND- 触发条件: 任何缺失资源的通用 404
- 消息: 未找到项目 (或返回说明缺失内容的更具体消息)
-
TOO_MANY_REQUESTS- 触发条件: 超出速率限制(HTTP 429)
- 消息: 无消息
-
UNSUPPORTED_ACTION- 触发条件: 执行资源类型不支持的操作
- 消息: 不支持更改基于用量的订阅套餐
最佳实践
处理 API 错误时,请遵循以下实践:- 在应用中处理每个错误响应,并根据
code而不是message进行分支处理。 - 记录每个失败请求的 HTTP 状态、
code和message。 - 向最终用户显示为其编写的消息,而不是原始 API
message。 - 仅在延迟一段时间后重试暂时性错误,例如
429和5xx响应或DISCOUNT_CONCURRENT_REDEMPTION。 - 对于无法解决的错误,请联系支持团队。