resend.emails.send को SendGrid, Postmark, SES या अपने SMTP relay से बदलें।- अपने dashboard में custom credit entitlement (emails) बनाना
- Credits को subscription plan और one-time top-up product से जोड़ना
- Resend के माध्यम से वास्तविक emails भेजना और ledger entry द्वारा प्रत्येक send पर एक credit debit करना
- अपने frontend से live credit balance query करना
- Dodo webhooks को सही ढंग से verify करना और customers के zero तक पहुंचने से पहले उन्हें सूचित करने के लिए
credit.balance_lowसंभालना
हम क्या बना रहे हैं
MailKit का pricing model यह है:- एक Dodo Payments account (test mode पर्याप्त है)
- एक free Resend account और API key
- Node.js 18+ और TypeScript की बुनियादी जानकारी
Step 1: अपना Email Credit Entitlement बनाएं
Credit entitlement उस unit को define करता है जिसे आपका platform बेचता है: इस मामले में, एक email send।
The Credits tab under Products lists all your credit entitlements.
Open the Credits section
- अपने Dodo Payments dashboard में log in करें
- बाएं sidebar में Products पर click करें
- Credits tab चुनें
- Create Credit पर click करें
Configure the credit unit
Email CreditsCredit Type: Custom Unit चुनेंUnit Name: emailPrecision: 0 (email हमेशा पूरी unit होता है; आप आधा email नहीं भेज सकते)Credit Expiry: 30 days (प्रत्येक cycle का allowance reset होता है)Leave the other defaults as-is
Save and copy the credit ID
cent_xxxxxxxxxxxx जैसी दिखाई देती है।Email Credits entitlement तैयार है। अगला चरण: customers को credits देने वाले products।Step 2: Plan और Top-Up Pack बनाएं
आप दो products बनाएंगे: एक recurring Subscription plan और एक Single Payment top-up। Plan प्रत्येक cycle में 5,000 emails देता है; top-up मांग पर 5,000 और जोड़ता है। दोनों एक हीEmail Credits entitlement से जुड़े होंगे।
MailKit Plan ($19/month, 5,000 emails)
Create the subscription
- Products → Create Product पर जाएं
- Product details भरें:
MailKit PlanDescription: 5,000 transactional emails per month.- Product type के रूप में Subscription चुनें
- Recurring price सेट करें:
19.00Billing Cycle: MonthlyCurrency: USDAttach the email credit entitlement
Email CreditsCredits issued per billing cycle: 5000Low Balance Threshold: 20 (percent; जब balance cycle allowance के 20% से कम, यानी 1,000 emails, हो जाता है तब credit.balance_low fire होता है)Import Default Credit Settings: enabled (Step 1 से 30-day expiry का उपयोग करता है)Add to Product पर click करें, फिर product को Save करें। Product ID (pdt_xxxxxxxxxxxx) copy करें।Top-Up Pack ($9 one-time, 5,000 emails)
Create a one-time product
- Products → Create Product पर जाएं
- Product details भरें:
Email Top-Up PackDescription: Add 5,000 emails to your MailKit balance instantly.- Product type के रूप में Single Payment चुनें
- Pricing सेट करें:
9.00Currency: USDAttach the credit grant
- Credit Entitlement:
Email Credits - Credits issued:
5000
Step 3: Backend सेट अप करें
अब वह Express server बनाएं जो checkout, sending, balance queries और webhooks को handle करता है।Initialize the project
package.json में dev script जोड़ें:Configure environment variables
.env बनाएं:DODO_WEBHOOK_KEY भरेंगे। Resend API key resend.com/api-keys से प्राप्त होती है।Build the server
server.ts बनाएं:Add a demo UI
public/index.html बनाएं:Step 4: Webhook Endpoint जोड़ें
credit.balance_low event customers के credits खत्म होने से पहले उन्हें सूचित करने देता है। इसके बिना, उन्हें समस्या का पहली बार तब पता चलेगा जब email भेजने में failure होगा।
Expose your local server
https://1234abcd.ngrok-free.app)।Register the endpoint in Dodo
- Developers → Webhooks → Add Endpoint पर जाएं
- URL:
https://1234abcd.ngrok-free.app/webhooks/dodo - Events:
credit.added,credit.balance_lowऔरcredit.rolled_overको subscribe करें - Save करें, फिर signing key को
.envमेंDODO_WEBHOOK_KEYके रूप में copy करें - अपना server restart करें
Step 5: पूरा Flow Test करें
Start the server
MailKit running on http://localhost:3000 दिखाई देगा। इसे अपने browser में खोलें।Subscribe a test customer
- Section 1 में test email और name दर्ज करें, Get checkout link पर click करें
- Link खोलें और test card से checkout पूरा करें
- Payment के बाद, अपने dashboard में Customers के अंतर्गत
customer_idखोजें
Send a real email
customer_idको section 3 में paste करेंtoकोdelivered@resend.devपर ही रहने दें (Resend का sandbox inbox जो सब कुछ स्वीकार करता है)- Send पर click करें
Trigger the low-balance webhook
- Customers → [Customer] → Credits → Email Credits पर जाएं
- Adjust Balance पर click करें और
4000debit करें - Demo के माध्यम से एक और email भेजें
Buy a top-up pack
customer_idको section 4 में paste करें- Buy 5,000 emails पर click करें और test checkout पूरा करें
- Balance refresh करें; यह 5,000 बढ़ जाएगा
credit.added event grant_source: one_time के साथ fire होता है। Top-up subscription credits के ऊपर जुड़ता है; दोनों pools FIFO (सबसे पुराना non-expired grant पहले) consume होते हैं।Test the hard stop
Troubleshooting
Webhook signature verification fails (401)
Webhook signature verification fails (401)
express.json() payload को parse और re-serialize करता है, जिससे HMAC टूट जाता है। सुनिश्चित करें कि /webhooks/dodo को express.raw({ type: 'application/json' }) के साथ app.use(express.json()) line से ऊपर register किया गया है और DODO_WEBHOOK_KEY endpoint detail page पर दिखाई गई signing key से match करता है।Balance is 0, customer not found, or credits don't deduct
Balance is 0, customer not found, or credits don't deduct
- Customer ने checkout पूरा किया (credits session creation पर नहीं, successful payment पर issue होते हैं)
- आपके
.envमेंCREDIT_ENTITLEMENT_IDproduct से जुड़े credit से match करता है (mismatched IDs चुपचाप गलत credit में लिखते हैं) - आप जो
customer_idभेज रहे हैं, वह Dodo से आया है (dashboard मेंcustomerstable), आपके अपने database से नहीं
Resend rejects the recipient
Resend rejects the recipient
onboarding@resend.dev केवल आपके Resend account के email या delivered@resend.dev पर deliver करता है। किसी अन्य को भेजने के लिए verify a domain करें और उस domain पर from address का उपयोग करें।आपने क्या बनाया
One reusable credit unit
Email Credits, जिसे एक बार define करके subscription plan और top-up pack दोनों से attach किया गया।Subscription with prepaid allowance
Top-up pack
Instant ledger debits
createLedgerEntry call। कोई meter नहीं, aggregation lag नहीं, और Resend के message id के माध्यम से retry पर idempotent।