Skip to main content
Sentraに統合コードを作成してもらいましょう。
VS Code、Cursor、またはWindsurfでAIアシスタントを使うと、必要なものを説明するだけでSDK/APIコード、webhookハンドラーなどを生成できます。
Sentraを試す:AIを活用した統合 →
このチュートリアルでは、顧客がメールクレジットのプールを前払いするトランザクションメールプラットフォーム、MailKitを構築します。プランでは毎月のメール利用枠が付与されます。残高が少なくなった場合、顧客は次のサイクルを待たずにトップアップパックを購入できます。メールを1通送信するたびに、クレジットが自動的に1つ差し引かれます。
このチュートリアルでは、メールプロバイダーとしてResendを使用します。無料プラン(月3,000通)で、有料アカウントなしにフロー全体を構築してテストできます。このパターンはどのプロバイダーでも利用できます。resend.emails.sendをSendGrid、Postmark、SES、または独自のSMTPリレーに置き換えてください。
このチュートリアルを終えると、次のことができるようになります。
  • ダッシュボードでカスタムクレジットエンタイトルメント(メール)を作成する
  • クレジットをサブスクリプションプランとワンタイムトップアッププロダクトに関連付ける
  • Resend経由で実際のメールを送信し、ledgerエントリによって送信ごとに1クレジットを差し引く
  • フロントエンドから最新のクレジット残高を取得する
  • Dodo webhookを正しく検証し、credit.balance_lowを処理して残高がゼロになる前に顧客へ通知する

構築するもの

MailKitの料金モデルは次のとおりです。 単位はメール1通 = 1クレジットです。顧客はトークン、バッチ、重み付き単位について考える必要がありません。「今月あと4,231通送信できます」と表示されるだけです。
開始する前に、次を用意してください。
  • Dodo Paymentsアカウント(test modeで問題ありません)
  • 無料のResendアカウントとAPI key
  • Node.js 18以降とTypeScriptの基本的な知識

Step 1:メールクレジットエンタイトルメントを作成する

クレジットエンタイトルメントは、プラットフォームが販売する単位を定義します。ここでは、メール1通の送信です。
Credits listing page

The Credits tab under Products lists all your credit entitlements.

1

Open the Credits section

  1. Dodo Paymentsダッシュボードにログインします
  2. 左側のサイドバーでProductsをクリックします
  3. Creditsタブを選択します
  4. Create Creditをクリックします
2

Configure the credit unit

クレジットの詳細を入力します。Credit Name: Email CreditsCredit Type: Custom Unitを選択しますUnit Name: emailPrecision: 0(メールは常に整数単位であり、半分のメールを送信することはできません)Credit Expiry: 30 days(各サイクルで利用枠がリセットされます)
Precisionは作成後に変更できません。メール、メッセージ、セッションなどの離散的な単位には、0が適しています。
3

Leave the other defaults as-is

このCookbookではrolloverやoverageを有効にしません。目的は、可能な限りシンプルなCBBフローを構築することです。これらは後からクレジットの関連付けで設定できます。
4

Save and copy the credit ID

Create Creditをクリックします。クレジットを開いてIDをコピーします。バックエンドから残高を取得する際に必要です。形式はcent_xxxxxxxxxxxxのようになります。
Email Creditsエンタイトルメントの準備ができました。次は、顧客にクレジットを付与するプロダクトを作成します。

Step 2:プランとトップアップパックを作成する

2つのプロダクトを作成します。定期的なSubscriptionプランと、ワンタイムのSingle Paymentトップアップです。プランでは各サイクルに5,000通を付与し、トップアップでは必要に応じてさらに5,000通を追加します。どちらも同じEmail Creditsエンタイトルメントを関連付けます。
このCookbookでは、usage-based meterではなく、直接的なledgerエントリでクレジットを差し引きます。Ledgerエントリは即時に反映され(残高は数ミリ秒で更新)、追加設定が不要で、1つのユーザー操作が正確に1クレジットに対応する場合に適しています。重み付き単位(「tokens」や「処理済みMB」など)の取り込み済みusageイベントから自動的に差し引きたい場合は、meterベースのパターンについてCredit-Based Billing → Usage Billing with Creditsを参照してください。

MailKit Plan(月額$19、5,000通)

1

Create the subscription

  1. Products → Create Productに移動します
  2. プロダクトの詳細を入力します。
Product Name: MailKit PlanDescription: 5,000 transactional emails per month.
  1. プロダクトタイプとしてSubscriptionを選択します
  2. 定期料金を設定します。
Recurring Price: 19.00Billing Cycle: MonthlyCurrency: USD
2

Attach the email credit entitlement

Entitlements → Credits → Attachまでスクロールし、次を設定します。Credit Entitlement: Email CreditsCredits issued per billing cycle: 5000Low Balance Threshold: 20(パーセント。残高がサイクルの利用枠の20%、つまり1,000通を下回ったときにcredit.balance_lowを発生させます)Import Default Credit Settings: 有効(Step 1の30日間のexpiryを使用)Add to Productをクリックし、プロダクトをSaveします。プロダクトID(pdt_xxxxxxxxxxxx)をコピーします。
プラン:月額$19 → 各サイクルで5,000通に更新されます。

Top-Up Pack(ワンタイム$9、5,000通)

1

Create a one-time product

  1. Products → Create Productに移動します
  2. プロダクトの詳細を入力します。
Product Name: Email Top-Up PackDescription: Add 5,000 emails to your MailKit balance instantly.
  1. プロダクトタイプとしてSingle Paymentを選択します
  2. 料金を設定します。
Price: 9.00Currency: USD
2

Attach the credit grant

Entitlements → Credits → Attachで次を設定します。
  • Credit Entitlement: Email Credits
  • Credits issued: 5000
ワンタイムプロダクトは、独自のexpiry(Step 1に従い購入から30日間)でクレジットを付与します。トップアップはサブスクリプションクレジットに積み上げられ、置き換えることはありません。
保存して、プロダクトIDをコピーします。
Top-Up Pack:$9 → +5,000通、すぐに利用可能です。

Step 3:バックエンドをセットアップする

チェックアウト、送信、残高取得、webhookを処理するExpressサーバーを構築します。
1

Initialize the project

package.jsonにdev scriptを追加します。
tsxは、build stepやtsconfig.jsonなしでTypeScriptを直接実行できるため、チュートリアルに最適です。本番環境ではtsconfig.jsonbuild scriptを追加してください。
2

Configure environment variables

.envを作成します。
.env
DODO_WEBHOOK_KEYは、endpointを作成した後のStep 4で入力します。Resend API keyはresend.com/api-keysから取得できます。
.envをすぐに.gitignoreへ追加してください。API keyは絶対にcommitしないでください。
3

Build the server

プロジェクトのrootにserver.tsを作成します。
Webhook bodyはrawでなければなりません。 express.json()はbodyをparseして再シリアライズするため、signature verificationが壊れます。app.use(express.json())行よりに、express.raw()を使用して/webhooks/dodoを定義してください。
バックエンドの準備ができました。subscribe、top-up、balance、send、webhook handlerがすべて接続されています。
4

Add a demo UI

public/index.htmlを作成します。

Step 4:Webhook endpointを接続する

credit.balance_lowイベントにより、顧客がクレジットを使い切るに通知できます。これがなければ、問題に気づくのはメール送信に失敗したときが初めてになります。
1

Expose your local server

Webhookにはpublic URLが必要です。開発中はngrok(または任意のtunnel)を使用します。
HTTPS forwarding URL(例:https://1234abcd.ngrok-free.app)をコピーします。
2

Register the endpoint in Dodo

  1. Developers → Webhooks → Add Endpointに移動します
  2. URLhttps://1234abcd.ngrok-free.app/webhooks/dodo
  3. Eventscredit.addedcredit.balance_lowcredit.rolled_overをsubscribeします
  4. 保存し、signing keyDODO_WEBHOOK_KEYとして.envにコピーします
  5. サーバーを再起動します

Step 5:フロー全体をテストする

1

Start the server

MailKit running on http://localhost:3000が表示されます。ブラウザで開いてください。
2

Subscribe a test customer

  1. セクション1でテスト用メールアドレスと名前を入力し、Get checkout linkをクリックします
  2. リンクを開き、test cardでチェックアウトを完了します
  3. 支払い後、ダッシュボードのCustomerscustomer_idを確認します。
顧客の残高に5,000通が付与されます。Customers → [Customer] → Creditsで確認してください。
3

Send a real email

  1. customer_idをセクション3に貼り付けます
  2. todelivered@resend.devのままにします(すべてを受け付けるResendのsandbox inboxです)
  3. Sendをクリックします
Resendのmessage idが返されます。セクション2で残高を更新すると、件数がすぐに4,999へ減少します。各ledger debitは書き込まれた瞬間にlive balanceへ反映されます。
4

Trigger the low-balance webhook

thresholdは20%(5,000通の利用枠のうち1,000通)です。4,000通の実メールを送信せずに発生させるには、ダッシュボードからmanually debit the balanceします。
  1. Customers → [Customer] → Credits → Email Creditsに移動します
  2. Adjust Balanceをクリックし、4000をdebitします
  3. デモからもう1通メールを送信します
数秒以内にサーバーへ次のログが出力されます。
サーバーがwebhookを受信し、検証しました。本番環境では、ここで顧客にメールを送信するか、アプリ内バナーを表示します。
5

Buy a top-up pack

  1. customer_idをセクション4に貼り付けます
  2. Buy 5,000 emailsをクリックし、test checkoutを完了します
  3. 残高を更新すると、5,000増加します
grant_source: one_timeを伴うcredit.addedイベントが発生します。トップアップはサブスクリプションクレジットに積み上げられ、両方のプールはFIFO(期限切れでない最古のgrantが最初)で消費されます。
6

Test the hard stop

残高を手動でゼロにしてから、もう1通送信してみます。次の結果が返されます。
この402は、アプリケーションレベルのenforcementです。Dodo balance APIがsource of truthであり、クライアント側でcacheしないでください。

トラブルシューティング

signatureはraw HTTP bodyに対して計算されます。express.json()はpayloadをparseして再シリアライズするため、HMACが壊れます。app.use(express.json())行より/webhooks/dodoexpress.raw({ type: 'application/json' })に登録されていること、およびDODO_WEBHOOK_KEYがendpoint detail pageに表示されるsigning keyと一致することを確認してください。
次の3点をこの順番で確認してください。
  1. 顧客がcheckoutを完了したこと(クレジットはsession creation時ではなく、支払い成功時に付与されます)
  2. .env内のCREDIT_ENTITLEMENT_IDが、プロダクトに関連付けられたクレジットと一致すること(IDが一致しない場合、誤ったクレジットに書き込まれても通知されません)
  3. 渡しているcustomer_idがDodo(ダッシュボードのcustomers table)から取得したものであり、独自のdatabaseからではないこと
sandbox sender onboarding@resend.devは、Resendアカウントのメールアドレスまたはdelivered@resend.devにのみ配信します。他の宛先へ送信するには、ドメインをverifyし、そのドメインのfromアドレスを使用してください。

構築したもの

One reusable credit unit

Email Creditsを1回定義し、サブスクリプションプランとトップアップパックの両方に関連付けました。

Subscription with prepaid allowance

月額$19で、各サイクルに5,000通を付与します。顧客は支払う内容を把握でき、提供側は最大コストを把握できます。

Top-up pack

5,000通を付与するワンタイムプロダクトです。プランを変更せずにサブスクリプションクレジットへ積み上げられます。

Instant ledger debits

送信ごとにcreateLedgerEntryを1回呼び出します。meterもaggregation lagもなく、Resendのmessage idによってretry時もidempotentです。

Credit-Based Billing Reference

rollover、overage modes、ledger management、完全なAPI surfaceについては、CBBのドキュメント全文を参照してください。
サポートが必要ですか?
最終更新日 2026年7月31日