Skip to main content
Seat-based billing は、アカウント上のユーザー数に基づいて顧客に料金を請求します。Dodo Payments では、add-on システムを使用して実装します。基本のサブスクリプション商品に、数量がシート数を表すシート単位の add-on を組み合わせます。

Implementation Tutorial

コード例付きのステップバイステップガイド。

Add-ons Documentation

席数ベースの課金を支えるアドオンシステムについて学ぶ。

Subscription Management

席数ベースのサブスクリプションとプラン変更を管理する。

Webhooks

サブスクリプションのWebhooksで席数の変更を追跡する。

シートベースの請求とは?

Seat-based billing は、製品にアクセスするユーザー数に基づいて顧客に料金を請求します。固定料金ではなく、チームの規模に応じて価格が変動します。

一般的な使用例

シートベースの価格設定の利点

ビジネスにとって:
  • 顧客の成長に応じて収益が拡大する
  • 顧客が予算を予測しやすい
  • 個人向けからチーム向け、エンタープライズ向けへ明確にアップグレードできる
  • チームの拡大に伴い顧客生涯価値が高まる
顧客にとって:
  • 利用しているユーザー分だけ支払える
  • コストを簡単に理解し、予測できる
  • 必要に応じてユーザーを追加・削除できる
  • チームの規模に見合った公平な料金設定

仕組み

Dodo Payments は、Add-ons システムを使用して Seat-based billing を実装します。Seat-based subscription は次の2つの部分で構成されます。 顧客の月額合計は次のとおりです。
例: Team Plan に8シートを追加する場合

価格設定戦略

ビジネスに合ったシートベースの価格設定戦略を選択してください:

戦略1: 基本 + シートごとのアドオン

基本プランに設定された数のシートを含め、追加シートに対して料金を請求します。
適しているケース: 基本プランだけでも小規模チームが運用できる商品。

Strategy 2: 純粋なシート単位の料金

基本料金なしで、シートごとに定額料金を請求します。
実装: ベースプランの価格を$0に設定し、シートアドオンのみを使用します。 最適な用途: シンプルで透明性の高い料金設定。

Strategy 3: 段階制のシート料金

基本プランごとに、異なるシート単価を設定します。
実装: add-on 価格が異なる複数の商品を、各ティア用に作成します。 適しているケース: 上位ティアへのアップグレードを促したい場合、エンタープライズ営業。

Strategy 4: シートバンドル

シートを1つずつではなく、パック単位で販売します。
実装: パックサイズごとに複数の add-on を作成します。 適しているケース: 購入判断を簡単にしたい場合、より大きな契約を促したい場合。

Seat-based billing の設定

Step 1: 料金を計画する

実装前に、料金体系を定義します。
1

Define Base Plan

ベースサブスクリプションに含める内容を決定します:
  • ベース価格(純粋なシート単位の課金では$0に設定可能)
  • 含まれるシート数
  • このティアで利用できる機能
2

Set Seat Pricing

シート単位の add-on 料金を決定します。
  • 追加シート1つあたりの料金
  • ボリュームディスカウント(複数の add-on による設定)
  • 許可する最大シート数(該当する場合)
3

Consider Billing Frequency

シート料金を請求サイクルに合わせます。
  • 月額サブスクリプション → 月額のシート料金
  • 年額サブスクリプション → 年額のシート料金(通常は割引あり)

Step 2: Seat add-on を作成する

Dodo Payments ダッシュボードで次の操作を行います。
  1. Products → Add-Ons に移動します
  2. Create Add-On をクリックします
  3. add-on を設定します。
請求書上で意味が伝わる、説明的なアドオン名を使用します。請求内容を確認する顧客にとって、“Seat Add-on” よりも “Additional Team Seat” のほうが明確です。

Step 3: 基本サブスクリプションを作成する

サブスクリプション商品を作成します。
  1. Products → Create Product に移動します
  2. Subscription を選択します
  3. 料金と詳細を設定します
  4. Add-Ons セクションでシート add-on を追加します

Step 4: 商品に add-on を追加する

シート add-on をサブスクリプションにリンクします。
  1. サブスクリプション商品を編集します
  2. Add-Ons セクションまでスクロールします
  3. Add Add-Ons をクリックします
  4. シート add-on を選択します
  5. 変更を保存します
これでサブスクリプション商品がシート単位の料金に対応します。顧客は checkout 中に追加シートを任意の数量で購入できます。

シートの管理

新しいサブスクリプションへのシート追加

checkout session の作成時に、シート数量を指定します。

既存のサブスクリプションのシート数変更

Change Plan API を使用してシート数を調整します。addons 配列には、差分ではなく新しい合計シート数を設定します。

シートの削除

シート数を減らすには、少ない数量を指定します。

追加シートをすべて削除する

空の addons 配列を渡すと、すべての add-on が削除されます。

シート変更時の Proration

サイクル途中でシート変更を適用すると、Dodo Payments は即時請求額を次の3段階で計算します。
クレジット額は、選択したproration mode によって異なります。請求額は常に1サイクル分です。
請求は常に1サイクル分全額に対して行われます。変動するのはクレジットのみです。そのため、請求額が「新しいシート数 × 価格 × 残り日数」になることはほとんどありません。prorated_immediately では、サイクルが進むにつれてクレジットが減少するため、同じシート変更でも実施が遅いほど費用が高くなります。difference_immediately と full_immediately では、クレジットはタイミングに左右されないため、サイクル中のどの日に変更しても費用は同じです。

各モードのクレジット処理

difference_immediately では、顧客は旧プラン価格と新プラン価格の差額のみを支払います。これがこの名前の由来であり、サイクル中のいつ変更しても金額が同じになる理由です。 クレジットが新しいサイクルの請求額を上回る場合、差額はサブスクリプション単位のクレジットとして保持され、今後の更新に自動的に適用されます。
prorated_immediately、difference_immediately、full_immediately はすべて、請求サイクルを変更日にリセットします。次回更新日は、シート変更が適用された日に再設定されます。元の更新日を維持するのは do_not_bill のみです(新しいシート数分の料金は次回更新時に全額請求され、変更時には請求されません)。
**do_not_bill は、更新時ではなくシート変更を即時適用します。**新しいシート数は呼び出しが成功するとすぐに有効になりますが、請求は次回更新まで発生しません。シートを追加する場合、顧客は現在のサイクルの残り期間、そのシートを無料で利用できます。30日サイクルの1日目に$10のシートを5つ追加すると、29日間は5シートを無料で利用でき、増額分が初めて請求されるのは元の更新日です。シートを削除する場合は逆になります。シートは直ちに削除され、すでに支払ったサイクルの残り期間分についてクレジットは付与されません。善意によるアップグレードや、営業上合意した追加シートの試用など、意図した動作がこれである場合は do_not_bill を使用してください。

具体例: シートを5つ追加する

4つすべてのモードで1つのシナリオを実行し、数値を直接比較します。
3つの即時適用モードではすべて、顧客は本日支払う金額と引き換えに、$130で新しい1か月分を全額受け取ります。

prorated_immediately でタイミングが重要な理由

現在のサイクルに残っていてクレジットできる期間が少なくなるため、サイクルの後半に変更するほど同じ変更の費用が高くなります。
どの行でも顧客は新しい1か月分を受け取ります。「すでに支払い済みの分」と「今回支払う分」の内訳だけが変わります。 変更のタイミングにかかわらずシート変更の費用を同じにするには、difference_immediately を使用します。

具体例: 「予想外の請求」

これは、merchant が最も驚くことの多いケースです。サイクル終盤に少額のシート add-on を追加すると、add-on の価格を大きく上回る請求が発生する場合があります。
$10/月のシートを追加すると、prorated_immediately では**$55.00**かかります。顧客には$60の新しい1か月分が全額請求され、旧月に残っていた$5がクレジットされ、更新日がリセットされます。 サイクル途中の少数のシート追加を、シート価格のみで、それ以上の費用をかけずに行うには、difference_immediately を使用します。

具体例: シートの削除(ダウングレード)

新しいプランの料金がクレジットを下回る場合、超過分はsubscription credit として保持され、このサブスクリプションの今後の更新に自動的に適用されます。Customer Wallet に追加されることも、credit entitlement になることもありません。
クレジットの対象は、削除するシートだけでなく、ベースプランとすべてのアドオンを含むサブスクリプション全体です。

Preview response の読み方

previewChangePlan は、請求される正確な明細項目を返します。各明細項目には proration_factor があります。
つまり、$50のベースと3 × $10のアドオンが50%分クレジットされ、$50のベース全額と8 × $10のアドオンが請求されます。クレジットは$40、請求額は$130、純額は$90です。
Proration は変更時刻の正確な時点を基準に秒単位で計算され、最も近い日単位には丸められません。上記の具体例では、わかりやすさのため日単位の丸めた数値を使用しています。
シート変更の proration mode を選択する
  • difference_immediately — 変更のタイミングにかかわらず、顧客は価格差額を支払います。頻繁にシートを調整するチームにとって最も予測しやすく、UIでの説明も最も簡単です。
  • prorated_immediately — 顧客には現在のサイクルの残り期間分のみがクレジットされます。サイクルの後半に変更するほど費用が高くなります。
  • full_immediately — 顧客は未使用期間のクレジットなしで、新しいサイクル全体の料金を支払います。
  • do_not_bill — シート変更は直ちに反映されますが、現時点では請求されません。追加したシートは次回更新まで無料で、削除したシートについてはクレジットが付与されません。更新日は維持され、次回更新以降は新しいシート数分が全額請求されます。請求サイクルをリセットしない唯一のモードです。
do_not_bill で付与されたシートは、請求されていないため、後のプラン変更時にクレジットされません。do_not_bill で5シートを追加した後、3シートに変更した場合、顧客には3シート分が全額請求され、保持していた5シート分のクレジットは発生しません。
確定前には必ず previewChangePlan を呼び出し、返された金額を表示してください。詳細な比較については、Proration Guide を参照してください。

変更前の Preview

変更を行う前に、必ず proration を preview します。

Webhook によるシートの追跡

subscription webhook をリッスンしてシート変更を監視します。

関連イベント

Webhook handler の例

Webhook payload の addons 配列には、現在の addon 数量が含まれます。合計して総シート数を取得してください。基本プランにシートが含まれる場合(例: 5シート込み)は、アプリケーションのロジックで addon の合計に加算します。

シート上限の適用

シート上限はアプリケーション側で適用する必要があります。Dodo Payments が管理するのは billing であり、アクセスを管理するのはあなたのアプリケーションです。
シート数を超えてユーザーを追加できないよう厳密に制限します。

高度なパターン

異なるシートタイプ

異なる料金で複数のシートタイプを提供します。
実装: シートタイプごとに個別の add-on を作成します。

年額シート割引

年額のシート料金を割引価格で提供します。
実装: add-on 価格が異なる月額プランと年額プランの商品を個別に作成します。

最低シート数要件

特定のプランで最低シート数を必須にします。

ベストプラクティス

料金に関するベストプラクティス

  • 明確なコミュニケーション: 料金ページでシート単価を目立つように表示する
  • 含まれるシート: 導入の障壁を下げるため、基本料金に数シートを含めることを検討する
  • ボリュームディスカウント: エンタープライズ契約を獲得するため、大規模チームには低いシート単価を提供する
  • 年額プランのインセンティブ: キャッシュフローと retention を改善するため、年額プランを割引する

Technical Best Practices

  • シート数をキャッシュする: リクエストごとの API 呼び出しを避けるため、サブスクリプションのシート数をローカルにキャッシュする
  • 定期的に同期する: API 経由で Dodo Payments とローカルのシート数を定期的に同期する
  • 失敗に対処する: シート変更に失敗した場合は、わかりやすいエラーメッセージと再試行オプションを表示する
  • 監査証跡: billing の異議申し立てとコンプライアンスのため、すべてのシート変更を記録する

User Experience Best Practices

  • リアルタイムのフィードバック: シートを調整した際の費用への影響をすぐに表示する
  • 確認ステップ: 請求変更の前に確認を必須にする
  • 日割り計算の透明性: 適用前に日割り料金を明確に説明する
  • 簡単なダウングレード: シートを減らしにくくしない(信頼の構築につながります)

トラブルシューティング

症状: アプリに表示されるシート数がサブスクリプションと異なる。原因:
  • Webhook を受信または処理できていない
  • シート変更中の race condition
  • キャッシュデータが更新されていない
解決策:
  1. subscription.plan_changed 用の webhook handler を実装する
  2. 現在のサブスクリプションを取得する「billing と同期」ボタンを追加する
  3. 定期的に更新されるよう cache TTL を設定する
症状: 顧客がサイクル途中の請求額に困惑している。原因: billing サイクルの後半で prorated_immediately を使用している(上記の予想外の請求の例を参照)。解決策:
  1. 変更前に必ず previewChangePlan を使用する
  2. 明確な内訳を表示する: “Xシートを追加すると、本日$Yかかります”
  3. 請求額を常に価格差額と一致させたい場合は、difference_immediately に切り替える
症状: checkout 中にシート add-on を利用できない。原因:
  • add-on が商品に追加されていない
  • add-on がアーカイブまたは削除されている
  • 商品と add-on の通貨が一致していない
解決策:
  1. 商品設定で add-on が追加されていることを確認する
  2. Add-Ons ダッシュボードで add-on の状態を確認する
  3. 通貨が完全に一致していることを確認する
症状: 顧客がユーザーを割り当てたままシートを減らしたい。解決策:
  1. シートを減らす前に削除が必要なユーザーを表示する
  2. 「ユーザーを削除 → シートを減らす」というワークフローを実装する
  3. シート削減を適用する前に猶予期間を設けることを検討する

関連ドキュメント

Seat-Based Pricing Tutorial

コードを含む完全な実装ガイド。

Add-ons

add-on システムを詳しく理解します。

Plan Changes & Proration

サブスクリプションの変更を処理します。

Subscription Webhooks

サブスクリプションイベントを追跡します。
最終更新日 2026年9月26日