Skip to main content
Deja que Sentra escriba tu código de integración por ti.
Usa nuestro asistente de IA en VS Code, Cursor o Windsurf para generar código de SDK/API, manejadores de webhooks y mucho más, simplemente describiendo lo que necesitas.
Prueba Sentra: integración con IA →
En este tutorial crearás MailKit, una plataforma de correo electrónico transaccional en la que los clientes pagan por adelantado por un conjunto de créditos de correo. El plan concede una cantidad mensual de correos; cuando a los clientes les quedan pocos, pueden comprar un paquete de recarga en lugar de esperar al siguiente ciclo. Cada envío descuenta automáticamente un crédito.
En este tutorial se usa Resend como proveedor de correo electrónico. Su nivel gratuito (3.000 correos al mes) es suficiente para crear y probar todo el flujo sin una cuenta de pago. El patrón funciona con cualquier proveedor; sustituye resend.emails.send por SendGrid, Postmark, SES o tu propio relay SMTP.
Al finalizar este tutorial, sabrás cómo:
  • Crear un entitlement de crédito personalizado (correos) en tu dashboard
  • Asociar créditos a un plan de suscripción y a un producto de recarga único
  • Enviar correos reales mediante Resend y descontar un crédito por envío mediante una entrada del ledger
  • Consultar un saldo de créditos activo desde tu frontend
  • Verificar correctamente los webhooks de Dodo y gestionar credit.balance_low para avisar a los clientes antes de que lleguen a cero

Lo que vamos a crear

Este es el modelo de precios de MailKit: La unidad es un correo = un crédito. Los clientes no tienen que pensar en tokens, lotes ni unidades ponderadas. Solo ven «te quedan 4.231 correos este mes».
Antes de empezar, asegúrate de tener:
  • Una cuenta de Dodo Payments (el modo de prueba es suficiente)
  • Una cuenta gratuita de Resend y una API key
  • Node.js 18 o posterior y conocimientos básicos de TypeScript

Paso 1: Crea tu entitlement de créditos de correo

El entitlement de crédito define la unidad que vende tu plataforma: en este caso, un envío de correo.
Credits listing page

The Credits tab under Products lists all your credit entitlements.

1

Open the Credits section

  1. Inicia sesión en tu dashboard de Dodo Payments
  2. Haz clic en Products en la barra lateral izquierda
  3. Selecciona la pestaña Credits
  4. Haz clic en Create Credit
2

Configure the credit unit

Completa los detalles del crédito:Credit Name: Email CreditsCredit Type: Selecciona Custom UnitUnit Name: emailPrecision: 0 (un correo siempre es una unidad completa; no puedes enviar medio correo)Credit Expiry: 30 days (la cantidad asignada de cada ciclo se restablece)
La precisión no se puede cambiar después de la creación. Para unidades discretas como correos, mensajes o sesiones, 0 es la opción correcta.
3

Leave the other defaults as-is

No habilitaremos el rollover ni el overage en este cookbook; el objetivo es crear el flujo de CBB más sencillo posible. Puedes revisar estas opciones más adelante, al asociar el crédito.
4

Save and copy the credit ID

Haz clic en Create Credit. Abre el crédito y copia su ID. Lo necesitarás para las consultas de saldo del backend. Tiene un formato similar a cent_xxxxxxxxxxxx.
Tu entitlement Email Credits está listo. A continuación: los productos que conceden créditos a los clientes.

Paso 2: Crea el plan y el paquete de recarga

Crearás dos productos: un plan de Subscription recurrente y una recarga de Single Payment. El plan concede 5.000 correos en cada ciclo; la recarga añade otros 5.000 bajo demanda. Ambos asocian el mismo entitlement Email Credits.
Este cookbook descuenta créditos mediante entradas directas del ledger en lugar de meters basados en el uso. Las entradas del ledger son inmediatas (el saldo se actualiza en milisegundos), no requieren configuración adicional y son adecuadas cuando una acción del usuario equivale exactamente a un crédito. Si prefieres la deducción automática a partir de eventos de uso ingeridos (útil para unidades ponderadas como «tokens» o «MB procesados»), consulta Credit-Based Billing → Usage Billing with Credits para ver el patrón basado en meters.

Plan MailKit (19 $/mes, 5.000 correos)

1

Create the subscription

  1. Ve a Products → Create Product
  2. Completa los detalles del producto:
Product Name: MailKit PlanDescription: 5,000 transactional emails per month.
  1. Selecciona Subscription como tipo de producto
  2. Establece el precio recurrente:
Recurring Price: 19.00Billing Cycle: MonthlyCurrency: USD
2

Attach the email credit entitlement

Desplázate hasta Entitlements → Credits → Attach y configura lo siguiente:Credit Entitlement: Email CreditsCredits issued per billing cycle: 5000Low Balance Threshold: 20 (porcentaje; activa credit.balance_low cuando el saldo cae por debajo del 20 % de la cantidad asignada en el ciclo, es decir, 1.000 correos)Import Default Credit Settings: habilitado (usa la caducidad de 30 días del paso 1)Haz clic en Add to Product y, después, en Save para guardar el producto. Copia el ID del producto (pdt_xxxxxxxxxxxx).
Plan: 19 $/mes → 5.000 correos renovados en cada ciclo.

Paquete de recarga (9 $ por única vez, 5.000 correos)

1

Create a one-time product

  1. Ve a Products → Create Product
  2. Completa los detalles del producto:
Product Name: Email Top-Up PackDescription: Add 5,000 emails to your MailKit balance instantly.
  1. Selecciona Single Payment como tipo de producto
  2. Establece el precio:
Price: 9.00Currency: USD
2

Attach the credit grant

En Entitlements → Credits → Attach:
  • Credit Entitlement: Email Credits
  • Credits issued: 5000
Los productos únicos conceden créditos con su propia caducidad (30 días desde la compra, según el paso 1). Las recargas se acumulan sobre los créditos de la suscripción; no los reemplazan.
Guarda y copia el ID del producto.
Paquete de recarga: 9 $ → +5.000 correos, disponibles inmediatamente.

Paso 3: Configura el backend

Ahora crea el servidor Express que gestionará el checkout, los envíos, las consultas de saldo y los webhooks.
1

Initialize the project

Añade un script de desarrollo a package.json:
tsx ejecuta TypeScript directamente sin un paso de compilación ni tsconfig.json, lo que resulta perfecto para un tutorial. En producción, añade un tsconfig.json y un script build.
2

Configure environment variables

Crea .env:
.env
Completarás DODO_WEBHOOK_KEY en el paso 4, después de crear el endpoint. La API key de Resend se obtiene en resend.com/api-keys.
Añade .env a .gitignore inmediatamente. No confirmes las API keys en el repositorio.
3

Build the server

Crea server.ts en la raíz del proyecto:
El cuerpo del webhook debe ser raw. express.json() analiza y vuelve a serializar el cuerpo, lo que rompe la verificación de la firma. Define /webhooks/dodo con express.raw() antes de la línea app.use(express.json()).
Backend listo: suscripción, recarga, saldo, envío y manejador de webhooks conectados.
4

Add a demo UI

Crea public/index.html:

Paso 4: Conecta el endpoint del webhook

El evento credit.balance_low permite avisar a los clientes antes de que se queden sin créditos. Sin él, se darán cuenta del problema por primera vez cuando un correo no pueda enviarse.
1

Expose your local server

Los webhooks necesitan una URL pública. Usa ngrok (o cualquier túnel) durante el desarrollo:
Copia la URL de reenvío HTTPS (por ejemplo, https://1234abcd.ngrok-free.app).
2

Register the endpoint in Dodo

  1. Ve a Developers → Webhooks → Add Endpoint
  2. URL: https://1234abcd.ngrok-free.app/webhooks/dodo
  3. Events: suscríbete a credit.added, credit.balance_low y credit.rolled_over
  4. Guarda y copia la signing key en tu .env como DODO_WEBHOOK_KEY
  5. Reinicia el servidor

Paso 5: Prueba el flujo completo

1

Start the server

Deberías ver MailKit running on http://localhost:3000. Ábrelo en tu navegador.
2

Subscribe a test customer

  1. En la sección 1, introduce un correo de prueba y un nombre, y haz clic en Get checkout link
  2. Abre el enlace y completa el checkout con una tarjeta de prueba
  3. Después del pago, busca customer_id en tu dashboard, dentro de Customers
El cliente debería tener ahora 5.000 correos en su saldo. Compruébalo en Customers → [Customer] → Credits.
3

Send a real email

  1. Pega customer_id en la sección 3
  2. Deja to establecido en delivered@resend.dev (la bandeja de entrada de pruebas de Resend que acepta todo)
  3. Haz clic en Send
Recibirás el ID del mensaje de Resend. Actualiza el saldo en la sección 2 y la cantidad bajará inmediatamente a 4.999. Cada débito del ledger se refleja en el saldo activo en el momento en que se registra.
4

Trigger the low-balance webhook

El umbral es del 20 % (1.000 de los 5.000 correos asignados). Para activarlo sin enviar 4.000 correos reales, debita manualmente el saldo desde el dashboard:
  1. Ve a Customers → [Customer] → Credits → Email Credits
  2. Haz clic en Adjust Balance y debita 4000
  3. Envía un correo más mediante la demo
Tu servidor debería registrar lo siguiente en unos segundos:
Tu servidor recibió y verificó el webhook. En producción, aquí enviarías un correo al cliente o mostrarías un banner dentro de la aplicación.
5

Buy a top-up pack

  1. Pega customer_id en la sección 4
  2. Haz clic en Buy 5,000 emails y completa el checkout de prueba
  3. Actualiza el saldo: aumentará en 5.000
Se activa un evento credit.added con grant_source: one_time. La recarga se acumula sobre los créditos de la suscripción; ambos grupos se consumen en orden FIFO (primero se utiliza la asignación no caducada más antigua).
6

Test the hard stop

Debita manualmente el saldo hasta cero y, después, intenta enviar otro correo. Obtendrás:
Ese 402 es la aplicación de la lógica de enforcement de tu aplicación. La API de saldo de Dodo es la fuente de verdad; nunca la almacenes en caché en el cliente.

Solución de problemas

La firma se calcula sobre el cuerpo HTTP raw. express.json() analiza y vuelve a serializar el payload, lo que rompe el HMAC. Asegúrate de que /webhooks/dodo esté registrado con express.raw({ type: 'application/json' }) por encima de la línea app.use(express.json()) y de que DODO_WEBHOOK_KEY coincida con la signing key que aparece en la página de detalles del endpoint.
Comprueba estas tres cosas, en este orden:
  1. El cliente completó el checkout (los créditos se conceden cuando el pago se realiza correctamente, no al crear la sesión)
  2. CREDIT_ENTITLEMENT_ID en tu .env coincide con el crédito asociado al producto (los ID que no coinciden escriben silenciosamente en el crédito equivocado)
  3. customer_id que estás pasando procede de Dodo (la tabla customers del dashboard), no de tu propia base de datos
El remitente de pruebas onboarding@resend.dev solo envía al correo de tu cuenta de Resend o a delivered@resend.dev. Para enviar a cualquier otra persona, verifica un dominio y usa una dirección from en él.

Lo que has creado

One reusable credit unit

Email Credits, definido una sola vez y asociado tanto al plan de suscripción como al paquete de recarga.

Subscription with prepaid allowance

19 $/mes concede 5.000 correos por ciclo. Los clientes saben por qué pagan y tú conoces tu coste máximo.

Top-up pack

Un producto único que concede 5.000 correos. Se acumula sobre los créditos de la suscripción sin necesidad de cambiar de plan.

Instant ledger debits

Una única llamada createLedgerEntry después de cada envío. Sin meter ni retraso de agregación; es idempotente al reintentarse mediante el ID del mensaje de Resend.

Credit-Based Billing Reference

Consulta la documentación completa de CBB para obtener información sobre rollover, modos de overage, gestión del ledger y toda la API.
¿Necesitas ayuda?
Última modificación el 31 de julio de 2026