PRODUCTION-READY PAYSTACK + AUTHENTICATION SYSTEM
=================================================
1. PURPOSE
----------
This system ensures that a user cannot create an account until they have made a successful payment
through Paystack.
It is designed to be production-ready, with strong security practices, a clear flow, and integration
between payment verification and user registration.
---
2. STACK USED
-------------
Backend:
- [Link]
- [Link]
Database:
- MongoDB with Mongoose
Security:
- bcrypt for hashing passwords
- Environment variables with dotenv
Payment Gateway:
- Paystack API (transaction initialize + verify)
- Paystack Webhook for backup verification
---
3. INSTALLATION STEPS
---------------------
1. Install [Link] and MongoDB (or use MongoDB Atlas cloud)
2. Create your project folder and run:
npm init -y
npm install express mongoose dotenv axios bcrypt body-parser
3. Get your Paystack API keys from [Link]
4. Create a `.env` file:
PAYSTACK_SECRET_KEY=sk_test_yourkeyhere
MONGO_URI=mongodb+srv://username:password@cluster-url/dbname
PORT=3000
5. Start MongoDB server locally or connect to Atlas.
6. Run the app:
node [Link]
---
4. HOW THE SYSTEM WORKS (FULL FLOW)
-----------------------------------
A. User opens the registration form and enters:
- Username
- Email
- Password / Confirm Password
- Exam Type
B. When the user clicks “Register & Pay”:
- The `/pay` route checks:
1. If email or username already exists
2. If passwords match
- If all is good → sends payment initialization request to Paystack
- Paystack responds with an `authorization_url`
- User is redirected to that Paystack payment page
C. After payment:
- Paystack redirects the user to `/payment/callback` with a payment reference
- The server calls Paystack's verify endpoint with that reference
- If payment is successful:
1. The server extracts registration info from the Paystack metadata
2. Password is hashed with bcrypt
3. User is stored in MongoDB
4. User is redirected to the login page with a success message
- If payment fails:
→ Redirect user back to registration with an error
D. Webhook Support:
- If user closes the browser after paying, Paystack sends a POST request to `/webhook/paystack`
- The webhook verifies payment and updates user status
---
5. DATABASE SCHEMA
------------------
User Model:
username: String, // unique
email: String, // unique
password: String, // hashed
examType: String,
status: { type: String, default: 'pending' }, // updated to 'active' after payment
paystackRef: String // store Paystack transaction reference
---
6. SECURITY BEST PRACTICES
--------------------------
- Always hash passwords with bcrypt (10+ salt rounds)
- Never store API keys in code; use .env
- Validate webhook signatures (compare Paystack signature header with your secret)
- Sanitize all user inputs before saving
- Use HTTPS in production
- Restrict CORS in production
---
7. COMMON PROBLEMS + FIXES
--------------------------
❌ Payment works in test mode but fails in live mode:
✅ Ensure you switched to live keys in Paystack dashboard and `.env`
✅ Verify your callback URL is HTTPS in live
❌ Payment verified but user not created:
✅ Check if webhook is firing — some payments succeed but redirect fails
✅ Implement both callback + webhook logic
❌ “Reference not found” when verifying payment:
✅ Make sure you pass the `reference` from Paystack’s redirect URL to your verify endpoint
❌ Duplicate users:
✅ Always check for existing email/username before saving new user
✅ Store payment reference to avoid reprocessing the same transaction
---
8. DEPLOYMENT NOTES
-------------------
- For production, deploy backend on services like:
→ [Link]
→ [Link]
→ Heroku
→ VPS