resend.emails.send bằng SendGrid, Postmark, SES hoặc SMTP relay của riêng bạn.- Tạo entitlement credit tùy chỉnh (email) trong dashboard
- Gắn credit vào một gói đăng ký và một sản phẩm nạp thêm một lần
- Gửi email thực qua Resend và trừ một credit cho mỗi lần gửi bằng một ledger entry
- Truy vấn số dư credit trực tiếp từ frontend
- Xác minh webhook Dodo chính xác và xử lý
credit.balance_lowđể nhắc khách hàng trước khi số dư về 0
Những gì chúng ta sẽ xây dựng
Sau đây là mô hình giá của MailKit:- Tài khoản Dodo Payments (chế độ test là đủ)
- Tài khoản Resend miễn phí và API key
- Node.js 18+ và kiến thức cơ bản về TypeScript
Bước 1: Tạo entitlement credit email
Entitlement credit xác định đơn vị mà nền tảng của bạn bán: trong trường hợp này là một lần gửi email.
The Credits tab under Products lists all your credit entitlements.
Open the Credits section
- Đăng nhập vào dashboard Dodo Payments của bạn
- Nhấp vào Products trong thanh bên trái
- Chọn tab Credits
- Nhấp vào Create Credit
Configure the credit unit
Email CreditsCredit Type: Chọn Custom UnitUnit Name: emailPrecision: 0 (email luôn là một đơn vị nguyên; bạn không thể gửi nửa email)Credit Expiry: 30 days (hạn mức của mỗi chu kỳ sẽ được đặt lại)Leave the other defaults as-is
Save and copy the credit ID
cent_xxxxxxxxxxxx.Email Credits của bạn đã sẵn sàng. Tiếp theo là các sản phẩm cấp credit cho khách hàng.Bước 2: Tạo gói đăng ký và gói nạp thêm
Bạn sẽ tạo hai sản phẩm: gói Subscription định kỳ và gói nạp thêm Single Payment. Gói đăng ký cấp 5.000 email mỗi chu kỳ; gói nạp thêm bổ sung 5.000 email theo nhu cầu. Cả hai đều gắn cùng entitlementEmail Credits.
Gói MailKit ($19/tháng, 5.000 email)
Create the subscription
- Đi đến Products → Create Product
- Điền thông tin sản phẩm:
MailKit PlanDescription: 5,000 transactional emails per month.- Chọn Subscription làm loại sản phẩm
- Thiết lập giá định kỳ:
19.00Billing Cycle: MonthlyCurrency: USDAttach the email credit entitlement
Email CreditsCredits issued per billing cycle: 5000Low Balance Threshold: 20 (phần trăm; kích hoạt credit.balance_low khi số dư giảm xuống dưới 20% hạn mức chu kỳ, tức 1.000 email)Import Default Credit Settings: đã bật (sử dụng thời hạn 30 ngày từ Bước 1)Nhấp vào Add to Product, sau đó Save sản phẩm. Sao chép product ID (pdt_xxxxxxxxxxxx).Gói nạp thêm ($9 một lần, 5.000 email)
Create a one-time product
- Đi đến Products → Create Product
- Điền thông tin sản phẩm:
Email Top-Up PackDescription: Add 5,000 emails to your MailKit balance instantly.- Chọn Single Payment làm loại sản phẩm
- Thiết lập giá:
9.00Currency: USDAttach the credit grant
- Credit Entitlement:
Email Credits - Credits issued:
5000
Bước 3: Thiết lập backend
Bây giờ hãy xây dựng Express server để xử lý checkout, gửi email, truy vấn số dư và webhook.Initialize the project
package.json:Configure environment variables
.env:DODO_WEBHOOK_KEY ở Bước 4 sau khi tạo endpoint. API key của Resend lấy từ resend.com/api-keys.Build the server
server.ts trong thư mục gốc của project:Add a demo UI
public/index.html:Bước 4: Kết nối webhook endpoint
Eventcredit.balance_low giúp bạn nhắc khách hàng trước khi họ hết credit. Nếu không có event này, lần đầu họ nhận ra vấn đề sẽ là khi email không thể gửi.
Expose your local server
https://1234abcd.ngrok-free.app).Register the endpoint in Dodo
- Đi đến Developers → Webhooks → Add Endpoint
- URL:
https://1234abcd.ngrok-free.app/webhooks/dodo - Events: đăng ký
credit.added,credit.balance_lowvàcredit.rolled_over - Lưu, sau đó sao chép signing key vào
.envdưới tênDODO_WEBHOOK_KEY - Khởi động lại server
Bước 5: Kiểm thử toàn bộ quy trình
Start the server
MailKit running on http://localhost:3000. Mở nó trong trình duyệt.Subscribe a test customer
- Trong phần 1, nhập email và tên test, nhấp Get checkout link
- Mở liên kết, hoàn tất checkout bằng test card
- Sau khi thanh toán, tìm
customer_idtrong dashboard tại Customers
Send a real email
- Dán
customer_idvào phần 3 - Giữ
toở giá trịdelivered@resend.dev(sandbox inbox của Resend chấp nhận mọi email) - Nhấp Send
Trigger the low-balance webhook
- Đi đến Customers → [Customer] → Credits → Email Credits
- Nhấp Adjust Balance và trừ
4000 - Gửi thêm một email qua bản demo
Buy a top-up pack
- Dán
customer_idvào phần 4 - Nhấp Buy 5,000 emails, hoàn tất checkout test
- Làm mới số dư và số lượng sẽ tăng thêm 5.000
credit.added được kích hoạt với grant_source: one_time. Gói nạp thêm được cộng dồn trên credit đăng ký; cả hai pool đều được tiêu thụ theo FIFO (grant chưa hết hạn cũ nhất trước).Test the hard stop
Xử lý sự cố
Webhook signature verification fails (401)
Webhook signature verification fails (401)
express.json() phân tích cú pháp rồi tuần tự hóa lại payload, khiến HMAC bị lỗi. Đảm bảo /webhooks/dodo được đăng ký bằng express.raw({ type: 'application/json' }) bên trên dòng app.use(express.json()) và DODO_WEBHOOK_KEY khớp với signing key hiển thị trên trang thông tin chi tiết của endpoint.Balance is 0, customer not found, or credits don't deduct
Balance is 0, customer not found, or credits don't deduct
- Khách hàng đã hoàn tất checkout (credit được cấp sau khi thanh toán thành công, không phải khi tạo session)
CREDIT_ENTITLEMENT_IDtrong.envkhớp với credit được gắn vào sản phẩm (ID không khớp sẽ âm thầm ghi vào credit sai)customer_idbạn truyền vào đến từ Dodo (bảngcustomerstrong dashboard), không phải database riêng của bạn
Resend rejects the recipient
Resend rejects the recipient
onboarding@resend.dev chỉ gửi đến email trên tài khoản Resend của bạn hoặc delivered@resend.dev. Để gửi cho người khác, verify a domain và sử dụng địa chỉ from trên domain đó.Những gì bạn đã xây dựng
One reusable credit unit
Email Credits, được định nghĩa một lần và gắn vào cả gói đăng ký lẫn gói nạp thêm.Subscription with prepaid allowance
Top-up pack
Instant ledger debits
createLedgerEntry duy nhất sau mỗi lần gửi. Không cần meter, không có độ trễ tổng hợp, idempotent khi retry nhờ message id của Resend.