Skip to main content
Để coding agent viết phần tích hợp cho bạn, hãy cài đặt Dodo Agent Plugin. Plugin này thêm các kỹ năng và máy chủ MCP của Dodo Payments vào Claude Code, Codex CLI, Cursor, VS Code / GitHub Copilot, Kiro và OpenCode.
Bạn sẽ xây dựng MailKit, một dịch vụ email giao dịch nơi khách hàng trả trước cho các credit email. Một gói hàng tháng cấp 5.000 email trong mỗi chu kỳ thanh toán. Khi sắp hết, khách hàng có thể mua một gói nạp thêm thay vì chờ đến chu kỳ tiếp theo. Mỗi lần gửi sẽ trừ một credit.
Hướng dẫn này sử dụng Resend làm nhà cung cấp email. Gói miễn phí của Resend (3.000 email mỗi tháng) đủ để xây dựng và kiểm thử toàn bộ quy trình. Mẫu tính phí này hoạt động với mọi nhà cung cấp: thay resend.emails.send bằng lệnh gọi đến SendGrid, Postmark, Amazon SES hoặc SMTP relay của riêng bạn.
Sau khi hoàn tất, bạn sẽ biết cách:
  • Tạo entitlement credit tùy chỉnh cho email trong dashboard.
  • Gắn credit vào một gói subscription và một sản phẩm top-up mua một lần.
  • Gửi email qua Resend và trừ một credit cho mỗi lần gửi bằng một ledger entry.
  • Đọc số dư credit hiện tại của khách hàng từ frontend.
  • Xác minh webhook của Dodo Payments và xử lý credit.balance_low để cảnh báo khách hàng trước khi số dư về không.

Những gì chúng ta sẽ xây dựng

MailKit bán hai sản phẩm: Đơn vị tính là một email = một credit. Khách hàng không cần suy nghĩ về token, batch hoặc đơn vị có trọng số. Họ sẽ thấy “còn 4.231 email trong tháng này.” Trước khi bắt đầu, bạn cần:
  • Một tài khoản Dodo Payments. Hãy xây dựng mọi thứ ở test mode.
  • Một tài khoản Resend miễn phí và API key.
  • Node.js 22 trở lên và kiến thức thực tế về TypeScript.

Bước 1: Tạo Email Credit Entitlement

Credit entitlement định nghĩa đơn vị mà MailKit bán: một lần gửi email.
Tab Credits trong Products, liệt kê các credit entitlement của doanh nghiệp

The Credits tab under Products lists all your credit entitlements.

1

Open the Credits Section

  1. Đăng nhập vào dashboard Dodo Payments.
  2. Nhấp Products trong thanh bên.
  3. Chọn tab Credits.
  4. Nhấp Create Credit.
2

Configure the Credit Unit

Nhập các giá trị sau:Credit Name: Email CreditsCredit Type: Custom UnitUnit Name: emailDefine Precision: 0. Email là một đơn vị nguyên, vì vậy số dư không bao giờ cần phần thập phân.Credit Expiry: 30 days. Credit chưa sử dụng sẽ hết hạn sau 30 ngày kể từ khi được cấp.
Không thể thay đổi precision sau khi tạo credit. Đối với các đơn vị rời rạc như email, message hoặc session, hãy sử dụng 0.
3

Leave the Other Defaults

Hướng dẫn này tắt rollover và overage để giữ cho luồng credit tối giản. Bạn có thể bật chúng sau, trên credit hoặc trên phần gắn credit của từng sản phẩm.
4

Save and Copy the Credit ID

Nhấp Create Credit. Mở credit và sao chép ID của nó, bắt đầu bằng cde_. Backend sử dụng ID này để đọc số dư và tạo ledger entry.
Entitlement Email Credits đã sẵn sàng. Tiếp theo, hãy tạo các sản phẩm cấp entitlement này cho khách hàng.

Bước 2: Tạo Plan và Top-Up Pack

Tạo hai sản phẩm cùng gắn entitlement Email Credits: một plan Subscription cấp 5.000 email trong mỗi chu kỳ thanh toán và một gói top-up One Time cộng thêm 5.000 email theo nhu cầu.
Hướng dẫn này trừ credit bằng ledger entry thay vì usage meter. Ledger debit được áp dụng khi API call trả về, không cần thiết lập meter và phù hợp với các trường hợp mỗi hành động của người dùng có giá chính xác một credit. Để tự động trừ credit từ các usage event được ingest, phù hợp với các đơn vị có trọng số như token hoặc megabyte đã xử lý, hãy xem Usage Billing with Credits trong hướng dẫn Credit-Based Billing.

Gói MailKit ($19/tháng, 5.000 Email)

1

Create the Subscription

  1. Đi đến Products và nhấp Add Product.
  2. Nhập thông tin sản phẩm:
Product Name: MailKit PlanDescription: 5,000 transactional emails per month.
  1. Trong Pricing Type, chọn Subscription.
  2. Đặt giá định kỳ:
Price: 19.00Repeat payment every: 1 thángCurrency: USD
2

Attach the Email Credit Entitlement

Trong phần Entitlements, nhấp Attach bên cạnh Credits và cấu hình:Select credits: Email CreditsCredits issued per billing cycle: 5000Low Balance Threshold (%): 20. Dodo Payments gửi credit.balance_low khi số dư giảm xuống dưới 20% số credit được cấp mỗi chu kỳ, tương đương 1.000 email.Import Default Credit Settings: bật để sản phẩm sử dụng thời hạn 30 ngày từ Bước 1.Thêm credit vào sản phẩm, sau đó lưu sản phẩm. Sao chép product ID, bắt đầu bằng pdt_.
Plan: $19/tháng, cấp 5.000 email trong mỗi chu kỳ thanh toán.

Gói Top-Up ($9 một lần, 5.000 Email)

1

Create a One-Time Product

  1. Đi đến Products và nhấp Add Product.
  2. Nhập thông tin sản phẩm:
Product Name: Email Top-Up PackDescription: Add 5,000 emails to your MailKit balance.
  1. Trong Pricing Type, chọn One Time.
  2. Đặt giá:
Price: 9.00Currency: USD
2

Attach the Credit Grant

Trong phần Entitlements, nhấp Attach bên cạnh Credits và cấu hình:
  • Select credits: Email Credits
  • No of credits issued: 5000
Sản phẩm mua một lần cấp credit với thời hạn riêng: 30 ngày kể từ ngày mua, theo mặc định bạn đặt ở Bước 1. Credit top-up được cộng vào credit subscription, không thay thế chúng.
Lưu sản phẩm và sao chép ID của sản phẩm.
Gói Top-Up: $9 cho 5.000 email, được cộng vào số dư sau khi thanh toán thành công.

Bước 3: Thiết lập Backend

Xây dựng Express server để tạo checkout, gửi email, đọc số dư và nhận webhook.
1

Initialize the Project

Thêm dev script vào package.json:
tsx chạy TypeScript trực tiếp, không cần build step hoặc tsconfig.json. Trong production, hãy thêm script tsconfig.json và build.
2

Configure Environment Variables

Tạo .env bằng test mode API key từ Developer → API Keys và các ID từ Bước 1 và 2:
.env
Bạn sẽ điền DODO_PAYMENTS_WEBHOOK_KEY ở Bước 4, sau khi tạo webhook endpoint. Tạo Resend API key tại resend.com/api-keys.
Thêm .env vào .gitignore trước commit đầu tiên. Không bao giờ commit API key.
3

Build the Server

Tạo server.ts ở thư mục gốc của project. Server cung cấp năm route: checkout subscription, checkout top-up, đọc số dư, gửi email và webhook receiver.
Webhook route phải nhận raw request body. express.json() thay thế body bằng parsed object, trong khi signature verification cần chính xác các byte mà Dodo Payments đã ký. Giữ route /webhooks/dodo, cùng với express.raw(), bên trên dòng app.use(express.json()).
Backend đã sẵn sàng: subscribe, top-up, balance, send và webhook handler.
4

Add a Demo UI

Tạo public/index.html. File này gọi từng route từ một form đơn giản để bạn có thể kiểm thử quy trình trong trình duyệt:

Bước 4: Kết nối Webhook Endpoint

Event credit.balance_low cho phép bạn cảnh báo khách hàng trước khi họ hết credit. Nếu không có event này, khách hàng chỉ nhận ra vấn đề khi email không gửi được.
1

Expose Your Local Server

Webhook cần một URL công khai. Trong quá trình phát triển, hãy dùng ngrok hoặc tunnel khác:
Sao chép HTTPS forwarding URL, ví dụ https://1234abcd.ngrok-free.app.
2

Register the Endpoint in Dodo Payments

  1. Đi đến Developer → Webhooks và nhấp Add endpoint.
  2. Nhập URL https://1234abcd.ngrok-free.app/webhooks/dodo, sử dụng tunnel host của bạn.
  3. Chọn các event credit.added, credit.balance_low và credit.rolled_over.
  4. Nhấp Create endpoint.
  5. Sao chép signing secret từ tab Overview của endpoint vào .env dưới dạng DODO_PAYMENTS_WEBHOOK_KEY.
  6. Khởi động lại server.

Bước 5: Kiểm thử Toàn bộ Quy trình

1

Start the Server

Server ghi log MailKit running on http://localhost:3000. Mở URL đó trong trình duyệt.
2

Subscribe a Test Customer

  1. Trong phần 1, nhập địa chỉ email và tên kiểm thử, sau đó nhấp Get checkout link.
  2. Mở link và hoàn tất checkout bằng test card.
  3. Trong dashboard, đi đến Customers và sao chép ID của customer mới, bắt đầu bằng cus_.
Customer có 5.000 email trong số dư. Để xác nhận, mở customer trong Customers và chọn tab Credits.
3

Send an Email

  1. Dán customer ID vào phần 3.
  2. Giữ To ở giá trị delivered@resend.dev, một địa chỉ kiểm thử Resend chấp nhận mọi message.
  3. Nhấp Send.
Trang hiển thị Resend message ID. Làm mới số dư trong phần 2: số dư là 4.999. Ledger debit được tính vào số dư ngay khi API call trả về.
4

Trigger the Low-Balance Webhook

Ngưỡng là 20%, tương đương 1.000 trong 5.000 email được cấp mỗi chu kỳ. Để đạt ngưỡng này mà không cần gửi 4.000 email, hãy trừ số dư thủ công trong dashboard:
  1. Mở customer trong Customers, chọn tab Credits và chọn Email Credits.
  2. Nhấp Apply Credit/Debit, chọn Debit và nhập 4000. Số dư lúc này chính xác là 1.000, vẫn chưa thấp hơn ngưỡng.
  3. Gửi thêm một email từ demo. Số dư giảm xuống 999.
Khi webhook đến, server ghi log:
Server đã nhận và xác minh webhook. Trong production, đây là nơi bạn gửi email cho customer hoặc hiển thị banner trong ứng dụng.
5

Buy a Top-Up Pack

  1. Dán customer ID vào phần 4.
  2. Nhấp Buy 5,000 emails và hoàn tất test checkout.
  3. Làm mới số dư. Số dư tăng thêm 5.000.
Dodo Payments gửi một event credit.added với transaction_type: "credit_added". Grant tương ứng có source_type: one_time, bạn có thể đọc lại bằng API List Customer Grants. Credit top-up được cộng vào credit subscription. Debit được trừ từ grant hết hạn trước, và từ grant cũ nhất khi hai grant hết hạn cùng lúc.
6

Test the Hard Stop

Trừ số dư về 0 trong dashboard, sau đó thử gửi thêm một email. Server phản hồi với 402:
402 đó là cơ chế enforcement của ứng dụng. Hãy xem balance API của Dodo Payments là nguồn dữ liệu chính xác và không cache số dư trên client.

Khắc phục sự cố

Signature bao phủ raw HTTP body. express.json() thay thế body bằng parsed object, nên việc xác minh thất bại. Đăng ký /webhooks/dodo với express.raw({ type: 'application/json' }) bên trên dòng app.use(express.json()). Sau đó kiểm tra DODO_PAYMENTS_WEBHOOK_KEY có khớp với signing secret trong tab Overview của endpoint hay không.
Kiểm tra ba điều sau theo thứ tự:
  1. Customer đã hoàn tất checkout. Credit được cấp khi thanh toán thành công, không phải khi checkout session được tạo.
  2. CREDIT_ENTITLEMENT_ID trong .env khớp với credit được gắn vào sản phẩm. Các lệnh gọi balance và ledger sử dụng ID này, vì vậy nếu không khớp, bạn sẽ đọc hoặc trừ một credit khác.
  3. customer_id bạn truyền vào là Dodo Payments customer ID (bắt đầu bằng cus_), không phải ID từ database riêng của bạn.
Test sender onboarding@resend.dev chỉ gửi đến địa chỉ email trên tài khoản Resend của bạn hoặc đến delivered@resend.dev. Để gửi đến người khác, xác minh 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ả subscription plan lẫn top-up pack.

Subscription with Prepaid Allowance

$19/tháng cấp 5.000 email trong mỗi chu kỳ thanh toán. Khách hàng biết họ trả tiền cho gì, còn bạn biết chi phí tối đa của mình.

Top-Up Pack

Một sản phẩm mua một lần cấp 5.000 email bổ sung trên credit subscription mà không thay đổi plan.

Direct Ledger Debits

Một lệnh gọi createLedgerEntry sau mỗi lần gửi, không cần meter và không có độ trễ tổng hợp. Resend message ID được dùng làm idempotency key để ngăn việc trừ lần thứ hai cho cùng một lần gửi.

Credit-Based Billing Reference

Rollover, các chế độ overage, quản lý ledger và toàn bộ credit API.
Nếu cần trợ giúp, hãy đặt câu hỏi trong Discord Community hoặc gửi email đến support@dodopayments.com.
Lần sửa đổi cuối 26 tháng 9, 2026