Online Payment Gateway (DodoPayments)
DodoPayments integration for online fee collection — order creation, webhook verification, and receipt generation.
The webhook (step 4 below) is the source of truth. Never trust the frontend redirect alone to confirm a payment — always wait for the webhook to update the fee account.
Payment Flow
- 1. View BalanceStudent/parent fetches fee account balance via GET /api/fees/accounts/my
- 2. Create OrderFrontend calls POST /api/payments/create-order → backend creates DodoPayments order → returns { orderId, paymentUrl }
- 3. CheckoutFrontend redirects to paymentUrl (or opens in WebView on mobile) — parent completes payment on DodoPayments page
- 4. Webhook ConfirmsDodoPayments POSTs to /api/payments/webhook → backend verifies HMAC signature → records FeePayment → updates StudentFeeAccount (source of truth)
- 5. Frontend ConfirmsDodoPayments redirects to successUrl/failureUrl → frontend polls GET /api/payments/status/:orderId to confirm result
Security
- Webhook signature verified via HMAC-SHA256 using DODOPAYMENTS_WEBHOOK_SECRET
- Idempotent webhook handling — duplicate webhooks for the same orderId are ignored
- PaymentOrder status transitions are one-way: created → pending → paid/failed — no rollback
- Amount stored in smallest currency unit (paise for INR) to avoid floating-point errors
- Order expiry enforced at 30 minutes — expired orders cannot be paid
API Routes
POST
/api/payments/create-orderCreate a DodoPayments order for a student fee account
GET
/api/payments/status/:orderIdPoll order status (used by frontend after redirect)
POST
/api/payments/webhookDodoPayments webhook — no JWT required; HMAC-verified
GET
/api/payments/historyCurrent user's payment history
GET
/api/payments/history/:studentIdAdmin/parent views a student's payment history
Environment Variables
DODOPAYMENTS_API_KEY=
DODOPAYMENTS_WEBHOOK_SECRET=
DODOPAYMENTS_BASE_URL=https://api.dodopayments.com
After Successful Payment
- FeePayment record created with transaction ID and receipt number
- StudentFeeAccount.totalPaid incremented, balance recomputed, status updated
- PDF receipt generated and stored
- Push notification sent to student and parent
- WhatsApp receipt message sent to opted-in parent