Skip to main content

Tổng Quan

Khi một yêu cầu không thành công, Dodo Payments API trả về mã trạng thái HTTP và phần nội dung JSON nêu rõ lỗi. Sử dụng trang này để tìm nguyên nhân gây lỗi và cách khắc phục. Mỗi phản hồi lỗi bao gồm:
  • Mã trạng thái HTTP cho biết nhóm lỗi chung.
  • code xác định lỗi cụ thể, ví dụ UNSUPPORTED_COUNTRY.
  • message giải thích lỗi bằng ngôn ngữ dễ hiểu. message có thể là null, chẳng hạn với lỗi máy chủ nội bộ.
Phân nhánh xử lý lỗi dựa trên code, không dựa trên message. Một số mã có thể trả về nhiều thông báo tùy theo nguyên nhân. Sử dụng các mã lỗi này để:
  • Gỡ lỗi các vấn đề tích hợp.
  • Xử lý lỗi chính xác trong ứng dụng.
  • Hiển thị phản hồi hữu ích cho khách hàng.
  • Duy trì độ tin cậy của quá trình xử lý thanh toán.
Đây là các lỗi API và logic nghiệp vụ. Để xem lý do thẻ bị từ chối được trả về khi thanh toán không thành công (chẳng hạn INSUFFICIENT_FUNDS hoặc CARD_DECLINED), hãy xem tài liệu tham chiếu Transaction Failures.

Mã lỗi API tiêu chuẩn

API sử dụng các mã trạng thái HTTP sau cho lỗi:

Định dạng phản hồi lỗi

Nội dung phản hồi lỗi chứa hai trường, code và message:

Tham chiếu mã lỗi

Các mã lỗi bên dưới được nhóm theo khu vực API liên quan. Mỗi mục liệt kê điều kiện kích hoạt lỗi và thông báo API trả về. Các placeholder như {id} đại diện cho các giá trị do API điền vào.

Xác thực & tài khoản

  • UNAUTHORIZED
    • Trigger: Yêu cầu không có API key hoặc API key không hợp lệ (HTTP 401), hoặc API key không có role mà hành động yêu cầu (HTTP 403)
    • Message: Bạn không được phép thực hiện hành động này
  • MERCHANT_NOT_LIVE
    • Trigger: Yêu cầu ở live mode đối với doanh nghiệp chưa bật live payments (HTTP 403). Trường hợp này bao gồm doanh nghiệp chỉ từng sử dụng test mode và doanh nghiệp chưa bật live payments vì verification chưa hoàn tất. Yêu cầu ở test mode không bị ảnh hưởng.
    • Message: Live payments chưa được bật cho merchant
  • BUSINESS_ARCHIVED
    • Trigger: Bất kỳ yêu cầu hướng đến khách hàng nào đối với doanh nghiệp đã được lưu trữ (HTTP 403). Trường hợp này bao gồm checkout, payment links, storefront, Customer Portal và kích hoạt license key.
    • Message: Doanh nghiệp này đã được lưu trữ và không còn chấp nhận yêu cầu

Thanh toán & Checkout

  • CHECKOUT_SESSION_CONSUMED
    • Trigger: Checkout session đã tạo payment (HTTP 403). Thay vào đó, hãy tạo checkout session mới.
    • Message: Payment với checkout session đã cho đã được tạo.
  • MANUAL_RETRY_ALREADY_PAID
    • Trigger: Manual retry của renewal invoice mà payment đã thành công. Gửi lại sẽ khiến khách hàng bị tính phí hai lần.
    • Message: Một payment trên invoice này đã thành công
  • MANUAL_RETRY_HARD_DECLINE
    • Trigger: Manual retry khi lỗi mới nhất trên invoice là hard decline hoặc không có error code được phân loại. Một lần tính phí khác trên cùng thẻ không thể thành công, vì vậy hãy cập nhật payment method.
    • Message: Lỗi gần nhất trên invoice này là hard decline nên retry không thể thành công (hoặc) Lỗi gần nhất trên invoice này không thể được phân loại nên không thể retry
  • MANUAL_RETRY_IN_FLIGHT
    • Trigger: Manual retry trong khi payment trên invoice đang processing hoặc chưa có status được ghi nhận. Hãy chờ kết quả của payment đó thay vì gửi lại.
    • Message: Một payment trên invoice này vẫn đang được xử lý
  • MANUAL_RETRY_LIMIT_REACHED
    • Trigger: Manual retry sau khi đã sử dụng cả 3 lần gửi trên invoice hoặc trước khi hết thời gian cooldown (HTTP 429). Lần gửi thứ hai chờ 1 giờ sau lần đầu, và lần thứ ba chờ 3 giờ sau lần thứ hai. Body chỉ chứa code và message. Để biết khi nào được phép gửi tiếp, hãy đọc retry_available_at từ GET /payments/{payment_id}/retry.
    • Message: Đã sử dụng hết mọi manual retry cho invoice này (hoặc) Chưa thể retry invoice này ngay
  • NO_ELIGIBLE_PAYMENT_METHODS
    • Trigger: Không còn payment method khả dụng cho payment sau khi lọc (HTTP 422)
    • Message: Không tìm thấy payment method đủ điều kiện
  • PAYMENT_NOT_PERMITTED
    • Trigger: Checkout hoặc payment attempt của khách hàng có trong blocklist của merchant (HTTP 403). Mã và thông báo cố ý không nêu nguyên nhân.
    • Message: Không thể xử lý payment này.
  • PAYMENT_NOT_RETRYABLE
    • Trigger: Manual retry của payment không thuộc phạm vi manual retry. Payment không có invoice, invoice không phải là open subscription renewal, chưa có payment nào trên invoice bị lỗi, subscription chưa cấu hình recurring billing (ví dụ subscription on-demand), hoặc khách hàng có trong blocklist.
    • Message: Thay đổi tùy theo nguyên nhân, ví dụ: Chỉ có thể retry payment của subscription renewal
  • PAYMENT_NOT_SUCCEEDED
    • Trigger: Cố gắng refund hoặc xử lý payment chưa thành công
    • Message: Payment được cung cấp chưa thành công
  • PREVIOUS_PAYMENT_PENDING
    • Trigger: Cố gắng tạo charge khi payment trước đó đang ở trạng thái chưa kết thúc. Cũng được trả về khi manual retry nếu payment mới nhất trên invoice không phải failed cũng không đang xử lý, chẳng hạn requires_customer_action hoặc cancelled.
    • Message: Không thể tạo charge mới vì payment trước đó chưa thành công (hoặc) Payment mới nhất trên invoice này chưa thất bại
  • UNSUCCESSFUL_PAYMENT_ID
    • Trigger: Payment ID tham chiếu đến payment chưa thành công
    • Message: Payment ID có status không thành công.

Connectors & BYOP

Các lỗi này liên quan đến payment connector do merchant sở hữu (Bring Your Own Processor, hoặc BYOP).
  • BYOP_CONNECTOR_DISABLED
    • Trigger: Cập nhật payment method của subscription được định tuyến qua BYOP connector đã tắt. Dodo Payments không chuyển dự phòng sang connector của mình, vì vậy trước tiên hãy bật lại connector.
    • Message: Subscription được định tuyến qua connector riêng của merchant (BYOP), hiện đang bị tắt
  • BYOP_CUSTOM_INVOICE_ADDRESS_MISSING
    • Trigger: Payment được định tuyến qua connector của merchant (BYOP) không có custom invoice address
    • Message: Cần có BYOP custom invoice address khi payment được định tuyến qua connector của merchant
  • CONNECTOR_LABEL_ALREADY_EXISTS
    • Trigger: Tạo connector với label đã tồn tại
    • Message: Connector với label này đã tồn tại. Vui lòng chọn label khác.

Refund

  • EXISTING_REFUND_REQUEST_PROCESSING
    • Trigger: Yêu cầu refund trước đó vẫn đang được xử lý
    • Message: Yêu cầu refund với status “Pending” vẫn đang được xử lý
  • LINE_ITEM_FULLY_REFUNDED
    • Trigger: Cố gắng refund line item đã được refund toàn bộ
    • Message: Line item {id} đã được refund toàn bộ và không thể refund thêm.
  • LINE_ITEM_NOT_FOUND
    • Trigger: Item ID không thuộc payment được tham chiếu
    • Message: Không tìm thấy line item {id} trong payment
  • LINE_ITEM_PRORATED
    • Trigger: Refund hoặc update được thực hiện trên line item prorated
    • Message: Không thể refund line item {id} vì line item này là prorated
  • LINE_ITEM_REFUND_AMOUNT_TOO_HIGH
    • Trigger: Số tiền refund, bao gồm tax, cao hơn số tiền đã thanh toán
    • Message: Số tiền refund được yêu cầu cho line item {id}, bao gồm tax, là {amount}, cao hơn số tiền đã thanh toán {amount}
  • LINE_ITEM_REFUND_AMOUNT_TOO_LOW
    • Trigger: Số tiền refund thấp hơn ngưỡng tối thiểu
    • Message: Số tiền refund được yêu cầu cho line item {id} là {amount}, quá thấp
  • NOTHING_TO_REFUND
    • Trigger: Không còn số tiền có thể refund vì tất cả line item dương đã được refund toàn bộ
    • Message: Không còn số tiền có thể refund. Tất cả line item dương đã được refund toàn bộ.
  • PARTIAL_REFUND_NOT_ALLOWED
    • Trigger: Cố gắng refund một phần bằng payment method chỉ hỗ trợ refund toàn bộ
    • Message: Payment method này không cho phép refund một phần
  • PAYMENT_ALREADY_REFUNDED
    • Trigger: Refund trùng lặp
    • Message: Payment này đã được refund
  • PAYMENT_HAS_BEEN_REFUNDED
    • Trigger: Payment đã được refund toàn bộ
    • Message: Payment ID đã được refund toàn bộ.
  • REFUND_AMOUNT_EXCEEDS_PAID_AMOUNT
    • Trigger: Tổng số tiền refund cao hơn số tiền đã thanh toán
    • Message: Số tiền refund được tính lớn hơn số tiền đã thanh toán
  • REFUND_WINDOW_EXPIRED
    • Trigger: Refund được yêu cầu ngoài khoảng thời gian cho phép
    • Message: Không thể bắt đầu refund {days} ngày sau khi tạo payment. Hãy liên hệ support@dodopayments.com.
  • ZERO_AMOUNT_PAYMENT_REFUND_NOT_ALLOWED
    • Trigger: Cố gắng refund payment có số tiền bằng 0
    • Message: Không thể refund payment có số tiền tiền tệ bằng 0

Subscription & Add-on

  • ADDONS_IN_USAGE_BASED_BILLING_NOT_SUPPORTED
    • Trigger: Cố gắng thêm add-on vào subscription usage-based billing
    • Message: Không hỗ trợ Addon trong Subscription cho Usage Based Billing
  • ADDONS_NOT_ALLOWED_FOR_ON_DEMAND
    • Trigger: Cố gắng thêm add-on vào subscription on-demand
    • Message: Không cho phép Addon đối với subscription on demand
  • CANCEL_SCHEDULED_PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED
    • Trigger: Customer Portal cố gắng hủy scheduled plan change trong khi doanh nghiệp đã tắt hành động này
    • Message: Đã tắt việc hủy scheduled plan change trên customer portal.
  • CHARGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION
    • Trigger: Cố gắng charge subscription được lên lịch hủy
    • Message: Subscription được lên lịch hủy
  • CUSTOMER_HAS_EXISTING_SUBSCRIPTION
    • Trigger: Tạo subscription cho khách hàng đã có một subscription, khi doanh nghiệp không cho phép nhiều subscription trên mỗi khách hàng
    • Message: Khách hàng {id} đã có subscription. Để cho phép nhiều subscription trên mỗi khách hàng, hãy thay đổi business settings
  • DO_NOT_BILL_NOT_ALLOWED_IN_CUSTOMER_PORTAL
    • Trigger: Sử dụng chế độ proration do_not_bill trong plan change của Customer Portal
    • Message: Chế độ proration do_not_bill không được phép trong customer portal
  • DUPLICATE_ADDON_IDS_IN_REQUEST
    • Trigger: Cùng một addon_id xuất hiện nhiều lần trong yêu cầu
    • Message: Không cho phép addon ID trùng lặp
  • INACTIVE_SUBSCRIPTION_PLAN_CHANGE_NOT_SUPPORTED
    • Trigger: Plan change trên subscription không hoạt động
    • Message: Không hỗ trợ thay đổi plan cho subscription không hoạt động
  • INVALID_PRORATION_MODE_WITH_NEXT_BILLING_DATE
    • Trigger: Sử dụng chế độ proration khác full_immediately với effective_at: next_billing_date
    • Message: Chỉ cho phép chế độ proration full_immediately với effective_at: next_billing_date
  • MISSING_ADDON_IDS
    • Trigger: Danh sách addon_id trống hoặc chứa ID không xác định
    • Message: Một hoặc nhiều product ID không tồn tại: {id}
  • ON_DEMAND_PLAN_CHANGE_NOT_SUPPORTED
    • Trigger: Plan change trên subscription on-demand
    • Message: Không hỗ trợ thay đổi plan cho subscription on demand
  • ON_DEMAND_USAGE_BASED_BILLING_NOT_SUPPORTED
    • Trigger: Cố gắng sử dụng subscription on-demand với usage-based billing
    • Message: Không hỗ trợ On Demand Subscriptions cho Usage Based Billing
  • ONE_TIME_PRODUCTS_NOT_ALLOWED_FOR_ON_DEMAND
    • Trigger: Thêm sản phẩm one-time vào subscription on-demand
    • Message: Không cho phép sản phẩm one-time đối với subscription on demand
  • PENDING_PLAN_CHANGE_EXISTS
    • Trigger: Yêu cầu plan change mới trong khi plan change trước đó vẫn đang chờ thanh toán
    • Message: Đã tồn tại plan change đang chờ xử lý cho subscription này. Vui lòng chờ payment hiện tại hoàn tất.
  • PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED
    • Trigger: Plan change qua Customer Portal trong khi doanh nghiệp đã tắt tính năng này
    • Message: Đã tắt subscription plan change cho customer portal.
  • PLAN_CHANGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION
    • Trigger: Plan change trên subscription được lên lịch hủy
    • Message: Subscription được lên lịch hủy
  • SCHEDULE_PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED
    • Trigger: Lên lịch plan change qua Customer Portal trong khi doanh nghiệp đã tắt tính năng này
    • Message: Doanh nghiệp này đã tắt việc lên lịch plan change.
  • SCHEDULED_PLAN_CHANGE_EXISTS
    • Trigger: Tạo scheduled plan change khi đã có một scheduled plan change khác
    • Message: Đã tồn tại scheduled plan change cho subscription này. Vui lòng hủy scheduled change hiện tại trước khi tạo change mới.
  • SCHEDULED_PLAN_CHANGE_NOT_FOUND
    • Trigger: Tham chiếu hoặc hủy scheduled plan change không tồn tại
    • Message: Không tìm thấy scheduled plan change cho subscription này.
  • SUBSCRIPTION_EXPIRED
    • Trigger: Billing subscription sau ngày expires_at
    • Message: Subscription đã hết hạn, không thể tạo charge mới
  • SUBSCRIPTION_HAS_NO_PAYMENT_METHOD
    • Trigger: Manual retry của subscription không có payment method đã lưu để charge off-session
    • Message: Subscription này không có payment method đã lưu để charge
  • SUBSCRIPTION_INACTIVE
    • Trigger: Subscription status không phải active
    • Message: Subscription không hoạt động (hoặc) Subscription này không live nên không thể lên lịch hủy
  • SUBSCRIPTION_NOT_ON_DEMAND
    • Trigger: Hành động on-demand trên subscription billing theo khoảng thời gian cố định
    • Message: Subscription vốn đã không phải on demand
  • SUBSCRIPTION_PAYMENT_RETRY_LIMIT_EXCEEDED
    • Trigger: Số lần retry payment của subscription vượt quá số lần thử tối đa
    • Message: Subscription đã vượt quá giới hạn retry tối đa là 10 lần thử

Khách hàng & Blocklist

  • CUSTOMER_ALREADY_BLOCKED
    • Trigger: Chặn khách hàng đã có trong blocklist và không còn live subscription nào cần hủy (HTTP 409)
    • Message: Khách hàng này đã có trong blocklist
  • PORTAL_ACTION_NOT_PERMITTED
    • Trigger: Khách hàng bị chặn gọi route ghi của Customer Portal: hủy, tạm dừng, tiếp tục, thay đổi plan hoặc cập nhật payment method (HTTP 403). Các route đọc vẫn hoạt động. Mã và thông báo cố ý không nêu nguyên nhân.
    • Message: Hành động này không khả dụng.

Sản phẩm, Cart & Brand

  • BRAND_ALREADY_ARCHIVED
    • Trigger: Lưu trữ brand đã được lưu trữ
    • Message: Brand đã được lưu trữ
  • BRAND_ARCHIVED
    • Trigger: Cập nhật brand đã lưu trữ, gửi brand để verification hoặc gắn sản phẩm, product collection hoặc subscription mới vào brand đó
    • Message: Brand đã được lưu trữ (hoặc) Brand đã được lưu trữ và không thể cập nhật (hoặc) Brand đã được lưu trữ và không thể gửi để verification
  • BRAND_ARCHIVE_TARGET_REQUIRED
    • Trigger: Lưu trữ brand vẫn còn chứa sản phẩm, live subscription hoặc product collection mà không có target move_products_to
    • Message: Brand có {count} sản phẩm. Đặt move_products_to thành brand đích để gắn thẻ lại. Thông báo sẽ nêu live subscription hoặc product collection nếu chúng là nguyên nhân ngăn việc lưu trữ.
  • BRAND_MISMATCH
    • Trigger: Các cart item thuộc các brand khác nhau
    • Message: Tất cả item trong product cart phải thuộc cùng một brand
  • BRAND_NOT_ENABLED
    • Trigger: Brand bị tắt hoặc không hoạt động
    • Message: Brand được cung cấp chưa được bật
  • BRAND_SUBMISSION_NOT_ENABLED
    • Trigger: Tính năng gửi lại brand verification chưa được bật
    • Message: Brand verificatin resubmission is not enabled (được viết chính xác như API trả về)
  • CANNOT_ARCHIVE_PRIMARY_BRAND
    • Trigger: Lưu trữ brand chính, brand có ID là business ID
    • Message: Không thể lưu trữ brand chính
  • FILE_IN_USE
    • Trigger: Xóa tệp sản phẩm kỹ thuật số vẫn được các active entitlement grant tham chiếu
    • Message: Tệp kỹ thuật số được các active grant tham chiếu
  • INVALID_BRAND_ARCHIVE_TARGET
    • Trigger: move_products_to chỉ định brand đang được lưu trữ, brand đã lưu trữ hoặc brand của doanh nghiệp khác
    • Message: move_products_to phải là brand của doanh nghiệp này và chưa được lưu trữ (hoặc) move_products_to không thể là brand bạn đang lưu trữ
  • INVALID_SUGGESTED_PRICE
    • Trigger: Giá đề xuất Pay What You Want thấp hơn giá tối thiểu
    • Message: Suggested Price không thể thấp hơn minimum price. Với pay what you want, price được xem là số tiền tối thiểu được chấp nhận
  • LOCALIZED_PRICE_ALREADY_EXISTS
    • Trigger: Đã tồn tại localized price cho sản phẩm và quốc gia hoặc currency này
    • Message: Đã tồn tại localized price cho sản phẩm và quốc gia/currency này
  • LOCALIZED_PRICE_DUPLICATES_BASE
    • Trigger: Localized price trùng với base currency hoặc quốc gia cơ sở của sản phẩm
    • Message: Localized price trùng với base currency/country của sản phẩm
  • LOCALIZED_PRICE_SHAPE_MISMATCH
    • Trigger: Cấu trúc localized price không khớp với pricing_mode của sản phẩm
    • Message: Cấu trúc localized price không khớp với pricing_mode của sản phẩm
  • MISSING_PRODUCT_INFORMATION
    • Trigger: Sản phẩm tồn tại nhưng thiếu thông tin bắt buộc
    • Message: Sản phẩm {id} tồn tại nhưng thiếu hoặc có thông tin bắt buộc không hợp lệ
  • PAY_AS_YOU_WANT_AMOUNT_REQUIRED
    • Trigger: Thiếu amount đối với sản phẩm Pay What You Want
    • Message: Amount là bắt buộc đối với sản phẩm pay as you want
  • PRODUCT_CART_EMTPY
    • Trigger: Gửi product cart trống
    • Message: product_cart trống (error code được viết cố ý là EMTPY để khớp chính xác với giá trị API trả về)
  • PRODUCT_COLLECTION_IS_DELETED
    • Trigger: Thao tác trên product collection đã bị xóa
    • Message: Không có thông báo
  • PRODUCT_COLLECTION_MUST_HAVE_PRODUCTS
    • Trigger: Xóa sản phẩm cuối cùng hoặc group cuối cùng chứa sản phẩm khỏi collection
    • Message: Không thể xóa sản phẩm cuối cùng trong collection. Thay vào đó, hãy lưu trữ collection. (hoặc) Không thể xóa group cuối cùng chứa sản phẩm. Thay vào đó, hãy lưu trữ collection.
  • PRODUCT_IS_DELETED
    • Trigger: Sản phẩm đã bị xóa
    • Message: Không có thông báo
  • PRODUCT_PRICING_MODE_REQUIRED
    • Trigger: Thêm localized price trước khi đặt pricing_mode của sản phẩm
    • Message: Phải đặt pricing_mode của sản phẩm trước khi thêm localized price
  • SLUG_ALREADY_TAKEN
    • Trigger: Product slug hoặc short URL được yêu cầu đã được sử dụng
    • Message: Slug đã được sử dụng
  • UNABLE_TO_EDIT_PRIMARY_BRAND
    • Trigger: Cố gắng cập nhật brand chính qua brand API thông thường
    • Message: Không thể cập nhật brand chính qua API endpoint này.

Discount

  • DISCOUNT_ALREADY_USED_ON_SUBSCRIPTION
    • Trigger: Áp dụng lại discount đã được sử dụng cho subscription này
    • Message: Discount này đã được sử dụng cho subscription này
  • DISCOUNT_CODE_ALREADY_EXISTS
    • Trigger: Tạo discount code đã tồn tại
    • Message: Discount Code đã tồn tại
  • DISCOUNT_CODE_EXPIRED
    • Trigger: Discount code đã quá ngày expires_at
    • Message: Discount code đã hết hạn
  • DISCOUNT_CODE_USAGE_LIMIT_EXCEEDED
    • Trigger: Discount code được sử dụng sau khi đạt usage_limit
    • Message: Usage limit không thể nhỏ hơn times_used (hoặc) Discount code đã đạt usage limit
    • Note: Terminal. Code đã cạn, vì vậy không retry.
  • DISCOUNT_CONCURRENT_REDEMPTION
    • Trigger: Một lần redemption khác của cùng code giữ usage-limit lock quá lâu (HTTP 503)
    • Message: Discount đang được redemption đồng thời; vui lòng retry
    • Note: Transient. Code vẫn có thể còn capacity, vì vậy yêu cầu an toàn để retry. Không hiển thị thông báo này cho khách hàng như thể code đã cạn.
  • DISCOUNT_CURRENCY_OPTION_INVALID
    • Trigger: currency_options không hợp lệ khi create hoặc update
    • Message: Flat discount yêu cầu ít nhất một currency option có default có thể phân giải (hoặc) Không cho phép currency option trùng lặp (hoặc) Chỉ một currency option có thể được đánh dấu là default
  • DISCOUNT_CUSTOMER_NOT_ELIGIBLE
    • Trigger: Khách hàng không đáp ứng customer_eligibility của code (first_time, existing hoặc không có trong allow list của code specific)
    • Message: Khách hàng không đủ điều kiện cho discount code này
  • DISCOUNT_MINIMUM_SUBTOTAL_NOT_MET
    • Trigger: Cart subtotal thấp hơn minimum_subtotal được cấu hình cho checkout currency
    • Message: Cart subtotal thấp hơn subtotal tối thiểu được yêu cầu của discount
  • DISCOUNT_NOT_YET_ACTIVE
    • Trigger: Code được sử dụng trước ngày starts_at
    • Message: Discount code chưa hoạt động (starts_at ở tương lai)
  • DISCOUNT_PER_CUSTOMER_USAGE_LIMIT_EXCEEDED
    • Trigger: Khách hàng đã redemption code per_customer_usage_limit lần
    • Message: Đã vượt quá usage limit trên mỗi khách hàng cho discount code này
  • DISCOUNT_NOT_APPLICABLE_TO_NEW_PRODUCT
    • Trigger: Plan change sang sản phẩm không áp dụng discount hiện tại
    • Message: Discount không áp dụng cho sản phẩm của plan mới
  • DISCOUNT_NOT_AVAILABLE_FOR_ON_DEMAND
    • Trigger: Áp dụng code cho subscription on-demand
    • Message: Discount coupon không khả dụng cho subscription on demand
  • DISCOUNT_NOT_AVAILABLE_FOR_PRODUCT
    • Trigger: Áp dụng code cho các sản phẩm không được code bao phủ
    • Message: Discount coupon không khả dụng cho sản phẩm này
  • INVALID_DISCOUNT_CODE
    • Trigger: Code không tồn tại hoặc không áp dụng cho bất kỳ sản phẩm nào trong cart
    • Message: Discount Code không hợp lệ (hoặc) Không thể áp dụng Discount Code cho bất kỳ sản phẩm nào trong cart
  • INVALID_PERCENTAGE
    • Trigger: Tỷ lệ cao hơn 100% (10.000 basis point)
    • Message: Percentage amount không thể lớn hơn 10000 (hoặc) Discount code amount không thể lớn hơn 100%
  • UNSUPPORTED_DISCOUNT_TYPE
    • Trigger: Loại discount không được hỗ trợ. percentage và flat đều được hỗ trợ; discount amount theo từng đơn vị thì không.
    • Message: Chỉ hỗ trợ discount code dạng percentage và flat (hoặc) Hiện chỉ hỗ trợ discount code dạng percentage

License Key

  • ACTIVATION_LIMIT_LESS_THAN_CURRENT_AMOUNT
    • Trigger: Activation limit mới của license key thấp hơn số instance hiện tại
    • Message: Activation limit mới không thể nhỏ hơn số instance hiện tại
  • INACTIVE_LICENSE_KEY
    • Trigger: License key status không phải active
    • Message: License key không hoạt động
  • LICENSE_KEY_LIMIT_REACHED
    • Trigger: Số activation đã đạt activation limit
    • Message: Đã đạt activation limit của license key
  • LICENSE_KEY_NOT_FOUND
    • Trigger: Instance ID hoặc license key ID không hợp lệ
    • Message: Không tìm thấy license key instance hoặc instance không thuộc license key này
  • NO_EXPIRY_ON_SUBSCRIPTION_LICENSE_KEYS
    • Trigger: Cố gắng đặt expiry date cho license key dựa trên subscription
    • Message: Không thể đặt expiry date cho license key dựa trên subscription

Usage-Based Billing & Meter

  • DUPLICATE_METER_IDS_IN_REQUEST
    • Trigger: Cùng một meter ID xuất hiện nhiều lần trong yêu cầu
    • Message: Không cho phép Meter Id trùng lặp
  • INVALID_QUANTITY
    • Trigger: Quantity khác 1 đối với sản phẩm có usage-based pricing
    • Message: Chỉ cho phép quantity bằng 1 trong sản phẩm usage based price
  • METER_IS_DELETED
    • Trigger: Cố gắng sử dụng meter đã bị xóa
    • Message: Meter đã bị xóa
  • MISSING_METER_IDS
    • Trigger: Danh sách meter ID trống hoặc chứa ID không hợp lệ
    • Message: Một hoặc nhiều meter ID không tồn tại: {id}

Credit-Based Billing

  • CREDIT_ENTITLEMENT_IS_DELETED
    • Trigger: Thao tác trên credit entitlement đã bị xóa
    • Message: Credit entitlement đã bị xóa
  • CREDIT_ENTITLEMENT_NAME_ALREADY_EXISTS
    • Trigger: Tạo credit entitlement với name đã tồn tại
    • Message: Credit entitlement với name này đã tồn tại
  • OVERAGE_LIMIT_EXCEEDED
    • Trigger: Việc sử dụng hoặc khấu trừ credit sẽ vượt quá overage limit đã cấu hình
    • Message: Đã vượt quá overage limit

Wallet

  • INSUFFICIENT_WALLET_FUNDS
    • Trigger: Số dư wallet thấp hơn số tiền debit
    • Message: Không đủ tiền trong wallet
  • NEGATIVE_BALANCE_ADJUSTMENT
    • Trigger: Cố gắng khiến số dư wallet âm
    • Message: Không cho phép số dư wallet bị âm

Currency, Tax & Region

  • EXCHANGE_RATE_NOT_FOUND
    • Trigger: Không tồn tại exchange rate cho cặp currency
    • Message: Không tìm thấy exchange rate để chuyển đổi từ {currency} sang {currency}
  • INVALID_TAX_ID
    • Trigger: VAT, GST hoặc TIN không vượt qua validation
    • Message: Tax Id không hợp lệ
  • REQUEST_AMOUNT_BELOW_MINIMUM
    • Trigger: Amount thấp hơn mức tối thiểu được đặt cho sản phẩm
    • Message: Amount không thể thấp hơn amount tối thiểu được chỉ định cho sản phẩm
  • TOTAL_PAYMENT_AMOUNT_BELOW_MINIMUM_AMOUNT
    • Trigger: Tổng cart kết hợp thấp hơn amount tối thiểu cần thiết để xử lý payment
    • Message: Cần amount tối thiểu {display_str} để xử lý payment
  • UNSUPPORTED_BILLING_CURRENCY
    • Trigger: Billing currency được yêu cầu không được hỗ trợ cho subscription này
    • Message: Không hỗ trợ billing currency khác USD cho subscription
  • UNSUPPORTED_COUNTRY
    • Trigger: Quốc gia không được hỗ trợ
    • Message: Quốc gia {country_name} hiện không được hỗ trợ
  • UNSUPPORTED_CURRENCY
    • Trigger: Currency của sản phẩm hoặc add-on không phải currency mà Dodo Payments có thể charge. Base price có thể được đặt bằng bất kỳ currency nào có thể charge, vì vậy lỗi này thường có nghĩa là currency code không hợp lệ hoặc không được hỗ trợ.
    • Message: Currency hiện không được hỗ trợ (hoặc) Hiện chỉ hỗ trợ sản phẩm USD và INR (hoặc) Hiện chỉ hỗ trợ USD và INR cho addon price (hoặc) Chỉ có thể yêu cầu USD hoặc INR cho billing_currency (hoặc) Currency Not Supported (hoặc) Currency không mong đợi cho Indian card subscription
  • UNSUPPORTED_TAX_CATEGORY
    • Trigger: Tax category không thuộc các giá trị được hỗ trợ
    • Message: Category {category} hiện không được hỗ trợ

Validation & Request

  • DUPLICATE_LINE_ITEMS_IN_REQUEST
    • Trigger: Cùng một item_id xuất hiện nhiều lần trong items[]
    • Message: Đã chỉ định item_ids trùng lặp trong items array
  • INVALID_QUERY_PARAMS
    • Trigger: Query parameters loại trừ lẫn nhau hoặc không đúng định dạng
    • Message: Query params chỉ được chứa time_frame hoặc (start, end) (hoặc) Start của range không được sau end
  • INVALID_REQUEST_BODY
    • Trigger: JSON không đúng định dạng hoặc vi phạm schema
    • Message: Request body không hợp lệ. Vui lòng kiểm tra request headers và object.
  • INVALID_REQUEST_PARAMETERS
    • Trigger: Giá trị parameter đúng định dạng nhưng không hợp lệ về ý nghĩa, chẳng hạn ngày trong quá khứ
    • Message: Không thể thay đổi next_billing_date thành thời điểm trong quá khứ
  • MAXIMUM_KEYS_REACHED
    • Trigger: Metadata hoặc custom fields vượt quá 50 cặp key-value
    • Message: Vượt quá 50 cặp key-value

Chung & Hệ thống

  • INTEGER_CONVERSION_FAILURE
    • Trigger: Chuyển đổi phía máy chủ giữa integer và string hoặc decimal không thành công, chẳng hạn khi tổng cart quá lớn để xử lý
    • Message: Integer Conversion Failure (hoặc) Cart total quá lớn để xử lý. Hãy giảm quantity hoặc chọn billing currency khác.
  • INTERNAL_SERVER_ERROR
    • Trigger: Lỗi máy chủ không mong muốn. Hãy ghi log chi tiết request ở phía bạn.
    • Message: Không có thông báo công khai (generic 500, message thường là null)
  • NOT_FOUND
    • Trigger: 404 chung cho mọi tài nguyên bị thiếu
    • Message: Không tìm thấy item (hoặc thông báo cụ thể hơn nêu rõ nội dung bị thiếu)
  • TOO_MANY_REQUESTS
    • Trigger: Đã vượt quá rate limit (HTTP 429)
    • Message: Không có thông báo
  • UNSUPPORTED_ACTION
    • Trigger: Hành động không được resource type hỗ trợ
    • Message: Không hỗ trợ thay đổi plan cho usage based subscription

Best Practices

Hãy tuân thủ các phương pháp sau khi xử lý lỗi API:
  1. Xử lý mọi phản hồi lỗi trong ứng dụng và phân nhánh dựa trên code thay vì message.
  2. Ghi log HTTP status, code và message của mọi request không thành công.
  3. Hiển thị cho người dùng cuối thông báo được viết dành cho họ thay vì message thô từ API.
  4. Chỉ retry các lỗi transient, chẳng hạn phản hồi 429 và 5xx hoặc DISCOUNT_CONCURRENT_REDEMPTION, sau một khoảng thời gian chờ.
  5. Liên hệ bộ phận hỗ trợ đối với các lỗi bạn không thể khắc phục.

Hỗ trợ

Để được trợ giúp thêm về mã lỗi hoặc vấn đề tích hợp, hãy liên hệ đội ngũ hỗ trợ tại support@dodopayments.com.
Lần sửa đổi cuối 26 tháng 9, 2026