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.

サブスクリプションのアップグレードまたはダウングレードとは?

顧客のサブスクリプションプランを変更して、異なるティア間で移動させたり、seat-based products の数量を調整したり、新しい product に移行したりできます。API は、選択した billing mode に基づいて日割り計算と請求を自動的に行います。
Plan changes can trigger an immediate charge depending on the proration mode you choose.

プラン変更を使用するタイミング

  • 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
詳細な設定手順については、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:
最適な用途:古いプランの未使用期間をクレジットとして付与したい SaaS applications。
  • 現在のサイクルの未使用部分を、残り時間に応じて日割りでクレジットします
  • その後、新しいプランの full サイクルを請求します。新しいプランの料金が日割りになることはありません
  • 正味の請求額 = 新しいサイクル全額 −(残りの割合 × 古いサイクル全額)
3

Implement the Change Plan API

Use the Change Plan API to modify subscription details:
string
必須
The ID of the active subscription to modify.
string
必須
サブスクリプションの変更先となる新しい product ID。
integer
必須
新しいプランのユニット数(seat-based products の場合)。
string
必須
即時 billing の処理方法:prorated_immediately、full_immediately、difference_immediately、または do_not_bill。
array
新しいプランのオプションアドオン。このフィールドを省略する、nullを送信する、または空の配列を送信すると、既存のアドオンがすべて削除されます。保持するには、現在のアドオンを含めてください。
string
プラン変更の支払いに失敗した場合の動作を制御します:
  • prevent_change:支払いが成功するまで現在のプランでサブスクリプションを維持
  • apply_change(デフォルト):支払い結果にかかわらず、直ちにプラン変更を適用
If not specified, uses the business-level default setting.
サブスクリプションに保存された支払い方法へ請求する代わりに、payment link でプラン変更額を回収します。顧客は hosted checkout page で支払います。business に allow_plan_change_via_payment_link capability(Settings → Subscriptions → Collect Plan Change Payments by Payment Link)、effective_at: immediately、および on_payment_failure: prevent_change が必要です。Collecting Payment via a Checkout Linkを参照してください。Preview routeでは無視されます。
string
顧客が payment link の支払い後に戻る URL。リダイレクトには subscription_id、payment_id、status が追加されます。collect_via_payment_link: true が必要です。指定しない場合、リクエストは 422 で失敗します。支払い後の顧客のリダイレクトを参照してください。
保留中のプラン変更に紐づく未払いの payment link をキャンセルし、このリクエストで置き換えます。支払い済みまたは処理中の支払いの場合、409 を返します。保留中の Payment Link の置き換えを参照してください。preview route では無視されます。
array
新しいプランに適用するオプションの積み重ね可能なdiscount codes(最大20個、array の順序で適用):
  • 未指定 / null — 新しい product に適用可能な場合、preserve_on_plan_change=true を含む既存の discounts は保持されます。
  • [](空の array) — サブスクリプションから既存の discounts をすべて削除します。
  • ["CODE_A", "CODE_B", ...] — 既存の discounts をこの stacked set に置き換えます。
string
非推奨
非推奨 — 新しい integrations では discount_codes を使用してください。この field は backward compatibility のため引き続き動作しますが、同じリクエストで discount_codes と併用できません。
string
デフォルト:"immediately"
プラン変更を適用するタイミング:
  • immediately(デフォルト):プラン変更を直ちに適用
  • next_billing_date:次回の billing date に変更を予約。billing period が終了するまで顧客は現在のプランを保持します。顧客が billing period の終了まで現在のプランの benefits を利用できるよう、downgrade にはこれを使用してください。
4

Handle Webhook Events

プラン変更の結果を追跡する webhook handling を設定します:
  • subscription.active:プラン変更成功、subscription updated
  • subscription.plan_changed:サブスクリプションのプラン変更(upgrade/downgrade/addon update)
  • subscription.on_hold:プラン変更の charge に失敗、renewals stopped
  • payment.succeeded:プラン変更の即時 charge に成功
  • payment.failed:即時 charge に失敗
常に webhook signatures を検証し、idempotent な event processing を実装してください。
5

Update Your Application State

webhook events に基づいてアプリケーションを更新します:
  • 新しいプランに基づいて features を付与/取り消し
  • 新しいプランの詳細で customer dashboard を更新
  • プラン変更の確認メールを送信
  • audit purposes のため billing changes を記録
6

Test and Monitor

実装を十分にテストします:
  • さまざまな scenarios で全 proration modes をテスト
  • webhook handling が正しく機能することを確認
  • プラン変更の成功率を監視
  • 失敗したプラン変更の alerts を設定
サブスクリプションのプラン変更実装は、production use の準備が整いました。

プラン変更のプレビュー

プラン変更を確定する前に、Preview API を使用して顧客に請求額を正確に表示します:
Preview API を使用して、顧客がプラン変更を確定する前に正確な請求額を表示する confirmation dialogs を構築します。
immediate_charge.summary では、customer_credits は、customer_credits_currency で示される顧客の credit balance の純変動です。これは顧客の credit wallet の通貨であり、subscription currency です。summary の currency とは異なる場合があります。summary の値は total_amount と tax に適用されます。たとえば、USD subscription を INR で支払う顧客には、USD の credits が表示されます。

Change Plan API

Change Plan API を使用して、active subscription の product、quantity、proration behavior を変更します。

クイックスタートの例

プラン変更に成功すると、200 OK が直ちに返されます。これは charge が実際に settle する前です。body(ChangePlanResponse)の内容は、変更の回収方法によって異なります:
この response は、charge が成功したことではなく、request が受理されたことを確認するものです。通常の即時 charge では、call の直後に off-session で結果が確定します。collect_via_payment_link request の場合、顧客が支払いを完了するまでサブスクリプションは現在のプランに留まります。webhook(payment.succeeded、payment.failed、subscription.plan_changed)で結果を確認するか、GET /subscriptions/{subscription_id} を使用してサブスクリプションを再読み込みしてください。payment-link case についてはリンクが未払いの間の動作を参照してください。
即時 charge に失敗すると、支払いが成功するまでサブスクリプションが subscription.on_hold に移行する場合があります。
デフォルトでは、即時のプラン変更によってサブスクリプションの保存済み payment method に直接請求されます。代わりに collect_via_payment_link: true を設定すると、顧客を hosted checkout page に移動できます。保存済み payment method がない場合や、顧客に新しい価格を明示的に確認してもらいたい場合に便利です。
これは Settings → Subscriptions にある Collect Plan Change Payments by Payment Link toggle を有効にし、Customer Portal のプラン変更 flow を checkout 経由にします。

Requirements

collect_via_payment_link: true が成功するには、次のすべてを満たす必要があります。満たさない場合、request は 422 で失敗します:
  • business で allow_plan_change_via_payment_link capability が有効になっている(Settings → Subscriptions → Collect Plan Change Payments by Payment Link)。
  • effective_at が immediately(デフォルト)である。scheduled change(next_billing_date)では checkout page は不要です。
  • request で on_payment_failure: prevent_change を設定する。明示的な apply_change は 422 で失敗します。
collect_via_payment_link は、上記の要件を満たす限り、charge が発生するすべての即時変更(downgrade を含む)に適用されます。
変更後の差額がゼロまたは credit になる場合、payment link は発行されません。payment_link とその他の checkout fields は null で返され、変更は直ちに適用されます。これは 422 ではありません。link を要求する前に、Preview Plan Change を呼び出して金額を確認してください。
成功した request は checkout handles を返します:
  • サブスクリプションは現在のプランに留まります。product_id、recurring_pre_tax_amount、next_billing_date は、link が支払われるまで変更されません。
  • link が pending の間、追加の change-plan request は 409 PendingPlanChangeExists で拒否されます。保留中の変更を置き換えるには、新しい request に cancel_older_payment_link: true を指定してください。保留中の Payment Link の置き換えを参照してください。
  • declined payment の後に再試行するには、change-plan を再度呼び出して新しい link を取得します。
  • link が一度も支払われない場合、expires_on 後に機能しなくなります。その後まもなく、サブスクリプションは自動的に新しい plan-change request を受け付けられる状態になります。
  • scheduled change がすでに存在し、それを cancel_scheduled_change_plan: true で置き換えた場合、link が未払いの間は元の schedule が維持され、link の支払い時(新しいプランを適用する同一 transaction 内)にのみキャンセルされます。
即時 payment-link change が発行されると、そのサブスクリプションに対する以降のすべての plan-change request(side-effect-free preview を含む)が、link の解決まで block されます。change-plan request は、cancel_older_payment_link: true を設定して link を置き換えられます。preview はこの field を無視するため、preview も block されたままです。

支払い後の顧客のリダイレクト

顧客が link の支払い後にサイトへ戻るようにするには、return_url を設定します:
checkout 後、顧客は次の query parameters を付けて return_url に移動します: 支払いに失敗しても、サブスクリプションは現在のプランで active のままです。payment webhook の到着後、まもなく新しいプランが適用される可能性があるため、新しいプランを表示する前にサブスクリプションを再度読み込んでください。 return_url には collect_via_payment_link: true が必要です。指定しない場合、request は 422 で失敗します。 顧客が支払わずに checkout を離れた場合、次の change-plan request で cancel_older_payment_link: true を設定します。Dodo Payments は未払いの link をキャンセルし、新しいプラン変更で保留中の変更を置き換えます。キャンセルされた link は、すでに開いている checkout page であっても支払いを受け付けなくなります。
link をキャンセルする前に request が検証されるため、無効な request では顧客の link は維持されます。link がキャンセルされるのは、顧客が支払いを開始していない場合のみです: 各 change-plan request は独自の invoice を発行します。置き換えられたプラン変更とその invoice はキャンセルされます。保留中のプラン変更がない場合、cancel_older_payment_link は効果がありません。
minimum charge amount など、validation 後に実行される check が、link のキャンセル後に失敗する場合もあります。その場合、サブスクリプションは open link のない現在のプランに留まります。request を再送して新しい link を発行してください。

Addons の管理

サブスクリプションプランの変更時に、addons も変更できます:
Addons は proration calculation に含まれ、選択した proration mode に従って請求されます。

Discount Codes の適用

サブスクリプションプランの変更時に、1つ以上の stacked discount codes を適用します(最大20個、array の順序で適用):

Plan Change 時の Discount Behavior

この endpoint の単数形 discount_code field は非推奨ですが、backward compatibility のため引き続き動作します。既存の integrations はすぐに変更する必要はありません。同じ request で discount_codes と併用できません。都合のよいタイミングで array form に移行してください。
Preview Plan Change API を discount_codes とともに使用し、プラン変更を確定する前に顧客がどれだけ節約できるかを正確に表示します。

Proration Modes

プラン変更時に顧客へ請求する方法を選択します:

prorated_immediately

  • 現在の cycle の未使用部分(base plan、quantity、add-ons)を、残り時間に応じて prorate し、credit します
  • その後、新しい plan、quantity、add-ons のfull cycle を請求します。charge 自体は prorate されません
  • Net immediate charge =(新しい full cycle)−(残りの割合 × 古い full cycle)
  • credit が新しい cycle の charge を超える場合(downgrade でよく発生)、差額は subscription-scoped credit として将来の renewals に使用されます
  • trial 中の場合は直ちに請求し、現在新しいプランに切り替えます

full_immediately

  • 新しいプランの全額を直ちに請求します
  • 古いプランの残り時間を無視します。現在の cycle に対する credit はありません
prorated_immediately によって作成された credits と、difference_immediately を使用した downgrades によって作成された credits は subscription-scoped であり、Credit-Based Billing entitlements とは異なります。これらは同じ subscription の将来の renewals に自動的に適用され、subscriptions 間で transfer できません。

difference_immediately

  • Upgrade:古いプランと新しいプランの price difference を直ちに請求
  • Downgrade:残りの value を subscription の internal credit として追加し、renewals に自動適用

do_not_bill

  • charges または credits は計算されません
  • billing adjustment なしで、顧客は直ちに新しいプランへ切り替わります
  • Billing cycle は変更されません
  • courtesy migrations、free plan switches、または cost differences の吸収に最適

Example Scenarios

次の canonical numbers を一貫して使用します:
  • Current plan:Basic($30/month)
  • Upgrade target:Pro($80/month)
  • Downgrade target(Pro から):Starter($20/month)
  • Billing cycle:30 days、January 1 に開始
  • Plan change:January 16 に実行(残り15日、使用済み15日)

各モードの Billing 処理

古いプランの未使用時間を credit し、新しいプランの full cycle を請求するには prorated_immediately を選択します。billing を再開するには full_immediately を選択します。単純な upgrades と downgrades の自動 credit には difference_immediately を使用します。billing adjustment なしでプランを切り替えるには do_not_bill を使用します。

Payment Failures の処理

on_payment_failure parameter を使用して、プラン変更の支払いに失敗した場合の動作を制御します。

Payment Failure Modes

指定しない場合、on_payment_failure parameter は dashboard で設定された business-level default setting を使用します。

各モードの使用場面

Business & Collection Defaults

Settings → Subscriptions の business level で、upgrade と downgrade の default behavior を設定します。これらの defaults はすべての customer-portal plan changes に適用され、product collection ごとに override できます。 upgrade と downgrade には別々の defaults があります: business defaults は Settings → Subscriptions で、collection overrides は各 product collection で設定します。各 collection field は独立しています。未設定のままにすると business default を継承し、値を設定すると override します。

Resolution Order

各 plan change では、各 setting が次の順序で解決されます:
Change Plan API に明示的に渡された value が常に優先されます。business と collection の defaults は、明示的な value が指定されていない場合にのみ適用されます。これは customer portal から開始されたすべての plan changes に該当します。
一般的な設定では、upgrades を immediately + difference_immediately にして、顧客が差額を支払い直ちに access できるようにします。また、downgrades は next_billing_date にして、cycle が終了するまで顧客が現在のプランを維持できるようにします。

Webhooks の処理

webhooks を通じて subscription state を追跡し、plan changes と payments を確認します。

処理する Event Types

  • subscription.active:subscription activated
  • subscription.plan_changed:subscription plan changed(upgrade/downgrade/addon changes)
  • subscription.on_hold:charge failed、renewals stopped
  • subscription.renewed:renewal succeeded
  • payment.succeeded:plan change または renewal の payment succeeded
  • payment.failed:payment failed
business logic は subscription events を基に動作させ、confirmation と reconciliation には payment events を使用します。

Signatures の検証と Intents の処理

詳細な payload schemas については、Subscription webhook payloads と Payment webhook payloads を参照してください。

Best Practices

Plan Change Strategy

  • 十分にテストする:production 前に必ず test mode で plan changes をテスト
  • proration を慎重に選択する:business model に合った proration mode を選択
  • failures を適切に処理する:適切な error handling と retry logic を実装
  • 成功率を監視する:plan change の成功/失敗率を追跡し、問題を調査

Webhook Implementation

  • signatures を検証する:authenticity を保証するため、常に webhook signatures を検証
  • idempotency を実装する:重複した webhook events を適切に処理
  • asynchronously 処理する:重い operations で webhook responses を block しない
  • すべてを log に記録する:debugging と audit purposes のため詳細な logs を維持

User Experience

  • 明確に伝える:billing changes と timing を顧客に通知
  • confirmations を提供する:成功した plan changes の email confirmations を送信
  • edge cases を処理する:trial periods、prorations、failed payments を考慮
  • UI を直ちに更新する:アプリケーション interface に plan changes を反映

Common Issues and Solutions

subscription plan changes 中に発生する一般的な問題を解決します:
Symptoms:API call は成功するが、サブスクリプションが古いプランのままCommon causes:
  • Webhook processing に失敗した、または遅延した
  • webhooks 受信後に application state が更新されていない
  • state update 中の database transaction issues
Solutions:
  • retry logic を備えた webhook handling を実装
  • state updates に idempotent operations を使用
  • missed webhook events を検出して alert する monitoring を追加
  • webhook endpoint にアクセスでき、正しく応答していることを確認
Symptoms:顧客が downgrade したが credit balance が表示されないCommon causes:
  • Proration mode の想定:downgrades は difference_immediately で full plan price difference を credit します。一方 prorated_immediately は古い cycle の未使用時間を credit し、新しいプランの full cycle を請求するため、その credit が新しいプラン価格を超えた場合にのみ credit balance が残ります
  • Credits は subscription-specific で、subscriptions 間で transfer されない
  • Customer dashboard に credit balance が表示されない
Solutions:
  • automatic credits が必要な downgrade には difference_immediately を使用
  • credits は同じ subscription の将来の renewals に適用されることを顧客に説明
  • credit balances を表示する customer portal を実装
  • next invoice preview で適用された credits を確認
Symptoms:invalid signature により webhook events が拒否されるCommon causes:
  • webhook secret key が正しくない
  • signature verification 前に raw request body が変更された
  • signature verification algorithm が間違っている
Solutions:
  • dashboard の正しい DODO_PAYMENTS_WEBHOOK_KEY を使用していることを確認
  • JSON parsing middleware の前に raw request body を読み取る
  • platform 用の standard webhook verification library を使用
  • development environment で webhook signature verification をテスト
Symptoms:API が 422 Unprocessable Entity error を返すCommon causes:
  • subscription ID または product ID が無効
  • Subscription が active state ではない
  • required parameters が不足
  • product が plan changes に利用できない
Solutions:
  • subscription が存在し、active であることを確認
  • product ID が有効で利用可能か確認
  • required parameters がすべて提供されていることを確認
  • parameter requirements について API documentation を確認
Symptoms:plan change は開始されたが、immediate charge に失敗するCommon causes:
  • 顧客の payment method の資金不足
  • payment method の期限切れまたは無効
  • bank が transaction を declined
  • fraud detection が charge を block
Solutions:
  • payment.failed webhook events を適切に処理
  • 顧客に payment method の更新を通知
  • temporary failures に対する retry logic を実装
  • failed immediate charges でも plan changes を許可することを検討
Symptoms:plan change charge に失敗し、subscription が on_hold state に移行するWhat happens: plan change charge に失敗すると、subscription は自動的に on_hold state になります。payment method が更新されるまで、subscription は自動的に renew されません。Solution:payment method を更新して subscription を再有効化しますfailed plan change の後、on_hold state から subscription を再有効化するには:
  1. payment method を更新:Update Payment Method API を使用
  2. Automatic charge creation:API が残りの dues に対する charge を自動作成
  3. Invoice generation:charge の invoice を生成
  4. Payment processing:新しい payment method で payment を処理
  5. Reactivation:payment 成功後、subscription を active state に再有効化
Webhook events to monitor:
  • subscription.on_hold:Subscription placed on hold(plan change charge の失敗時に受信)
  • payment.succeeded:remaining dues の payment succeeded(payment method 更新後)
  • subscription.active:successful payment 後に subscription reactivated
Best practices:
  • plan change charge の失敗時に顧客へ直ちに通知
  • payment method の更新方法について明確な instructions を提供
  • reactivation status を追跡するため webhook events を監視
  • temporary payment failures に対する automatic retry logic の実装を検討

Update Payment Method API Reference

payment methods の更新と subscriptions の再有効化について、完全な API documentation を確認してください。

実装のテスト

subscription plan change implementation を十分にテストします:
1

Set up test environment

  • test API keys と test products を使用
  • 異なる plan types で test subscriptions を作成
  • test webhook endpoint を設定
  • monitoring と logging を設定
2

Test different proration modes

  • さまざまな billing cycle positions で prorated_immediately をテスト
  • upgrades と downgrades で difference_immediately をテスト
  • billing cycles を reset するため full_immediately をテスト
  • no-charge/no-credit plan switches で do_not_bill をテスト
  • credit calculations が正しいことを確認
3

Test webhook handling

  • 関連するすべての webhook events が受信されることを確認
  • webhook signature verification をテスト
  • duplicate webhook events を適切に処理
  • webhook processing failure scenarios をテスト
4

Test error scenarios

  • invalid subscription IDs でテスト
  • expired payment methods でテスト
  • network failures と timeouts をテスト
  • insufficient funds でテスト
5

Monitor in production

  • failed plan changes の alerts を設定
  • webhook processing times を監視
  • plan change success rates を追跡
  • plan change issues に関する customer support tickets を確認

Error Handling

実装で一般的な API errors を適切に処理します:

HTTP Status Codes

Plan change request は正常に処理されました。response body は payment_id、payment_link、client_secret、expires_on を含む ChangePlanResponse です。4つすべて nullable であるため、通常の off-session change では body は {} として serialize されます。成功した collect_via_payment_link request では checkout handles が返されます。Checkout Link による支払いの回収を参照してください。on_payment_failure=prevent_change の場合、plan change は payment が成功するまで pending のままです。
Invalid request parameters。required fields がすべて提供され、正しく format されていることを確認してください。
API key が無効または不足しています。DODO_PAYMENTS_API_KEY が正しく、適切な permissions を持つことを確認してください。
この subscription にはすでに pending plan change(PendingPlanChangeExists)があります。scheduled change の場合は、新しいものを送信する前に DELETE /subscriptions/{subscription_id}/change-plan/scheduled でキャンセルしてください。pending payment-link change の場合は、新しい request に cancel_older_payment_link: true を指定して置き換えてください。保留中の Payment Link の置き換えを参照してください。cancel_older_payment_link: true を指定した場合、409 は顧客が以前の link を現在支払っている(PLAN_CHANGE_PAYMENT_IN_PROGRESS)か、すでに支払い済み(PLAN_CHANGE_PAYMENT_ALREADY_COMPLETED)であることを意味します。
cancel_older_payment_link: true を指定した場合、以前の payment link をキャンセルできませんでした(PLAN_CHANGE_LINK_CANCEL_FAILED)。変更はないため、request を再試行できます。
Subscription が inactive または on-demand であるか、request が collect_via_payment_link の対象外です。business で capability が有効になっていない、effective_at が immediately ではない、または on_payment_failure が prevent_change ではありません。Requirementsを参照してください。存在しない、またはアカウントに属していない subscription ID は、NOT_FOUND code とともに 404 を返します。
Server error が発生しました。少し待ってから request を再試行してください。

Error Response Format

Errors は code と human-readable な message を含む JSON body を返します:
完全な一覧についてはError Codesを参照してください。

Next Steps

最終更新日 2026年10月8日