A production-ready MERN application that automates WhatsApp notifications when a donor payment is recorded. Built for campus donation management.
┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ React UI │────▶│ Express API │────▶│ MongoDB │
│ (Tailwind) │ │ (JWT Auth) │ │ (Mongoose) │
└─────────────┘ └────────┬─────────┘ └──────────────┘
│ setImmediate (non-blocking)
┌────────▼─────────┐
│ WhatsApp Service│────▶ Meta Cloud API
│ (3x retry) │
└──────────────────┘
- Node.js 18+
- MongoDB (local or Atlas)
- Meta WhatsApp Business Account
git clone <repo>
cd DonorConnect
# Install backend deps
cd backend && npm install
# Install frontend deps
cd ../frontend && npm installcd backend
cp .env.example .env
# Edit .env with your actual credentialsRequired .env values:
| Variable | Description |
|---|---|
MONGODB_URI |
MongoDB connection string |
JWT_SECRET |
Long random string (32+ chars) |
WHATSAPP_PHONE_NUMBER_ID |
From Meta Developer Dashboard |
WHATSAPP_ACCESS_TOKEN |
Permanent access token |
WHATSAPP_TEMPLATE_NAME |
Approved template name |
ADMIN_EMAIL |
Seed admin email |
ADMIN_PASSWORD |
Seed admin password |
Create an approved template in Meta Business Manager:
English template (donor_payment_confirmation):
Hello {{1}}, We received your contribution of {{2}}. Thank you 🤍
Malayalam template (donor_payment_confirmation_ml):
നമസ്കാരം {{1}}, ₹{{2}} സംഭാവന ലഭിച്ചു. നന്ദി 🤍
Both templates need to be approved by Meta before use.
Terminal 1 — Backend API:
cd backend
npm run dev
# Runs on http://localhost:5000Terminal 2 — Frontend:
cd frontend
npm start
# Opens http://localhost:3000Email: admin@amanahtrack.com
Password: Admin@123456
Change these in .env before seeding.
# Build and start all services
docker-compose up -d --build
# View logs
docker-compose logs -f backend
docker-compose logs -f workerAccess at: http://localhost:3000
- Create a Railway project
- Add services: MongoDB, Redis, Backend (Node), Worker (Node), Frontend (Static)
- Set environment variables in Railway dashboard
- Link your GitHub repo and deploy
Backend start command: node server.js
Worker start command: node queue/worker.js
- Build Command:
npm install - Start Command:
node server.js - Add all
.envvariables in dashboard
- Start Command:
node queue/worker.js
- Build Command:
npm install && npm run build - Publish Directory:
build
| Method | Route | Description |
|---|---|---|
| POST | /api/auth/login |
Admin login |
| GET | /api/auth/me |
Get current admin |
| Method | Route | Description |
|---|---|---|
| GET | /api/donors |
List donors (search, pagination) |
| POST | /api/donors |
Add donor |
| PUT | /api/donors/:id |
Update donor |
| DELETE | /api/donors/:id |
Soft-delete donor |
| GET | /api/donors/analytics |
Dashboard stats |
| GET | /api/donors/export/csv |
Export CSV |
| Method | Route | Description |
|---|---|---|
| POST | /api/mark-paid |
Mark single donor paid |
| POST | /api/mark-paid/bulk |
Bulk mark paid |
| GET | /api/logs |
Message logs |
curl -X POST http://localhost:5000/api/mark-paid \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"donorId": "...", "amount": 500, "language": "en"}'- JWT Authentication — Secure admin-only access
- Donor Management — Add, edit, deactivate donors
- Payment Recording — Single & bulk mark as paid
- WhatsApp Automation — Template messages via Meta Cloud API
- Retry Logic — 3-attempt exponential backoff (2s, 4s, 8s) built-in
- Message Logs — Full audit trail of every notification
- Analytics Dashboard — Totals, averages, delivery rate
- CSV Export — Download all donor data
- Search & Filter — Real-time donor search
- Multi-language — English & Malayalam message support
- Responsive UI — Works on mobile and desktop
- Helmet.js HTTP security headers
- Rate limiting (100 req/15min global, 10 req/15min on login)
- JWT token validation on all protected routes
- Phone number E.164 format validation
- Input sanitization via express-validator
- MongoDB injection protection via Mongoose
- Environment variables for all secrets
DonorConnect/
├── backend/
│ ├── controllers/
│ │ ├── authController.js
│ │ ├── donorController.js
│ │ └── paymentController.js
│ ├── middleware/
│ │ ├── auth.js
│ │ └── errorHandler.js
│ ├── models/
│ │ ├── Admin.js
│ │ ├── Donor.js
│ │ └── MessageLog.js
│ ├── queue/
│ │ ├── redisConnection.js
│ │ ├── whatsappQueue.js
│ │ └── worker.js
│ ├── routes/
│ │ ├── auth.js
│ │ ├── donors.js
│ │ └── payments.js
│ ├── services/
│ │ └── whatsappService.js
│ ├── utils/
│ │ ├── logger.js
│ │ ├── seedAdmin.js
│ │ └── validators.js
│ └── server.js
└── frontend/
└── src/
├── components/
│ ├── common/Layout.jsx
│ └── donors/
│ ├── DonorTable.jsx
│ ├── AddDonorModal.jsx
│ ├── MarkPaidModal.jsx
│ └── BulkMarkPaidModal.jsx
├── context/AuthContext.jsx
├── pages/
│ ├── LoginPage.jsx
│ ├── DashboardPage.jsx
│ ├── DonorsPage.jsx
│ └── LogsPage.jsx
├── services/api.js
└── App.jsx