resend.emails.send dengan pemanggilan ke SendGrid, Postmark, Amazon SES, atau SMTP relay Anda sendiri.- Membuat custom credit entitlement untuk email di dashboard.
- Menambahkan credits ke subscription plan dan produk top-up one-time.
- Mengirim email melalui Resend dan mengurangi satu kredit per pengiriman dengan ledger entry.
- Membaca live credit balance pelanggan dari frontend.
- Memverifikasi webhook Dodo Payments dan menangani
credit.balance_lowuntuk memperingatkan pelanggan sebelum saldo mereka mencapai nol.
What We’re Building
MailKit menjual dua produk:- Akun Dodo Payments. Bangun semuanya dalam test mode.
- Akun Resend gratis dan API key.
- Node.js 22 atau yang lebih baru, serta pemahaman tentang TypeScript.
Langkah 1: Buat Email Credit Entitlement Anda
Credit entitlement mendefinisikan unit yang dijual MailKit: satu pengiriman email.
The Credits tab under Products lists all your credit entitlements.
Open the Credits Section
- Masuk ke dashboard Dodo Payments.
- Klik Products di sidebar.
- Pilih tab Credits.
- Klik Create Credit.
Configure the Credit Unit
Email CreditsCredit Type: Custom UnitUnit Name: emailDefine Precision: 0. Email adalah unit utuh, jadi saldo tidak memerlukan angka desimal.Credit Expiry: 30 days. Kredit yang tidak digunakan akan kedaluwarsa 30 hari setelah diterbitkan.Leave the Other Defaults
Save and Copy the Credit ID
cde_. Backend menggunakannya untuk membaca saldo dan membuat ledger entry.Email Credits siap digunakan. Selanjutnya, buat produk yang memberikannya kepada pelanggan.Langkah 2: Buat Plan dan Top-Up Pack
Buat dua produk yang menambahkan entitlementEmail Credits yang sama: plan Subscription yang memberikan 5.000 email setiap billing cycle, dan top-up One Time yang menambahkan 5.000 email sesuai kebutuhan.
MailKit Plan ($19/bulan, 5.000 Email)
Create the Subscription
- Buka Products dan klik Add Product.
- Masukkan detail produk:
MailKit PlanDescription: 5,000 transactional emails per month.- Pada Pricing Type, pilih Subscription.
- Tetapkan harga berulang:
19.00Repeat payment every: 1 bulanCurrency: USDAttach the Email Credit Entitlement
Email CreditsCredits issued per billing cycle: 5000Low Balance Threshold (%): 20. Dodo Payments mengirim credit.balance_low ketika saldo turun di bawah 20% dari credits yang diterbitkan per cycle, yaitu 1.000 email.Import Default Credit Settings: aktif, sehingga produk menggunakan expiry 30 hari dari Langkah 1.Tambahkan credit ke produk, lalu simpan produk tersebut. Salin product ID, yang dimulai dengan pdt_.Top-Up Pack ($9 One-Time, 5.000 Email)
Create a One-Time Product
- Buka Products dan klik Add Product.
- Masukkan detail produk:
Email Top-Up PackDescription: Add 5,000 emails to your MailKit balance.- Pada Pricing Type, pilih One Time.
- Tetapkan harga:
9.00Currency: USDAttach the Credit Grant
- Select credits:
Email Credits - No of credits issued:
5000
Langkah 3: Siapkan Backend
Bangun Express server yang membuat checkout, mengirim email, membaca saldo, dan menerima webhook.Initialize the Project
package.json:Configure Environment Variables
.env menggunakan API key test mode dari Developer → API Keys dan ID dari Langkah 1 dan 2:DODO_PAYMENTS_WEBHOOK_KEY pada Langkah 4, setelah membuat webhook endpoint. Buat API key Resend di resend.com/api-keys.Build the Server
server.ts di root project. Server ini menyediakan lima route: subscribe checkout, top-up checkout, balance read, send, dan webhook receiver.Add a Demo UI
public/index.html. File ini memanggil setiap route dari form sederhana, sehingga Anda dapat menguji flow di browser:Langkah 4: Hubungkan Webhook Endpoint
Eventcredit.balance_low memungkinkan Anda memperingatkan pelanggan sebelum kredit mereka habis. Tanpanya, pelanggan baru menyadari masalah ketika email gagal dikirim.
Expose Your Local Server
https://1234abcd.ngrok-free.app.Register the Endpoint in Dodo Payments
- Buka Developer → Webhooks dan klik Add endpoint.
- Masukkan URL
https://1234abcd.ngrok-free.app/webhooks/dodo, menggunakan tunnel host Anda sendiri. - Pilih event
credit.added,credit.balance_low, dancredit.rolled_over. - Klik Create endpoint.
- Salin signing secret dari tab Overview endpoint ke
.envsebagaiDODO_PAYMENTS_WEBHOOK_KEY. - Restart server.
Langkah 5: Uji Full Flow
Start the Server
MailKit running on http://localhost:3000. Buka URL tersebut di browser.Subscribe a Test Customer
- Di bagian 1, masukkan alamat email dan nama untuk pengujian, lalu klik Get checkout link.
- Buka link tersebut dan selesaikan checkout dengan test card.
- Di dashboard, buka Customers dan salin ID pelanggan baru, yang dimulai dengan
cus_.
Send an Email
- Tempelkan customer ID ke bagian 3.
- Biarkan To tetap
delivered@resend.dev, alamat pengujian Resend yang menerima setiap pesan. - Klik Send.
Trigger the Low-Balance Webhook
- Buka pelanggan di Customers, pilih tab Credits, lalu pilih Email Credits.
- Klik Apply Credit/Debit, pilih Debit, dan masukkan
4000. Saldo kini tepat 1.000, yang belum berada di bawah threshold. - Kirim satu email lagi dari demo. Saldo turun menjadi 999.
Buy a Top-Up Pack
- Tempelkan customer ID ke bagian 4.
- Klik Buy 5,000 emails dan selesaikan test checkout.
- Refresh balance. Saldo bertambah 5.000.
credit.added dengan transaction_type: "credit_added". Grant di baliknya memiliki source_type: one_time, yang dapat Anda baca kembali menggunakan API List Customer Grants. Kredit top-up ditambahkan ke kredit subscription. Debit diambil dari grant yang kedaluwarsa lebih dahulu, dan dari grant paling lama jika dua grant kedaluwarsa pada waktu yang sama.Test the Hard Stop
402:402 tersebut adalah enforcement aplikasi Anda. Perlakukan balance API Dodo Payments sebagai source of truth, dan jangan menyimpan saldo dalam cache di client.Troubleshooting
Webhook signature verification fails (401)
Webhook signature verification fails (401)
express.json() mengganti body dengan parsed object, sehingga verification gagal. Daftarkan /webhooks/dodo dengan express.raw({ type: 'application/json' }) di atas baris app.use(express.json()). Lalu periksa bahwa DODO_PAYMENTS_WEBHOOK_KEY cocok dengan signing secret pada tab Overview endpoint.Balance is 0, customer not found, or credits don't deduct
Balance is 0, customer not found, or credits don't deduct
- Pelanggan menyelesaikan checkout. Credit diterbitkan saat pembayaran berhasil, bukan saat checkout session dibuat.
CREDIT_ENTITLEMENT_IDdi.envcocok dengan credit yang ditambahkan ke produk. Panggilan balance dan ledger menggunakan ID ini, sehingga ketidakcocokan akan membaca atau mengurangi credit yang berbeda.customer_idyang Anda teruskan adalah customer ID Dodo Payments (dimulai dengancus_), bukan ID dari database Anda sendiri.
Resend rejects the recipient
Resend rejects the recipient
onboarding@resend.dev hanya mengirim ke alamat email pada akun Resend Anda, atau ke delivered@resend.dev. Untuk mengirim ke pihak lain, verifikasi domain dan gunakan alamat from pada domain tersebut.Yang Anda Bangun
One Reusable Credit Unit
Email Credits, yang didefinisikan sekali dan ditambahkan ke subscription plan serta top-up pack.Subscription with Prepaid Allowance
Top-Up Pack
Direct Ledger Debits
createLedgerEntry setelah setiap pengiriman, tanpa meter dan tanpa aggregation delay. Resend message ID sebagai idempotency key mencegah debit kedua untuk pengiriman yang sama.