概述
Dodo Payments API 使用标准 HTTP 状态代码和自定义错误代码来指示 API 请求的成功或失败。当发生错误时,API 会返回适当的 HTTP 状态代码和包含错误详细信息的 JSON 响应。 每个错误响应包括:- 指示错误一般类别的 HTTP 状态代码
- 识别错误确切性质的特定错误代码
- 解释出错原因的人类可读错误消息
- 适用时关于错误的附加详细信息
- 调试集成问题
- 在您的应用程序中实现适当的错误处理
- 向最终用户提供有意义的反馈
- 维护强大的支付处理系统
INSUFFICIENT_FUNDS 或 CARD_DECLINED),请参阅 交易失败 参考。
标准 API 错误代码
| HTTP 状态 | 名称 | 描述 |
|---|---|---|
| 400 | 错误请求 | 请求格式错误或包含无效参数 |
| 401 | 未授权 | 认证失败或 API 密钥无效 |
| 403 | 禁止 | API 密钥无权限访问请求的资源 |
| 404 | 未找到 | 请求的资源不存在 |
| 405 | 方法不允许 | 此端点不支持 HTTP 方法 |
| 409 | 冲突 | 请求与资源的当前状态冲突 |
| 422 | 无法处理的实体 | 请求格式正确但包含语义错误 |
| 429 | 请求过多 | 超出速率限制 |
| 500 | 内部服务器错误 | 服务器发生意外错误 |
| 502 | 错误网关 | 服务器从上游服务器收到无效响应 |
| 503 | 服务不可用 | 服务暂时不可用 |
| 504 | 网关超时 | 服务器在等待上游响应时超时 |
错误响应格式
当发生错误时,API 返回具有以下结构的 JSON 响应:错误代码参考
下面的错误代码按与 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- 触发条件: 尝试对已全额退款的订单项进行退款
- 消息: 订单项 已被全额退款,无法进一步退款。
-
LINE_ITEM_NOT_FOUND- 触发条件: 项目 ID 不在所引用的付款中
- 消息: 付款中未找到订单项
-
LINE_ITEM_PRORATED- 触发条件: 尝试对按比例分配的订单进行退款或更新
- 消息: 订单项 无法退款,因为它是按比例分配的
-
LINE_ITEM_REFUND_AMOUNT_TOO_HIGH- 触发条件: 退款金额 > 支付金额(含税)
- 消息: 订单项 请求的退款金额含税为 ,超过支付金额
-
LINE_ITEM_REFUND_AMOUNT_TOO_LOW- 触发条件: 退款金额低于最低阈值
- 消息: 订单项 请求的退款金额为 ,过低
-
NOTHING_TO_REFUND- 触发条件: 无可退款金额;所有正数订单项已全额退款
- 消息: 无可退款金额。所有正数订单项已被全额退款。
-
PARTIAL_REFUND_NOT_ALLOWED- 触发条件: 尝试对仅支持全额退款的支付方式进行部分退款
- 消息: 此付款方式不允许部分退款
-
PAYMENT_ALREADY_REFUNDED- 触发条件: 重复退款
- 消息: 此付款已被退款
-
PAYMENT_HAS_BEEN_REFUNDED- 触发条件: 付款已全额退款
- 消息: 付款 ID 已被全额退款。
-
REFUND_AMOUNT_EXCEEDS_PAID_AMOUNT- 触发条件: 汇总退款金额 > 支付金额
- 消息: 计算的退款金额大于支付金额
-
REFUND_WINDOW_EXPIRED- 触发条件: 超出允许的退款时间窗口
- 消息: 付款创建 天后无法发起退款。联系 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- 触发条件: 为已经有订阅的客户创建订阅,而不允许每个客户有多个订阅
- 消息: 客户 已有现有订阅。要允许每个客户有多个订阅,请更改业务设置
-
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 不存在:
- 触发条件:
-
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- 触发条件: 产品存在但缺少必要信息
- 消息: 产品 存在但其他必要信息缺失或无效
-
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 不存在:
基于信用的计费
-
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- 触发条件: 购物车总计 < 网关最低金额
- 消息: 需要最低金额 才可处理付款
-
UNSUPPORTED_BILLING_CURRENCY- 触发条件: 订阅仅限 USD
- 消息: 订阅不支持非 USD 计费货币
-
UNSUPPORTED_COUNTRY- 触发条件: 地区尚未支持
- 消息: 目前不支持国家
-
UNSUPPORTED_CURRENCY- 触发条件: 产品或附加项货币无效
- 消息: 当前不支持该货币/目前只支持 USD 和 INR 产品/仅支持 USD 和 INR 附加价格/只能请求 USD 或 INR 作为计费货币/货币不支持/印度卡订阅的意外货币
-
UNSUPPORTED_TAX_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- 触发条件: 不支持资源类型操作
- 消息: 不支持基于使用量的订阅更改计划
最佳实践
- 始终在应用程序中优雅地处理错误
- 实现适当的错误日志记录
- 为最终用户使用适当的错误消息
- 为瞬时错误实施重试逻辑
- 对于未解决的问题请联系支持