メインコンテンツへスキップ
ダイナミックプライシングを使用すると、複数の製品エントリを作成することなく、製品に対して可変価格を提供できます。単一の製品で**好きな金額で支払う(PWYW)**を有効にすることで、最小価格と最大価格の範囲を設定し、チェックアウトセッションリンクを作成する際に動的な金額を渡すことができます。 このアプローチは、次のような場合に最適です:
  • 可変価格を管理することなく、複数の製品を管理する必要がない
  • 顧客主導の価格設定で、購入者が自分の金額を選択する
  • プログラムによる価格制御で、APIを介して動的に金額を設定する
  • デジタル製品、寄付、または実験的なローンチのための柔軟な価格モデル
好きな金額で支払うは、単一支払い(一回限り)の製品にのみ利用可能です。サブスクリプション製品では使用できません。

仕組み

好きな金額で支払うを有効にすると、次のことができます:
  1. 価格の範囲を設定:最小価格(必須)を定義し、オプションで最大価格を設定します
  2. 動的な金額を渡す:チェックアウトセッションを作成する際に、製品カートにamountフィールドを含めます
  3. 顧客に選ばせる:金額が提供されていない場合、顧客は自分の価格を入力できます(あなたの範囲内で)
製品カートにamountを渡すと、その金額がチェックアウトに使用されます。amountフィールドを省略すると、顧客はチェックアウト中に自分の価格を選択できます(あなたの最小/最大設定に従います)。

ステップ1:好きな金額で支払う製品を作成する

まず、Dodo Paymentsダッシュボードで一回限りの製品を作成し、好きな金額で支払う価格設定を有効にします。
1

新しい製品を作成

Dodo Paymentsダッシュボードの製品に移動し、製品を追加をクリックします。
2

製品の詳細を設定

必要な製品情報を入力します:
  • 製品名:製品の表示名
  • 製品説明:顧客が購入する内容の明確な説明
  • 製品画像:画像をアップロード(PNG/JPG/WebP、最大3MB)
  • 税カテゴリ:適切な税カテゴリを選択
3

価格タイプを設定

価格タイプ単一支払い(一回限りの支払い)として選択します。
4

好きな金額で支払うを有効にする

価格設定セクションで、好きな金額で支払うトグルを有効にします。
5

最小価格を設定

顧客が支払う必要がある最小価格を入力します。これは必須で、収益の底を維持することを保証します。:最小価格が$5.00の場合、5.00(または500セント)を入力します。
6

最大価格を設定(オプション)

オプションで、顧客が支払うことができる金額を制限するために最大価格を設定します。
7

推奨価格を設定(オプション)

オプションで、顧客をガイドするために表示される推奨価格を入力します。これにより期待値が固定され、平均注文額が向上する可能性があります。
8

製品を保存

製品を追加をクリックして保存します。チェックアウトセッションで使用するために製品ID(例:pdt_123abc456def)をメモしておいてください。
製品IDは、ダッシュボードの製品詳細を表示で見つけるか、製品一覧APIを使用して見つけることができます。

ステップ2:ダイナミックプライシングでチェックアウトセッションを作成する

製品が好きな金額で支払うように設定されたら、動的な金額でチェックアウトセッションを作成できます。製品カートのamountフィールドを使用して、各チェックアウトセッションの価格をプログラムで設定できます。

金額フィールドの理解

チェックアウトセッションを作成する際に、各製品カートアイテムにamountフィールドを含めることができます:
  • amountが提供されている場合:チェックアウトはこの正確な金額を使用します(あなたの最小/最大範囲内である必要があります)
  • amountが省略されている場合:顧客はチェックアウト中に自分の価格を入力できます(あなたの範囲内で)
amountフィールドは、好きな金額で支払う製品にのみ適用されます。通常の製品では、このフィールドは無視されます。

コード例

import DodoPayments from 'dodopayments';

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

async function createDynamicPricingCheckout(
  productId: string,
  amountInCents: number,
  returnUrl: string
) {
  try {
    const session = await client.checkoutSessions.create({
      product_cart: [
        {
          product_id: productId,
          quantity: 1,
          // Dynamic amount in cents (e.g., 1500 = $15.00)
          amount: amountInCents
        }
      ],
      return_url: returnUrl,
      // Optional: Pre-fill customer information
      customer: {
        email: '[email protected]',
        name: 'John Doe'
      },
      // Optional: Add metadata for tracking
      metadata: {
        order_id: 'order_123',
        pricing_tier: 'custom'
      }
    });

    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: Create checkout with $25.00 (2500 cents)
const session = await createDynamicPricingCheckout(
  'prod_123abc456def',
  2500, // $25.00 in cents
  'https://yoursite.com/checkout/success'
);

// Example: Create checkout with $10.00 (1000 cents)
const session2 = await createDynamicPricingCheckout(
  'prod_123abc456def',
  1000, // $10.00 in cents
  'https://yoursite.com/checkout/success'
);
金額形式amountフィールドは、通貨の最小単位でなければなりません。USDの場合、これはセントを意味します(例:$25.00 = 2500)。他の通貨の場合は、最小単位を使用します(例:INRの場合はパイセ)。

ステップ3:顧客に自分の価格を選ばせる

顧客にチェックアウト中に自分の価格を選択させたい場合は、製品カートからamountフィールドを省略するだけです。チェックアウトページには、顧客があなたの最小および最大範囲内で任意の金額を入力できる入力フィールドが表示されます。
async function createCustomerChoiceCheckout(
  productId: string,
  returnUrl: string
) {
  try {
    const session = await client.checkoutSessions.create({
      product_cart: [
        {
          product_id: productId,
          quantity: 1
          // No amount field - customer will choose their price
        }
      ],
      return_url: returnUrl,
      customer: {
        email: '[email protected]',
        name: 'John Doe'
      }
    });

    return session;
  } catch (error) {
    console.error('Failed to create checkout session:', error);
    throw error;
  }
}

一般的なユースケース

ユースケース1:ユーザータイプに基づく階層価格設定

同じ製品を使用して異なる顧客セグメントに異なる価格を提供します:
// Student discount: $10.00
const studentSession = await createDynamicPricingCheckout(
  'prod_123abc456def',
  1000, // $10.00
  'https://yoursite.com/success'
);

// Regular price: $25.00
const regularSession = await createDynamicPricingCheckout(
  'prod_123abc456def',
  2500, // $25.00
  'https://yoursite.com/success'
);

// Premium price: $50.00
const premiumSession = await createDynamicPricingCheckout(
  'prod_123abc456def',
  5000, // $50.00
  'https://yoursite.com/success'
);

ユースケース2:数量に基づくダイナミックプライシング

購入数量に基づいて価格を調整します:
async function createQuantityBasedCheckout(
  productId: string,
  quantity: number
) {
  // Base price: $20.00 per unit
  // Discount: 10% for 2+ items, 20% for 5+ items
  const basePrice = 2000; // $20.00 in cents
  let discount = 0;
  
  if (quantity >= 5) {
    discount = 0.20; // 20% off
  } else if (quantity >= 2) {
    discount = 0.10; // 10% off
  }
  
  const totalAmount = Math.round(basePrice * quantity * (1 - discount));
  
  const session = await client.checkoutSessions.create({
    product_cart: [
      {
        product_id: productId,
        quantity: quantity,
        amount: totalAmount
      }
    ],
    return_url: 'https://yoursite.com/success'
  });
  
  return session;
}

ユースケース3:時間ベースまたはプロモーション価格設定

特定の期間中にプロモーション価格を適用します:
async function createPromotionalCheckout(productId: string) {
  const isPromoActive = checkIfPromotionActive(); // Your logic
  const regularPrice = 3000; // $30.00
  const promoPrice = 2000; // $20.00
  
  const amount = isPromoActive ? promoPrice : regularPrice;
  
  const session = await client.checkoutSessions.create({
    product_cart: [
      {
        product_id: productId,
        quantity: 1,
        amount: amount
      }
    ],
    return_url: 'https://yoursite.com/success',
    metadata: {
      pricing_type: isPromoActive ? 'promotional' : 'regular'
    }
  });
  
  return session;
}

ベストプラクティス

合理的な範囲を設定

コストをカバーしつつアクセス可能な最小価格を選択します。顧客の期待をガイドするために推奨価格を使用します。

金額を検証

常に動的な金額が製品の最小および最大範囲内に収まることを確認してから、チェックアウトセッションを作成します。

価格決定を追跡

メタデータを使用して、特定の金額が選ばれた理由を追跡します(例:pricing_tierdiscount_codeuser_segment)。

エッジケースを処理

金額が最大範囲を超えたり、最小範囲を下回ったりする場合に、アプリケーションが適切に処理できるようにします。

検証とエラーハンドリング

常に金額を製品の最小および最大設定と照らし合わせて検証します:
async function createValidatedCheckout(
  productId: string,
  amountInCents: number,
  minAmount: number,
  maxAmount: number | null
) {
  // Validate minimum
  if (amountInCents < minAmount) {
    throw new Error(
      `Amount ${amountInCents} is below minimum ${minAmount}`
    );
  }
  
  // Validate maximum (if set)
  if (maxAmount !== null && amountInCents > maxAmount) {
    throw new Error(
      `Amount ${amountInCents} exceeds maximum ${maxAmount}`
    );
  }
  
  // Create checkout session
  return await client.checkoutSessions.create({
    product_cart: [
      {
        product_id: productId,
        quantity: 1,
        amount: amountInCents
      }
    ],
    return_url: 'https://yoursite.com/success'
  });
}

APIリファレンス

トラブルシューティング

amountフィールドが無視されている場合は、次のことを確認してください:
  • ダッシュボードで製品に好きな金額で支払うが有効になっている
  • 製品が単一支払い(一回限りの支払い)製品であり、サブスクリプションではない
  • 金額が正しい形式である(通貨の最小単位、例:USDの場合はセント)
APIは、金額が製品の価格範囲に違反するチェックアウトセッションを拒否します。チェックアウトセッションを作成する前に常に金額を検証するか、amountフィールドを省略して顧客に価格を選ばせてください。
顧客が価格入力フィールドを見ていない場合は、製品カートからamountフィールドを省略していることを確認してください。amountが提供されている場合、チェックアウトはその正確な金額を使用します。