Saltar al contenido principal
El precio dinámico te permite ofrecer precios variables para tus productos sin crear múltiples entradas de productos. Al habilitar Paga lo que Quieras (PWYW) en un solo producto, puedes establecer límites de precio mínimo y máximo, y luego pasar montos dinámicos al crear enlaces de sesión de checkout. Este enfoque es ideal cuando necesitas:
  • Precios variables sin gestionar múltiples productos
  • Precios impulsados por el cliente donde los compradores eligen su monto
  • Control de precios programático donde estableces el monto dinámicamente a través de la API
  • Modelos de precios flexibles para productos digitales, donaciones o lanzamientos experimentales
Pay What You Want solo está disponible para productos de Single Payment (pago único). No se puede usar con productos de suscripción.

Cómo Funciona

Con Paga lo que Quieras habilitado, puedes:
  1. Establece límites de precio: Define un precio mínimo (obligatorio) y, opcionalmente, un precio máximo
  2. Pasa montos dinámicos: Incluye un campo amount en el carrito del producto al crear sesiones de pago
  3. Deja que los clientes elijan: Si no se proporciona un monto, los clientes pueden ingresar su propio precio (dentro de tus límites)
Cuando agregas un amount en el carrito del producto, ese monto se usa para el checkout. Si omites el campo amount, los clientes pueden seleccionar su propio precio durante el checkout (sujeto a tus ajustes de mínimo/máximo).

Paso 1: Crear un Producto con Paga lo que Quieras

Primero, crea un producto de pago único en tu panel de Dodo Payments y habilita el precio de Paga lo que Quieras.
1

Create a new product

Ve a Products en tu panel de Dodo Payments y haz clic en Add Product.
2

Configure product details

Rellena la información obligatoria del producto:
  • Product Name: Nombre que se mostrará del producto
  • Product Description: Descripción clara de lo que los clientes están comprando
  • Product Image: Sube una imagen (PNG/JPG/WebP, hasta 3 MB)
  • Tax Category: Selecciona la categoría tributaria adecuada
3

Set pricing type

Selecciona Pricing Type como Single Payment (pago único).
4

Enable Pay What You Want

En la sección Pricing, activa el interruptor Pay What You Want.
5

Set minimum price

Introduce el Minimum Price que los clientes deben pagar. Esto es obligatorio y garantiza que mantienes un umbral de ingresos.Ejemplo: Si tu mínimo es $5.00, introduce 5.00 (o 500 centavos).
6

Set maximum price (optional)

Opcionalmente, establece un Maximum Price para limitar el monto que los clientes pueden pagar.
7

Set suggested price (optional)

Opcionalmente, introduce un Suggested Price que se mostrará para guiar a los clientes. Esto ayuda a anclar expectativas y puede mejorar el valor promedio del pedido.
8

Save the product

Haz clic en Add Product para guardar. Anota tu ID de producto (p. ej., pdt_123abc456def) para usarlo en las sesiones de pago.
Puedes encontrar tu ID de producto en el panel bajo ProductsView Details, o usando la List Products API.

Paso 2: Crear Sesiones de Checkout con Precios Dinámicos

Una vez que tu producto esté configurado con Pay What You Want, puedes crear sesiones de pago con montos dinámicos. El campo amount en el carrito del producto te permite establecer el precio programáticamente para cada sesión de pago.

Entendiendo el Campo de Monto

Al crear una sesión de pago, puedes incluir un campo amount en cada artículo del carrito del producto:
  • Si amount está proporcionado: El checkout usa este monto exacto (debe estar dentro de tus límites de mínimo/máximo)
  • Si se omite amount: Los clientes pueden ingresar su propio precio durante el checkout (dentro de tus límites)
El campo amount solo aplica para productos Pay What You Want. Para productos regulares, este campo se ignora.

Ejemplos de Código

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'
);
Formato del monto: El campo amount debe estar en la denominación más baja de la moneda. Para USD, esto significa centavos (p. ej., $25.00 = 2500). Para otras monedas, usa la unidad más pequeña (por ejemplo, paise para INR).

Paso 3: Dejar que los Clientes Elijan su Precio

Si deseas que los clientes seleccionen su propio precio durante el checkout, omite el campo amount del carrito del producto. La página de checkout mostrará un campo donde los clientes pueden ingresar cualquier monto dentro de tus límites mínimo y máximo.
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;
  }
}

Casos de Uso Comunes

Caso de Uso 1: Precios por Niveles Basados en el Tipo de Usuario

Ofrece diferentes precios a diferentes segmentos de clientes utilizando el mismo producto:
// 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'
);

Caso de Uso 2: Precios Dinámicos Basados en la Cantidad

Ajusta el precio según la cantidad comprada:
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;
}

Caso de Uso 3: Precios Basados en el Tiempo o Promocionales

Aplica precios promocionales durante períodos específicos:
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;
}

Mejores Prácticas

Set Reasonable Bounds

Elige un precio mínimo que cubra tus costos sin dejar de ser accesible. Usa un precio sugerido para orientar las expectativas del cliente.

Validate Amounts

Siempre valida que los montos dinámicos estén dentro de los límites mínimo y máximo de tu producto antes de crear sesiones de pago.

Track Pricing Decisions

Usa metadata para rastrear por qué se eligieron montos específicos (por ejemplo, pricing_tier, discount_code, user_segment).

Handle Edge Cases

Asegúrate de que tu aplicación maneje con elegancia los casos en los que los montos superan los límites máximos o caen por debajo de los mínimos.

Validación y Manejo de Errores

Siempre valida los montos contra las configuraciones mínimas y máximas de tu producto:
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'
  });
}

Referencia de API

Solución de Problemas

Si tu campo amount está siendo ignorado, verifica que:
  • El producto tenga habilitado Pay What You Want en el panel
  • El producto sea de Single Payment (pago único), no una suscripción
  • El monto esté en el formato correcto (denominación más baja de la moneda, p. ej., centavos para USD)
La API rechazará sesiones de pago donde el monto viole los límites de precio de tu producto. Siempre valida los montos antes de crear sesiones, o deja que los clientes elijan su precio omitiendo el campo amount.
Si los clientes no ven el campo de entrada de precio, asegúrate de haber omitido el campo amount del carrito del producto. Cuando amount está proporcionado, el checkout usa ese monto exacto.