Skip to main content

Change Plan API

Full API docs for updating subscriptions.

Plan Change Preview

See charge amounts before changing plans.

Integration Guide

Step-by-step subscription setup.

What is a subscription upgrade or downgrade?

Changing plans lets you move a customer between subscription tiers or quantities. Use it to:
  • Align pricing with usage or features
  • Move from monthly to annual (or vice versa)
  • Adjust quantity for seat-based products
Plan changes can trigger an immediate charge depending on the proration mode you choose.

When to use plan changes

  • Upgrade when a customer needs more features, usage, or seats
  • Downgrade when usage decreases
  • Migrate users to a new product or price without cancelling their subscription

Plan Change Flow

Prerequisites

Before implementing subscription plan changes, ensure you have:
  • A Dodo Payments merchant account with active subscription products
  • API credentials (API key and webhook secret key) from the dashboard
  • An existing active subscription to modify
  • Webhook endpoint configured to handle subscription events
For detailed setup instructions, see our Integration Guide.

Step-by-Step Implementation Guide

Follow this comprehensive guide to implement subscription plan changes in your application:
1

Understand Plan Change Requirements

Before implementing, determine:
  • Which subscription products can be changed to which others
  • What proration mode fits your business model
  • How to handle failed plan changes gracefully
  • Which webhook events to track for state management
Test plan changes thoroughly in test mode before implementing in production.
2

Choose Your Proration Strategy

Select the billing approach that aligns with your business needs:
Best for: SaaS applications wanting to charge fairly for unused time
  • Calculates exact prorated amount based on remaining cycle time
  • Charges a prorated amount based on unused time remaining in the cycle
  • Provides transparent billing to customers
3

Implement the Change Plan API

Use the Change Plan API to modify subscription details:
string
bắt buộc
The ID of the active subscription to modify.
string
bắt buộc
The new product ID to change the subscription to.
integer
bắt buộc
Number of units for the new plan (for seat-based products).
string
bắt buộc
How to handle immediate billing: prorated_immediately, full_immediately, difference_immediately, or do_not_bill.
array
Optional addons for the new plan. Leaving this empty removes any existing addons.
string
Controls behavior when the plan change payment fails:
  • prevent_change: Keep subscription on current plan until payment succeeds
  • apply_change (default): Apply plan change immediately regardless of payment outcome
If not specified, uses the business-level default setting.
Thu khoản tiền thay đổi gói bằng payment link thay vì tính phí vào phương thức thanh toán đã lưu của subscription. Khách hàng thanh toán trên trang checkout được lưu trữ.Yêu cầu capability allow_plan_change_via_payment_link của doanh nghiệp (Settings → Subscriptions → Collect Plan Change Payments by Payment Link), effective_at: immediatelyon_payment_failure: prevent_change. Xem Thu tiền qua Checkout Link.Bị bỏ qua bởi preview route.
array
Các mã giảm giá stacked tùy chọn để áp dụng cho gói mới (tối đa 20 mã, được áp dụng theo thứ tự trong array). Hành vi phụ thuộc vào giá trị bạn truyền:
  • Không được cung cấp / null — các khoản giảm giá hiện có với preserve_on_plan_change=true được giữ lại nếu áp dụng cho product mới.
  • [] (array rỗng) — xóa tất cả khoản giảm giá hiện có khỏi subscription.
  • ["CODE_A", "CODE_B", ...] — thay thế mọi khoản giảm giá hiện có bằng tập mã stacked này.
string
không còn sử dụng
Đã ngừng sử dụng — ưu tiên discount_codes cho các tích hợp mới. Field này vẫn hoạt động để đảm bảo khả năng tương thích ngược, nhưng không thể kết hợp với discount_codes trong cùng request.
string
mặc định:"immediately"
Thời điểm áp dụng thay đổi gói:
  • immediately (mặc định): Áp dụng thay đổi gói ngay lập tức
  • next_billing_date: Lên lịch thay đổi vào ngày thanh toán tiếp theo. Khách hàng giữ gói hiện tại cho đến khi kỳ thanh toán kết thúc.
Sử dụng next_billing_date cho các lần hạ cấp để khách hàng giữ được quyền lợi của gói hiện tại cho đến hết kỳ thanh toán.
4

Handle Webhook Events

Thiết lập việc xử lý webhook để theo dõi kết quả thay đổi gói:
  • subscription.active: Thay đổi gói thành công, subscription đã được cập nhật
  • subscription.plan_changed: Gói của subscription đã thay đổi (nâng cấp/hạ cấp/cập nhật addon)
  • subscription.on_hold: Tính phí thay đổi gói thất bại, các lần gia hạn bị dừng
  • payment.succeeded: Tính phí ngay cho thay đổi gói thành công
  • payment.failed: Tính phí ngay thất bại
Luôn xác minh chữ ký webhook và triển khai việc xử lý event theo cơ chế idempotent.
5

Update Your Application State

Dựa trên các event webhook, hãy cập nhật application của bạn:
  • Cấp/thu hồi các tính năng dựa trên gói mới
  • Cập nhật dashboard của khách hàng với thông tin gói mới
  • Gửi email xác nhận về thay đổi gói
  • Ghi log các thay đổi billing cho mục đích kiểm toán
6

Test and Monitor

Kiểm thử kỹ implementation của bạn:
  • Kiểm thử tất cả proration mode với nhiều tình huống khác nhau
  • Xác minh việc xử lý webhook hoạt động chính xác
  • Theo dõi tỷ lệ thay đổi gói thành công
  • Thiết lập cảnh báo cho các lần thay đổi gói thất bại
Implementation thay đổi gói subscription của bạn hiện đã sẵn sàng để sử dụng trong production.

Preview thay đổi gói

Trước khi xác nhận thay đổi gói, hãy sử dụng Preview API để hiển thị chính xác khoản phí khách hàng sẽ phải trả:
Sử dụng preview API để xây dựng các hộp thoại xác nhận hiển thị chính xác khoản phí khách hàng sẽ phải trả trước khi xác nhận thay đổi gói.

Change Plan API

Sử dụng Change Plan API để sửa đổi product, quantity và proration behavior cho một subscription đang active.

Ví dụ bắt đầu nhanh

Thay đổi gói thành công trả về 200 OK ngay lập tức — trước khi bất kỳ khoản phí nào thực sự được thanh toán. Nội dung body (ChangePlanResponse) phụ thuộc vào cách thu tiền cho thay đổi:
Trong mọi trường hợp, response này không phải là kết quả thanh toán — nó chỉ cho biết request đã được chấp nhận. Response không cho biết khoản phí ngay lập tức có thực sự thành công hay không.Với tính phí ngay thông thường, kết quả được xử lý off-session ngay sau khi gọi.Với request collect_via_payment_link, kết quả được xử lý sau đó theo cơ chế bất đồng bộ — response chỉ cung cấp checkout link, subscription vẫn giữ gói hiện tại và không thể biết kết quả cho đến khi khách hàng thực sự hoàn tất thanh toán qua link đó.Trong cả hai trường hợp, không suy luận kết quả từ response này. Hãy xác nhận qua webhook (payment.succeeded, payment.failed, subscription.plan_changed) hoặc đọc lại subscription bằng GET /subscriptions/{subscription_id} — xem Điều gì xảy ra khi link chưa được thanh toán để biết riêng về trường hợp payment-link.
Nếu khoản phí ngay lập tức thất bại, subscription có thể chuyển sang trạng thái subscription.on_hold cho đến khi thanh toán thành công.
Theo mặc định, thay đổi gói ngay lập tức sẽ tính phí trực tiếp vào phương thức thanh toán đã lưu của subscription. Đặt collect_via_payment_link: true để chuyển khách hàng đến trang checkout được lưu trữ thay thế — hữu ích khi không có phương thức thanh toán đã lưu được phép tính phí off-session, hoặc khi bạn muốn khách hàng chủ động xác nhận mức giá mới.
Đây cũng là cơ chế vận hành toggle Collect Plan Change Payments by Payment Link trong Settings → Subscriptions, định tuyến quy trình thay đổi gói của Customer Portal tích hợp sẵn qua checkout thay vì thẻ đã lưu.

Yêu cầu

collect_via_payment_link: true chỉ thành công khi tất cả điều kiện sau đều được đáp ứng — nếu không, request sẽ thất bại với 422:
  • Doanh nghiệp đã bật capability allow_plan_change_via_payment_link (Settings → Subscriptions → Collect Plan Change Payments by Payment Link).
  • effective_atimmediately (mặc định). Thay đổi theo lịch (next_billing_date) không cần trang checkout vì chỉ tính phí khi thay đổi được áp dụng.
  • on_payment_failure hiệu lực phân giải thành prevent_change. Bạn không cần gửi rõ field này — nếu giá trị mặc định cấp doanh nghiệp (xem Business & Collection Defaults bên dưới) đã là prevent_change thì việc bỏ qua field cũng đáp ứng điều kiện. apply_change rõ ràng hoặc giá trị mặc định được phân giải thành apply_change sẽ thất bại với 422.
collect_via_payment_link không chỉ áp dụng cho nâng cấp — nó áp dụng cho mọi thay đổi ngay lập tức dẫn đến khoản phí, bao gồm cả hạ cấp, miễn là đáp ứng các yêu cầu trên.
Nếu thay đổi có giá trị bằng 0 hoặc là một khoản creditproration_billing_mode: do_not_bill hoặc một mode khác vô tình có tổng giá trị bằng 0 trong chu kỳ này — thì không có gì để đưa lên checkout page. Không phát hành payment link, payment_link và các field liên quan trả về null, đồng thời thay đổi được áp dụng ngay lập tức, giống như khi không dùng collect_via_payment_link. Đây không phải 422; flag chỉ có hiệu lực khi có một khoản tiền dương cần thu. Nếu đặt collect_via_payment_link cho các thay đổi gói nói chung thay vì chỉ cho các lần nâng cấp rõ ràng, hãy gọi Preview Plan Change trước và chỉ yêu cầu link khi khoản tiền trong preview đáng để thu.
Request thành công trả về các checkout handle:
  • Subscription vẫn giữ gói hiện tạiproduct_id, recurring_pre_tax_amountnext_billing_date đều không thay đổi cho đến khi link được thanh toán.
  • Một request change-plan tiếp theo trên cùng subscription sẽ bị từ chối với 409 PendingPlanChangeExists trong khi link đang chờ xử lý. Nếu cần, hãy hủy thay đổi theo lịch bằng DELETE /subscriptions/{subscription_id}/change-plan/scheduled, nhưng endpoint đó không hủy thay đổi payment-link đang chờ — chỉ thanh toán thành công hoặc hết hạn mới thực hiện việc này.
  • Khách hàng có thể thử lại thẻ trong cùng checkout session sau khi bị từ chối; gọi change-plan mới không phải cách retry.
  • Nếu link không bao giờ được thanh toán, link sẽ ngừng hoạt động sau expires_on — subscription tự động có thể nhận request thay đổi gói mới sau đó không lâu.
  • Nếu đã có thay đổi theo lịch (next_billing_date) và bạn thay thế bằng cancel_scheduled_change_plan: true, lịch ban đầu vẫn được giữ trong khi link chưa được thanh toán và chỉ bị hủy sau khi link được thanh toán — trong cùng transaction áp dụng gói mới.
Sau khi phát hành thay đổi qua payment-link ngay lập tức, mọi request thay đổi gói tiếp theo trên subscription đó — bao gồm cả preview không gây side effect — đều bị chặn cho đến khi link được xử lý. Đừng phát hành một link mà bạn không định để khách hàng thanh toán ngay.

Quản lý Addon

Khi thay đổi gói subscription, bạn cũng có thể sửa đổi addon:
Addon được tính vào phép tính proration và sẽ được tính phí theo proration mode đã chọn.

Áp dụng mã giảm giá

Bạn có thể áp dụng một hoặc nhiều mã giảm giá stacked khi thay đổi gói subscription (tối đa 20 mã, áp dụng theo thứ tự trong array). Điều này hữu ích khi cung cấp mức giá khuyến mãi cho các lần nâng cấp hoặc migration.

Hành vi của discount khi thay đổi gói

Field discount_code dạng singular trên endpoint này đã ngừng sử dụng nhưng vẫn hoạt động để đảm bảo khả năng tương thích ngược — các integration hiện có không cần thay đổi ngay. Field này không thể kết hợp với discount_codes trong cùng request. Hãy chuyển sang dạng array khi thuận tiện.
Sử dụng Preview Plan Change API với discount_codes để hiển thị chính xác khoản tiền khách hàng sẽ tiết kiệm trước khi xác nhận thay đổi gói.

Các proration mode

Chọn cách tính phí khách hàng khi thay đổi gói:

prorated_immediately

  • Tính phí phần chênh lệch theo tỷ lệ trong chu kỳ hiện tại
  • Nếu đang trial, tính phí ngay và chuyển sang gói mới ngay
  • Hạ cấp: có thể tạo credit theo tỷ lệ, áp dụng cho các lần gia hạn sau

full_immediately

  • Tính toàn bộ giá của gói mới ngay lập tức
  • Bỏ qua thời gian còn lại của gói cũ
Các credit được tạo bởi việc hạ cấp sử dụng difference_immediately thuộc phạm vi subscription và khác với các entitlement của Credit-Based Billing. Chúng tự động được áp dụng cho các lần gia hạn sau của cùng subscription và không thể chuyển giữa các subscription.

difference_immediately

  • Nâng cấp: tính ngay khoản chênh lệch giá giữa gói cũ và gói mới
  • Hạ cấp: cộng giá trị còn lại thành credit nội bộ cho subscription và tự động áp dụng khi gia hạn

do_not_bill

  • Không tính toán khoản phí hoặc credit nào
  • Khách hàng chuyển sang gói mới ngay lập tức mà không điều chỉnh billing
  • Chu kỳ billing không thay đổi
  • Phù hợp nhất cho migration hỗ trợ, chuyển sang gói miễn phí hoặc hấp thụ phần chênh lệch chi phí

Các tình huống ví dụ

Sử dụng nhất quán các số liệu chuẩn sau:
  • Gói hiện tại: Basic ở mức $30/tháng
  • Gói mục tiêu khi nâng cấp: Pro ở mức $80/tháng
  • Gói mục tiêu khi hạ cấp (từ Pro): Starter ở mức $20/tháng
  • Chu kỳ billing: 30 ngày, bắt đầu từ January 1
  • Thay đổi gói diễn ra vào January 16 (còn 15 ngày, đã sử dụng 15 ngày)

Cách mỗi mode xử lý billing

Chọn prorated_immediately để tính phí công bằng theo thời gian; chọn full_immediately để khởi động lại billing; sử dụng difference_immediately cho các lần nâng cấp đơn giản và tự động tạo credit khi hạ cấp; hoặc sử dụng do_not_bill để chuyển gói mà không điều chỉnh billing.

Xử lý lỗi thanh toán

Kiểm soát điều gì xảy ra khi thanh toán cho thay đổi gói thất bại bằng parameter on_payment_failure.

Các chế độ lỗi thanh toán

Nếu không được chỉ định, parameter on_payment_failure sẽ sử dụng thiết lập mặc định cấp doanh nghiệp được cấu hình trong dashboard.

Khi nào nên dùng từng mode

Mặc định cấp doanh nghiệp & thu tiền

Thay vì truyền parameter proration trong mỗi lần thay đổi gói, bạn có thể thiết lập hành vi nâng cấp & hạ cấp mặc định một lần ở cấp doanh nghiệp. Các giá trị mặc định này áp dụng cho mọi thay đổi gói từ customer portal và có thể được ghi đè theo từng product collection. Có các giá trị mặc định riêng cho nâng cấp và hạ cấp: Cấu hình các giá trị mặc định cấp doanh nghiệp trong Settings → Subscriptions, và các giá trị ghi đè của collection trong từng product collection. Mỗi field của collection độc lập — để trống để kế thừa từ giá trị mặc định cấp doanh nghiệp, hoặc đặt giá trị để ghi đè chỉ cho collection đó.

Thứ tự phân giải

Với mỗi thay đổi gói cụ thể, từng thiết lập được phân giải theo thứ tự sau:
Giá trị được truyền rõ ràng vào Change Plan API luôn được ưu tiên. Các giá trị mặc định cấp doanh nghiệp và collection chỉ có hiệu lực khi không có giá trị rõ ràng — đây là trường hợp của mọi thay đổi gói được khởi tạo từ customer portal.
Một thiết lập phổ biến: giữ các lần nâng cấp ở immediately + difference_immediately để khách hàng thanh toán phần chênh lệch và có quyền truy cập ngay, đồng thời giữ các lần hạ cấp ở next_billing_date để khách hàng giữ gói hiện tại cho đến hết chu kỳ.

Xử lý webhook

Theo dõi trạng thái subscription qua webhook để xác nhận thay đổi gói và các khoản thanh toán.

Các loại event cần xử lý

  • subscription.active: subscription đã được kích hoạt
  • subscription.plan_changed: gói subscription đã thay đổi (nâng cấp/hạ cấp/thay đổi addon)
  • subscription.on_hold: tính phí thất bại, các lần gia hạn bị dừng
  • subscription.renewed: gia hạn thành công
  • payment.succeeded: thanh toán cho thay đổi gói hoặc gia hạn thành công
  • payment.failed: thanh toán thất bại
Chúng tôi khuyến nghị điều khiển business logic từ các event subscription và sử dụng event payment để xác nhận và đối soát.

Xác minh chữ ký và xử lý intent

Để biết schema payload chi tiết, xem Subscription webhook payloadsPayment webhook payloads.

Các phương pháp hay nhất

Hãy làm theo các khuyến nghị sau để thay đổi gói subscription đáng tin cậy:

Chiến lược thay đổi gói

  • Kiểm thử kỹ lưỡng: Luôn kiểm thử thay đổi gói ở test mode trước khi đưa lên production
  • Lựa chọn proration cẩn thận: Chọn proration mode phù hợp với mô hình kinh doanh
  • Xử lý lỗi phù hợp: Triển khai error handling và retry logic thích hợp
  • Theo dõi tỷ lệ thành công: Theo dõi tỷ lệ thay đổi gói thành công/thất bại và điều tra vấn đề

Triển khai webhook

  • Xác minh chữ ký: Luôn xác thực chữ ký webhook để đảm bảo tính xác thực
  • Triển khai idempotency: Xử lý phù hợp các event webhook trùng lặp
  • Xử lý bất đồng bộ: Không chặn response webhook bằng các thao tác nặng
  • Ghi log mọi thứ: Duy trì log chi tiết để debug và kiểm toán

Trải nghiệm người dùng

  • Trao đổi rõ ràng: Thông báo cho khách hàng về các thay đổi billing và thời điểm áp dụng
  • Cung cấp xác nhận: Gửi email xác nhận khi thay đổi gói thành công
  • Xử lý trường hợp đặc biệt: Cân nhắc thời gian trial, proration và các khoản thanh toán thất bại
  • Cập nhật UI ngay lập tức: Phản ánh thay đổi gói trong giao diện application

Các vấn đề thường gặp và giải pháp

Giải quyết các vấn đề điển hình gặp phải trong quá trình thay đổi gói subscription:
Triệu chứng: API call thành công nhưng subscription vẫn ở gói cũNguyên nhân thường gặp:
  • Xử lý webhook thất bại hoặc bị trì hoãn
  • State của application không được cập nhật sau khi nhận webhook
  • Vấn đề transaction cơ sở dữ liệu trong quá trình cập nhật state
Giải pháp:
  • Triển khai xử lý webhook mạnh mẽ với retry logic
  • Sử dụng các thao tác idempotent để cập nhật state
  • Thêm monitoring để phát hiện và cảnh báo các event webhook bị bỏ lỡ
  • Xác minh webhook endpoint có thể truy cập và phản hồi chính xác
Triệu chứng: Khách hàng hạ cấp nhưng không thấy số dư creditNguyên nhân thường gặp:
  • Kỳ vọng về proration mode: với difference_immediately, hạ cấp tạo credit bằng toàn bộ chênh lệch giá của gói, trong khi prorated_immediately tạo credit theo tỷ lệ dựa trên thời gian còn lại trong chu kỳ
  • Credit gắn với subscription cụ thể và không thể chuyển giữa các subscription
  • Số dư credit không hiển thị trong dashboard khách hàng
Giải pháp:
  • Sử dụng difference_immediately cho các lần hạ cấp khi muốn tự động tạo credit
  • Giải thích cho khách hàng rằng credit được áp dụng cho các lần gia hạn sau của cùng subscription
  • Triển khai customer portal để hiển thị số dư credit
  • Kiểm tra preview invoice tiếp theo để xem các credit đã áp dụng
Triệu chứng: Event webhook bị từ chối do chữ ký không hợp lệNguyên nhân thường gặp:
  • Webhook secret key không chính xác
  • Raw request body bị thay đổi trước khi xác minh chữ ký
  • Thuật toán xác minh chữ ký không đúng
Giải pháp:
  • Xác minh bạn đang sử dụng DODO_WEBHOOK_SECRET chính xác từ dashboard
  • Đọc raw request body trước bất kỳ JSON parsing middleware nào
  • Sử dụng thư viện xác minh webhook tiêu chuẩn cho platform của bạn
  • Kiểm thử việc xác minh chữ ký webhook trong môi trường development
Triệu chứng: API trả về lỗi 422 Unprocessable EntityNguyên nhân thường gặp:
  • Subscription ID hoặc product ID không hợp lệ
  • Subscription không ở trạng thái active
  • Thiếu parameter bắt buộc
  • Product không khả dụng cho thay đổi gói
Giải pháp:
  • Xác minh subscription tồn tại và đang active
  • Kiểm tra product ID hợp lệ và khả dụng
  • Đảm bảo đã cung cấp tất cả parameter bắt buộc
  • Xem tài liệu API để biết yêu cầu về parameter
Triệu chứng: Đã khởi tạo thay đổi gói nhưng tính phí ngay lập tức thất bạiNguyên nhân thường gặp:
  • Không đủ tiền trong phương thức thanh toán của khách hàng
  • Phương thức thanh toán hết hạn hoặc không hợp lệ
  • Ngân hàng từ chối giao dịch
  • Hệ thống phát hiện gian lận đã chặn khoản phí
Giải pháp:
  • Xử lý phù hợp các event webhook payment.failed
  • Thông báo khách hàng cập nhật phương thức thanh toán
  • Triển khai retry logic cho các lỗi tạm thời
  • Cân nhắc cho phép thay đổi gói dù khoản phí ngay lập tức thất bại
Triệu chứng: Tính phí thay đổi gói thất bại và subscription chuyển sang trạng thái on_holdĐiều gì xảy ra: Khi tính phí thay đổi gói thất bại, subscription tự động được chuyển sang trạng thái on_hold. Subscription sẽ không tự động gia hạn cho đến khi phương thức thanh toán được cập nhật.Giải pháp: Cập nhật phương thức thanh toán để kích hoạt lại subscriptionĐể kích hoạt lại subscription từ trạng thái on_hold sau khi thay đổi gói thất bại:
  1. Cập nhật phương thức thanh toán bằng Update Payment Method API
  2. Tự động tạo charge: API tự động tạo charge cho các khoản còn phải trả
  3. Tạo invoice: Một invoice được tạo cho charge
  4. Xử lý thanh toán: Khoản thanh toán được xử lý bằng phương thức thanh toán mới
  5. Kích hoạt lại: Sau khi thanh toán thành công, subscription được kích hoạt lại về trạng thái active
Các event webhook cần theo dõi:
  • subscription.on_hold: Subscription bị tạm dừng (nhận được khi tính phí thay đổi gói thất bại)
  • payment.succeeded: Thanh toán các khoản còn phải trả thành công (sau khi cập nhật phương thức thanh toán)
  • subscription.active: Subscription được kích hoạt lại sau khi thanh toán thành công
Phương pháp hay nhất:
  • Thông báo ngay cho khách hàng khi tính phí thay đổi gói thất bại
  • Cung cấp hướng dẫn rõ ràng về cách cập nhật phương thức thanh toán
  • Theo dõi event webhook để kiểm tra trạng thái kích hoạt lại
  • Cân nhắc triển khai retry logic tự động cho các lỗi thanh toán tạm thời

Update Payment Method API Reference

Xem tài liệu API đầy đủ về cách cập nhật phương thức thanh toán và kích hoạt lại subscription.

Kiểm thử implementation

Hãy làm theo các bước sau để kiểm thử kỹ implementation thay đổi gói subscription:
1

Set up test environment

  • Sử dụng API key test và product test
  • Tạo subscription test với các loại gói khác nhau
  • Cấu hình webhook endpoint test
  • Thiết lập monitoring và logging
2

Test different proration modes

  • Kiểm thử prorated_immediately với nhiều thời điểm khác nhau trong chu kỳ billing
  • Kiểm thử difference_immediately cho nâng cấp và hạ cấp
  • Kiểm thử full_immediately để đặt lại chu kỳ billing
  • Kiểm thử do_not_bill cho việc chuyển gói không tính phí/không credit
  • Xác minh phép tính credit chính xác
3

Test webhook handling

  • Xác minh đã nhận tất cả event webhook liên quan
  • Kiểm thử xác minh chữ ký webhook
  • Xử lý phù hợp các event webhook trùng lặp
  • Kiểm thử các tình huống xử lý webhook thất bại
4

Test error scenarios

  • Kiểm thử với subscription ID không hợp lệ
  • Kiểm thử với phương thức thanh toán hết hạn
  • Kiểm thử lỗi mạng và timeout
  • Kiểm thử khi không đủ tiền
5

Monitor in production

  • Thiết lập cảnh báo cho các lần thay đổi gói thất bại
  • Theo dõi thời gian xử lý webhook
  • Theo dõi tỷ lệ thay đổi gói thành công
  • Xem lại ticket hỗ trợ khách hàng về các vấn đề thay đổi gói

Xử lý lỗi

Xử lý phù hợp các lỗi API thường gặp trong implementation của bạn:

HTTP Status Codes

Request thay đổi gói đã được xử lý thành công. Response body trống, ngoại trừ request collect_via_payment_link thành công, request này trả về checkout handle — xem Thu tiền qua Checkout Link. Nếu on_payment_failure=prevent_change, thay đổi gói vẫn ở trạng thái pending cho đến khi thanh toán thành công.
Parameter request không hợp lệ. Kiểm tra tất cả field bắt buộc đã được cung cấp và có đúng định dạng.
API key không hợp lệ hoặc bị thiếu. Xác minh DODO_PAYMENTS_API_KEY chính xác và có quyền phù hợp.
Không tìm thấy Subscription ID hoặc subscription không thuộc account của bạn.
Subscription đã có thay đổi gói đang chờ xử lý (PendingPlanChangeExists). Với thay đổi theo lịch, hãy hủy bằng DELETE /subscriptions/{subscription_id}/change-plan/scheduled trước khi gửi thay đổi mới. Với thay đổi payment-link đang chờ xử lý, không có endpoint hủy — subscription sẽ chấp nhận request thay đổi gói mới khi khách hàng thanh toán hoặc link hết hạn.
Subscription không active hoặc là on-demand, hoặc request không đủ điều kiện sử dụng collect_via_payment_link — doanh nghiệp chưa bật capability, effective_at không phải immediately hoặc on_payment_failure không phải prevent_change. Xem Yêu cầu.
Đã xảy ra lỗi server. Hãy thử lại request sau một khoảng trễ ngắn.

Định dạng error response

Bước tiếp theo

Lần sửa đổi cuối 26 tháng 8, 2026