> ## 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.

# Thanh Toán Giá Động với Pay What You Want

> Tạo các liên kết thanh toán linh hoạt với giá biến đổi bằng cách sử dụng một sản phẩm duy nhất. Bật Pay What You Want để cho phép khách hàng chọn giá của họ hoặc thiết lập các khoản tiền động một cách lập trình.

**Giá động** cho phép bạn cung cấp giá biến đổi cho các sản phẩm của mình mà không cần tạo nhiều mục sản phẩm. Bằng cách bật **Pay What You Want (PWYW)** trên một sản phẩm duy nhất, bạn có thể thiết lập các giới hạn giá tối thiểu và tối đa, sau đó truyền các khoản tiền động khi tạo các liên kết phiên thanh toán.

Cách tiếp cận này lý tưởng khi bạn cần:

* **Giá biến đổi** mà không cần quản lý nhiều sản phẩm
* **Giá do khách hàng quyết định** nơi người mua chọn số tiền của họ
* **Kiểm soát giá lập trình** nơi bạn thiết lập số tiền một cách động qua API
* **Mô hình giá linh hoạt** cho các sản phẩm kỹ thuật số, quyên góp hoặc các buổi ra mắt thử nghiệm

<Warning>
  Pay What You Want chỉ khả dụng cho các sản phẩm **Single Payment** (thanh toán một lần). Không thể sử dụng với sản phẩm đăng ký.
</Warning>

## Cách Hoạt Động

Với Pay What You Want được bật, bạn có thể:

1. **Set price bounds**: Xác định một mức giá tối thiểu (bắt buộc) và tùy chọn mức giá tối đa
2. **Pass dynamic amounts**: Bao gồm một trường `amount` trong giỏ hàng sản phẩm khi tạo phiên thanh toán
3. **Let customers choose**: Nếu không cung cấp số tiền, khách hàng có thể nhập giá của riêng họ (trong giới hạn của bạn)

<Info>
  Khi bạn cung cấp một `amount` trong giỏ hàng sản phẩm, số tiền đó sẽ được sử dụng cho thanh toán. Nếu bạn bỏ qua trường `amount`, khách hàng có thể chọn mức giá riêng của họ trong quá trình thanh toán (theo giới hạn tối thiểu/tối đa của bạn).
</Info>

## Bước 1: Tạo Sản Phẩm với Pay What You Want

Đầu tiên, tạo một sản phẩm một lần trong bảng điều khiển Dodo Payments của bạn và bật giá Pay What You Want.

<Steps>
  <Step title="Create a new product">
    Đi tới **Products** trong bảng điều khiển Dodo Payments của bạn và nhấp vào **Add Product**.
  </Step>

  <Step title="Configure product details">
    Điền thông tin sản phẩm bắt buộc:

    * **Product Name**: Tên hiển thị cho sản phẩm của bạn
    * **Product Description**: Mô tả rõ ràng về những gì khách hàng đang mua
    * **Product Image**: Tải lên hình ảnh (PNG/JPG/WebP, tối đa 3 MB)
    * **Tax Category**: Chọn danh mục thuế phù hợp
  </Step>

  <Step title="Set pricing type">
    Chọn **Pricing Type** là **Single Payment** (thanh toán một lần).
  </Step>

  <Step title="Enable Pay What You Want">
    Trong phần **Pricing**, bật công tắc **Pay What You Want**.
  </Step>

  <Step title="Set minimum price">
    Nhập **Minimum Price** mà khách hàng phải trả. Đây là bắt buộc và đảm bảo bạn duy trì mức doanh thu tối thiểu.

    **Example**: Nếu mức tối thiểu của bạn là \$5.00, hãy nhập `5.00` (hoặc `500` cent).
  </Step>

  <Step title="Set maximum price (optional)">
    Bạn có thể tùy chọn đặt **Maximum Price** để giới hạn số tiền khách hàng có thể trả.
  </Step>

  <Step title="Set suggested price (optional)">
    Bạn có thể nhập **Suggested Price** để hiển thị như một gợi ý cho khách hàng. Điều này giúp định hình kỳ vọng và có thể cải thiện giá trị đơn hàng trung bình.
  </Step>

  <Step title="Save the product">
    Nhấp **Add Product** để lưu. Ghi chú ID sản phẩm của bạn (ví dụ: `pdt_123abc456def`) để sử dụng trong các phiên thanh toán.
  </Step>
</Steps>

<Tip>
  Bạn có thể tìm ID sản phẩm trong bảng điều khiển dưới **Products** → **View Details**, hoặc bằng cách sử dụng [List Products API](/api-reference/products/get-products).
</Tip>

## Bước 2: Tạo Các Phiên Thanh Toán với Giá Động

Sau khi sản phẩm của bạn được cấu hình với Pay What You Want, bạn có thể tạo các phiên thanh toán với số tiền động. Trường `amount` trong giỏ hàng sản phẩm cho phép bạn đặt giá theo chương trình cho mỗi phiên thanh toán.

### Hiểu Về Trường Số Tiền

Khi tạo phiên thanh toán, bạn có thể bao gồm một trường `amount` trong mỗi mục giỏ hàng sản phẩm:

* **Nếu `amount` được cung cấp**: Thanh toán sẽ sử dụng đúng số tiền này (phải nằm trong giới hạn tối thiểu/tối đa của bạn)
* **Nếu `amount` bị bỏ qua**: Khách hàng có thể nhập mức giá tùy ý trong quá trình thanh toán (trong giới hạn của bạn)

<Warning>
  Trường `amount` chỉ áp dụng cho sản phẩm Pay What You Want. Đối với sản phẩm thông thường, trường này sẽ bị bỏ qua.
</Warning>

### Ví Dụ Mã

<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**: Trường `amount` phải được biểu diễn bằng đơn vị nhỏ nhất của tiền tệ. Với USD, điều này có nghĩa là cents (ví dụ: \$25.00 = `2500`). Với các loại tiền khác, hãy dùng đơn vị nhỏ nhất (ví dụ: paise cho INR).
</Note>

## Bước 3: Cho Khách Hàng Chọn Giá Của Họ

Nếu bạn muốn khách hàng tự chọn giá trong quá trình thanh toán, chỉ cần bỏ trường `amount` khỏi giỏ hàng sản phẩm. Trang thanh toán sẽ hiển thị một ô nhập liệu để khách hàng có thể nhập bất kỳ số tiền nào trong khoảng tối thiểu và tối đa của bạn.

<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>

## Các Trường Hợp Sử Dụng Thông Thường

### Trường Hợp Sử Dụng 1: Giá Theo Bậc Dựa Trên Loại Người Dùng

Cung cấp các mức giá khác nhau cho các phân khúc khách hàng khác nhau bằng cách sử dụng cùng một sản phẩm:

```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'
);
```

### Trường Hợp Sử Dụng 2: Giá Động Dựa Trên Số Lượng

Điều chỉnh giá dựa trên số lượng đã mua:

```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;
}
```

### Trường Hợp Sử Dụng 3: Giá Dựa Trên Thời Gian Hoặc Khuyến Mãi

Áp dụng giá khuyến mãi trong các khoảng thời gian cụ thể:

```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;
}
```

## Các Thực Hành Tốt Nhất

<CardGroup cols={2}>
  <Card title="Set Reasonable Bounds" icon="sliders">
    Hãy chọn một mức giá tối thiểu đủ để trang trải chi phí của bạn trong khi vẫn giữ được sự tiếp cận. Sử dụng mức giá gợi ý để hướng dẫn kỳ vọng của khách hàng.
  </Card>

  <Card title="Validate Amounts" icon="shield-check">
    Luôn xác thực rằng các số tiền động nằm trong giới hạn tối thiểu và tối đa của sản phẩm trước khi tạo các phiên thanh toán.
  </Card>

  <Card title="Track Pricing Decisions" icon="chart-line">
    Sử dụng metadata để theo dõi lý do chọn số tiền cụ thể (ví dụ: `pricing_tier`, `discount_code`, `user_segment`).
  </Card>

  <Card title="Handle Edge Cases" icon="exclamation-triangle">
    Đảm bảo ứng dụng của bạn xử lý mượt mà các trường hợp số tiền vượt quá giới hạn tối đa hoặc thấp hơn giới hạn tối thiểu.
  </Card>
</CardGroup>

## Xác Thực và Xử Lý Lỗi

Luôn xác thực các khoản tiền so với các cài đặt tối thiểu và tối đa của sản phẩm của bạn:

<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>

## Tài Liệu API

<CardGroup cols={2}>
  <Card title="Pay What You Want Feature" icon="dollar-sign" href="/features/pay-what-you-want">
    Tìm hiểu thêm về mô hình định giá Pay What You Want và những khả năng của nó.
  </Card>

  <Card title="Checkout Sessions Guide" icon="cart-shopping" href="/developer-resources/checkout-session">
    Khám phá các tính năng phiên thanh toán nâng cao và các tùy chọn tùy chỉnh.
  </Card>
</CardGroup>

## Khắc Phục Sự Cố

<AccordionGroup>
  <Accordion title="Amount is being ignored">
    Nếu trường `amount` của bạn bị bỏ qua, hãy kiểm tra:

    * Sản phẩm đã bật **Pay What You Want** trong bảng điều khiển
    * Sản phẩm là **Single Payment** (thanh toán một lần), không phải đăng ký
    * Số tiền có định dạng đúng (đơn vị nhỏ nhất của tiền tệ, ví dụ cents cho USD)
  </Accordion>

  <Accordion title="Amount exceeds maximum or is below minimum">
    API sẽ từ chối các phiên thanh toán nếu số tiền vi phạm giới hạn giá của sản phẩm. Luôn xác thực các số tiền trước khi tạo phiên thanh toán, hoặc để khách hàng tự chọn giá bằng cách bỏ trường `amount`.
  </Accordion>

  <Accordion title="Customer can't enter their own price">
    Nếu khách hàng không thấy ô nhập giá, hãy đảm bảo bạn đã bỏ trường `amount` khỏi giỏ hàng sản phẩm. Khi `amount` được cung cấp, thanh toán sẽ sử dụng đúng số tiền đó.
  </Accordion>
</AccordionGroup>
