Chuyển đến nội dung chính
Subscriptions let you sell ongoing access with automated renewals. Use flexible billing cycles, free trials, plan changes, and add‑ons to tailor pricing for each customer.

Upgrade & Downgrade

Control plan changes with proration and quantity updates.

On‑Demand Subscriptions

Authorize a mandate now and charge later with custom amounts.

Customer Portal

Let customers manage plans, billing, and cancellations.

Subscription Webhooks

React to lifecycle events like created, renewed, and canceled.

What Are Subscriptions?

Subscriptions are recurring products customers purchase on a schedule. They’re ideal for:
  • SaaS licenses: Apps, APIs, or platform access
  • Memberships: Communities, programs, or clubs
  • Digital content: Courses, media, or premium content
  • Support plans: SLAs, success packages, or maintenance

Key Benefits

  • Predictable revenue: Recurring billing with automated renewals
  • Flexible cycles: Monthly, annual, custom intervals, and trials
  • Plan agility: Proration for upgrades and downgrades
  • Add‑ons and seats: Attach optional, quantifiable upgrades
  • Seamless checkout: Hosted checkout and customer portal
  • Developer-first: Clear APIs for creation, changes, and usage tracking

Creating Subscriptions

Create subscription products in your Dodo Payments dashboard, then sell them through checkout or your API. Separating products from active subscriptions lets you version pricing, attach add‑ons, and track performance independently.

Subscription product creation

Configure the fields in the dashboard to define how your subscription sells, renews, and bills. The sections below map directly to what you see in the creation form.

Product details

  • Product Name (required): The display name shown in checkout, customer portal, and invoices.
  • Product Description (required): A clear value statement that appears in checkout and invoices.
  • Product Image (required): PNG/JPG/WebP up to 3 MB. Used on checkout and invoices.
  • Brand: Associate the product with a specific brand for theming and emails.
  • Tax Category (required): Choose the category (for example, SaaS) to determine tax rules.
Pick the most accurate tax category to ensure correct tax collection per region.

Pricing

  • Pricing Type: Choose Subscription (this guide). Alternatives are Single Payment and Usage Based Billing.
  • Price (required): Base recurring price with currency.
  • Discount Applicable (%): Optional percentage discount applied to the base price; reflected in checkout and invoices.
  • Repeat payment every (required): Interval for renewals, e.g., every 1 Month. Select the cadence (months or years) and quantity.
  • Subscription Period (required): Total term for which the subscription remains active (e.g., 10 Years). After this period ends, renewals stop unless extended.
  • Trial Period Days (required): Set trial length in days. Use 0 to disable trials. The first charge occurs automatically when the trial ends.
  • Select add‑on: Attach up to 10 add‑ons that customers can purchase alongside the base plan.
Changing pricing on an active product affects new purchases. Existing subscriptions follow your plan‑change and proration settings.
Add‑ons are ideal for quantifiable extras such as seats or storage. You can control allowed quantities and proration behavior when customers change them.

Advanced settings

  • Tax Inclusive Pricing: Display prices inclusive of applicable taxes. Final tax calculation still varies by customer location.
  • Generate license keys: Issue a unique key to each customer after purchase. See the License Keys guide.
  • Digital Product Delivery: Deliver files or content automatically after purchase. Learn more in Digital Product Delivery.
  • Metadata: Attach custom key–value pairs for internal tagging or client integrations. See Metadata.
Use metadata to store identifiers from your system (e.g., accountId) so you can reconcile events and invoices later.

Subscription Trials

Trials let customers access subscriptions without immediate payment. The first charge occurs automatically when the trial ends.

Configuring Trials

Set Trial Period Days in the product pricing section (use 0 to disable). You can override this when creating subscriptions:
// Via subscription creation
const subscription = await client.subscriptions.create({
  customer_id: 'cus_123',
  product_id: 'prod_monthly',
  trial_period_days: 14  // Overrides product's trial period
});

// Via checkout session
const session = await client.checkoutSessions.create({
  product_cart: [{ product_id: 'prod_monthly', quantity: 1 }],
  subscription_data: { trial_period_days: 14 }
});
The trial_period_days value must be between 0 and 10,000 days.

Detecting Trial Status

Currently, there is no direct field to detect trial status. The following is a workaround that requires querying payments, which is inefficient. We are working on a more efficient solution.
To determine if a subscription is in trial, retrieve the list of payments for the subscription. If there is exactly one payment with amount 0, the subscription is in trial period:
const subscription = await client.subscriptions.retrieve('sub_123');
const payments = await client.payments.list({
  subscription_id: subscription.subscription_id
});

// Check if subscription is in trial
const isInTrial = payments.items.length === 1 && 
                  payments.items[0].total_amount === 0;

Updating Trial Period

Extend the trial by updating next_billing_date:
await client.subscriptions.update('sub_123', {
  next_billing_date: '2025-02-15T00:00:00Z'  // New trial end date
});
You cannot set next_billing_date to a past time. The date must be in the future.

Subscription Plan Changes

Plan changes let you upgrade or downgrade subscriptions, adjust quantities, or migrate to different products. Depending on the proration mode you select, a change may trigger an immediate charge, create credit, or apply no billing adjustment.
You can change subscription plans and update the next billing date directly from the Dodo Payments dashboard. This provides a quick way to adjust subscriptions for customer support requests, promotional upgrades, or plan migrations without making API calls.
Enable self-service plan changes: Want customers to upgrade or downgrade their own subscriptions via the Customer Portal? Add your subscription products to a Product Collection and enable “Allow Subscription Updates” in your Subscription Settings.

Product Collections

Group related products into collections to enable seamless upgrade/downgrade paths in the Customer Portal.

Proration Modes

Choose how customers are billed when changing plans:
Quick comparison of the four proration modes:
prorated_immediatelydifference_immediatelyfull_immediatelydo_not_bill
Nâng cấpPhí theo tỷ lệ cho các ngày còn lạiTính toàn bộ sự chênh lệch giáTính toàn bộ giá gói mớiKhông tính phí — chuyển ngay lập tức
Giảm cấpTín dụng theo tỷ lệ cho các ngày còn lạiToàn bộ số chênh lệch giá thành tín dụngKhông tín dụng, tính toàn bộ phíKhông tín dụng — chuyển ngay lập tức
Chu kỳ thanh toánĐặt lại về hôm nayĐặt lại về hôm nayĐặt lại về hôm nayGiữ nguyên
Tốt nhất choThanh toán theo thời gian hợp lýThay đổi cấp độ đơn giảnĐặt lại chu kỳ thanh toánDi chuyển miễn phí hoặc chuyển đổi danh nghĩa

prorated_immediately

Charges prorated amount based on remaining time in the current billing cycle. Best for fair billing that accounts for unused time.
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately'
});

difference_immediately

Charges the price difference immediately (upgrade) or adds credit for future renewals (downgrade). Best for simple upgrade/downgrade scenarios.
// Upgrade: charges $50 (difference between $30 and $80)
// Downgrade: credits remaining value, auto-applied to renewals
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'difference_immediately'
});
Credits from downgrades using difference_immediately are subscription-scoped and auto-applied to future renewals. They’re distinct from Credit-Based Billing entitlements.
When a customer downgrades with difference_immediately, the unused value becomes a subscription-scoped credit that automatically offsets future renewals:

full_immediately

Charges full new plan amount immediately, ignoring remaining time. Best for resetting billing cycles.
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_monthly',
  quantity: 1,
  proration_billing_mode: 'full_immediately'
});

do_not_bill

Switches to the new plan without any billing adjustment. No proration charges, no credits — the customer simply moves to the new plan. Best for courtesy migrations, free plan switches, or scenarios where you want to absorb the cost difference.
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_new_plan',
  quantity: 1,
  proration_billing_mode: 'do_not_bill'
});
Scenario: Customer on Basic (30/month)upgradestoPro(30/month) upgrades to Pro (80/month) on day 16 of a 30-day cycle using prorated_immediately.
Unused credit from Basic = $30 × (15 remaining / 30 total) = $15.00
Prorated cost of Pro     = $80 × (15 remaining / 30 total) = $40.00
────────────────────────────────────────────────────────────────────
Immediate charge         = $40.00 − $15.00 = $25.00
Gia hạn tiếp theo vào ngày 15 tháng 2 (16 tháng 1 + 30 ngày): 80,00 USD/tháng.
For more detailed calculation examples and edge cases, see our full Upgrade & Downgrade Guide.
Scenario: Customer on Pro (80/month)downgradestoStarter(80/month) downgrades to Starter (20/month) using difference_immediately.
Credit = Old plan − New plan = $80 − $20 = $60.00
The $60 credit auto-applies to future renewals:
  • Renewal 1: 2020 − 20 (credit) = **0.00(0.00** (40 credit remaining)
  • Renewal 2: 2020 − 20 (credit) = **0.00(0.00** (20 credit remaining)
  • Renewal 3: 2020 − 20 (credit) = $0.00 (credit exhausted)
  • Renewal 4: $20.00 (full price)
Learn more about how credits are managed in the Upgrade & Downgrade Guide.

Changing Plans with Add-ons

Modify add-ons when changing plans. Add-ons are included in proration calculations:
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'difference_immediately',
  addons: [{ addon_id: 'addon_extra_seats', quantity: 2 }]  // Add add-ons
  // addons: []  // Empty array removes all existing add-ons
});
Plan changes trigger immediate charges. Failed charges may move the subscription to on_hold status. Track changes via subscription.plan_changed webhook events.

Previewing Plan Changes

Before committing to a plan change, preview the exact charge and resulting subscription:
const preview = await client.subscriptions.previewChangePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately'
});

// Show customer the charge before confirming
console.log('You will be charged:', preview.immediate_charge.summary);

Preview Change Plan API

Preview plan changes before committing to them.

Subscription States

Một đăng ký sẽ trải qua một tập hợp trạng thái xác định trong suốt vòng đời của nó. Bảng này là tài liệu tham khảo cho mọi trạng thái, nguyên nhân xảy ra và cách (hoặc nếu có thể) bạn có thể khôi phục nó.
Trạng tháiÝ nghĩaCó thể khôi phục?Đường dẫn khôi phục / bước tiếp theo
pendingĐăng ký đang được tạo hoặc xử lýChờ subscription.active (hoặc subscription.failed)
activeĐăng ký đang hoạt động và sẽ tự động gia hạnKhông cần hành động nào
on_holdThanh toán gia hạn (hoặc phí thay đổi gói) đã thất bại; đăng ký bị tạm dừngCập nhật phương thức thanh toán để kích hoạt lại — tự động qua Thử Lại Thanh ToánDunning, hoặc thủ công qua API Cập nhật Phương thức Thanh toán
cancelledĐăng ký đã bị hủy và sẽ không được gia hạnChỉ có thể mua lạiKhách hàng phải bắt đầu đăng ký mới; Dunning có thể nhắc nhở mua lại
failedTạo đăng ký không thành công (ủy nhiệm ban đầu hoặc thanh toán không thành công)Không — cuối cùngKhách hàng phải tạo đăng ký mới với phương thức thanh toán hoạt động
expiredĐăng ký đã hết hạnKhách hàng phải bắt đầu đăng ký mới nếu muốn
on_holdfailed thường bị nhầm lẫn. on_hold là trạng thái có thể khôi phục cho một đăng ký đã hoạt động nhưng gia hạn thất bại. failed là trạng thái cuối cùng chỉ xảy ra khi tạo đăng ký ban đầu thất bại — không thể kích hoạt lại.

Máy Trạng Thái

Trạng Thái Tạm Dừng

Một đăng ký sẽ vào trạng thái on_hold khi:
  • Thanh toán gia hạn thất bại (không đủ tiền, thẻ hết hạn, v.v.)
  • Phí thay đổi gói thất bại
  • Ủy quyền phương thức thanh toán thất bại
Khi một đăng ký ở trạng thái on_hold, nó sẽ không tự động gia hạn. Bạn phải cập nhật phương thức thanh toán để kích hoạt lại đăng ký.

Kích Hoạt Lại từ Trạng Thái Tạm Dừng

Để kích hoạt lại một đăng ký từ trạng thái on_hold, cập nhật phương thức thanh toán. Điều này tự động:
  1. Tạo một khoản phí cho các khoản nợ còn lại
  2. Tạo hóa đơn
  3. Xử lý thanh toán bằng phương thức thanh toán mới
  4. Kích hoạt lại đăng ký về trạng thái active khi thanh toán thành công
// Reactivate subscription from on_hold
const response = await client.subscriptions.updatePaymentMethod('sub_123', {
  type: 'new',
  return_url: 'https://example.com/return'
});

// For on_hold subscriptions, a charge is automatically created
if (response.payment_id) {
  console.log('Charge created:', response.payment_id);
  // Redirect customer to response.payment_link to complete payment
  // Monitor webhooks for payment.succeeded and subscription.active
}
Sau khi cập nhật thành công phương thức thanh toán cho một đăng ký on_hold, bạn sẽ nhận được các sự kiện webhook payment.succeeded tiếp theo là subscription.active.

Sự Kiện Webhook theo Chuyển Đổi

Mỗi chuyển đổi phát ra một webhook để bạn có thể thực hiện logic quyền mà không cần khảo sát liên tục:
Chuyển đổiSự kiện
Đăng ký được kích hoạtsubscription.active
Gia hạn thành côngsubscription.renewed
Gia hạn thất bại → tạm dừngsubscription.on_hold
Tạo thất bạisubscription.failed
Nâng cấp/giảm cấp góisubscription.plan_changed
Bị hủysubscription.cancelled
Kết thúc thời hạnsubscription.expired
Bất kỳ thay đổi trường nàosubscription.updated

Subscription Webhook Payloads

Xem toàn bộ lược đồ payload cho các sự kiện vòng đời đăng ký.

Quản Lý API

Sử dụng POST /subscriptions để tạo đăng ký theo cách lập trình từ các sản phẩm, với các giai đoạn thử nghiệm và bổ sung tùy chọn.

API Reference

Xem API tạo đăng ký.
Sử dụng PATCH /subscriptions/{id} để cập nhật số lượng, hủy vào ngày lập hóa đơn tiếp theo hoặc sửa đổi metadata.

API Reference

Tìm hiểu cách cập nhật chi tiết đăng ký.
Thay đổi sản phẩm và số lượng đang hoạt động với kiểm soát tỷ lệ.

API Reference

Xem xét tùy chọn thay đổi kế hoạch.
Đối với đăng ký theo yêu cầu, tính phí các khoản cụ thể theo yêu cầu.

API Reference

Tính phí một đăng ký theo yêu cầu.
Sử dụng GET /subscriptions để liệt kê tất cả các đăng ký và GET /subscriptions/{id} để lấy thông tin một đăng ký.

API Reference

Duyệt API danh sách và truy xuất.
Lấy lịch sử sử dụng đã ghi nhận cho các mô hình định giá đo lường hoặc hỗn hợp.

API Reference

Xem API lịch sử sử dụng.
Cập nhật phương thức thanh toán cho một đăng ký. Đối với các đăng ký đang hoạt động, điều này cập nhật phương thức thanh toán cho các lần gia hạn tiếp theo. Đối với các đăng ký trong trạng thái on_hold, điều này kích hoạt lại đăng ký bằng cách tạo một khoản phí cho các khoản nợ còn lại.Khi tạo một liên kết phương thức thanh toán mới (loại yêu cầu New), bạn có thể truyền allowed_payment_method_types để giới hạn các phương thức thanh toán mà khách hàng nhìn thấy trên trang đó. Khách hàng sẽ không bao giờ thấy một phương pháp không nằm trong danh sách, mặc dù bao gồm một phương pháp không đảm bảo nó xuất hiện (sự sẵn có vẫn phụ thuộc vào các yếu tố như vị trí của khách hàng và cài đặt doanh nghiệp của bạn).

API Reference

Tìm hiểu cách cập nhật phương thức thanh toán và kích hoạt lại đăng ký.

Trường Hợp Sử Dụng Phổ Biến

  • SaaS và API: Truy cập phân cấp với bổ sung cho chỗ ngồi hoặc sử dụng
  • Nội dung và truyền thông: Truy cập hàng tháng với các giai đoạn thử nghiệm giới thiệu
  • Kế hoạch hỗ trợ B2B: Hợp đồng hàng năm với bổ sung hỗ trợ cao cấp
  • Công cụ và plugin: Khóa giấy phép và phát hành theo phiên bản

Ví Dụ Tích Hợp

Phiên Thanh Toán (đăng ký)

Khi tạo phiên thanh toán, bao gồm sản phẩm đăng ký và bổ sung tùy chọn của bạn:
const session = await client.checkoutSessions.create({
  product_cart: [
    {
      product_id: 'prod_subscription',
      quantity: 1
    }
  ]
});

Thay đổi gói với tỷ lệ

Nâng cấp hoặc giảm cấp một đăng ký và kiểm soát hành vi tỷ lệ:
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_new',
  quantity: 1,
  proration_billing_mode: 'difference_immediately'
});

Hủy vào ngày lập hóa đơn tiếp theo

Lên lịch hủy bỏ có hiệu lực vào cuối kỳ lập hóa đơn hiện tại:
await client.subscriptions.update('sub_123', {
  cancel_at_next_billing_date: true
});

Đăng ký theo Yêu Cầu

Tạo một đăng ký theo yêu cầu và tính phí sau nếu cần:
const onDemand = await client.subscriptions.create({
  customer_id: 'cus_123',
  product_id: 'prod_on_demand',
  on_demand: true
});

await client.subscriptions.charge(onDemand.id, {
  amount: 4900,
  currency: 'USD',
  description: 'Extra usage for September'
});

Cập nhật phương thức thanh toán cho đăng ký đang hoạt động

Cập nhật phương thức thanh toán cho một đăng ký đang hoạt động:
// Update with new payment method
const response = await client.subscriptions.updatePaymentMethod('sub_123', {
  type: 'new',
  return_url: 'https://example.com/return'
});

// Or use existing payment method
await client.subscriptions.updatePaymentMethod('sub_123', {
  type: 'existing',
  payment_method_id: 'pm_abc123'
});

Kích hoạt lại đăng ký từ on_hold

Kích hoạt lại một đăng ký đã bị tạm dừng do thanh toán thất bại:
// Update payment method - automatically creates charge for remaining dues
const response = await client.subscriptions.updatePaymentMethod('sub_123', {
  type: 'new',
  return_url: 'https://example.com/return'
});

if (response.payment_id) {
  // Charge created for remaining dues
  // Redirect customer to response.payment_link
  // Monitor webhooks: payment.succeeded → subscription.active
}

Đăng ký với Ủy Nhiệm Tuân Thủ RBI

Đăng ký UPI và thẻ Ấn Độ hoạt động theo quy định của RBI (Ngân hàng Dự trữ Ấn Độ) với yêu cầu ủy nhiệm cụ thể:

Giới Hạn Ủy Nhiệm

Loại và số lượng ủy nhiệm phụ thuộc vào khoản phí định kỳ của đăng ký của bạn:
  • Phí dưới mức sàn ủy nhiệm (mặc định ₹15,000): Chúng tôi tạo một ủy nhiệm theo yêu cầu cho số tiền sàn. Số tiền đăng ký được tính định kỳ theo tần suất đăng ký của bạn, lên đến giới hạn ủy nhiệm.
  • Phí tại hoặc trên mức sàn ủy nhiệm: Chúng tôi tạo một ủy nhiệm đăng ký (hoặc ủy nhiệm theo yêu cầu) cho chính xác số tiền đăng ký.
Mức sàn ủy nhiệm có thể cấu hình cho mỗi thương nhân hoặc theo yêu cầu qua mandate_min_amount_inr_paise (INR paise). Số tiền đăng ký với ngân hàng là max(mandate_floor, billing_amount) — do đó, mức sàn thực tế sẽ trở thành giới hạn ủy quyền mà khách hàng thấy khi mô tả khi phí thấp hơn. Để biết thông tin chi tiết về các ủy nhiệm tuân thủ RBI và mức sàn ủy nhiệm có thể cấu hình cho các phương thức thanh toán tại Ấn Độ, xem trang Phương thức Thanh toán tại Ấn Độ.

Lưu Ý về Nâng cấp và Giảm cấp

Quan trọng: Khi nâng cấp hoặc giảm cấp đăng ký, cần cân nhắc kỹ về giới hạn ủy nhiệm:
  • Nếu nâng cấp/giảm cấp dẫn đến số tiền phí vượt quá Rs 15,000 và vượt qua giới hạn thanh toán theo yêu cầu hiện tại, phí giao dịch có thể thất bại.
  • Trong những trường hợp như vậy, khách hàng có thể cần cập nhật phương thức thanh toán của họ hoặc thay đổi đăng ký một lần nữa để thiết lập một ủy nhiệm mới với giới hạn chính xác.

Ủy quyền cho các khoản phí có giá trị cao

Đối với các khoản phí đăng ký từ Rs 15,000 trở lên:
  • Khách hàng sẽ được ngân hàng yêu cầu để ủy quyền cho giao dịch.
  • Nếu khách hàng không ủy quyền giao dịch, việc giao dịch sẽ thất bại và đăng ký sẽ bị tạm dừng.

48 Giờ Trì Hoãn Xử Lý

Thời gian Xử lý: Các khoản phí định kỳ trên thẻ Ấn Độ và đăng ký UPI tuân theo một mô hình xử lý duy nhất:
  • Các khoản phí được khởi tạo vào ngày đã lên lịch theo tần suất đăng ký của bạn.
  • Thực tế khấu trừ từ tài khoản khách hàng chỉ diễn ra sau 48 giờ từ khi khởi tạo thanh toán.
  • Khoảng thời gian 48 giờ này có thể kéo dài thêm lên tới 2-3 giờ tùy thuộc vào các phản hồi của API ngân hàng.

Cửa Sổ Hủy Ủy Nhiệm

Trong khoảng thời gian 48 giờ xử lý:
  • Khách hàng có thể hủy ủy nhiệm qua ứng dụng ngân hàng của họ.
  • Nếu khách hàng hủy ủy nhiệm trong thời gian này, đăng ký sẽ vẫn hoạt động (đây là một trường hợp đặc biệt đối với đăng ký tự động UPI và thẻ Ấn Độ).
  • Tuy nhiên, việc khấu trừ thực tế có thể thất bại, và trong trường hợp đó, chúng tôi sẽ đặt đăng ký tạm dừng.
Xử lý Trường hợp Đặc biệt: Nếu bạn cung cấp quyền lợi, tín dụng hoặc sử dụng đăng ký cho khách hàng ngay lập tức khi bắt đầu khoản phí, bạn cần xử lý khoảng thời gian 48 giờ này một cách thích hợp trong ứng dụng của mình. Xem xét:
  • Trì hoãn kích hoạt quyền lợi cho đến khi xác nhận thanh toán
  • Triển khai các giai đoạn ân hạn hoặc quyền truy cập tạm thời
  • Giám sát trạng thái đăng ký để phát hiện hủy ủy nhiệm
  • Xử lý trạng thái tạm dừng đăng ký trong logic ứng dụng của bạn
Giám sát webhook đăng ký để theo dõi thay đổi trạng thái thanh toán và xử lý các trường hợp đặc biệt khi ủy nhiệm bị hủy trong khoảng thời gian 48 giờ.

Thực Hành Tốt Nhất

  • Bắt đầu với các cấp rõ ràng: 2–3 kế hoạch có sự khác biệt rõ ràng
  • Truyền đạt giá cả: Hiển thị tổng cộng, tỷ lệ, và lần gia hạn tiếp theo
  • Sử dụng thử nghiệm một cách khôn ngoan: Chuyển đổi với quá trình onboarding, không chỉ là thời gian
  • Tận dụng bổ sung: Giữ các kế hoạch cơ bản đơn giản và bán thêm những thứ phụ
  • Thử nghiệm thay đổi: Xác nhận các thay đổi kế hoạch và tỷ lệ trong chế độ thử nghiệm
Đăng ký là một nền tảng linh hoạt cho doanh thu định kỳ. Bắt đầu đơn giản, kiểm tra kỹ lưỡng, và lặp lại dựa trên số liệu chấp nhận, rời bỏ và mở rộng.
Lần sửa đổi cuối 18 tháng 6, 2026