Saltar al contenido principal
En este tutorial, aprenderás a implementar precios por asiento utilizando los complementos de Dodo Payments. Crearemos un producto de suscripción con complementos para asientos adicionales y te mostraremos cómo generar enlaces de pago con cantidades de complementos personalizadas.
Este tutorial proporciona código de implementación de ejemplo para una aplicación Node.js/Express. Puedes modificar este código para tu marco específico (Next.js, React, Vue, etc.) y personalizar la interfaz de usuario según las necesidades de tu aplicación.
Al final de este tutorial, sabrás cómo:
  • Crear productos de suscripción con precios por asiento
  • Configurar complementos para asientos adicionales
  • Generar enlaces de pago con cantidades de complementos personalizadas
  • Manejar sesiones de pago con conteos de asientos dinámicos

Lo que Estamos Construyendo

Vamos a crear un modelo de precios por asiento:
  • Plan Base: $49/mes para hasta 5 miembros del equipo
  • Complemento por Asiento: $2/mes por asiento adicional
  • Enlaces de Pago: Pago dinámico con cantidades de asientos personalizadas
Antes de comenzar, asegúrate de tener:
  • Una cuenta de Dodo Payments
  • Familiaridad básica con TypeScript/Node.js

Paso 1: Crea Tu Complemento de Asiento

Ahora necesitamos crear un complemento que represente asientos adicionales. Este complemento se adjuntará a nuestra suscripción base y permitirá a los clientes comprar asientos adicionales.
Creando producto de suscripción base
Lo que estamos construyendo: Un complemento que cuesta $2/mes por asiento y se puede agregar a cualquier suscripción base.
1

Navegar a Complementos

  1. En tu panel de Dodo Payments, permanece en la sección Productos
  2. Haz clic en la pestaña Complementos
  3. Haz clic en Crear Complemento
Esto abrirá el formulario de creación de complementos.
2

Ingresa los detalles del complemento

Completa estos valores para nuestro complemento de asiento:Nombre del Complemento: Additional Team SeatDescripción: Add extra team members to your workspace with full access to all featuresPrecio: Ingresa → 2.00Moneda: Debe coincidir con la moneda de tu suscripción baseCategoría de Impuestos: Selecciona la categoría apropiada para tu producto.
3

Guarda tu complemento

  1. Revisa todos tus ajustes:
    • Nombre: Asiento Adicional para el Equipo
    • Precio: $2.00/mes
  2. Haz clic en Crear Complemento
¡Complemento creado! Tu complemento de asiento ahora está disponible para adjuntarse a las suscripciones.

Paso 2: Crea Tu Producto de Suscripción Base

Comenzaremos creando un producto de suscripción base que incluya 5 miembros del equipo. Esta será la base de nuestro modelo de precios por asiento.
Creando producto de suscripción base
1

Navegar a Productos

  1. Inicia sesión en tu panel de Dodo Payments
  2. Haz clic en Productos en la barra lateral izquierda
  3. Haz clic en el botón Crear Producto
  4. Selecciona Suscripción como tipo de producto
Deberías ver un formulario donde configuraremos nuestra suscripción base.
2

Completa los detalles de la suscripción

Ahora ingresaremos los detalles específicos para nuestro plan base:Nombre del Producto: MotionDescripción: Where your team's documentation lives.Precio Recurrente: Ingresa → 49.00Ciclo de Facturación: Selecciona → MonthlyMoneda: Selecciona tu moneda preferida (por ejemplo, USD)

Paso 3: Conectar el Complemento a la Suscripción

Ahora necesitamos asociar nuestro complemento de asiento con la suscripción base para que los clientes puedan comprar asientos adicionales durante el pago.
1

Adjuntar el complemento de asiento

Adjuntando complemento a la suscripción
  1. Desplázate hacia abajo hasta la sección Complementos
  2. Haz clic en Agregar Complementos
  3. Desde el menú desplegable, selecciona tu complemento de asiento
  4. Confirma que aparece en la configuración de tu suscripción
2

Guarda los cambios de la suscripción

  1. Revisa la configuración completa de tu suscripción:
    • Plan base: $49/mes por 5 asientos
    • Complemento: $2/mes por asiento adicional
    • Prueba gratuita: 14 días
  2. Haz clic en Guardar Cambios
¡Precios por asiento configurados! Los clientes ahora pueden comprar tu plan base y agregar asientos adicionales según sea necesario.

Paso 4: Generar Enlaces de Pago con Cantidades de Complementos Personalizadas

Ahora vamos a crear una aplicación Express.js que genere enlaces de pago con cantidades de complementos personalizadas. Aquí es donde entra el verdadero poder de los precios por asiento: puedes crear dinámicamente sesiones de pago con cualquier número de asientos adicionales.
1

Configura tu proyecto

Crea un nuevo proyecto de Node.js e instala las dependencias requeridas:
mkdir seat-based-pricing
cd seat-based-pricing
npm init -y
npm install dodopayments express dotenv
npm install -D @types/node @types/express typescript ts-node
Crea un archivo tsconfig.json:
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}
2

Crea tu archivo de entorno

Crea un archivo .env con tu clave API de Dodo Payments:
DODO_PAYMENTS_API_KEY=your_actual_dodo_api_key_here
Nunca cometas tu clave API en el control de versiones. Agrega .env a tu archivo .gitignore.
3

Implementa la creación de la sesión de pago

Crea un archivo src/server.ts con el siguiente código:
// Add this new endpoint for dynamic seat quantities
import 'dotenv/config';
import DodoPayments from 'dodopayments';
import express, { Request, Response } from 'express';

const app = express();

// Initialize the Dodo Payments client
const client = new DodoPayments({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: 'test_mode'
});

async function createCheckoutSession(seatCount: number) {
  try {
    const session = await client.checkoutSessions.create({
      // Products to sell - use IDs from your Dodo Payments dashboard
      product_cart: [
        {
          product_id: 'pdt_7Rl9OWT2Mz4wwUTKz74iZ', // Replace with your actual product ID
          quantity: 1,
          addons: [
            {
              addon_id: 'adn_eKQbNakKrivDpaxmI8wKI', // Replace with your actual addon ID
              quantity: seatCount
            }
          ]
        }
      ],
      
      // Pre-fill customer information to reduce friction
      customer: {
        email: '[email protected]',
        name: 'Steve Irwin',
      },
      // Where to redirect after successful payment
      return_url: 'https://example.com/checkout/success',
    });

    // Redirect your customer to this URL to complete payment
    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 usage in an Express.js route
app.post('/create-checkout/:seatCount', async (req: Request, res: Response) => {
  try {
    const seatCount = parseInt(req.params.seatCount);
    const session = await createCheckoutSession(seatCount);
    res.json({ checkout_url: session.checkout_url });
  } catch (error) {
    res.status(500).json({ error: 'Failed to create checkout session' });
  }
});

// Add this line after your other middleware
app.use(express.static('public'));

// Add this route to serve the demo page
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/../public/index.html');
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});
4

Agrega una interfaz web simple

Crea un archivo public/index.html para facilitar las pruebas:
<!DOCTYPE html>
<html>
<head>
    <title>Seat-Based Pricing Demo</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
        .form-group { margin: 20px 0; }
        label { display: block; margin-bottom: 5px; font-weight: bold; }
        input { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; }
        button { background: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; }
        button:hover { background: #0056b3; }
        .result { margin-top: 20px; padding: 15px; background: #f8f9fa; border-radius: 4px; }
    </style>
</head>
<body>
    <h1>Seat-Based Pricing Demo</h1>
    <p>Generate checkout links with custom seat quantities:</p>
    
    <div class="form-group">
        <label for="seatCount">Number of Additional Seats:</label>
        <input type="number" id="seatCount" value="3" min="0" max="50">
    </div>
    
    <button onclick="createCheckout()">Generate Checkout Link</button>
    
    <div id="result" class="result" style="display: none;">
        <h3>Checkout Link Generated!</h3>
        <p><strong>Seat Count:</strong> <span id="seatCountDisplay"></span></p>
        <p><strong>Total Cost:</strong> $<span id="totalCost"></span>/month</p>
        <p><strong>Checkout URL:</strong></p>
        <a id="checkoutUrl" href="#" target="_blank">Click here to checkout</a>
    </div>

    <script>
        async function createCheckout() {
            const seatCount = document.getElementById('seatCount').value;
            
            try {
                const response = await fetch(`/create-checkout/${seatCount}`, {
                    method: 'POST'
                });
                
                const data = await response.json();
                
                if (response.ok) {
                    document.getElementById('seatCountDisplay').textContent = seatCount;
                    document.getElementById('totalCost').textContent = data.total_cost;
                    document.getElementById('checkoutUrl').href = data.checkout_url;
                    document.getElementById('result').style.display = 'block';
                } else {
                    alert('Error: ' + data.error);
                }
            } catch (error) {
                alert('Error creating checkout session');
            }
        }
    </script>
</body>
</html>
¡Interfaz web creada! Ahora tienes una interfaz simple para probar diferentes cantidades de asientos.
5

Sirve archivos estáticos

Agrega esto a tu src/server.ts para servir el archivo HTML:
// Add this line after your other middleware
app.use(express.static('public'));

// Add this route to serve the demo page
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/../public/index.html');
});
¡Archivos estáticos configurados! Visita http://localhost:3000 para ver tu interfaz de demostración.

Paso 5: Prueba Tu Implementación

Probemos nuestra implementación de precios por asiento para asegurarnos de que todo funcione correctamente.
1

Inicia tu servidor

  1. Asegúrate de tener tu archivo .env con la clave API correcta
  2. Actualiza los IDs de producto y complemento en tu código con los valores reales de tu panel de Dodo Payments
  3. Inicia tu servidor:
npm run dev
Tu servidor debería iniciarse correctamente y mostrar “Servidor en ejecución en http://localhost:3000
2

Prueba la interfaz web

Creando producto de suscripción base
  1. Abre tu navegador y ve a http://localhost:3000
  2. Deberías ver la interfaz de demostración de precios por asiento
  3. Prueba diferentes cantidades de asientos (0, 3, 10, etc.)
  4. Haz clic en “Generar Enlace de Pago” para cada cantidad
  5. Verifica que las URL de pago se generen correctamente
3

Prueba una sesión de pago

  1. Genera un enlace de pago con 3 asientos adicionales
  2. Haz clic en la URL de pago para abrir el pago de Dodo Payments
  3. Verifica que el pago muestre:
    • Plan base: $49/mes
    • Asientos adicionales: 3 × 2 dólares = $6/mes
  4. Completa la compra de prueba
El pago debería mostrar el desglose de precios correcto y permitirte completar la compra.
4

Escucha los webhooks y actualiza tu base de datos

Para mantener tu base de datos sincronizada con los cambios de suscripción y asientos, necesitas escuchar los eventos de webhook de Dodo Payments. Los webhooks notifican a tu backend cuando un cliente completa el pago, actualiza su suscripción o cambia la cantidad de asientos.Sigue la guía oficial de webhooks de Dodo Payments para obtener instrucciones paso a paso sobre cómo configurar los puntos finales de webhook y manejar eventos:

Documentación de Webhooks de Dodo Payments

Aprende cómo recibir y procesar de manera segura eventos de webhook para la gestión de suscripciones y asientos.

Solución de Problemas

Problemas comunes y sus soluciones:
Causas posibles:
  • ID de producto o ID de complemento inválido
  • La clave API no tiene permisos suficientes
  • Complemento no asociado correctamente con la suscripción
  • Problemas de conectividad de red
Soluciones:
  1. Verifica que los IDs de producto y complemento existan en tu panel de Dodo Payments
  2. Asegúrate de que el complemento esté correctamente adjunto a la suscripción
  3. Asegúrate de que la clave API tenga permisos para crear sesiones de pago
  4. Prueba la conectividad de la API con una simple solicitud GET

¡Felicidades! Has Implementado Precios por Asiento

¡Has creado con éxito un sistema de precios por asiento con Dodo Payments! Esto es lo que lograste:

Suscripción Base

Creado un producto de suscripción con 5 asientos incluidos a $49/mes

Complementos por Asiento

Configurados complementos para asientos adicionales a $2/mes por asiento

Pago

Construida una API que genera sesiones de pago con cantidades de asientos personalizadas

Interfaz Web

Creada una interfaz web simple para probar diferentes cantidades de asientos
Este ejemplo demuestra solo una implementación mínima de precios por asiento. Para uso en producción, deberías agregar un manejo de errores robusto, autenticación, validación de datos, medidas de seguridad y adaptar la lógica para ajustarse a los requisitos de tu aplicación.