resend.emails.send por SendGrid, Postmark, SES o tu propio relay SMTP.- 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_lowpara avisar a los clientes antes de que lleguen a cero
Lo que vamos a crear
Este es el modelo de precios de MailKit:- 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.
The Credits tab under Products lists all your credit entitlements.
Open the Credits section
- Inicia sesión en tu dashboard de Dodo Payments
- Haz clic en Products en la barra lateral izquierda
- Selecciona la pestaña Credits
- Haz clic en Create Credit
Configure the credit unit
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)Leave the other defaults as-is
Save and copy the credit ID
cent_xxxxxxxxxxxx.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 entitlementEmail Credits.
Plan MailKit (19 $/mes, 5.000 correos)
Create the subscription
- Ve a Products → Create Product
- Completa los detalles del producto:
MailKit PlanDescription: 5,000 transactional emails per month.- Selecciona Subscription como tipo de producto
- Establece el precio recurrente:
19.00Billing Cycle: MonthlyCurrency: USDAttach the email 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).Paquete de recarga (9 $ por única vez, 5.000 correos)
Create a one-time product
- Ve a Products → Create Product
- Completa los detalles del producto:
Email Top-Up PackDescription: Add 5,000 emails to your MailKit balance instantly.- Selecciona Single Payment como tipo de producto
- Establece el precio:
9.00Currency: USDAttach the credit grant
- Credit Entitlement:
Email Credits - Credits issued:
5000
Paso 3: Configura el backend
Ahora crea el servidor Express que gestionará el checkout, los envíos, las consultas de saldo y los webhooks.Initialize the project
package.json:Configure environment variables
.env: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.Build the server
server.ts en la raíz del proyecto:Add a demo UI
public/index.html:Paso 4: Conecta el endpoint del webhook
El eventocredit.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.
Expose your local server
https://1234abcd.ngrok-free.app).Register the endpoint in Dodo
- Ve a Developers → Webhooks → Add Endpoint
- URL:
https://1234abcd.ngrok-free.app/webhooks/dodo - Events: suscríbete a
credit.added,credit.balance_lowycredit.rolled_over - Guarda y copia la signing key en tu
.envcomoDODO_WEBHOOK_KEY - Reinicia el servidor
Paso 5: Prueba el flujo completo
Start the server
MailKit running on http://localhost:3000. Ábrelo en tu navegador.Subscribe a test customer
- En la sección 1, introduce un correo de prueba y un nombre, y haz clic en Get checkout link
- Abre el enlace y completa el checkout con una tarjeta de prueba
- Después del pago, busca
customer_iden tu dashboard, dentro de Customers
Send a real email
- Pega
customer_iden la sección 3 - Deja
toestablecido endelivered@resend.dev(la bandeja de entrada de pruebas de Resend que acepta todo) - Haz clic en Send
Trigger the low-balance webhook
- Ve a Customers → [Customer] → Credits → Email Credits
- Haz clic en Adjust Balance y debita
4000 - Envía un correo más mediante la demo
Buy a top-up pack
- Pega
customer_iden la sección 4 - Haz clic en Buy 5,000 emails y completa el checkout de prueba
- Actualiza el saldo: aumentará en 5.000
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).Test the hard stop
Solución de problemas
Webhook signature verification fails (401)
Webhook signature verification fails (401)
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.Balance is 0, customer not found, or credits don't deduct
Balance is 0, customer not found, or credits don't deduct
- El cliente completó el checkout (los créditos se conceden cuando el pago se realiza correctamente, no al crear la sesión)
CREDIT_ENTITLEMENT_IDen tu.envcoincide con el crédito asociado al producto (los ID que no coinciden escriben silenciosamente en el crédito equivocado)customer_idque estás pasando procede de Dodo (la tablacustomersdel dashboard), no de tu propia base de datos
Resend rejects the recipient
Resend rejects the recipient
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
Top-up pack
Instant ledger debits
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.