Documentation Index
Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
Use this file to discover all available pages before exploring further.
Change Plan API
Plan Change Preview
Integration Guide
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
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
Step-by-Step Implementation Guide
Follow this comprehensive guide to implement subscription plan changes in your application:Understand Plan Change Requirements
- 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
Choose Your Proration Strategy
- prorated_immediately
- difference_immediately
- full_immediately
- do_not_bill
- 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
Implement the Change Plan API
prorated_immediately, full_immediately, difference_immediately, or do_not_bill.prevent_change: Keep subscription on current plan until payment succeedsapply_change(default): Apply plan change immediately regardless of payment outcome
- Không cung cấp /
null— các giảm giá hiện có vớipreserve_on_plan_change=trueđược bảo lưu nếu áp dụng cho sản phẩm mới. [](mảng trống) — xóa tất cả các giảm giá hiện có khỏi đăng ký.["CODE_A", "CODE_B", ...]— thay thế bất kỳ giảm giá hiện có nào bằng tập hợp chồng lên nhau này.
discount_codes cho các tích hợp mới. Trường này vẫn hoạt động cho sự tương thích ngược, nhưng không thể kết hợp với discount_codes trong cùng một yêu cầu.immediately(mặc định): Áp dụng thay đổi gói ngay lập tứcnext_billing_date: Lên lịch thay đổi cho ngày thanh toán tiếp theo. Khách hàng giữ lại gói hiện tại của họ cho đến khi kết thúc kỳ thanh toán.
next_billing_date cho việc hạ cấp để khách hàng giữ lại các lợi ích của gói hiện tại cho đến khi kỳ thanh toán kết thúc.Handle Webhook Events
subscription.active: Thay đổi gói thành công, đăng ký được cập nhậtsubscription.plan_changed: Kế hoạch đăng ký thay đổi (nâng cấp/hạ cấp/ cập nhật addon)subscription.on_hold: Phí thay đổi gói thất bại, đăng ký tạm dừngpayment.succeeded: Phí ngay lập tức cho thay đổi gói thành côngpayment.failed: Phí ngay lập tức thất bại
Update Your Application State
- Cấp/phục hồi tính năng dựa trên gói mới
- Cập nhật bảng điều khiển khách hàng với chi tiết gói mới
- Gửi email xác nhận về thay đổi gói
- Ghi lại thay đổi thanh toán cho mục đích kiểm tra
Test and Monitor
- Kiểm tra tất cả chế độ phân bổ với các kịch bản khác nhau
- Xác minh xử lý webhook hoạt động chính xác
- Giám sát tỷ lệ thành công thay đổi gói
- Thiết lập cảnh báo cho lỗi thay đổi gói
Xem trước Thay đổi Gói
Trước khi cam kết thay đổi gói, sử dụng API Xem trước để hiển thị cho khách hàng chính xác số tiền họ sẽ phải trả:- Node.js SDK
- Python SDK
API Thay đổi Gói
Sử dụng API Thay đổi Gói để thay đổi sản phẩm, số lượng và hành vi phân bổ cho một đăng ký đang hoạt động.Ví dụ khởi đầu nhanh
- Node.js SDK
- Python SDK
- Go SDK
- HTTP
invoice_id và payment_id chỉ được trả về khi một khoản phí ngay lập tức và/hoặc hóa đơn được tạo ra trong quá trình thay đổi gói. Luôn dựa vào sự kiện webhook (vd., payment.succeeded, subscription.plan_changed) để xác nhận kết quả.Quản lý Addons
Khi thay đổi kế hoạch đăng ký, bạn cũng có thể sửa đổi addons:Áp dụng Mã Giảm Giá
Bạn có thể áp dụng một hoặc nhiều mã giảm giá chồng lên nhau khi thay đổi đăng ký (tối đa 20, áp dụng theo thứ tự mảng). Điều này hữu ích cho việc cung cấp giá khuyến mại khi nâng cấp hoặc di cư.- Node.js SDK
- Python SDK
- HTTP
Hành vi giảm giá khi thay đổi gói
discount_codes value | Hành vi |
|---|---|
Không cung cấp / null | Các giảm giá hiện có với preserve_on_plan_change=true được tự động bảo lưu nếu áp dụng cho sản phẩm mới. |
[] (mảng trống) | Tất cả các giảm giá hiện có sẽ bị xóa khỏi đăng ký. |
["CODE_A", "CODE_B", ...] | Thay thế bất kỳ giảm giá hiện có nào bằng tập hợp chồng lên nhau này, được xác nhận và áp dụng theo thứ tự mảng. |
discount_code trên đầu cuối này là không dùng nhưng vẫn hoạt động để tương thích ngược — các tích hợp hiện tại không cần thay đổi ngay lập tức. Nó không thể kết hợp với discount_codes trong cùng một yêu cầu. Di chuyển sang dạng mảng khi thuận tiện.Các chế độ phân bổ
Chọn cách tính phí cho khách hàng khi thay đổi gói:prorated_immediately
- Tính phí cho sự khác biệt tương đương trong chu kỳ hiện tại
- Nếu trong giai đoạn thử nghiệm, tính phí ngay lập tức và chuyển sang gói mới ngay
- Hạ cấp: có thể tạo ra một khoản tín dụng phân bổ được áp dụng cho các gia hạn trong tương lai
full_immediately
- Tính phí toàn bộ số tiền 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ũ
difference_immediately là phạm vi đăng ký và khác biệt với các quyền lợi Tính phí Dựa trên Tín dụng. Chúng tự động áp dụng cho các gia hạn trong tương lai của cùng một đăng ký và không thể chuyển nhượng giữa các đăng ký.difference_immediately
- Nâng cấp: tính ngay sự khác biệt về giá giữa các gói cũ và mới
- Hạ cấp: thêm giá trị còn lại làm tín dụng nội bộ cho đăng ký và tự động áp dụng khi gia hạn
do_not_bill
- Không tính phí hoặc tính toán tín dụng
- Khách hàng chuyển sang gói mới ngay lập tức mà không có bất kỳ điều chỉnh thanh toán nào
- Chu kỳ thanh toán không thay đổi
- Tốt nhất cho chuyển đổi ân huệ, chuyển đổi gói miễn phí hoặc hấp thụ sự khác biệt chi phí
| Tính năng | prorated_immediately | difference_immediately | full_immediately | do_not_bill |
|---|---|---|---|---|
| Phí nâng cấp | Khác biệt theo thời gian đã sử dụng | Sự khác biệt toàn bộ giá giữa các gói | Toàn bộ giá của gói mới | Không phí |
| Tín dụng hạ cấp | Tín dụng theo thời gian còn lại | Sự khác biệt toàn bộ giá như tín dụng | Không tín dụng | Không tín dụng |
| Chu kỳ thanh toán | Không thay đổi | Không thay đổi | Khởi động lại từ hôm nay | Không thay đổi |
| Hành vi thử nghiệm | Kết thúc thử nghiệm, tính phí ngay | Kết thúc thử nghiệm, tính phí ngay | Kết thúc thử nghiệm, tính phí toàn bộ | Kết thúc thử nghiệm, không tính phí |
| Tốt nhất cho | Tính phí công bằng theo thời gian | Toán học nâng cấp/hạ cấp đơn giản | Khởi động lại các chu kỳ thanh toán | Chuyển đổi miễn phí hoặc ân huệ |
| Độ phức tạp | Trung bình (tính toán ngày) | Thấp (trừ đơn giản) | Thấp (tính phí toàn bộ) | Không có |
Các kịch bản ví dụ
Sử dụng những con số chuẩn này một cách nhất quán:- Gói hiện tại: Cơ bản với $30/tháng
- Mục tiêu nâng cấp: Pro với $80/tháng
- Mục tiêu hạ cấp (từ Pro): Khởi đầu với $20/tháng
- Chu kỳ thanh toán: 30 ngày, bắt đầu từ 1 tháng 1
- Thay đổi kế hoạch xảy ra vào 16 tháng 1 (còn 15 ngày, đã sử dụng 15 ngày)
Upgrade: Basic ($30) → Pro ($80) with prorated_immediately
Upgrade: Basic ($30) → Pro ($80) with prorated_immediately
Downgrade: Pro ($80) → Starter ($20) with prorated_immediately
Downgrade: Pro ($80) → Starter ($20) with prorated_immediately
Upgrade: Basic ($30) → Pro ($80) with difference_immediately
Upgrade: Basic ($30) → Pro ($80) with difference_immediately
Downgrade: Pro ($80) → Starter ($20) with difference_immediately
Downgrade: Pro ($80) → Starter ($20) with difference_immediately
Upgrade: Basic ($30) → Pro ($80) with full_immediately
Upgrade: Basic ($30) → Pro ($80) with full_immediately
Mid-cycle upgrade with add-ons using prorated_immediately
Mid-cycle upgrade with add-ons using prorated_immediately
Cách mỗi chế độ xử lý việc thanh toán
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 cách sử dụng tham sốon_payment_failure.
Chế độ Lỗi Thanh toán
- prevent_change (Recommended for critical upgrades)
- apply_change (Default)
- Thay đổi gói được đánh dấu là “đang chờ xử lý”
- Khách hàng giữ quyền truy cập vào gói hiện tại của họ
- Đăng ký chuyển sang trạng thái
activechỉ sau khi thanh toán thành công - Hữu ích khi bạn muốn đảm bảo thanh toán trước khi cung cấp các tính năng nâng cấp
on_payment_failure sử dụng cài đặt mặc định cấp doanh nghiệp của bạn được cấu hình trong bảng điều khiển.Khi nào sử dụng mỗi chế độ
| Kịch bản | Chế độ được Khuyến nghị | Lý do |
|---|---|---|
| Nâng cấp lên các tính năng cao cấp | prevent_change | Đảm bảo thanh toán trước khi cung cấp quyền truy cập |
| Tăng số lượng (nhiều chỗ) | prevent_change | Ngăn chặn việc sử dụng mà không có thanh toán |
| Hạ cấp kế hoạch | apply_change | Khách hàng đang giảm tiêu dùng |
| Khách hàng doanh nghiệp đáng tin cậy | apply_change | Rủi ro thấp không thanh toán |
| Chuyển đổi thử nghiệm sang thanh toán | prevent_change | Khoảnh khắc thanh toán quan trọng |
Xử lý webhooks
Theo dõi trạng thái đăng ký thông qua webhooks để xác nhận thay đổi gói và thanh toán.Các loại sự kiện cần xử lý
subscription.active: đăng ký được kích hoạtsubscription.plan_changed: gói đăng ký thay đổi (nâng cấp/hạ cấp/thay đổi addon)subscription.on_hold: phí thất bại, đăng ký tạm dừngsubscription.renewed: gia hạn thành côngpayment.succeeded: thanh toán cho thay đổi gói hoặc gia hạn thành côngpayment.failed: thanh toán thất bại
Xác minh chữ ký và xử lý ý định
- Next.js Route Handler
- Express.js
Thực hành Tốt nhất
Tuân thủ các khuyến nghị này để thay đổi gói đăng ký đáng tin cậy:Chiến lược Thay đổi Gói
- Kiểm tra kỹ lưỡng: Luôn kiểm tra thay đổi gói trong chế độ thử nghiệm trước sản xuất
- Chọn phân bổ cẩn thận: Chọn chế độ phân bổ phù hợp với mô hình kinh doanh của bạn
- Xử lý lỗi một cách tinh tế: Triển khai xử lý lỗi và logic thử lại thích hợp
- Giám sát tỷ lệ thành công: Theo dõi tỷ lệ thành công/thất bại của thay đổi gói và điều tra các 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
- Thực hiện idempotency: Xử lý các sự kiện webhook trùng lặp một cách tinh tế
- Xử lý không đồng bộ: Không chặn các phản hồi webhook với các hoạt động nặng
- Ghi lại mọi thứ: Duy trì nhật ký chi tiết để gỡ lỗi và kiểm tra
Trải nghiệm người dùng
- Thông báo rõ ràng: Thông báo cho khách hàng về thay đổi thanh toán và thời gian
- Cung cấp xác nhận: Gửi email xác nhận cho các thay đổi gói thành công
- Xử lý các trường hợp đặc biệt: Xem xét các kỳ thử nghiệm, phân bổ, và thanh toán thất bại
- Cập nhật giao diện người dùng ngay lập tức: Phản ánh các thay đổi gói trong giao diện ứng dụng của bạn
Vấn đề Thông thường và Giải pháp
Giải quyết các vấn đề thường gặp khi thay đổi kế hoạch đăng ký:Charge created but subscription not updated
Charge created but subscription not updated
- Xử lý webhook thất bại hoặc bị trì hoãn
- Trạng thái ứng dụng không được cập nhật sau khi nhận webhook
- Vấn đề giao dịch cơ sở dữ liệu khi cập nhật trạng thái
- Triển khai xử lý webhook mạnh mẽ với logic thử lại
- Sử dụng các hoạt động idempotent để cập nhật trạng thái
- Thêm giám sát để phát hiện và cảnh báo về sự kiện webhook bị bỏ lỡ
- Xác minh endpoint webhook có thể truy cập và phản hồi đúng cách
Credits not applied after downgrade
Credits not applied after downgrade
- Kỳ vọng chế độ phân bổ: hạ cấp tín dụng sự khác biệt giá toàn bộ với
difference_immediately, trong khiprorated_immediatelytạo tín dụng phân bổ dựa trên thời gian còn lại trong chu kỳ - Tín dụng cụ thể cho đăng ký và không chuyển nhượng giữa các đăng ký
- Số dư tín dụng không hiển thị trong bảng điều khiển khách hàng
- Sử dụng
difference_immediatelycho các hạ cấp khi bạn muốn tự động tín dụng - Giải thích cho khách hàng rằng các khoản tín dụng áp dụng cho các gia hạn trong tương lai của cùng một đăng ký
- Triển khai cổng thông tin khách hàng để hiển thị số dư tín dụng
- Kiểm tra xem trước hóa đơn tiếp theo để thấy các tín dụng đã áp dụng
Webhook signature verification fails
Webhook signature verification fails
- Key bí mật webhook không chính xác
- Dữ liệu yêu cầu thô bị thay đổi trước khi xác minh chữ ký
- Sai thuật toán xác minh chữ ký
- Xác minh bạn đang sử dụng đúng
DODO_WEBHOOK_SECRETtừ bảng điều khiển - Đọc dữ liệu yêu cầu thô trước bất kỳ middleware phân giải JSON nào
- Sử dụng thư viện xác minh webhook tiêu chuẩn cho nền tảng của bạn
- Kiểm tra xác minh chữ ký webhook trong môi trường phát triển
Plan change fails with 422 error
Plan change fails with 422 error
- ID đăng ký hoặc ID sản phẩm không hợp lệ
- Đăng ký không ở trạng thái hoạt động
- Thiếu các tham số cần thiết
- Sản phẩm không có sẵn để thay đổi kế hoạch
- Xác minh đăng ký tồn tại và đang hoạt động
- Kiểm tra ID sản phẩm hợp lệ và có sẵn
- Đảm bảo tất cả tham số cần thiết được cung cấp
- Xem lại tài liệu API để biết các yêu cầu về tham số
Immediate charge fails during plan change
Immediate charge fails during plan change
- Không đủ tiền trên 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
- Phát hiện gian lận đã chặn khoản phí
- Xử lý các sự kiện webhook
payment.failedmột cách thích hợp - Thông báo khách hàng để cập nhật phương thức thanh toán
- Triển khai logic thử lại cho các lỗi tạm thời
- Xem xét cho phép thay đổi gói với các khoản phí ngay lập tức thất bại
Subscription on hold after plan change
Subscription on hold after plan change
on_holdĐiều gì xảy ra:
Khi phí thay đổi gói thất bại, đăng ký sẽ tự động được đặt ở trạng thái on_hold. Đăng ký sẽ không được gia hạn tự động 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 để tái kích hoạt đăng kýĐể tái kích hoạt đăng ký từ trạng thái on_hold sau khi thay đổi gói thất bại:- Cập nhật phương thức thanh toán sử dụng API Cập nhật Phương thức Thanh toán
- Tạo khoản phí tự động: API tự động tạo khoản phí cho các khoản còn nợ
- Tạo hóa đơn: Hóa đơn được tạo cho khoản phí
- Xử lý thanh toán: Thanh toán được xử lý bằng phương thức thanh toán mới
- Tái kích hoạt: Khi thanh toán thành công, đăng ký được tái kích hoạt về trạng thái
active
subscription.on_hold: Đăng ký bị tạm ngưng (nhận được khi phí thay đổi gói thất bại)payment.succeeded: Thanh toán cho các khoản còn lại thành công (sau khi cập nhật phương thức thanh toán)subscription.active: Đăng ký được tái kích hoạt sau khi thanh toán thành công
- Thông báo ngay lập tức cho khách hàng khi 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
- Giám sát sự kiện webhook để theo dõi trạng thái tái kích hoạt
- Xem xét triển khai logic thử lại tự động cho các lỗi thanh toán tạm thời
Update Payment Method API Reference
Kiểm tra Triển khai của Bạn
Thực hiện các bước sau để kiểm tra kỹ lưỡng việc triển khai thay đổi kế hoạch đăng ký của bạn:Set up test environment
- Sử dụng khóa API kiểm tra và sản phẩm kiểm tra
- Tạo đăng ký kiểm tra với các loại gói khác nhau
- Cấu hình endpoint webhook kiểm tra
- Thiết lập giám sát và ghi nhật ký
Test different proration modes
- Kiểm tra
prorated_immediatelyvới các vị trí chu kỳ thanh toán khác nhau - Kiểm tra
difference_immediatelycho nâng cấp và hạ cấp - Kiểm tra
full_immediatelyđể khởi động lại chu kỳ thanh toán - Kiểm tra
do_not_billcho chuyển đổi gói không tính phí/không tín dụng - Xác minh tính toán tín dụng là chính xác
Test webhook handling
- Xác minh tất cả các sự kiện webhook liên quan được nhận
- Kiểm tra xác minh chữ ký webhook
- Xử lý các sự kiện webhook trùng lặp một cách tinh tế
- Kiểm tra các kịch bản thất bại xử lý webhook
Test error scenarios
- Kiểm tra với các ID đăng ký không hợp lệ
- Kiểm tra với phương thức thanh toán hết hạn
- Kiểm tra các lỗi mạng và hết thời gian
- Kiểm tra với tiền không đủ
Xử lý lỗi
Xử lý các lỗi API phổ biến một cách tinh tế trong triển khai của bạn:Mã Trạng thái HTTP
200 OK
200 OK
400 Bad Request
400 Bad Request
401 Unauthorized
401 Unauthorized
404 Not Found
404 Not Found
422 Unprocessable Entity
422 Unprocessable Entity
500 Internal Server Error
500 Internal Server Error
Định dạng Phản hồi Lỗi
Bước tiếp theo
- Xem lại API Thay đổi Gói
- Khám phá Tính phí Dựa trên Tín dụng
- Triển khai cảnh báo cho
subscription.on_hold - Xem hướng dẫn Tích hợp Webhook
Next steps
- Review the Change Plan API
- Explore Credit-Based Billing
- Implement alerts for
subscription.on_hold - Check out our Webhook Integration Guide