credit-based-billing について
credit-based-billingは、Dodo Paymentsで前払いまたは付帯クレジットの課金を実装するためのスキルです。サブスクリプション枠や追加購入、利用量の控除を構築する開発者向けで、付与、ライフサイクル、超過処理、監査可能な台帳を扱います。
主な機能
- 01クレジット単位とライフサイクルの定義
- 02有効期限・繰り越し・超過の設定
- 03サブスクリプションや単発商品への付与
- 04計測した利用量に応じた控除
- 05残高の確認と台帳記録の監査
活用シーン
- 01サブスクリプションに定期クレジットを付ける
- 02使い切りの前払いクレジットを販売する
- 03APIや計算の利用量をクレジットから控除する
- 04顧客残高と台帳記録を照合する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dodopayments/ skills --skill credit-based-billingインストール後、Claude Code で/credit-based-billingを入力して読み込まれたか確認します。
同梱ファイルreferences/ai-token-example.mdreferences/credit-webhooks.md
詳細
Dodo Payments のクレジットベース課金
このスキルを使用すると、監査可能な付与と差し引きを備えた、トークン、API 呼び出し、コンピューティング、ストレージ、または通貨建ての価値に対する前払い課金やクレジット込みの課金を構築できます。
このスキルを使用するタイミング
- サブスクリプションに定期的なクレジット枠を含める。
- 1 回限りのチャージパックや前払い利用分を販売する。
- 計測対象の AI、API、またはコンピューティングの消費量に応じてクレジットを差し引く。
- プロモーションクレジットやサポートクレジットを付与し、その理由を記録する。
- 有効期限、繰り越し、残高不足アラート、または超過分課金を設定する。
- 不変の台帳記録と顧客の残高を照合する。
課金モデルを選択する
| 要件 | 選択肢 | 理由 |
|---|---|---|
| 消費量を追跡しない固定の商品 | 通常のサブスクリプションまたは 1 回限りの支払い | 残高や利用量の処理パイプラインは不要です。 |
| 計測した各単位を金額で直接課金する | 純粋な従量課金 | メーターが price_per_unit で利用量を料金に換算するため、前払いプールは不要です。 |
| 消費可能な枠を含める、または前売りする | クレジットベース課金 | クレジットの付与によって残高が作成され、利用量に応じて消費できます。 |
| クレジットを含め、その枠を超えた分を課金する | 超過分課金付きクレジット | まずクレジットプールを消費し、不足分には設定済みの超過分課金を適用します。 |
| 基本料金、クレジット込み枠、計測利用分を組み合わせる | クレジット特典にリンクされた従量課金商品 | メーターが利用単位をクレジットの差し引きに換算します。 |
クレジットベース課金と従量課金は相互に補完するものです。メーターの定義とテストには usage-based-billing スキルを使用してください。このスキルでは、クレジット側とメーターからクレジットへのリンクを扱います。
主な概念
クレジット特典と付与
クレジット特典は、クレジット単位とそのライフサイクルを再利用可能な形で定義するものです。名前、単位、精度、有効期限、繰り越し、超過分課金が含まれます。付与は、そのクレジットを顧客 1 名に発行することです。付与元には次のものがあります。
- サブスクリプション。各請求サイクルで再発行されます。
- 1 回限りの商品またはアドオン。
- API から直接行う台帳へのクレジット記帳。
- 以前の付与からの繰り越し。
クレジットは、顧客が消費できる量を制限します。別の entitlements リソースは、機能へのアクセス、ファイル、ライセンスの提供などの履行を制限します。次の SDK 名前空間を混同しないでください。
client.creditEntitlements credit definitions and balances
client.creditEntitlements.balances customer credit balances and ledger
client.entitlements feature/file/license entitlements
client.entitlements.files entitlement files
client.entitlements.grants fulfillment grants
顧客単位のクレジット特典ビューには client.customers.listCreditEntitlements(customerID) を使用してください。別の特典システムを参照する client.customers.listEntitlements(...) で代用しないでください。
カスタム単位クレジットと法定通貨クレジット
| クレジットモデル | 表現 | 例 |
|---|---|---|
| カスタム単位 | アプリケーション定義の単位 | トークン、呼び出し、コンピューティング時間、GB 時間 |
| 法定通貨 | 通貨価値 | USD または EUR の前払い残高 |
カスタム単位の精度は 0 から 10 の範囲で設定でき、ダッシュボードのデフォルトは 2 です。作成後に精度を変更することはできないため、付与を発行する前に選択してください。リクエスト全体など、分割できない単位には 0 を使用します。小数のクレジットに意味がある場合にのみ、小数精度を使用してください。
法定通貨の例では、通貨の最小単位を使用します。ドキュメントに記載された OpenAI の例では、クレジット 5,000 は USD 50 を表します。ドキュメントに記載された最小通貨単位のモデルを超えて、法定通貨の精度に共通のルールがあると推定しないでください。金額はすべて通貨の最小単位(たとえば USD のセント)で表されます。
1 つの商品には、最大 5 つのクレジット特典を設定できます。それぞれに個別の発行設定とライフサイクル設定を指定できます。
残高と台帳
残高レスポンスには、balance、overage、last_transaction_at、識別子、タイムスタンプが含まれます。クレジット額は 10 進数の文字列として扱い、2 進浮動小数点演算に渡さないでください。
すべての取引には、次の情報を含む台帳記録があります。
balance_beforeとbalance_after。overage_beforeとoverage_after。- 金額と取引種別。
- 参照元と付与 ID。
- 説明、メタデータ、タイムスタンプ。
この台帳が監査記録となり、取引ごとの残高スナップショットを提供します。履歴残高スナップショット専用のエンドポイントは、別途ドキュメントに記載されていません。
TypeScript SDK を初期化する
API キーはサーバー側に保管してください。Dodo Payments のキーには dodo_test_... および dodo_live_... のプレフィックスが付いています。
import DodoPayments from 'dodopayments';
const client = new DodoPayments({
bearerToken: process.env['DODO_PAYMENTS_API_KEY'],
environment: 'test_mode',
});
environment を省略すると、SDK はデフォルトで live_mode を使用します。開発時は明示的に test_mode を使用してください。
クレジットエンタイトルメントを作成して設定する
確認済みの TypeScript メソッドは client.creditEntitlements.create(...) です。
import DodoPayments from 'dodopayments';
const client = new DodoPayments({
bearerToken: process.env['DODO_PAYMENTS_API_KEY'],
environment: 'test_mode',
});
const tokenCredits = await client.creditEntitlements.create({
name: 'AI Token Credits',
description: 'Credits consumed by model token usage',
unit: 'token credit',
precision: 0,
expires_after_days: 30,
rollover_enabled: true,
rollover_percentage: 25,
rollover_timeframe_count: 1,
rollover_timeframe_interval: 'Month',
max_rollover_count: 2,
overage_enabled: true,
overage_behavior: 'invoice_at_billing',
overage_limit: 100000,
price_per_unit: '1',
currency: 'USD',
});
console.log(tokenCredits.id);
price_per_unit は、設定した通貨での10進数文字列です。金額は通貨の最小単位で指定します。この例では、USD の超過クレジット1単位あたり '1' は1セントです。
確認済みの作成オプション
| フィールド | 必須 | 意味と制約 |
|---|---|---|
name | はい | クレジットエンタイトルメントの表示名です。 |
unit | はい | API Calls、Tokens、Credits などの単位ラベルです。 |
precision | はい | 小数点以下の桁数(0–10)です。作成後は変更できません。 |
description | いいえ | 任意の説明です。 |
expires_after_days | いいえ | 発行後、有効期限が切れるまでの日数です。null を指定できます。 |
rollover_enabled | はい | 繰り越しを有効または無効にします。 |
rollover_percentage | いいえ | 繰り越しの割合(0–100)です。 |
rollover_timeframe_count | いいえ | 繰り越しの有効期間の数です。 |
rollover_timeframe_interval | いいえ | Day、Week、Month、Year のいずれかです。 |
max_rollover_count | いいえ | 失効するまでに連続して繰り越せる最大回数です。 |
overage_enabled | はい | クレジットを使い切った後の不足分の処理を許可します。 |
overage_behavior | いいえ | 以下の正確な列挙値で指定する、サイクル終了時の動作です。 |
overage_limit | いいえ | 許可される超過単位の上限です。 |
price_per_unit | 条件付き | 10進数文字列です。超過を有効にする場合は必須です。 |
currency | 条件付き | 価格を指定する場合に必須です。金額は通貨の最小単位で指定します。 |
繰り越しを設定する
繰り越しでは、条件を満たす未使用のクレジットを新しい付与分に引き継ぎます。次のように設定してください。
rollover_enabled: true。rollover_percentageに、繰り越しの上限として0から100までの値を指定します。rollover_timeframe_countとrollover_timeframe_intervalの両方を指定します。片方だけを指定しないでください。- クレジットを連続して繰り越せる回数に上限を設ける場合は、
max_rollover_countを指定します。
繰り越しは有効期限の処理より先に適用され、残りのクレジットのみが失効します。
有効期限を設定する
API では、有効期限は null を指定できる expires_after_days として表されます。ダッシュボードでは、7日、30日、60日、90日、カスタム日数、または無期限を選択できます。デフォルトは30日で、カスタムの有効期限は最短1日です。現在の API フォームで許可されている場合に限り、API で有効期限を設定しないときは null を使用してください。
超過を設定する
overage_behavior の正確な値 | 課金サイクル終了時の結果 |
|---|---|
forgive_at_reset | 課金せず、不足分も保持しません。これがデフォルトです。 |
invoice_at_billing | 課金時に超過分を請求し、その後リセットします。 |
carry_deficit | マイナス残高を保持します。 |
carry_deficit_auto_repay | 不足分を保持し、新たに発行されたクレジットから返済します。 |
overage_enabled が true の場合、price_per_unit は必須です。価格を指定する場合は currency も必須です。許可する超過単位数の上限には overage_limit を使用してください。
超過が無効の場合、残高がゼロに達すると Dodo はそれ以上の差し引きを停止します。メーター処理は非同期であるため、アプリケーションのリクエストを同期的に承認するものではありません。リクエストをただちに拒否する必要がある場合は、アプリケーション側で制御を実装してください。
クレジットを商品やサブスクリプションに紐付ける
クレジットは、商品の作成または編集フローで、クレジットエンタイトルメントとして商品に紐付けます。クレジット残高を紐付けたり発行したりするために、client.entitlements.grants は使用しないでください。
サブスクリプション商品
Products → Create Productまたは既存の商品で、次の手順を実行します。
- サブスクリプションの価格設定を選択します。
- Entitlements & Creditsを開き、既存のクレジット特典を関連付けます。
- 各請求期間に付与するクレジット数を設定します。
- 必要に応じて、残高低下の通知額、トライアルクレジット数、トライアル終了後に未使用のトライアルクレジットを失効させるかどうか、プラン変更時のクレジット按分を設定します。
- 特典のデフォルトの繰り越し、超過利用、失効のルールをそのまま使用するか、この商品向けにカスタマイズします。
顧客には、請求サイクルごとに新しい付与が行われます。
一回限りの商品またはアドオン
クレジット特典を一回限りの支払い商品またはアドオンに関連付け、一回限りの付与額を設定します。購入時に一度だけ付与されます。プリペイドパック、チャージ、プロモーションバンドルには、この方法がサポートされています。
従量課金商品
クレジット特典をメーターと同じ従量課金商品に関連付けます。確認済みのメーター関連付けフィールドは次のとおりです。
| フィールド | 目的 |
|---|---|
meter_id | 使用量を集計するメーターです。 |
free_threshold | 料金計算の前に除外される無料使用量です。メーターが金額で請求する場合にのみ適用されます。クレジット請求のメーターでは無視され、すべての単位がクレジット残高から差し引かれます。 |
credit_entitlement_id | このメーターが消費するクレジットプールです。 |
meter_units_per_credit | クレジットを1単位差し引くために必要な使用量です。credit_entitlement_idが設定されている場合は必須です。 |
price_per_unit | 従量課金のみを使用する場合の、単位ごとの直接的な金額です。小数文字列です。 |
商品関連付けのリクエスト形式は変更される場合があります。ダッシュボードで設定するか、Create Product APIから最新のスキーマをコピーしてください。entitlements、credits、grantsのペイロードを独自に作成しないでください。
関連付けた商品のチェックアウトを開始する
商品購入によって顧客への付与が作成されます。チェックアウトでは、任意のクレジット額を指定できません。
const session = await client.checkoutSessions.create({
product_cart: [
{
product_id: 'pdt_ai_pro_plan',
quantity: 1,
},
],
customer: { email: '[email protected]' },
return_url: 'https://app.example.com/billing/success',
});
console.log(session);
非推奨のpayments.createまたはsubscriptions.createメソッドではなく、checkoutSessions.createを使用してください。
顧客のクレジット特典を確認する
顧客に関連付けられたすべてのクレジット特典を確認する必要がある場合は、顧客リソースを使用します。
const customerCredits = await client.customers.listCreditEntitlements(
'cus_TV52uJWWXt2yIoBBxpjaa',
);
console.log(customerCredits);
クレジット特典IDがすでにわかっていて、正確な残高が必要な場合は、以下の残高リソースを使用します。
顧客の残高を確認する
確認済みのメソッドでは、顧客IDを最初に指定し、クレジット特典IDをオプションオブジェクト内に指定します。
const customerCreditBalance = await client.creditEntitlements.balances.retrieve(
'cus_TV52uJWWXt2yIoBBxpjaa',
{ credit_entitlement_id: 'cde_ztxm5XJsKxWucRWA3rjdM' },
);
console.log({
balance: customerCreditBalance.balance,
overage: customerCreditBalance.overage,
lastTransactionAt: customerCreditBalance.last_transaction_at,
});
balanceとoverageは、特典のクレジット単位による小数文字列です。特典自体が法定通貨の価値を表す場合を除き、通貨額ではありません。
クレジットを手動で付与する
手動でのクレジット付与は、プロモーション、移行、クレジットによる返金、サポート対応に適しています。業務上の処理から生成した安定した冪等性キーを使用すると、再試行による二重付与を防げます。
async function grantSupportCredits(
customerId: string,
creditEntitlementId: string,
supportCaseId: string,
): Promise<string> {
const entry = await client.creditEntitlements.balances.createLedgerEntry(
customerId,
{
credit_entitlement_id: creditEntitlementId,
amount: '500',
entry_type: 'credit',
expires_at: '2027-01-31T23:59:59Z',
idempotency_key: `support-credit:${supportCaseId}`,
reason: `Support gesture for case ${supportCaseId}`,
metadata: { support_case_id: supportCaseId },
},
);
return entry.id;
}
amountはNUMERIC(38,28)で保持される小数文字列で、整数部は10^10未満である必要があります。expires_atはクレジットに適用されます。金額は特典に設定された精度の範囲内にしてください。
同じidempotency_keyがすでに存在する場合、APIは409を返すことがあります。これは元の処理を照合するためのシグナルとして扱い、新しいキーを生成して付与を再試行してよいという意味ではありません。
クレジットを手動で差し引く
同じメソッドでentry_type: 'debit'を指定します。差し引きでは、有効期限が最も早い付与分から消費されます。残高が不足している場合は400が返されることがあります。
async function deductJobCredits(
customerId: string,
creditEntitlementId: string,
jobId: string,
amount: string,
): Promise<{ balanceAfter: string; overageAfter: string }> {
const entry = await client.creditEntitlements.balances.createLedgerEntry(
customerId,
{
credit_entitlement_id: creditEntitlementId,
amount,
entry_type: 'debit',
idempotency_key: `job-debit:${jobId}`,
reason: `Credit deduction for job ${jobId}`,
metadata: { job_id: jobId },
},
);
return {
balanceAfter: entry.balance_after,
overageAfter: entry.overage_after,
};
}
自動的なメーターからクレジットへの差し引きにも関連付けられている使用量を、手動で差し引かないでください。同じ使用量に対して二重に請求されます。
監査証跡として台帳を確認する
SDKは自動ページネーションに対応した反復可能オブジェクトを返します。
for await (const entry of client.creditEntitlements.balances.listLedger(
'cus_TV52uJWWXt2yIoBBxpjaa',
{ credit_entitlement_id: 'cde_ztxm5XJsKxWucRWA3rjdM' },
)) {
console.log({
id: entry.id,
amount: entry.amount,
balanceBefore: entry.balance_before,
balanceAfter: entry.balance_after,
overageBefore: entry.overage_before,
overageAfter: entry.overage_after,
createdAt: entry.created_at,
});
}
Dodoの台帳エントリーIDを、内部の注文ID、サポートケースID、またはジョブIDとともに保存してください。照合作業では、キャッシュされた残高で履歴を上書きするのではなく、台帳エントリーと参照元を比較してください。
メーターからクレジットへの自動控除を設定する
- 従量課金の商品にクレジット権利を関連付けます。
- 同じ商品にメーターを追加します。
- そのメーターで クレジットで利用料金を請求 を有効にします。
credit_entitlement_idとmeter_units_per_creditを設定します。- 大文字と小文字を区別する
event_nameがメーターと一致するイベントを取り込みます。
バックグラウンドワーカーは、新しい利用状況を約1分ごとに処理し、メーターに従って集計して、meter_units_per_credit を使ってメーター単位を換算し、有効期限の早い付与分から順に、期限切れでない付与分から控除します。クレジット請求メーターには無料利用枠はありません。複数のメーターで、換算率を変えて1つの共通クレジットプールを利用できます。
この遅延は重要です。利用イベントが受理されたからといって、その直後の残高読み取りに控除が反映されているとは限りません。
usage-based-billing スキルを使用してメーターを作成し、count、sum、max、last のいずれかを選択してフィルターを定義し、イベントのバッチ処理とメタデータを検証します。
エンドツーエンドの AI トークンの例
完全なガイド:references/ai-token-example.md。
クレジットの Webhook を処理する
完全なガイド:references/credit-webhooks.md。
対象:
- 残高低下のペイロード
- 残高低下の通知フロー
クレジットを安全に適用する
ベストエフォートの残高チェック
精度が 0 の権利の場合、サーバーでは整数安全な解析を使って、大まかな事前チェックを実行できます。
async function hasAtLeastWholeCredits(
customerId: string,
creditEntitlementId: string,
required: bigint,
): Promise<boolean> {
const response = await client.creditEntitlements.balances.retrieve(
customerId,
{ credit_entitlement_id: creditEntitlementId },
);
return BigInt(response.balance) >= required;
}
この方法は精度が 0 の場合にのみ使用してください。小数クレジットの場合は、権利に設定された精度を保持する任意精度の小数実装を使用してください。
この読み取りは予約ではありません。2つの同時リクエストがどちらも十分な残高があると判断する可能性があり、自動メーター控除がまだ反映されていない場合もあります。
リクエストへの厳格な適用
以下のいずれかのパターンを選択します。
- 予測可能な固定コスト: 提供前に冪等な手動控除を作成します。残高不足を示す
400は拒否として扱います。控除後に処理が失敗した場合は、理由を紐付けて、別個の冪等な補填クレジットを発行します。同じ利用状況をメーターでも記録しないでください。 - AI トークンなどの変動コスト: 独自のデータストアで推定容量をアトミックに予約し、顧客ごとの同時実行数を制限してから、実際の利用状況を取り込み、ローカルの予約を Dodo の Webhook および台帳のエントリーと照合します。
- 超過利用商品:
balance > 0だけで判断せず、商品の超過利用ポリシーと独自のリスク上限に基づいて認可します。
認可に失敗した場合は、チャージまたはアップグレードの手段を提示する、アプリケーションレベルの支払い/クレジット必須レスポンスを返します。Dodo API のエラーやシークレットをクライアントに公開しないでください。
避けるべき競合状態
- 確認してから実行: リモートの残高読み取りと、その後の処理はアトミックではありません。
- イベント送信直後の読み取り: メーターワーカーがイベントをまだ処理していない場合があります。
- 並列ワーカー: ローカルの予約やアトミックな控除がなければ、複数のジョブが同じ残高をあるものとして利用する可能性があります。
- 新しい ID での再試行: タイムアウト後に
event_idまたはidempotency_keyを変更すると、利用状況や調整が重複する可能性があります。 - キャッシュを正とすること: Webhook で更新される残高は表示には便利ですが、厳格な認可には使えません。
- 控除経路の混在: 自動メーター控除と手動控除を併用すると、消費量が二重に計上されます。
よくある間違い
- 2 つのリソースを混同する。
creditEntitlementsとentitlementsは別物です。クレジット残高はclient.entitlements.grantsの下にはありません。 - 存在しない残高メソッドを呼び出す。
balances.get(creditId, customerId)ではなく、balances.retrieve(customerId, { credit_entitlement_id })を使用してください。 - 台帳の引数の順序を間違える。
createLedgerEntryは最初にcustomerIdを受け取ります。credit_entitlement_idはリクエストオブジェクトに指定します。 - 調整に
typeやdescriptionを使用する。 確認済みのフィールドはentry_typeとreasonです。 - 付与分の引数の順序を間違える。
creditEntitlements.balances.listGrants(customerID, params)は実際に存在し、最初に顧客 ID を受け取り、エンタイトルメントは params オブジェクトで指定します。ページネーションされたページを返すため、結果を配列として扱うのではなく、.itemsを読み取ってください。顧客レベルの概要が必要な場合は、代わりにcustomers.listCreditEntitlements(customerID)を使用してください。 available_balanceを残高 API のフィールドとして扱う。 確認済みの残高レスポンスで使われるのはbalanceとoverageです。available_balanceは、低残高専用の Webhook ペイロードに属します。- 精度を安易に選択する。 カスタム単位では
0–10に対応し、作成後に変更できません。 - クレジットに JavaScript の浮動小数点数を使用する。 API の金額は 10 進数文字列です。文字列のまま保持するか、10 進演算を使用してください。
- 調整額の上限を超える。 台帳の金額は
NUMERIC(38,28)に対応し、整数部は10^10未満である必要があります。 - 金額の単位を誤って記載する。 通貨額には通貨の最小単位を使用します。セントをドルと表記しないでください。
- 安定しない冪等性キーを使用する。 再試行ごとにタイムスタンプやランダムなキーを使うと、重複排除の効果が失われます。不変のビジネス操作からキーを導出してください。
- 残高不足のデビットをそのまま再試行する。 手動デビットでは残高不足により
400が返ることがあります。顧客をチャージするか、超過利用ポリシーに従うよう案内してください。 - イベントの取り込みが同期的な減算だと想定する。 メーターからクレジットへの処理は約 1 分ごとに行われます。
- Dodo の残高をリクエスト単位のロックとして使う。 ドキュメントでは、非同期で報告されるメーター残高に基づく厳密な認可を明示的に避けるよう警告しています。
- メーター名を一致させない。 使用量の
event_nameは大文字と小文字を区別して照合されます。 - 1 回のバッチ内で ID を重複させる。 同じ取り込みリクエスト内で
event_idが重複すると、リクエスト全体が拒否されます。以前に取り込まれた ID は、再試行時に無視されます。 - 重複排除の期間を勝手に設定する。 現行ドキュメントでは一意のイベント ID が必要とされていますが、保持期間は公開されていません。
- 換算方法を逆にする。
meter_units_per_creditは 1 クレジットに必要な使用量の単位数です。また、credit_entitlement_idを設定する場合は必須です。 - クレジット課金メーターに無料しきい値を期待する。
free_thresholdは金額で課金されるメーターにのみ適用されます。Bill usage in Credits がオンの場合、すべての単位でクレジットが差し引かれます。代わりに、付与するクレジットとして無料利用分をモデル化してください。 - ロールオーバーの期間フィールドを 1 つだけ指定する。
rollover_timeframe_countとrollover_timeframe_intervalは必ずセットで指定してください。 - ロールオーバーの列挙値の大文字小文字を間違える。 確認済みの値は
Day、Week、Month、Yearです。 - 有効期限がロールオーバーより先に適用されると想定する。 最初にロールオーバーが適用され、残りのみが失効します。
- 超過利用の列挙値を勝手に追加する。
forgive_at_reset、invoice_at_billing、carry_deficit、carry_deficit_auto_repayのみを使用してください。 - 超過利用の価格設定に必要な依存フィールドを省略する。 超過利用を有効にするには
price_per_unitが必要です。また、価格にはcurrencyが必要です。 - クレジットを付けすぎる。 現在、1 商品に付けられるクレジットエンタイトルメントは 5 つまでです。
- チェックアウトで任意のクレジットを付与できると想定する。 クレジットは、購入した商品またはアドオンにあらかじめ付与されている必要があります。
- よく使われる Webhook だけを処理する。 追加、減算、低残高のイベントだけでなく、
credit.overage_resetとcredit.rollover_forfeitedも含めてください。 - 検証されていない Webhook を解析する。
webhook-integrationで説明されているとおり、client.webhooks.unwrap()を使用して生の本文を検証してください。HMAC を独自に実装したり、再シリアライズした JSON を信頼したりしないでください。 - 過去のスナップショット API を勝手に作る。 トランザクション単位の履歴には、台帳の
balance_beforeとbalance_afterを使用してください。 - 非推奨の購入メソッドを使用する。 新しいチェックアウトフローでは、
payments.create(...)やsubscriptions.create(...)ではなく、client.checkoutSessions.create(...)を使用してください。 - ホストまたはキー形式を間違える。 有効なホストは
https://test.dodopayments.comとhttps://live.dodopayments.comです。キーはdodo_test_またはdodo_live_で始まります。