概述
当请求失败时,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- 触发条件: 在之前的计划变更仍在等待付款时请求新的计划变更。要替换待处理的 payment-link 变更,请设置
cancel_older_payment_link: true。 - 消息: 此订阅已存在待处理的计划变更。请等待当前付款完成。
- 触发条件: 在之前的计划变更仍在等待付款时请求新的计划变更。要替换待处理的 payment-link 变更,请设置
-
PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED- 触发条件: 通过 Customer Portal 进行套餐变更,但业务已禁用此功能
- 消息: Customer Portal 的订阅套餐变更已禁用。
-
PLAN_CHANGE_LINK_CANCEL_FAILED- 触发条件: 带有
cancel_older_payment_link: true的计划变更无法取消之前的付款链接。没有任何更改,因此可以重试请求。 - 消息: 无法取消之前的付款链接。请重试。
- 触发条件: 带有
-
PLAN_CHANGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION- 触发条件: 对已安排取消的订阅进行计划变更
- 消息: 订阅已安排取消
-
PLAN_CHANGE_PAYMENT_ALREADY_COMPLETED- 触发条件: 在客户已支付之前的计划变更时,发起带有
cancel_older_payment_link: true的计划变更。该变更会生效,因此不要重试。 - 消息: 客户已支付之前的计划变更。该变更很快就会生效。
- 触发条件: 在客户已支付之前的计划变更时,发起带有
-
PLAN_CHANGE_PAYMENT_IN_PROGRESS- 触发条件: 在客户正在支付之前的计划变更时,发起带有
cancel_older_payment_link: true的计划变更,例如正在进行 3D Secure 验证时。请在付款完成或失败后重试。 - 消息: 客户正在支付之前的计划变更。请稍后重试。
- 触发条件: 在客户正在支付之前的计划变更时,发起带有
-
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- 触发条件: 手动重试没有已保存 payment method、无法进行非现场扣款的订阅
- 消息: 此订阅没有可用于扣款的已保存 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 写入路由:取消、暂停、恢复、变更计划或更新 payment method(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 endpoint 更新主品牌。
折扣
-
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均受支持;不支持按单位金额折扣。 - 消息: 仅支持百分比和固定金额折扣代码 (或) 目前仅支持百分比折扣代码
- 触发条件: 不支持的折扣类型。
License Keys
-
ACTIVATION_LIMIT_LESS_THAN_CURRENT_AMOUNT- 触发条件: License Key 的新激活限制低于其当前实例数
- 消息: 新激活限制不能低于当前实例数
-
INACTIVE_LICENSE_KEY- 触发条件: License Key 状态不是
active - 消息: License Key 未处于活跃状态
- 触发条件: License Key 状态不是
-
LICENSE_KEY_LIMIT_REACHED- 触发条件: 激活次数已达到激活限制
- 消息: License Key 已达到激活限制
-
LICENSE_KEY_NOT_FOUND- 触发条件: 实例 ID 或 License Key ID 无效
- 消息: 未找到 License Key 实例,或该实例不属于此 License Key
-
NO_EXPIRY_ON_SUBSCRIPTION_LICENSE_KEYS- 触发条件: 尝试为基于订阅的 License Key 设置过期日期
- 消息: 无法为基于订阅的 License Key 设置过期日期
基于用量的计费与计量器
-
DUPLICATE_METER_IDS_IN_REQUEST- 触发条件: 同一 meter ID 在请求中出现多次
- 消息: 不允许重复的 Meter ID
-
INVALID_QUANTITY- 触发条件: 对使用量计费产品设置不为 1 的数量
- 消息: 使用量计费产品只允许数量为 1
-
METER_IS_DELETED- 触发条件: 尝试使用已删除的 meter
- 消息: Meter 已被删除
-
MISSING_METER_IDS- 触发条件: meter ID 列表为空或包含无效 ID
- 消息: 一个或多个 meter ID 不存在:
{id}
基于额度的计费
-
CREDIT_ENTITLEMENT_IS_DELETED- 触发条件: 对已删除的额度权益执行操作
- 消息: 额度权益已被删除
-
CREDIT_ENTITLEMENT_NAME_ALREADY_EXISTS- 触发条件: 创建名称已存在的额度权益
- 消息: 已存在具有此名称的额度权益
-
OVERAGE_LIMIT_EXCEEDED- 触发条件: 用量或额度扣减将超过配置的超额限制
- 消息: 已超过超额限制
Wallet
-
INSUFFICIENT_WALLET_FUNDS- 触发条件: Wallet 余额低于扣款金额
- 消息: Wallet 余额不足
-
NEGATIVE_BALANCE_ADJUSTMENT- 触发条件: 尝试使 Wallet 余额变为负数
- 消息: 不允许将 Wallet 余额变为负数
货币、税费与地区
-
EXCHANGE_RATE_NOT_FOUND- 触发条件: 不存在该货币对的汇率
- 消息: 未找到将货币从
{currency}转换为{currency}的汇率
-
INVALID_TAX_ID- 触发条件: VAT、GST 或 TIN 验证失败
- 消息: Tax Id 无效
-
REQUEST_AMOUNT_BELOW_MINIMUM- 触发条件: 金额低于产品设置的最低金额
- 消息: 金额不能低于产品指定的最低金额
-
TOTAL_PAYMENT_AMOUNT_BELOW_MINIMUM_AMOUNT- 触发条件: 包含税费的购物车总额低于处理付款所需的最低金额。最低金额取决于计费货币,以及付款是一次性付款还是订阅付款。对于 USD、EUR 和 GBP 以外的货币,还会将总额与 USD 最低金额进行比较。请参阅最低金额
- 消息: 处理付款需要至少
{display_str},例如Minimum amount of 1.00 USD is required to process payment
-
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 格式错误或违反 schema
- 消息: 请求正文无效。请检查请求标头和对象。
-
INVALID_REQUEST_PARAMETERS- 触发条件: 参数值格式有效但语义无效,例如使用过去的日期
- 消息: 无法将 next_billing_date 更改为过去的时间 (或) 包含多个订阅产品的结账不能包含一次性产品 (或) 所有产品 ID 必须唯一 (或) 按需订阅不能包含多个产品 (或) 一次结账最多可包含 20 个订阅产品 (或) 一次结账中不允许存在重复的订阅产品
-
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。 - 对于无法自行解决的错误,请联系支持团队。