メインコンテンツへスキップ
このチュートリアルでは、Dodo Paymentsのアドオンを使用して座席ベースの価格設定を実装する方法を学びます。追加の座席用のアドオンを持つサブスクリプション製品を作成し、カスタムアドオン数量を持つ支払いリンクを生成する方法を示します。
このチュートリアルでは、Node.js/Expressアプリケーションのサンプル実装コードを提供します。このコードは、特定のフレームワーク(Next.js、React、Vueなど)に合わせて修正し、アプリケーションのニーズに応じてユーザーインターフェースをカスタマイズできます。
このチュートリアルの終わりまでに、次のことができるようになります:
  • 座席ベースの価格設定を持つサブスクリプション製品を作成する
  • 追加の座席用のアドオンを設定する
  • カスタムアドオン数量を持つ支払いリンクを生成する
  • 動的な座席数を持つチェックアウトセッションを処理する

何を作成するか

座席ベースの価格モデルを作成しましょう:
  • 基本プラン: 5人のチームメンバーまで月額49ドル
  • 座席アドオン: 追加の座席1つにつき月額2ドル
  • 支払いリンク: カスタム座席数量での動的チェックアウト
始める前に、次のものを用意してください:
  • Dodo Paymentsアカウント
  • TypeScript/Node.jsの基本的な知識

ステップ1: 座席アドオンを作成する

追加の座席を表すアドオンを作成する必要があります。このアドオンは基本のサブスクリプションに添付され、顧客が追加の座席を購入できるようにします。
基本サブスクリプション製品の作成
何を作成するか: 1座席あたり月額2ドルのアドオンで、任意の基本サブスクリプションに追加できます。
1

アドオンに移動する

  1. Dodo Paymentsダッシュボードで、製品セクションに留まります
  2. アドオンタブをクリックします
  3. アドオンを作成をクリックします
これにより、アドオン作成フォームが開きます。
2

アドオンの詳細を入力する

座席アドオンのために次の値を入力します:アドオン名: Additional Team Seat説明: Add extra team members to your workspace with full access to all features価格: 入力 → 2.00通貨: 基本サブスクリプションの通貨と一致する必要があります税カテゴリ: 製品に適切なカテゴリを選択します。
3

アドオンを保存する

  1. すべての設定を確認します:
    • 名前: 追加チーム座席
    • 価格: 月額2.00ドル
  2. アドオンを作成をクリックします
アドオンが作成されました! あなたの座席アドオンは、サブスクリプションに添付できるようになりました。

ステップ2: 基本サブスクリプション製品を作成する

5人のチームメンバーを含む基本サブスクリプション製品を作成します。これが座席ベースの価格モデルの基盤となります。
基本サブスクリプション製品の作成
1

製品に移動する

  1. Dodo Paymentsダッシュボードにログインします
  2. 左のサイドバーで製品をクリックします
  3. 製品を作成ボタンをクリックします
  4. 製品タイプとしてサブスクリプションを選択します
基本サブスクリプションを構成するフォームが表示されるはずです。
2

サブスクリプションの詳細を入力する

基本プランの具体的な詳細を入力します:製品名: Motion説明: Where your team's documentation lives.定期価格: 入力 → 49.00請求サイクル: 選択 → Monthly通貨: お好みの通貨を選択します(例: USD

ステップ3: アドオンをサブスクリプションに接続する

座席アドオンを基本サブスクリプションに関連付ける必要があります。これにより、顧客はチェックアウト中に追加の座席を購入できます。
1

座席アドオンを添付する

サブスクリプションにアドオンを添付する
  1. アドオンセクションまでスクロールします
  2. アドオンを追加をクリックします
  3. ドロップダウンから座席アドオンを選択します
  4. サブスクリプション設定に表示されていることを確認します
2

サブスクリプションの変更を保存する

  1. 完全なサブスクリプション設定を確認します:
    • 基本プラン: 5座席まで月額49ドル
    • アドオン: 追加の座席1つにつき月額2ドル
    • 無料トライアル: 14日間
  2. 変更を保存をクリックします
座席ベースの価格設定が構成されました! 顧客は基本プランを購入し、必要に応じて追加の座席を追加できます。

ステップ4: カスタムアドオン数量で支払いリンクを生成する

次に、カスタムアドオン数量で支払いリンクを生成するExpress.jsアプリケーションを作成します。これが座席ベースの価格設定の真の力です - 追加の座席の数に応じて動的にチェックアウトセッションを作成できます。
1

プロジェクトを設定する

新しいNode.jsプロジェクトを作成し、必要な依存関係をインストールします:
mkdir seat-based-pricing
cd seat-based-pricing
npm init -y
npm install dodopayments express dotenv
npm install -D @types/node @types/express typescript ts-node
tsconfig.jsonファイルを作成します:
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}
2

環境ファイルを作成する

.envファイルを作成し、Dodo Payments APIキーを入力します:
DODO_PAYMENTS_API_KEY=your_actual_dodo_api_key_here
APIキーをバージョン管理にコミットしないでください。.env.gitignoreファイルに追加してください。
3

チェックアウトセッション作成の実装

次のコードを持つsrc/server.tsファイルを作成します:
// Add this new endpoint for dynamic seat quantities
import 'dotenv/config';
import DodoPayments from 'dodopayments';
import express, { Request, Response } from 'express';

const app = express();

// Initialize the Dodo Payments client
const client = new DodoPayments({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: 'test_mode'
});

async function createCheckoutSession(seatCount: number) {
  try {
    const session = await client.checkoutSessions.create({
      // Products to sell - use IDs from your Dodo Payments dashboard
      product_cart: [
        {
          product_id: 'pdt_7Rl9OWT2Mz4wwUTKz74iZ', // Replace with your actual product ID
          quantity: 1,
          addons: [
            {
              addon_id: 'adn_eKQbNakKrivDpaxmI8wKI', // Replace with your actual addon ID
              quantity: seatCount
            }
          ]
        }
      ],
      
      // Pre-fill customer information to reduce friction
      customer: {
        email: '[email protected]',
        name: 'Steve Irwin',
      },
      // Where to redirect after successful payment
      return_url: 'https://example.com/checkout/success',
    });

    // Redirect your customer to this URL to complete payment
    console.log('Checkout URL:', session.checkout_url);
    console.log('Session ID:', session.session_id);
    
    return session;
    
  } catch (error) {
    console.error('Failed to create checkout session:', error);
    throw error;
  }
}

// Example usage in an Express.js route
app.post('/create-checkout/:seatCount', async (req: Request, res: Response) => {
  try {
    const seatCount = parseInt(req.params.seatCount);
    const session = await createCheckoutSession(seatCount);
    res.json({ checkout_url: session.checkout_url });
  } catch (error) {
    res.status(500).json({ error: 'Failed to create checkout session' });
  }
});

// Add this line after your other middleware
app.use(express.static('public'));

// Add this route to serve the demo page
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/../public/index.html');
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});
4

シンプルなウェブインターフェースを追加する

簡単なテスト用にpublic/index.htmlファイルを作成します:
<!DOCTYPE html>
<html>
<head>
    <title>Seat-Based Pricing Demo</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
        .form-group { margin: 20px 0; }
        label { display: block; margin-bottom: 5px; font-weight: bold; }
        input { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; }
        button { background: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; }
        button:hover { background: #0056b3; }
        .result { margin-top: 20px; padding: 15px; background: #f8f9fa; border-radius: 4px; }
    </style>
</head>
<body>
    <h1>Seat-Based Pricing Demo</h1>
    <p>Generate checkout links with custom seat quantities:</p>
    
    <div class="form-group">
        <label for="seatCount">Number of Additional Seats:</label>
        <input type="number" id="seatCount" value="3" min="0" max="50">
    </div>
    
    <button onclick="createCheckout()">Generate Checkout Link</button>
    
    <div id="result" class="result" style="display: none;">
        <h3>Checkout Link Generated!</h3>
        <p><strong>Seat Count:</strong> <span id="seatCountDisplay"></span></p>
        <p><strong>Total Cost:</strong> $<span id="totalCost"></span>/month</p>
        <p><strong>Checkout URL:</strong></p>
        <a id="checkoutUrl" href="#" target="_blank">Click here to checkout</a>
    </div>

    <script>
        async function createCheckout() {
            const seatCount = document.getElementById('seatCount').value;
            
            try {
                const response = await fetch(`/create-checkout/${seatCount}`, {
                    method: 'POST'
                });
                
                const data = await response.json();
                
                if (response.ok) {
                    document.getElementById('seatCountDisplay').textContent = seatCount;
                    document.getElementById('totalCost').textContent = data.total_cost;
                    document.getElementById('checkoutUrl').href = data.checkout_url;
                    document.getElementById('result').style.display = 'block';
                } else {
                    alert('Error: ' + data.error);
                }
            } catch (error) {
                alert('Error creating checkout session');
            }
        }
    </script>
</body>
</html>
ウェブインターフェースが作成されました! 異なる座席数量をテストするためのシンプルなUIがあります。
5

静的ファイルを提供する

このコードをsrc/server.tsに追加して、HTMLファイルを提供します:
// Add this line after your other middleware
app.use(express.static('public'));

// Add this route to serve the demo page
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/../public/index.html');
});
静的ファイルが構成されました! http://localhost:3000にアクセスして、デモインターフェースを確認してください。

ステップ5: 実装をテストする

座席ベースの価格設定の実装が正しく機能するかどうかをテストしましょう。
1

サーバーを起動する

  1. 正しいAPIキーを持つ.envファイルを用意します
  2. Dodo Paymentsダッシュボードから実際の値で製品およびアドオンIDをコードに更新します
  3. サーバーを起動します:
npm run dev
サーバーが正常に起動し、「サーバーがhttp://localhost:3000で実行中」と表示されるはずです。
2

ウェブインターフェースをテストする

基本サブスクリプション製品の作成
  1. ブラウザを開き、http://localhost:3000にアクセスします
  2. 座席ベースの価格設定デモインターフェースが表示されるはずです
  3. 異なる座席数量(0、3、10など)を試します
  4. 各数量の「チェックアウトリンクを生成」をクリックします
  5. チェックアウトURLが正しく生成されていることを確認します
3

チェックアウトセッションをテストする

  1. 追加の座席3つでチェックアウトリンクを生成します
  2. チェックアウトURLをクリックしてDodo Paymentsのチェックアウトを開きます
  3. チェックアウトに次の内容が表示されることを確認します:
    • 基本プラン: 月額49ドル
    • 追加の座席: 3 × 2ドル = 月額6ドル
  4. テスト購入を完了します
チェックアウトは正しい価格の内訳を表示し、購入を完了できるようにします。
4

WebhookをリッスンしてDBを更新する

サブスクリプションや座席の変更に合わせてデータベースを同期させるために、Dodo PaymentsからのWebhookイベントをリッスンする必要があります。Webhookは、顧客がチェックアウトを完了したり、サブスクリプションを更新したり、座席数を変更したりしたときにバックエンドに通知します。Webhookエンドポイントを設定し、イベントを処理する手順については、公式のDodo Payments Webhookガイドを参照してください:

Dodo Payments Webhooks Documentation

サブスクリプションと座席管理のためのWebhookイベントを安全に受信し、処理する方法を学びます。

トラブルシューティング

一般的な問題とその解決策:
考えられる原因:
  • 無効な製品IDまたはアドオンID
  • APIキーに十分な権限がない
  • アドオンがサブスクリプションに正しく関連付けられていない
  • ネットワーク接続の問題
解決策:
  1. Dodo Paymentsダッシュボードで製品およびアドオンIDが存在することを確認します
  2. アドオンがサブスクリプションに正しく添付されていることを確認します
  3. APIキーにチェックアウトセッション作成の権限があることを確認します
  4. 簡単なGETリクエストでAPI接続をテストします

おめでとうございます!座席ベースの価格設定を実装しました

Dodo Paymentsを使用して座席ベースの価格設定システムを成功裏に作成しました!達成したことは次のとおりです:

基本サブスクリプション

5座席を含むサブスクリプション製品を月額49ドルで作成しました

座席アドオン

追加の座席を月額2ドルで設定しました

チェックアウト

カスタム座席数量でチェックアウトセッションを生成するAPIを構築しました

ウェブインターフェース

異なる座席数量をテストするためのシンプルなウェブインターフェースを作成しました
この例は、座席ベースの価格設定の最小限の実装のみを示しています。本番環境で使用する場合は、堅牢なエラーハンドリング、認証、データ検証、セキュリティ対策を追加し、アプリケーションの要件に合わせてロジックを適応させる必要があります。