> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 好きな金額で支払うダイナミックプライシングチェックアウト

> 単一の製品を使用して、可変価格の柔軟なチェックアウトリンクを作成します。好きな金額で支払うを有効にして、顧客が自分の価格を選択したり、プログラムで動的な金額を設定したりできるようにします。

**ダイナミックプライシング**を使用すると、複数の製品エントリを作成することなく、製品に対して可変価格を提供できます。単一の製品で\*\*好きな金額で支払う（PWYW）\*\*を有効にすることで、最小価格と最大価格の範囲を設定し、チェックアウトセッションリンクを作成する際に動的な金額を渡すことができます。

このアプローチは、次のような場合に最適です：

* **可変価格**を管理することなく、複数の製品を管理する必要がない
* **顧客主導の価格設定**で、購入者が自分の金額を選択する
* **プログラムによる価格制御**で、APIを介して動的に金額を設定する
* デジタル製品、寄付、または実験的なローンチのための**柔軟な価格モデル**

<Warning>
  Pay What You Want は**Single Payment**（単発）商品でのみ利用可能です。サブスクリプション商品では使用できません。
</Warning>

## 仕組み

好きな金額で支払うを有効にすると、次のことができます：

1. **価格の範囲を設定**: 最低価格（必須）を定義し、必要に応じて最高価格を設定
2. **動的な金額を渡す**: チェックアウトセッション作成時に製品カートに`amount`フィールドを含める
3. **顧客に選ばせる**: 金額が提供されない場合、顧客が自分の価格を入力できる（設定された範囲内）

<Info>
  製品カートに`amount`フィールドを渡すと、その金額がチェックアウトに使用されます。`amount`フィールドを省略すると、顧客はチェックアウト中に自身の価格を選択できます（最低/最高設定に従う）。
</Info>

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

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

<Steps>
  <Step title="Create a new product">
    Dodo Payments ダッシュボードで **Products** に移動し、**Add Product** をクリックしてください。
  </Step>

  <Step title="Configure product details">
    必要な製品情報を入力:

    * **Product Name**: 製品の表示名
    * **Product Description**: 顧客が購入する内容の明確な説明
    * **Product Image**: 画像をアップロード（PNG/JPG/WebP、最大3 MB）
    * **Tax Category**: 適切な税区分を選択
  </Step>

  <Step title="Set pricing type">
    **Pricing Type** を **Single Payment**（単発払い）に設定してください。
  </Step>

  <Step title="Enable Pay What You Want">
    **Pricing** セクションで **Pay What You Want** トグルを有効にします。
  </Step>

  <Step title="Set minimum price">
    顧客が支払う必要がある **Minimum Price** を入力してください。これは必須で、収益の下限を確保します。

    **例**: 最低価格が \$5.00 の場合、`5.00`（または `500` セント）を入力してください。
  </Step>

  <Step title="Set maximum price (optional)">
    必要に応じて **Maximum Price** を設定し、顧客が支払える金額の上限を設けます。
  </Step>

  <Step title="Set suggested price (optional)">
    必要に応じて **Suggested Price** を入力すると、顧客への案内に役立ち平均注文額の向上につながります。
  </Step>

  <Step title="Save the product">
    **Add Product** をクリックして保存します。チェックアウトセッションで使用するため、製品ID（例: `pdt_123abc456def`）を控えてください。
  </Step>
</Steps>

<Tip>
  製品IDはダッシュボードの **Products** → **View Details** で確認できます。または[List Products API](/api-reference/products/get-products) を使用してください。
</Tip>

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

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

### 金額フィールドの理解

チェックアウトセッションを作成する際、各製品カートアイテムに `amount` フィールドを含めることができます:

* **`amount` が提供されている場合**: チェックアウトはこの正確な金額を使用します（最低/最高範囲内である必要があります）
* **`amount` が省略されている場合**: 顧客はチェックアウト中に自身の価格を入力できます（設定範囲内）

<Warning>
  `amount` フィールドは Pay What You Want 商品にのみ適用されます。通常の商品ではこのフィールドは無視されます。
</Warning>

### コード例

<CodeGroup>
  ```typescript TypeScript theme={null}
  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'
  );
  ```

  ```python Python theme={null}
  import os
  from dodopayments import DodoPayments

  # Initialize the Dodo Payments client
  client = DodoPayments(
      bearer_token=os.environ.get("DODO_PAYMENTS_API_KEY"),
  )

  def create_dynamic_pricing_checkout(
      product_id: str,
      amount_in_cents: int,
      return_url: str
  ):
      """
      Create a checkout session with dynamic pricing.
      
      Args:
          product_id: The product ID with Pay What You Want enabled
          amount_in_cents: The amount in cents (e.g., 2500 for $25.00)
          return_url: URL to redirect after payment completion
      
      Returns:
          Session object with checkout_url and session_id
      """
      try:
          session = client.checkout_sessions.create(
              product_cart=[
                  {
                      "product_id": product_id,
                      "quantity": 1,
                      # Dynamic amount in cents (e.g., 1500 = $15.00)
                      "amount": amount_in_cents
                  }
              ],
              return_url=return_url,
              # 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"
              }
          )
          
          print(f"Checkout URL: {session.checkout_url}")
          print(f"Session ID: {session.session_id}")
          
          return session
      except Exception as error:
          print(f"Failed to create checkout session: {error}")
          raise error

  # Example: Create checkout with $25.00 (2500 cents)
  session = create_dynamic_pricing_checkout(
      "prod_123abc456def",
      2500,  # $25.00 in cents
      "https://yoursite.com/checkout/success"
  )

  # Example: Create checkout with $10.00 (1000 cents)
  session2 = create_dynamic_pricing_checkout(
      "prod_123abc456def",
      1000,  # $10.00 in cents
      "https://yoursite.com/checkout/success"
  )
  ```
</CodeGroup>

<Note>
  **Amount Format**: `amount` フィールドは通貨の最小単位で指定する必要があります。USDの場合はセント（例: \$25.00 = `2500`）。その他の通貨では最小単位（例: INRではパイサ）を使用してください。
</Note>

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

顧客にチェックアウト中に自身の価格を選択させたい場合は、製品カートから `amount` フィールドを省略するだけです。チェックアウトページには、顧客が設定した最低/最高範囲内の任意の金額を入力できるフィールドが表示されます。

<CodeGroup>
  ```typescript TypeScript theme={null}
  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;
    }
  }
  ```

  ```python Python theme={null}
  def create_customer_choice_checkout(
      product_id: str,
      return_url: str
  ):
      """
      Create a checkout session where customers choose their own price.
      """
      try:
          session = client.checkout_sessions.create(
              product_cart=[
                  {
                      "product_id": product_id,
                      "quantity": 1
                      # No amount field - customer will choose their price
                  }
              ],
              return_url=return_url,
              customer={
                  "email": "customer@example.com",
                  "name": "John Doe"
              }
          )
          
          return session
      except Exception as error:
          print(f"Failed to create checkout session: {error}")
          raise error
  ```
</CodeGroup>

## 一般的なユースケース

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

同じ製品を使用して異なる顧客セグメントに異なる価格を提供します：

```typescript theme={null}
// 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：数量に基づくダイナミックプライシング

購入数量に基づいて価格を調整します：

```typescript theme={null}
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：時間ベースまたはプロモーション価格設定

特定の期間中にプロモーション価格を適用します：

```typescript theme={null}
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;
}
```

## ベストプラクティス

<CardGroup cols={2}>
  <Card title="Set Reasonable Bounds" icon="sliders">
    費用をカバーしつつ手頃な最低価格を選んでください。Suggested Price を使って顧客の期待を誘導しましょう。
  </Card>

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

  <Card title="Track Pricing Decisions" icon="chart-line">
    特定の金額を選択した理由を追跡するためにメタデータを使用します（例: `pricing_tier`、`discount_code`、`user_segment`）。
  </Card>

  <Card title="Handle Edge Cases" icon="exclamation-triangle">
    金額が最大範囲を超えたり最小範囲を下回ったりするケースに対して、アプリケーションが適切に対応するようにしてください。
  </Card>
</CardGroup>

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

常に金額を製品の最小および最大設定と照らし合わせて検証します：

<CodeGroup>
  ```typescript TypeScript theme={null}
  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'
    });
  }
  ```

  ```python Python theme={null}
  def create_validated_checkout(
      product_id: str,
      amount_in_cents: int,
      min_amount: int,
      max_amount: int | None
  ):
      """
      Create a checkout session with amount validation.
      """
      # Validate minimum
      if amount_in_cents < min_amount:
          raise ValueError(
              f"Amount {amount_in_cents} is below minimum {min_amount}"
          )
      
      # Validate maximum (if set)
      if max_amount is not None and amount_in_cents > max_amount:
          raise ValueError(
              f"Amount {amount_in_cents} exceeds maximum {max_amount}"
          )
      
      # Create checkout session
      return client.checkout_sessions.create(
          product_cart=[
              {
                  "product_id": product_id,
                  "quantity": 1,
                  "amount": amount_in_cents
              }
          ],
          return_url="https://yoursite.com/success"
      )
  ```
</CodeGroup>

## APIリファレンス

<CardGroup cols={2}>
  <Card title="Pay What You Want Feature" icon="dollar-sign" href="/features/pay-what-you-want">
    Pay What You Want 価格モデルとその機能について詳しく学んでください。
  </Card>

  <Card title="Checkout Sessions Guide" icon="cart-shopping" href="/developer-resources/checkout-session">
    高度なチェックアウトセッション機能とカスタマイズオプションを探索してください。
  </Card>
</CardGroup>

## トラブルシューティング

<AccordionGroup>
  <Accordion title="Amount is being ignored">
    `amount` フィールドが無視されている場合は、次を確認してください:

    * ダッシュボードで製品に **Pay What You Want** が有効になっている
    * 製品がサブスクリプションではなく **Single Payment**（単発払い）である
    * 金額が正しい形式（通貨の最小単位、例: USD はセント）になっている
  </Accordion>

  <Accordion title="Amount exceeds maximum or is below minimum">
    API は金額が製品の価格範囲に違反するチェックアウトセッションを拒否します。セッション作成前に常に金額を検証するか、`amount` フィールドを省略して顧客に価格を選ばせてください。
  </Accordion>

  <Accordion title="Customer can't enter their own price">
    顧客が価格入力フィールドを見ていない場合は、製品カートから `amount` フィールドを省略していることを確認してください。`amount` が提供されていると、チェックアウトではその金額が正確に使用されます。
  </Accordion>
</AccordionGroup>
