Chuyển đến nội dung chí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
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ý.

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

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

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

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
3

Set pricing type

Chọn Pricing TypeSingle Payment (thanh toán một lần).
4

Enable Pay What You Want

Trong phần Pricing, bật công tắc Pay What You Want.
5

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).
6

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

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

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.
Bạn có thể tìm ID sản phẩm trong bảng điều khiển dưới ProductsView Details, hoặc bằng cách sử dụng List Products API.

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

Ví Dụ Mã

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: 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).

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

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:
// 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:
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ể:
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

Set Reasonable Bounds

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.

Validate Amounts

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.

Track Pricing Decisions

Sử dụng metadata để theo dõi lý do chọn số tiền cụ thể (ví dụ: pricing_tier, discount_code, user_segment).

Handle Edge Cases

Đả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.

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:
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'
  });
}

Tài Liệu API

Khắc Phục Sự Cố

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)
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.
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 đó.