Skip to main content

概要

オンデマンドサブスクリプションでは、顧客の支払い方法を一度承認すると、固定スケジュールではなく、必要なときにいつでも変動する金額を請求できます。この機能はすべてのアカウントで利用でき、承認は必要ありません。 このガイドでは、次の方法を説明します。
  • オンデマンドサブスクリプションを作成する(任意の初回価格で mandate を承認)
  • カスタム金額で後続の請求をトリガーする
  • webhook を使用して結果を追跡する
一般的なサブスクリプションの設定については、サブスクリプション統合ガイドを参照してください。

前提条件

  • Dodo Payments merchant account と API key
  • webhook secret が設定され、イベントを受信する endpoint があること
  • カタログにサブスクリプション product があること
このガイドでは、checkout session(POST /checkouts)を介してオンデマンドサブスクリプションを作成します。この session は常にホスト型の checkout_url を返します。顧客をその URL にリダイレクトして mandate を承認してもらい、return_url には、その後に移動させる場所を設定します。

オンデマンドの仕組み

  1. on_demand object を使用して subscription を作成し、支払い方法を承認して、必要に応じて初回請求を回収します。
  2. 後から、専用の charge endpoint を使用し、カスタム金額でその subscription に対する charge を作成します。
  3. webhook(例:payment.succeededpayment.failed)をリッスンして、システムを更新します。

オンデマンドサブスクリプションを作成する

Endpoint: POST /checkouts 主要な request fields(body):
Create Checkout Sessionで確認してください

オンデマンドサブスクリプションを作成する

Success

オンデマンドサブスクリプションに請求する

mandate の承認後、必要に応じて charge を作成します。 Endpoint: POST /subscriptions/{subscription_id}/charge 主要な request fields(body):
integer
必須
請求する金額(最小通貨単位)。例:$25.00 を請求するには、2500 を渡します。
string
この請求に対する任意の currency override。
string
この請求に対する任意の description override。
boolean
true の場合、Adaptive Currency の手数料を product_price に含めます。false の場合、手数料は上乗せされます。
object
支払いに関する追加 metadata。省略した場合は、subscription の metadata が使用されます。
Success
オンデマンドではない subscription に請求すると失敗する可能性があります。請求する前に、subscription の details に on_demand: true があることを確認してください。

失敗した請求の処理

オンデマンドサブスクリプションに対する請求が失敗した場合、次に何をするかはあなたが決定します。スケジュールされたサブスクリプションでは、更新に失敗すると以降の自動課金が停止しますが、オンデマンドサブスクリプションは失敗後も請求可能な状態を維持します。独自の retry ロジックの一部として、charge endpoint を再度呼び出せます。

失敗時の動作

1

Charge attempt fails

POST /subscriptions/{subscription_id}/charge request は、error response を返すか、非同期で完了して、decline reason を含む payment.failed webhook を発行します。
2

Subscription may transition to on_hold

subscription が on_hold state に移行し、subscription.on_hold webhook を発行することがあります(Subscription States → On Holdを参照)。これはシグナルであり、ロックではありません。オンデマンドサブスクリプションでは、on_hold によって再度請求できなくなることはありません。
3

Retry the charge (your call)

オンデマンドフローでは、Dodo は自動 retry を行いません。POST /subscriptions/{subscription_id}/charge はいつでも再度呼び出して retry できます。以下の safe retry policy を適用してください。exponential backoff を使用し、hard decline をスキップし、burst パターンを避けることで、retry が当社の fraud および risk system によって検知されないようにします。
4

Optionally, ask the customer for a new payment method

支払い方法自体に問題があるため retry が続けて失敗する場合(カードの有効期限切れ、アカウント閉鎖など)は、POST /subscriptions/{subscription_id}/update-payment-method を使用して、顧客から新しい支払い方法を収集します。成功すると subscription は active に戻り、payment.succeeded に続いて subscription.active webhook が発行されます。
オンデマンドとスケジュールの違い:スケジュールされたサブスクリプションでは、Dodo が独自の更新 retry と dunning を実行します。オンデマンドサブスクリプションでは、次の請求をいつ行うべきかを把握しているのはあなただけです(カレンダーではなく usage event に基づくため)、retry ポリシーをあなたが管理します。

オンデマンド請求が失敗した場合の webhook sequence

3 と 4 の event は、後続の請求が成功した場合にのみ発生します。

retry の責任

Dodo Payments 失敗したオンデマンド請求を自動 retry しません。retry ポリシーはあなたが管理します。カードテストとして当社の fraud detection system に検知されないよう、以下の安全な retry ガイドラインに従ってください。
Subscription Dunning(組み込みの email recovery sequence)は、スケジュールされたサブスクリプションの失敗した renewal payment と、顧客が開始した cancellation を対象とします。オンデマンド請求の失敗向けには設計されていません。支払い方法を更新する必要があると判断した場合は、顧客に直接(transactional email やアプリ内 prompt などで)連絡してください。

Payment retries

当社の fraud detection system は、積極的な retry パターンをブロックすることがあり(card testing の可能性としてフラグを付けることもあります)、安全な retry ポリシーに従ってください。
短時間に集中した retry パターンは、当社の risk system や processor によって不正または card testing の疑いとしてフラグ付けされることがあります。retry を集中させず、以下の backoff schedule と時刻の整合に関するガイダンスに従ってください。

安全な retry ポリシーの原則

  • Backoff mechanism:retry の間隔には exponential backoff を使用します。
  • Retry limits:retry の合計回数を制限します(最大 3~4 回)。
  • Intelligent filtering:retry 可能な失敗(network/issuer error、残高不足など)の場合のみ retry し、hard decline は決して retry しません。
  • Card testing preventionDO_NOT_HONORSTOLEN_CARDLOST_CARDPICKUP_CARDFRAUDULENTAUTHENTICATION_FAILURE などの失敗は retry しないでください。
  • Vary metadata(任意):独自の retry system を運用している場合は、metadata(例:retry_attempt)で retry を区別します。

推奨 retry schedule(subscriptions)

  • 1 回目:charge の作成時に即時実行
  • 2 回目:3 日後
  • 3 回目:さらに 7 日後(合計 10 日後)
  • 4 回目(最終):さらに 7 日後(合計 17 日後)
最終手順:それでも未払いの場合は、ポリシーに基づいて subscription を unpaid としてマークするか、cancel します。支払い方法を更新できる期間中に顧客へ通知してください。

burst retry を避け、承認時刻に合わせる

  • portfolio 全体で「burst」動作が発生しないよう、retry の基準を元の authorization timestamp に合わせます。
  • 例:顧客が今日の午後 1:10 に trial または mandate を開始した場合、backoff(例:+3 日 → 午後 1:10、+7 日 → 午後 1:10)に従い、後続の retry を各日の午後 1:10 にスケジュールします。
  • または、最後に成功した支払い時刻を T に保存している場合は、時刻の整合性を維持するため、次の試行を T + X days にスケジュールします。
Time-zone と DST:スケジュールには一貫した time standard を使用し、interval を維持するため、表示時のみ変換します。

retry すべきでない decline codes

  • STOLEN_CARD
  • DO_NOT_HONOR
  • FRAUDULENT
  • PICKUP_CARD
  • AUTHENTICATION_FAILURE
  • LOST_CARD
decline reason の包括的な一覧と、ユーザーが修正可能かどうかについては、Transaction Failures のドキュメントを参照してください。
soft/temporary issue(例:insufficient_fundsissuer_unavailableprocessing_error、network timeout)の場合のみ retry します。同じ decline が繰り返される場合は、それ以上の retry を一時停止してください。

実装ガイドライン(コードなし)

  • 正確な timestamp を永続化する scheduler/queue を使用し、時刻単位の offset(例:同じ HH:MM の T + 3 days)で次の試行時刻を計算します。
  • 最後に成功した支払いの timestamp T を保持・参照して次の試行を計算し、複数の subscription を同じ時刻に集中させないでください。
  • 常に最後の decline reason を評価し、上記の skip list にある hard decline の retry を停止します。
  • 偶発的な急増を防ぐため、顧客ごとおよびアカウントごとの同時 retry 数を制限します。
  • 事前に連絡します。次回の scheduled attempt より前に、顧客へ email/SMS で支払い方法の更新を依頼してください。
  • metadata は observability の目的にのみ使用し(例:retry_attempt)、意味のない field を変更して fraud/risk system を「回避」しようとしないでください。

Cancellation

オンデマンドサブスクリプションでは、即時の終了日を基準にする固定の billing cycle がないため、スケジュールされたサブスクリプションとは異なる cancellation flow に従います。

Customer Portal の動作

顧客が Customer Portal からオンデマンドサブスクリプションを cancel すると、デフォルトでは 次の billing date に cancellation がスケジュールされます。オンデマンドサブスクリプションでは、Cancel Now option は意図的に表示されません。 理由は、オンデマンドサブスクリプションには予測可能な定期更新日がなく、次の請求時刻が完全に usage event によって決まるためです。次の billing date に cancellation をスケジュールすることで、period boundary まで mandate を有効に保ち、進行中の usage を請求してから subscription を正常に終了できます。 顧客が cancellation を確認した後:
  • subscription は active のままとなり、scheduled cancellation date まで POST /subscriptions/{id}/charge を介して引き続き請求できます。
  • subscription の cancel_at_next_billing_datetrue に設定されます。
  • cancellation が有効になった時点で subscription.cancelled webhook が発行されます。
subscription を直ちに終了する必要がある場合(たとえば refund や support request への対応時)は、Customer Portal flow に頼らず、API を介して programmatically に cancel してください。

Programmatically に cancel する

API を介して、いつでもオンデマンドサブスクリプションを cancel できます。cancellation を即時に行うか、スケジュールするかを制御できます。 Endpoint: PATCH /subscriptions/{subscription_id}
subscription の statuscancelled に設定すると、直ちに終了します。mandate は revoked になり、それ以降の charge は作成できません。
cURL

cancellation 時の webhook

handler でオンデマンドの cancellation とスケジュールされた subscription の cancellation を区別するには、webhook の処理時に subscription の on_demand flag を確認してください。

webhook で結果を追跡する

顧客の journey を追跡するため、webhook handling を実装します。Implementing Webhooksを参照してください。
  • subscription.active:mandate が承認され、subscription が有効化された
  • subscription.failed:作成に失敗した(例:mandate failure)
  • subscription.on_hold:subscription が hold された(例:unpaid state)
  • subscription.cancelled:subscription が完全に cancel された(Cancellationを参照)
  • payment.succeeded:charge が成功した
  • payment.failed:charge が失敗した
オンデマンドフローでは、usage-based charge を照合するため、payment.succeededpayment.failed に注目します。payment.failed の後に subscription.on_hold が続く場合は、失敗した請求の処理を参照して subscription を復旧してください。

テストと次のステップ

1

Create in test mode

test API key を使用して subscription を作成し、返された checkout_url を開いて mandate を完了します。
2

Trigger a charge

小さな product_price(例:100)で charge endpoint を呼び出し、payment.succeeded を受信したことを確認します。
3

Go live

event と内部 state の更新を検証したら、live API key に切り替えます。

トラブルシューティング

  • 422 Invalid Request:作成時に on_demand.mandate_only が提供され、charge に product_price が提供されていることを確認してください。
  • Currency errorsproduct_currency を override する場合、アカウントと顧客でサポートされていることを確認してください。
  • webhook を受信できない:webhook URL と signature secret の設定を確認してください。
最終更新日 2026年7月31日