Skip to main content
Deixe o Sentra escrever seu código de integração para você.
Use nosso assistente de IA no VS Code, Cursor ou Windsurf para gerar código de SDK/API, manipuladores de webhooks e muito mais, apenas descrevendo o que você deseja.
Experimente o Sentra: integração com tecnologia de IA →
Neste tutorial, você criará o MailKit, uma plataforma de e-mail transacional na qual os clientes pagam antecipadamente por um conjunto de créditos de e-mail. O plano concede uma quantidade mensal de e-mails; quando os clientes ficam com poucos créditos, podem comprar um pacote de recarga em vez de esperar pelo próximo ciclo. Cada envio deduz automaticamente um crédito.
Este tutorial usa o Resend como provedor de e-mail. O plano gratuito (3.000 e-mails/mês) é suficiente para criar e testar todo o fluxo sem uma conta paga. O padrão funciona com qualquer provedor; substitua resend.emails.send por SendGrid, Postmark, SES ou seu próprio relay SMTP.
Ao final deste tutorial, você saberá como:
  • Criar um entitlement de crédito personalizado (e-mails) no dashboard
  • Associar créditos a um plano de assinatura e a um produto de recarga avulso
  • Enviar e-mails reais via Resend e debitar um crédito por envio usando uma entrada no ledger
  • Consultar um saldo de créditos atualizado no frontend
  • Verificar corretamente os webhooks do Dodo e lidar com credit.balance_low para avisar os clientes antes que o saldo chegue a zero

O que vamos criar

Este é o modelo de preços do MailKit: A unidade é um e-mail = um crédito. Os clientes não precisam pensar em tokens, lotes ou unidades ponderadas. Eles simplesmente veem “você tem 4.231 e-mails restantes este mês”.
Antes de começar, certifique-se de ter:
  • Uma conta do Dodo Payments (o modo de teste é suficiente)
  • Uma conta gratuita do Resend e uma API key
  • Node.js 18+ e familiaridade básica com TypeScript

Etapa 1: crie seu entitlement de crédito de e-mail

O entitlement de crédito define a unidade que sua plataforma vende: neste caso, um envio de e-mail.
Página de listagem de créditos

The Credits tab under Products lists all your credit entitlements.

1

Open the Credits section

  1. Acesse o dashboard do Dodo Payments
  2. Clique em Products na barra lateral esquerda
  3. Selecione a aba Credits
  4. Clique em Create Credit
2

Configure the credit unit

Preencha os detalhes do crédito:Credit Name: Email CreditsCredit Type: selecione Custom UnitUnit Name: emailPrecision: 0 (um e-mail é sempre uma unidade inteira; não é possível enviar meio e-mail)Credit Expiry: 30 days (a quantidade de cada ciclo é redefinida)
A precisão não pode ser alterada após a criação. Para unidades discretas, como e-mails, mensagens ou sessões, 0 está correto.
3

Leave the other defaults as-is

Não habilitaremos rollover nem overage neste cookbook; o objetivo é obter o fluxo de CBB mais simples possível. Você poderá revisar essas opções posteriormente no anexo do crédito.
4

Save and copy the credit ID

Clique em Create Credit. Abra o crédito e copie o ID. Você precisará dele para consultar o saldo no backend. Ele terá uma aparência semelhante a cent_xxxxxxxxxxxx.
Seu entitlement Email Credits está pronto. Em seguida, criaremos os produtos que concedem créditos aos clientes.

Etapa 2: crie o plano e o pacote de recarga

Você criará dois produtos: um plano recorrente de Subscription e uma recarga de Single Payment. O plano concede 5.000 e-mails a cada ciclo; a recarga adiciona outros 5.000 sob demanda. Ambos associam o mesmo entitlement Email Credits.
Este cookbook deduz créditos com entradas diretas no ledger, em vez de meters baseados em uso. As entradas no ledger são imediatas (o saldo é atualizado em milissegundos), não exigem configuração adicional e são a escolha certa quando uma ação do usuário equivale exatamente a um crédito. Se você preferir a dedução automática a partir de eventos de uso ingeridos (útil para unidades ponderadas, como “tokens” ou “MB processados”), consulte Credit-Based Billing → Usage Billing with Credits para ver o padrão baseado em meters.

Plano MailKit (US$ 19/mês, 5.000 e-mails)

1

Create the subscription

  1. Acesse Products → Create Product
  2. Preencha os detalhes do produto:
Product Name: MailKit PlanDescription: 5,000 transactional emails per month.
  1. Selecione Subscription como tipo de produto
  2. Defina o preço recorrente:
Recurring Price: 19.00Billing Cycle: MonthlyCurrency: USD
2

Attach the email credit entitlement

Role até Entitlements → Credits → Attach e configure:Credit Entitlement: Email CreditsCredits issued per billing cycle: 5000Low Balance Threshold: 20 (percentual; dispara credit.balance_low quando o saldo fica abaixo de 20% da quantidade do ciclo, ou seja, 1.000 e-mails)Import Default Credit Settings: habilitado (usa a expiração de 30 dias da Etapa 1)Clique em Add to Product e depois em Save para salvar o produto. Copie o ID do produto (pdt_xxxxxxxxxxxx).
Plano: US$ 19/mês → 5.000 e-mails renovados a cada ciclo.

Pacote de recarga (US$ 9 avulso, 5.000 e-mails)

1

Create a one-time product

  1. Acesse Products → Create Product
  2. Preencha os detalhes do produto:
Product Name: Email Top-Up PackDescription: Add 5,000 emails to your MailKit balance instantly.
  1. Selecione Single Payment como tipo de produto
  2. Defina o preço:
Price: 9.00Currency: USD
2

Attach the credit grant

Em Entitlements → Credits → Attach:
  • Credit Entitlement: Email Credits
  • Credits issued: 5000
Produtos avulsos concedem créditos com sua própria expiração (30 dias após a compra, conforme a Etapa 1). As recargas são acumuladas sobre os créditos da assinatura; elas não os substituem.
Salve e copie o ID do produto.
Pacote de recarga: US$ 9 → +5.000 e-mails, disponíveis imediatamente.

Etapa 3: configure o backend

Agora crie o servidor Express que gerenciará o checkout, os envios, as consultas de saldo e os webhooks.
1

Initialize the project

Adicione um script de desenvolvimento ao package.json:
tsx executa TypeScript diretamente, sem uma etapa de build ou tsconfig.json, o que é perfeito para um tutorial. Em produção, adicione um tsconfig.json e um script build.
2

Configure environment variables

Crie .env:
.env
Você preencherá o DODO_WEBHOOK_KEY na Etapa 4, depois de criar o endpoint. A API key do Resend vem de resend.com/api-keys.
Adicione .env ao .gitignore imediatamente. Nunca faça commit de API keys.
3

Build the server

Crie server.ts na raiz do projeto:
O corpo do webhook deve ser bruto. express.json() analisa e serializa novamente o corpo, o que quebra a verificação da assinatura. Defina /webhooks/dodo com express.raw() antes da linha app.use(express.json()).
Backend pronto: assinatura, recarga, saldo, envio e manipulador de webhook configurados.
4

Add a demo UI

Crie public/index.html:

Etapa 4: conecte o endpoint de webhook

O evento credit.balance_low permite avisar os clientes antes que eles fiquem sem créditos. Sem ele, a primeira vez que perceberão o problema será quando um e-mail não conseguir ser enviado.
1

Expose your local server

Webhooks precisam de uma URL pública. Use o ngrok (ou qualquer tunnel) durante o desenvolvimento:
Copie a URL de encaminhamento HTTPS (por exemplo, https://1234abcd.ngrok-free.app).
2

Register the endpoint in Dodo

  1. Acesse Developers → Webhooks → Add Endpoint
  2. URL: https://1234abcd.ngrok-free.app/webhooks/dodo
  3. Events: assine credit.added, credit.balance_low e credit.rolled_over
  4. Salve e copie a signing key para o seu .env como DODO_WEBHOOK_KEY
  5. Reinicie o servidor

Etapa 5: teste o fluxo completo

1

Start the server

Você deverá ver MailKit running on http://localhost:3000. Abra-o no navegador.
2

Subscribe a test customer

  1. Na seção 1, insira um e-mail e um nome de teste e clique em Get checkout link
  2. Abra o link e conclua o checkout com um cartão de teste
  3. Após o pagamento, encontre o customer_id no dashboard, em Customers
Agora o cliente deverá ter 5.000 e-mails no saldo. Verifique em Customers → [Customer] → Credits.
3

Send a real email

  1. Cole o customer_id na seção 3
  2. Mantenha to definido como delivered@resend.dev (a caixa de entrada sandbox do Resend que aceita tudo)
  3. Clique em Send
Você receberá de volta um ID de mensagem do Resend. Atualize o saldo na seção 2; a contagem cairá imediatamente para 4.999. Cada débito no ledger é refletido no saldo atualizado assim que é gravado.
4

Trigger the low-balance webhook

O limite é 20% (1.000 dos 5.000 e-mails permitidos). Para acioná-lo sem enviar 4.000 e-mails reais, debite manualmente o saldo no dashboard:
  1. Acesse Customers → [Customer] → Credits → Email Credits
  2. Clique em Adjust Balance e debite 4000
  3. Envie mais um e-mail pela demonstração
Seu servidor deverá registrar, em poucos segundos:
Seu servidor recebeu e verificou o webhook. Em produção, é aqui que você enviaria um e-mail ao cliente ou exibiria um banner no app.
5

Buy a top-up pack

  1. Cole o customer_id na seção 4
  2. Clique em Buy 5,000 emails e conclua o checkout de teste
  3. Atualize o saldo; ele aumentará em 5.000
Um evento credit.added é disparado com grant_source: one_time. A recarga é acumulada sobre os créditos da assinatura; os dois conjuntos são consumidos em ordem FIFO (a concessão não expirada mais antiga primeiro).
6

Test the hard stop

Debite manualmente o saldo até zero e tente enviar mais um e-mail. Você receberá:
Esse 402 é a aplicação da regra no nível da sua aplicação. A API de saldo do Dodo é a fonte de verdade; nunca armazene esse valor em cache no cliente.

Solução de problemas

A assinatura é calculada sobre o corpo HTTP bruto. express.json() analisa e serializa novamente o payload, quebrando o HMAC. Certifique-se de que /webhooks/dodo esteja registrado com express.raw({ type: 'application/json' }) acima da linha app.use(express.json()) e que DODO_WEBHOOK_KEY corresponda à signing key exibida na página de detalhes do endpoint.
Verifique estas três coisas, nesta ordem:
  1. O cliente concluiu o checkout (os créditos são concedidos após o pagamento bem-sucedido, não na criação da sessão)
  2. CREDIT_ENTITLEMENT_ID no seu .env corresponde ao crédito associado ao produto (IDs incompatíveis gravam silenciosamente no crédito errado)
  3. O customer_id que você está enviando veio do Dodo (a tabela customers no dashboard), não do seu próprio banco de dados
O remetente sandbox onboarding@resend.dev só entrega para o e-mail da sua conta do Resend ou para delivered@resend.dev. Para enviar a qualquer outra pessoa, verifique um domínio e use um endereço from nele.

O que você criou

One reusable credit unit

Email Credits, definido uma única vez e associado ao plano de assinatura e ao pacote de recarga.

Subscription with prepaid allowance

US$ 19/mês concede 5.000 e-mails por ciclo. Os clientes sabem pelo que estão pagando, e você conhece seu custo máximo.

Top-up pack

Um produto avulso que concede 5.000 e-mails. Ele é acumulado sobre os créditos da assinatura sem exigir alteração no plano.

Instant ledger debits

Uma única chamada createLedgerEntry após cada envio. Sem meter, sem atraso de agregação e idempotente em novas tentativas por meio do ID da mensagem do Resend.

Credit-Based Billing Reference

Leia a documentação completa de CBB para conhecer rollover, modos de overage, gerenciamento do ledger e toda a superfície da API.
Precisa de ajuda?
Última modificação em 22 de julho de 2026