resend.emails.send con una chiamata a SendGrid, Postmark, Amazon SES o al tuo relay SMTP.- Creare nel dashboard un’entitlement di crediti personalizzata per le email.
- Collegare i crediti a un piano di abbonamento e a un prodotto di ricarica una tantum.
- Inviare email tramite Resend e addebitare un credito per ogni invio con una voce nel ledger.
- Leggere il saldo crediti aggiornato di un cliente dal frontend.
- Verificare i webhook di Dodo Payments e gestire
credit.balance_lowper avvisare i clienti prima che il saldo raggiunga lo zero.
What We’re Building
MailKit vende due prodotti:- Un account Dodo Payments. Crea tutto in modalità test.
- Un account Resend gratuito e una API key.
- Node.js 22 o versioni successive e una conoscenza operativa di TypeScript.
Passaggio 1: crea l’entitlement di crediti email
L’entitlement di crediti definisce l’unità venduta da MailKit: un invio email.
The Credits tab under Products lists all your credit entitlements.
Open the Credits Section
- Accedi al dashboard di Dodo Payments.
- Fai clic su Products nella barra laterale.
- Seleziona la scheda Credits.
- Fai clic su Create Credit.
Configure the Credit Unit
Email CreditsCredit Type: Custom UnitUnit Name: emailDefine Precision: 0. Un’email è un’unità intera, quindi il saldo non avrà mai valori decimali.Credit Expiry: 30 days. I crediti inutilizzati scadono 30 giorni dopo l’emissione.Leave the Other Defaults
Save and Copy the Credit ID
cde_. Il backend lo usa per leggere i saldi e creare le voci nel ledger.Email Credits è pronto. Ora crea i prodotti che lo concederanno ai clienti.Passaggio 2: crea il piano e il pacchetto di ricarica
Crea due prodotti che associano lo stesso entitlementEmail Credits: un piano Subscription che concede 5.000 email per ogni ciclo di fatturazione e una ricarica One Time che ne aggiunge altre 5.000 su richiesta.
Piano MailKit ($19/mese, 5.000 email)
Create the Subscription
- Vai a Products e fai clic su Add Product.
- Inserisci i dettagli del prodotto:
MailKit PlanDescription: 5,000 transactional emails per month.- In Pricing Type, seleziona Subscription.
- Imposta il prezzo ricorrente:
19.00Repeat payment every: 1 monthCurrency: USDAttach the Email Credit Entitlement
Email CreditsCredits issued per billing cycle: 5000Low Balance Threshold (%): 20. Dodo Payments invia credit.balance_low quando il saldo scende sotto il 20% dei crediti emessi per ciclo, cioè 1.000 email.Import Default Credit Settings: attivato, così il prodotto usa la scadenza di 30 giorni del Passaggio 1.Aggiungi il credito al prodotto, quindi salva il prodotto. Copia l’ID del prodotto, che inizia con pdt_.Pacchetto di ricarica ($9 una tantum, 5.000 email)
Create a One-Time Product
- Vai a Products e fai clic su Add Product.
- Inserisci i dettagli del prodotto:
Email Top-Up PackDescription: Add 5,000 emails to your MailKit balance.- In Pricing Type, seleziona One Time.
- Imposta il prezzo:
9.00Currency: USDAttach the Credit Grant
- Select credits:
Email Credits - No of credits issued:
5000
Passaggio 3: configura il backend
Crea il server Express che genera i checkout, invia le email, legge i saldi e riceve i webhook.Initialize the Project
package.json:Configure Environment Variables
.env con una API key in modalità test da Developer → API Keys e gli ID dei Passaggi 1 e 2:DODO_PAYMENTS_WEBHOOK_KEY nel Passaggio 4, dopo aver creato l’endpoint webhook. Crea la API key di Resend su resend.com/api-keys.Build the Server
server.ts nella root del progetto. Il server espone cinque route: checkout dell’abbonamento, checkout della ricarica, lettura del saldo, invio e ricezione del webhook.Add a Demo UI
public/index.html. Chiama ogni route da un semplice form, così puoi testare il flusso nel browser:Passaggio 4: collega l’endpoint webhook
L’eventocredit.balance_low ti consente di avvisare i clienti prima che esauriscano i crediti. Senza di esso, un cliente si accorge del problema solo quando un’email non viene inviata.
Expose Your Local Server
https://1234abcd.ngrok-free.app.Register the Endpoint in Dodo Payments
- Vai a Developer → Webhooks e fai clic su Add endpoint.
- Inserisci l’URL
https://1234abcd.ngrok-free.app/webhooks/dodo, usando l’host del tuo tunnel. - Seleziona gli eventi
credit.added,credit.balance_lowecredit.rolled_over. - Fai clic su Create endpoint.
- Copia il signing secret dalla scheda Overview dell’endpoint in
.envcomeDODO_PAYMENTS_WEBHOOK_KEY. - Riavvia il server.
Passaggio 5: testa il flusso completo
Start the Server
MailKit running on http://localhost:3000. Apri quell’URL nel browser.Subscribe a Test Customer
- Nella sezione 1, inserisci un indirizzo email e un nome di test, quindi fai clic su Get checkout link.
- Apri il link e completa il checkout con una carta di test.
- Nel dashboard, vai a Customers e copia l’ID del nuovo cliente, che inizia con
cus_.
Send an Email
- Incolla l’ID del cliente nella sezione 3.
- Lascia To impostato su
delivered@resend.dev, un indirizzo di test di Resend che accetta ogni messaggio. - Fai clic su Send.
Trigger the Low-Balance Webhook
- Apri il cliente in Customers, seleziona la scheda Credits e scegli Email Credits.
- Fai clic su Apply Credit/Debit, seleziona Debit e inserisci
4000. Il saldo è ora esattamente 1.000, quindi non è ancora sotto la soglia. - Invia un’altra email dalla demo. Il saldo scende a 999.
Buy a Top-Up Pack
- Incolla l’ID del cliente nella sezione 4.
- Fai clic su Buy 5,000 emails e completa il checkout di test.
- Aggiorna il saldo. Aumenta di 5.000.
credit.added con transaction_type: "credit_added". Il grant associato ha source_type: one_time, che puoi leggere nuovamente con l’API List Customer Grants. I crediti della ricarica si aggiungono a quelli dell’abbonamento. Gli addebiti vengono scalati dal grant con la scadenza più vicina e, quando due grant scadono contemporaneamente, da quello più vecchio.Test the Hard Stop
402:402 è l’applicazione della regola nella tua app. Considera l’API del saldo di Dodo Payments come fonte autorevole e non memorizzare il saldo nella cache del client.Risoluzione dei problemi
Webhook signature verification fails (401)
Webhook signature verification fails (401)
express.json() sostituisce il body con un oggetto analizzato, quindi la verifica fallisce. Registra /webhooks/dodo con express.raw({ type: 'application/json' }) sopra la riga app.use(express.json()). Controlla quindi che DODO_PAYMENTS_WEBHOOK_KEY corrisponda al signing secret nella scheda Overview dell’endpoint.Balance is 0, customer not found, or credits don't deduct
Balance is 0, customer not found, or credits don't deduct
- Il cliente ha completato il checkout. I crediti vengono emessi quando il pagamento va a buon fine, non quando viene creata la sessione di checkout.
CREDIT_ENTITLEMENT_IDin.envcorrisponde al credito associato al prodotto. Le chiamate per il saldo e il ledger usano questo ID, quindi una discrepanza legge o addebita un credito diverso.customer_idpassato è l’ID cliente di Dodo Payments (inizia concus_), non un ID del tuo database.
Resend rejects the recipient
Resend rejects the recipient
onboarding@resend.dev consegna solo all’indirizzo email del tuo account Resend o a delivered@resend.dev. Per inviare a chiunque altro, verifica un dominio e usa un indirizzo from su quel dominio.Cosa hai creato
One Reusable Credit Unit
Email Credits, definito una sola volta e associato sia al piano di abbonamento sia al pacchetto di ricarica.Subscription with Prepaid Allowance
Top-Up Pack
Direct Ledger Debits
createLedgerEntry dopo ogni invio, senza meter né ritardo di aggregazione. L’ID del messaggio Resend come chiave di idempotenza impedisce un secondo addebito per lo stesso invio.