メインコンテンツへスキップ

概要

オンデマンドサブスクリプションを使用すると、顧客の支払い方法を一度認証し、その後必要に応じて変動額を請求できます。固定スケジュールではなく、必要なときに請求することができます。この機能はすべてのアカウントで利用可能で、承認は不要です。 このガイドを使用して:
  • オンデマンドサブスクリプションを作成する(オプションの初期価格でのマンダテを認証)
  • カスタム金額での後続の請求をトリガーする
  • Webhookを使用して結果を追跡する
一般的なサブスクリプションの設定については、サブスクリプション統合ガイドを参照してください。

前提条件

  • Dodo PaymentsのマーチャントアカウントとAPIキー
  • Webhookシークレットが設定されており、イベントを受信するエンドポイントがあること
  • カタログにサブスクリプション商品があること
ホスト型チェックアウトで顧客にマンダテ(mandate)を承認してもらうには、payment_link: true を設定し、return_url を提供してください。

オンデマンドの仕組み

  1. 決済手段を認可し、必要であれば初回請求を行うために on_demand オブジェクトでサブスクリプションを作成します。
  2. 後で専用のチャージエンドポイントを使って、そのサブスクリプションに対してカスタム金額の請求を作成します。
  3. WEBHOOK(例: payment.succeededpayment.failed)をリッスンしてシステムを更新します。

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

エンドポイント:POST /checkouts 主要なリクエストフィールド(ボディ):
チェックアウトセッションの作成で確認してください。

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

import DodoPayments from 'dodopayments';

const client = new DodoPayments({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: 'test_mode', // defaults to 'live_mode'
});

async function main() {
  const subscription = await client.checkoutSessions.create({
    product_cart: [{ product_id: 'pdt_123', quantity: 1 }],
    billing_address:  { city: 'SF', country: 'US', state: 'CA', street: '1 Market St', zipcode: '94105' },
    customer: { customer_id: 'cus_123' },
    return_url: 'https://example.com/billing/success',
    subscription_data: {
        on_demand: {
            mandate_only: true // set false to collect an initial charge
            // product_price: 1000, // optional: charge $10.00 now if mandate_only is false
            // product_currency: 'USD',
            // product_description: 'Custom initial charge',
            // adaptive_currency_fees_inclusive: false,
        }
    }
  });

  console.log(subscription.checkout_url);
}

main().catch(console.error);
Success
{
  "session_id": "cks_123",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks123"
}

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

マンダテが認証された後、必要に応じて請求を作成します。 エンドポイント:POST /subscriptions/{subscription_id}/charge 主要なリクエストフィールド(ボディ):
product_price
integer
必須
請求金額(通貨の最小単位)。例:$25.00 を請求するには 2500 を渡します。
product_currency
string
この請求に対する通貨の任意のオーバーライド。
product_description
string
この請求専用の説明の任意オーバーライド。
adaptive_currency_fees_inclusive
boolean
true の場合、product_price に適応通貨手数料が含まれます。false の場合は手数料が別途加算されます。
metadata
object
決済に追加するメタデータ。省略した場合はサブスクリプションのメタデータが使用されます。
import DodoPayments from 'dodopayments';

const client = new DodoPayments({ bearerToken: process.env.DODO_PAYMENTS_API_KEY });

async function chargeNow(subscriptionId) {
  const res = await client.subscriptions.charge(subscriptionId, { product_price: 2500 });
  console.log(res.payment_id);
}

chargeNow('sub_123').catch(console.error);
Success
{ "payment_id": "pay_abc123" }
オンデマンド以外のサブスクリプションに請求すると失敗する可能性があります。請求前に詳細に on_demand: true が含まれていることを確認してください。

支払いの再試行

当社の不正検出システムは、攻撃的な再試行パターンをブロックする場合があります(そしてそれらを潜在的なカードテストとしてフラグ付けすることがあります)。安全な再試行ポリシーに従ってください。
バーストリトライパターンはリスクシステムやプロセッサによって不正やカードテストの疑いとしてフラグが立つ可能性があります。クラスタ化された再試行を避け、以下のバックオフスケジュールと時間調整のガイダンスに従ってください。

安全な再試行ポリシーの原則

  • バックオフ機構:再試行間に指数バックオフを使用します。
  • 再試行制限:合計再試行回数を上限(最大3〜4回)に抑えます。
  • インテリジェントフィルタリング:ネットワーク/発行元エラーや資金不足など、再試行可能な失敗のみを再試行します。ハードディクラインは再試行しないでください。
  • カードテスト防止DO_NOT_HONORSTOLEN_CARDLOST_CARDPICKUP_CARDFRAUDULENTAUTHENTICATION_FAILURE のような失敗は再試行しないでください。
  • メタデータを変化させる(任意):独自の再試行システムを維持している場合は、retry_attempt などのメタデータで再試行を識別してください。

推奨再試行スケジュール(サブスクリプション)

  • 1回目の試行:請求を作成したときに即時
  • 2回目の試行:3日後
  • 3回目の試行:さらに7日後(合計10日)
  • 4回目の試行(最終):さらに7日後(合計17日)
最終ステップ:未払いの場合は、サブスクリプションを未払いとしてマークするか、ポリシーに基づいてキャンセルします。顧客に支払い方法を更新するためのウィンドウ内で通知します。

バースト再試行を避け、承認時間に合わせる

  • 再試行を元の認可タイムスタンプにアンカーし、ポートフォリオ全体での「バースト」挙動を避けます。
  • 例:1:10 pm にトライアルやマンダテを開始した場合、バックオフに従って翌日以降も 1:10 pm に再試行(例:+3日→1:10 pm、+7日→1:10 pm)をスケジューリングします。
  • または、最後に成功した支払い時刻 T を保持している場合は、次の試行を時間帯整合性を維持するために T + X days にスケジュールします。
タイムゾーンと夏時間:スケジュールには一貫した時刻基準を使用し、間隔を維持するために表示時のみ変換してください。

再試行しないべき拒否コード

  • STOLEN_CARD
  • DO_NOT_HONOR
  • FRAUDULENT
  • PICKUP_CARD
  • AUTHENTICATION_FAILURE
  • LOST_CARD
ユーザーが修正可能かどうかを含む拒否理由の完全なリストについては、 Transaction Failures ドキュメントを参照してください。
ソフトまたは一時的な問題(例:insufficient_fundsissuer_unavailableprocessing_error、ネットワークタイムアウト)に対してのみ再試行してください。同じ拒否が繰り返される場合は、それ以上の再試行を停止してください。

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

  • 正確なタイムスタンプを保持するスケジューラ/キューを使用し、次の試行を当該時刻オフセット(例:T + 3 days と同じ HH:MM)で計算します。
  • 次の試行を計算するために最後に成功した支払い時刻 T を維持して参照し、複数のサブスクリプションを同じ瞬間にまとめないでください。
  • 常に最後の拒否理由を評価し、上記のスキップリストにあるハードディクラインの場合は再試行を停止してください。
  • 顧客およびアカウントごとの同時再試行数を制限し、意図しない急増を防ぎます。
  • 積極的にコミュニケーション:次の予定された試行前に顧客にメール/SMSで決済方法の更新を促します。
  • メタデータは観測性のためだけに使用し(例:retry_attempt)、些細なフィールドを切り替えて不正/リスクシステムを「回避」しようとしないでください。

Webhookで結果を追跡する

Webhook処理を実装して顧客の旅を追跡します。Webhookの実装を参照してください。
  • subscription.active:マンダテが認証され、サブスクリプションがアクティブ化されました
  • subscription.failed:作成に失敗しました(例:マンダテの失敗)
  • subscription.on_hold:サブスクリプションが保留中です(例:未払い状態)
  • payment.succeeded:請求が成功しました
  • payment.failed:請求が失敗しました
オンデマンドフローでは、使用量ベースの請求を照合するために payment.succeeded および payment.failed に注力してください。

テストと次のステップ

1

Create in test mode

テストAPIキーを使用して payment_link: true でサブスクリプションを作成し、リンクを開いてマンダテを完了します。
2

Trigger a charge

小額の product_price(例:100)でチャージエンドポイントを呼び出し、payment.succeeded を受け取ることを確認します。
3

Go live

イベントと内部状態の更新を検証したら、ライブAPIキーに切り替えます。

トラブルシューティング

  • 422 Invalid Request:作成時に on_demand.mandate_only、チャージ時に product_price が提供されていることを確認してください。
  • 通貨エラーproduct_currency をオーバーライドする場合、その通貨がアカウントおよび顧客に対してサポートされていることを確認してください。
  • Webhook を受信しない:Webhook URL と署名シークレットの設定を確認してください。