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

仕組み

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

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

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

Create a new product

Dodo Payments ダッシュボードで Products に移動し、Add Product をクリックしてください。
2

Configure product details

必要な製品情報を入力:
  • Product Name: 製品の表示名
  • Product Description: 顧客が購入する内容の明確な説明
  • Product Image: 画像をアップロード(PNG/JPG/WebP、最大3 MB)
  • Tax Category: 適切な税区分を選択
3

Set pricing type

Pricing TypeSingle Payment(単発払い)に設定してください。
4

Enable Pay What You Want

Pricing セクションで Pay What You Want トグルを有効にします。
5

Set minimum price

顧客が支払う必要がある Minimum Price を入力してください。これは必須で、収益の下限を確保します。: 最低価格が $5.00 の場合、5.00(または 500 セント)を入力してください。
6

Set maximum price (optional)

必要に応じて Maximum Price を設定し、顧客が支払える金額の上限を設けます。
7

Set suggested price (optional)

必要に応じて Suggested Price を入力すると、顧客への案内に役立ち平均注文額の向上につながります。
8

Save the product

Add Product をクリックして保存します。チェックアウトセッションで使用するため、製品ID(例: pdt_123abc456def)を控えてください。
製品IDはダッシュボードの ProductsView Details で確認できます。またはList Products API を使用してください。

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

Pay What You Want で製品を設定したら、動的な金額でチェックアウトセッションを作成できます。製品カートの amount フィールドを使用すると、各チェックアウトセッションごとに価格をプログラムで設定できます。

金額フィールドの理解

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

コード例

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: 'customer@example.com',
        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 Format: 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: 'customer@example.com',
        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;
}

ベストプラクティス

Set Reasonable Bounds

費用をカバーしつつ手頃な最低価格を選んでください。Suggested Price を使って顧客の期待を誘導しましょう。

Validate Amounts

チェックアウトセッションを作成する前に、動的な金額が製品の最低/最大範囲内に収まっているかを常に検証してください。

Track Pricing Decisions

特定の金額を選択した理由を追跡するためにメタデータを使用します(例: pricing_tierdiscount_codeuser_segment)。

Handle Edge Cases

金額が最大範囲を超えたり最小範囲を下回ったりするケースに対して、アプリケーションが適切に対応するようにしてください。

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

常に金額を製品の最小および最大設定と照らし合わせて検証します:
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 フィールドが無視されている場合は、次を確認してください:
  • ダッシュボードで製品に Pay What You Want が有効になっている
  • 製品がサブスクリプションではなく Single Payment(単発払い)である
  • 金額が正しい形式(通貨の最小単位、例: USD はセント)になっている
API は金額が製品の価格範囲に違反するチェックアウトセッションを拒否します。セッション作成前に常に金額を検証するか、amount フィールドを省略して顧客に価格を選ばせてください。
顧客が価格入力フィールドを見ていない場合は、製品カートから amount フィールドを省略していることを確認してください。amount が提供されていると、チェックアウトではその金額が正確に使用されます。