Skip to main content

概述

当请求失败时,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。
    • 消息: 此发票的所有手动重试次数均已用尽 (或) 此发票暂时无法立即重试
  • 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 按比例计费模式
  • 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。
    • 消息: 此订阅已存在待处理的计划变更。请等待当前付款完成。
  • 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_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 错误时,请遵循以下实践:
  1. 在应用中处理每个错误响应,并根据 code 而不是 message 进行分支处理。
  2. 记录每个失败请求的 HTTP 状态、code 和 message。
  3. 向最终用户显示为其编写的消息,而不是原始 API message。
  4. 仅在延迟一段时间后重试临时错误,例如 429 和 5xx 响应,或 DISCOUNT_CONCURRENT_REDEMPTION。
  5. 对于无法自行解决的错误,请联系支持团队。

支持

如需有关错误代码或集成问题的更多帮助,请通过 support@dodopayments.com 联系支持团队。
最后修改于 2026年10月8日