-
CASHFREE_APP_IDset in production -
CASHFREE_SECRET_KEYset in production -
CASHFREE_WEBHOOK_SECRETset in production -
CRON_SECRETset in production -
BILLING_ACCOUNTS_IDcollection ID set -
BILLING_AUDIT_LOGS_IDcollection ID set -
EMAIL_API_KEYset for reminder emails -
NEXT_PUBLIC_APP_URLset to production URL
- Webhook URL configured:
https://app.fairlx.com/api/webhooks/cashfree - Webhook events enabled:
-
PAYMENT_SUCCESS_WEBHOOK -
PAYMENT_FAILED_WEBHOOK -
PAYMENT_USER_DROPPED_WEBHOOK -
REFUND_SUCCESS_WEBHOOK -
REFUND_FAILED_WEBHOOK
-
- Test mode (sandbox) verified before production
- Cron script deployed to Droplet
-
process-cyclescheduled for 1st of month -
enforce-gracescheduled daily at 1 AM UTC -
send-remindersscheduled daily at 9 AM UTC - Log directory created:
/var/log/fairlx-billing/
- Create billing account - Organization setup creates billing record
- Wallet top-up - Cashfree Checkout opens and completes payment
- Webhook received - PAYMENT_SUCCESS_WEBHOOK event processed
- Wallet credited - Balance updated with correct USD amount
- Account activated - Status set to ACTIVE
- Usage aggregated - Traffic, storage, compute summed correctly
- Invoice generated - Invoice document created with breakdown
- Wallet deduction - Auto-deduct from wallet balance
- Success flow - Invoice marked PAID, account ACTIVE
- Failure flow - Invoice marked FAILED, account DUE
- 14-day countdown - Grace period end calculated correctly
- Warning banner - Displays on all pages during DUE status
- Day 1 email - Initial payment failure notification sent
- Day 7 email - Reminder email sent
- Day 13 email - Final warning email sent
- Day 14+ suspension - Account status set to SUSPENDED
- Writes blocked - Cannot create projects, tasks, etc.
- Reads allowed - Can view existing data
- Billing page accessible - Can access billing settings
- Other pages blocked - Redirected to billing
- Suspension UI - Full-screen overlay displayed
- Payment from suspended - Can complete wallet top-up
- Instant restoration - Access restored immediately
- Status updated - Account back to ACTIVE
- Audit logged - Recovery event recorded
- Duplicate webhooks ignored
- Multiple payment attempts handled
- No double wallet credits
- Invalid webhook signatures rejected (HMAC-SHA256 with timestamp)
- Missing billing account handled gracefully
- Database errors logged and don't crash
- Invoice created BEFORE charge attempt
- Usage snapshots immutable after billing
- Audit trail complete for all events
- USD → INR conversion correct (amounts in major units for Cashfree)
- Wallet credits in original USD cents
- Exchange rate stored in order tags for auditability
- Webhook signatures verified (HMAC-SHA256 with timestamp)
- CRON_SECRET required for cron endpoints
- No sensitive data in client-side code
- Payment method details not stored
- Admin client used for billing operations
- Webhook responds within 5 seconds
- Cron jobs complete within 60 seconds
- Billing status cached appropriately
- No N+1 queries in aggregation
| Item | Date | Verified By |
|---|---|---|
| Dev Testing | ||
| Staging Testing | ||
| Production Deployment | ||
| First Billing Cycle |