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
必須
The ID of the active subscription to modify.
string
必須
The new product ID to change the subscription to.
integer
必須
Number of units for the new plan (for seat-based products).
string
必須
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.
サブスクリプションに保存されている支払い方法で請求する代わりに、payment linkでプラン変更額を回収します。顧客はホスト型のcheckoutページで支払います。ビジネスでallow_plan_change_via_payment_link機能(Settings → Subscriptions → Collect Plan Change Payments by Payment Link)が有効であり、effective_at: immediatelyおよびon_payment_failure: prevent_changeが必要です。Collecting Payment via a Checkout Linkを参照してください。プレビュー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のため引き続き動作しますが、同じrequestでdiscount_codesと併用することはできません。
string
デフォルト:"immediately"
プラン変更を適用するタイミング:
  • immediately(デフォルト):プラン変更を直ちに適用します
  • next_billing_date:次回のbilling dateに変更をscheduleします。billing periodが終了するまで、顧客は現在のプランを維持します。
downgradeではnext_billing_dateを使用し、billing periodの終了まで顧客が現在のプランのbenefitsを維持できるようにします。
4

Handle Webhook Events

プラン変更の結果を追跡するため、webhook handlingを設定します。
  • subscription.active:プラン変更に成功し、subscriptionが更新された
  • subscription.plan_changed:subscription planが変更された(upgrade/downgrade/addon update)
  • subscription.on_hold:プラン変更のchargeに失敗し、renewalsが停止された
  • payment.succeeded:プラン変更の即時chargeに成功した
  • payment.failed:即時chargeに失敗した
常にwebhook signaturesを検証し、idempotentなevent processingを実装してください。
5

Update Your Application State

webhook eventsに基づいてapplicationを更新します。
  • 新しいplanに基づいてfeaturesを付与/取り消す
  • 新しいplanの詳細でcustomer dashboardを更新する
  • plan changesについてconfirmation emailsを送信する
  • audit purposesのためbilling changesをlogに記録する
6

Test and Monitor

実装を十分にテストします。
  • さまざまなscenarioですべてのproration modesをテストする
  • webhook handlingが正しく動作することを確認する
  • plan change success ratesを監視する
  • failed plan changesのalertsを設定する
subscription plan changeの実装は、productionで使用できる状態になりました。

プラン変更のプレビュー

プラン変更を確定する前に、Preview APIを使用して、顧客に請求される正確な金額を表示します。
preview APIを使用して、顧客がplan changeを確認する前に正確な請求額を表示するconfirmation dialogsを作成します。

Change Plan API

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

クイックスタートの例

plan changeが成功すると、実際にchargeがsettleする前に200 OKが直ちに返されます。body(ChangePlanResponse)の内容は、変更の回収方法によって異なります。
いずれの場合も、このresponseはpayment resultではなく、request自体が受け付けられたことだけを示します。即時chargeが実際に成功したかどうかは示しません。通常の即時chargeでは、その結果はcall直後にoff-sessionで確定します。collect_via_payment_link requestでは、結果は後から非同期に確定します。responseで渡されるのはcheckout linkだけで、subscriptionは現在のplanにとどまり、顧客が実際にlinkでpaymentを完了するまで結果は分かりません。いずれの場合も、このresponseから結果を推測しないでください。webhook(payment.succeededpayment.failedsubscription.plan_changed)で確認するか、GET /subscriptions/{subscription_id}でsubscriptionを再読み込みしてください。payment-linkの場合の詳細はWhat Happens While the Link Is Unpaidを参照してください。
即時chargeに失敗すると、paymentが成功するまでsubscriptionがsubscription.on_holdに移行する場合があります。

Checkout LinkによるPaymentの回収

デフォルトでは、即時のplan changeによってsubscriptionの保存済み支払い方法に直接chargeされます。collect_via_payment_link: trueを設定すると、代わりに顧客をhosted checkout pageへ誘導できます。off-sessionでchargeできる保存済み支払い方法がない場合や、顧客に新しい価格を明示的に確認してもらいたい場合に便利です。
これは、Settings → SubscriptionsにあるCollect Plan Change Payments by Payment Link toggleの機能でも使用されています。このtoggleは、組み込みのCustomer Portalのplan-change flowを、保存済みカードではなくcheckout経由にします。

要件

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_atimmediately(デフォルト)であること。scheduled change(next_billing_date)では、適用されるまでchargeされないためcheckout pageは不要です。
  • effectiveなon_payment_failureprevent_changeに解決されること。明示的に送る必要はありません。business-level default(下記のBusiness & Collection Defaultsを参照)がすでにprevent_changeであれば、fieldを省略してもこの条件を満たします。明示的なapply_change、または解決されたdefaultがapply_changeの場合は422で失敗します。
collect_via_payment_linkはupgradeに限定されません。上記の要件を満たし、chargeが発生する即時変更であれば、downgradeを含めて適用されます。
変更額がゼロまたはcreditになる場合(proration_billing_mode: do_not_bill、または今cycleの合計がたまたまゼロになる別のmode)は、checkout pageに表示するものがありません。payment linkは発行されず、payment_linkなどはnullとして返され、変更はcollect_via_payment_linkなしの場合と同じく直ちに適用されます。これは422ではありません。このflagは回収すべき正の金額がある場合にのみ有効です。明確なupgrade以外のplan changesに一般的にcollect_via_payment_linkを設定する場合は、まずPreview Plan Changeを呼び出し、previewされた金額を回収する価値がある場合にのみlinkを要求してください。
成功したrequestはcheckout handlesを返します。

Linkが未払いの間に発生すること

  • subscriptionは現在のplanにとどまります。product_idrecurring_pre_tax_amountnext_billing_dateは、linkが支払われるまで変更されません。
  • linkがpendingの間、同じsubscriptionへの追加のchange-plan requestは409 PendingPlanChangeExistsで拒否されます。必要に応じてDELETE /subscriptions/{subscription_id}/change-plan/scheduledscheduled changeをcancelできますが、このendpointではpending payment-link changeはcancelできません。cancelされるのは、paymentの成功またはexpiryによってのみです。
  • decline後も、顧客は同じcheckout sessionでカードを再試行できます。新しいchange-plan callはretry pathではありません。
  • linkが一度も支払われない場合、expires_on後に機能しなくなり、その少し後にsubscriptionは新しいplan-change requestを受け付けられる状態になります。
  • scheduled change(next_billing_date)がすでに存在し、それをcancel_scheduled_change_plan: trueで置き換えた場合、linkが未払いの間は元のscheduleが維持されます。linkの支払いが完了した時点で、新しいplanを適用するtransaction内でのみcancelされます。
即時payment-link changeが発行されると、そのsubscriptionへの以後のすべてのplan-change request(副作用のないpreviewを含む)が、linkの解決までblockedになります。顧客にすぐ支払ってもらう意図のないlinkは発行しないでください。

Addonsの管理

subscription plansを変更する際、addonsも変更できます。
addonsはproration calculationに含まれ、選択したproration modeに従ってchargeされます。

Discount Codesの適用

subscription plansの変更時に、1つ以上のstacked discount codes(最大20個、arrayの順序で適用)を適用できます。upgradeやmigrationにpromotional pricingを提供する場合に便利です。

Plan change時のDiscountの動作

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

Proration modes

plansの変更時に顧客へどのようにbillするかを選択します。

prorated_immediately

  • 現在のcycleにおける差額の一部をchargeする
  • trial中の場合は直ちにchargeし、今すぐ新しいplanに切り替える
  • Downgrade:prorated creditが発生し、今後のrenewalsに適用される場合がある

full_immediately

  • 新しいplanの全額を直ちにchargeする
  • 旧planの残り期間を無視する
difference_immediatelyを使用したdowngradeによって作成されるcreditsはsubscriptionにスコープされ、Credit-Based Billingのentitlementsとは別物です。同じsubscriptionの今後のrenewalsに自動適用され、subscription間でtransferすることはできません。

difference_immediately

  • Upgrade:旧planと新planの価格差を直ちにchargeする
  • Downgrade:残りのvalueをsubscriptionへのinternal creditとして追加し、renewalsに自動適用する

do_not_bill

  • chargesもcreditsも計算しない
  • billing adjustmentなしで、顧客を直ちに新しいplanへ切り替える
  • billing cycleは変更しない
  • courtesy migrations、free plan switches、またはcost differencesの吸収に最適

シナリオ例

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

各modeでのbilling処理

時間に基づく公平なaccountingにはprorated_immediately、billingをrestartするにはfull_immediately、単純なupgradesとdowngrades時の自動creditにはdifference_immediately、billing adjustmentなしのplan切り替えにはdo_not_billを選択します。

Payment Failuresの処理

on_payment_failure parameterを使用して、plan change paymentが失敗した場合の動作を制御します。

Payment Failure Modes

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

各Modeの使用タイミング

Business & Collection Defaults

すべてのplan changeでproration parametersを渡す代わりに、default upgrade & downgrade behaviorをbusiness levelで一度設定できます。これらのdefaultsはすべてのcustomer-portal plan changesに適用され、product collectionごとにoverrideできます。 upgradeとdowngradeにはそれぞれ別のdefaultsがあります。 business defaultsはSettings → Subscriptionsで、collection overridesは各product collectionで設定します。各collection fieldは独立しています。未設定のままにするとbusiness defaultをinheritし、値を設定するとそのcollectionにのみoverrideされます。

Resolution order

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

Webhooksの処理

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

処理するEvent types

  • subscription.active:subscriptionがactivated
  • subscription.plan_changed:subscription planが変更された(upgrade/downgrade/addon changes)
  • subscription.on_hold:chargeに失敗し、renewalsが停止された
  • subscription.renewed:renewalに成功した
  • payment.succeeded:plan changeまたはrenewalのpaymentに成功した
  • payment.failed:paymentに失敗した
business logicはsubscription eventsを基準にし、confirmationとreconciliationにはpayment eventsを使用することを推奨します。

Signaturesの検証とIntentsの処理

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

Best Practices

信頼性の高いsubscription plan changesのため、次の推奨事項に従ってください。

Plan Change Strategy

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

Webhook Implementation

  • signaturesを検証する:authenticityを確保するため、常にwebhook signaturesをvalidateする
  • idempotencyを実装する:重複したwebhook eventsを適切に処理する
  • 非同期で処理する:重い処理で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を直ちに更新する:application interfaceにplan changesを反映する

よくある問題と解決策

subscription plan changes中に発生する一般的な問題を解決します。
Symptoms:API callは成功するが、subscriptionがold planのまま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にaccessでき、正しくresponseしていることを確認する
Symptoms:顧客がdowngradeしたが、credit balanceが表示されないCommon causes
  • Proration modeの想定:downgradeではdifference_immediatelyによりfull plan price differenceがcreditされる一方、prorated_immediatelyではcycleの残り時間に基づくprorated creditが作成される
  • Creditsはsubscription-specificで、subscription間でtransferされない
  • Customer dashboardにcredit balanceが表示されない
Solutions
  • automatic creditsが必要なdowngradeにはdifference_immediatelyを使用する
  • creditsは同じsubscriptionのfuture renewalsに適用されることを顧客に説明する
  • credit balancesを表示するcustomer portalを実装する
  • next invoice previewで適用されたcreditsを確認する
Symptoms:invalid signatureによりWebhook eventsがrejectされるCommon causes
  • webhook secret keyが正しくない
  • signature verification前にraw request bodyが変更された
  • signature verification algorithmが間違っている
Solutions
  • dashboardの正しいDODO_WEBHOOK_SECRETを使用していることを確認する
  • 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が開始されたが、即時chargeに失敗するCommon causes
  • 顧客のpayment methodの残高不足
  • payment methodの期限切れまたは無効
  • bankがtransactionをdeclineした
  • fraud detectionがchargeをblockした
Solutions
  • payment.failed webhook eventsを適切に処理する
  • 顧客にpayment methodの更新を通知する
  • 一時的な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をreactivateするfailed plan change後、on_hold stateのsubscriptionをreactivateするには:
  1. payment methodを更新する:Update Payment Method APIを使用します
  2. Automatic charge creation:APIが未払い残額へのchargeを自動作成します
  3. Invoice generation:chargeのinvoiceが生成されます
  4. Payment processing:新しいpayment methodでpaymentが処理されます
  5. Reactivation:payment成功後、subscriptionはactive stateにreactivateされます
監視するWebhook events
  • subscription.on_hold:subscriptionがholdされる(plan change charge失敗時に受信)
  • payment.succeeded:未払い残額のpaymentに成功(payment method更新後)
  • subscription.active:payment成功後にsubscriptionがreactivateされた
Best practices
  • plan change charge失敗時に顧客へ直ちに通知する
  • payment methodの更新方法を明確に案内する
  • reactivation statusを追跡するためwebhook eventsを監視する
  • 一時的なpayment failuresに対するautomatic retry logicの実装を検討する

Update Payment Method API Reference

payment methodsの更新とsubscriptionsのreactivationに関する完全なAPI documentationを確認してください。

実装のテスト

subscription plan changeの実装を十分にテストするには、次の手順に従います。
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をテストする
  • chargeも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は空ですが、成功したcollect_via_payment_link requestの場合はcheckout handlesを返します。詳しくはCollecting Payment via a Checkout Linkを参照してください。on_payment_failure=prevent_changeの場合、paymentが成功するまでplan changeはpendingのままです。
request parametersが無効です。required fieldsがすべて指定され、正しい形式であることを確認してください。
API keyが無効または不足しています。DODO_PAYMENTS_API_KEYが正しく、適切なpermissionsを持つことを確認してください。
Subscription IDが見つからないか、アカウントに属していません。
このsubscriptionにはpending plan changeがすでに存在します(PendingPlanChangeExists)。scheduled changeの場合は、別のものをsubmitする前にDELETE /subscriptions/{subscription_id}/change-plan/scheduledでcancelしてください。pending payment-link changeにはcancel endpointがありません。顧客が支払うかlinkがexpiryすると、subscriptionは新しいplan-change requestを受け付けます。
subscriptionがinactiveまたはon-demandであるか、requestがcollect_via_payment_linkの対象外です。businessでcapabilityが有効になっていない、effective_atimmediatelyではない、またはon_payment_failureprevent_changeではありません。Requirementsを参照してください。
Server errorが発生しました。少し待ってからrequestをretryしてください。

Error Response Format

次のステップ

最終更新日 2026年8月26日