Project Name: Eternix
Type: Full-Stack E-commerce Web Application
Tech Stack: React (Vite) + Node.js (Express) + MongoDB
Created by: Vasu Bhalodiya
- Prerequisites
- Project Overview
- Project Folder Structure
- Third-Party Services Required
- Step-by-Step Setup
- Environment Variables — Backend
- Environment Variables — Frontend
- Running the Project
- API Routes Reference
- Database Models
- Stripe Webhook Setup (Local)
- Deployment Notes
- Troubleshooting
Make sure you have these installed on your system before starting:
| Tool | Version | Download Link |
|---|---|---|
| Node.js | v22.x+ | https://nodejs.org |
| npm | v10.x+ | Comes with Node.js |
| Git | Latest | https://git-scm.com |
| Stripe CLI | Latest | https://stripe.com/docs/stripe-cli |
Important
Verify installations by running:
node -v # Should show v22.x.x
npm -v # Should show 10.x.x
git --versionEternix is a full-stack e-commerce platform for fashion (T-shirts, Shirts, Jackets, Shoes) with these features:
- 🔐 Google Authentication (Firebase Auth)
- 🛍️ Product Catalog with category/gender filters
- 🛒 Shopping Cart (guest + logged-in user support)
- 💳 Stripe Payment Gateway (Checkout Sessions)
- 📦 Order Management with status tracking
- 🧾 PDF Receipt Generation (Puppeteer)
- 📧 Email Notifications (Welcome email + Order receipt via Resend)
- 👤 User Profile management
- 🔧 Admin Panel for product management (CRUD + Cloudinary image upload)
┌─────────────────────┐ API Calls ┌─────────────────────┐
│ │ ──────────────────► │ │
│ FRONTEND (React) │ │ BACKEND (Express) │
│ Port: 5173 │ ◄────────────────── │ Port: 5000 │
│ │ JSON + Cookies │ │
└─────────────────────┘ └──────────┬──────────┘
│
┌──────────▼──────────┐
│ MongoDB Atlas │
│ (Database) │
└─────────────────────┘
Ecommerce With Backend/
├── frontend/ # React (Vite) Frontend
│ ├── public/
│ │ └── favicon.svg
│ ├── src/
│ │ ├── assets/ # Static images/icons
│ │ ├── components/
│ │ │ └── common/
│ │ │ ├── Button/
│ │ │ ├── Drawer/
│ │ │ ├── Footer/
│ │ │ ├── Form/
│ │ │ ├── Header/
│ │ │ ├── Loader/
│ │ │ ├── Modal/
│ │ │ ├── PixelArtCanvas/
│ │ │ └── ProductQuickView/
│ │ ├── config/
│ │ │ └── firebase.js # Firebase client config
│ │ ├── contexts/
│ │ │ ├── ToastContext.jsx # Global toast notifications
│ │ │ └── Toast.css
│ │ ├── data/
│ │ │ └── mockData.js # Static UI data
│ │ ├── pages/
│ │ │ ├── Admin/ # Admin panel + login
│ │ │ ├── Auth/ # Google Auth page
│ │ │ ├── Cart/ # Cart sidebar
│ │ │ ├── CartPage/ # Full cart page
│ │ │ ├── Checkout/ # Checkout flow
│ │ │ ├── Collections/ # Product listing + filters
│ │ │ ├── DownloadReceipt/ # PDF receipt download
│ │ │ ├── Home/ # Landing page
│ │ │ ├── NotFound/ # 404 page
│ │ │ ├── PaymentRecipt/ # Payment success page
│ │ │ └── Profile/ # User profile
│ │ ├── store/
│ │ │ ├── actions/ # RTK Query API slices
│ │ │ │ ├── authActions.js
│ │ │ │ ├── cartActions.js
│ │ │ │ ├── paymentActions.js
│ │ │ │ ├── productActions.js
│ │ │ │ └── userActions.js
│ │ │ ├── reducers/
│ │ │ │ └── authReducer.js
│ │ │ └── index.js # Redux store configuration
│ │ ├── utils/
│ │ │ ├── AppRouter.jsx # React Router + route guards
│ │ │ ├── formatebook.js # Format utilities
│ │ │ └── guestCart.js # Guest cart (localStorage)
│ │ ├── App.jsx # Root component
│ │ ├── main.jsx # Entry point
│ │ └── index.css # Global styles
│ ├── .env.example # 👈 Frontend env template
│ ├── index.html
│ ├── vite.config.js
│ ├── vercel.json # Vercel SPA rewrites
│ ├── eslint.config.js
│ └── package.json
│
├── backend/ # Node.js (Express) Backend
│ ├── src/
│ │ ├── config/
│ │ │ ├── db.js # MongoDB connection
│ │ │ ├── cloudinary.js # Cloudinary config
│ │ │ └── firebaseAdmin.js # Firebase Admin SDK
│ │ ├── controllers/
│ │ │ ├── authController.js # Google Auth + JWT
│ │ │ ├── cartController.js # Cart CRUD
│ │ │ ├── orderController.js # Order management + PDF
│ │ │ ├── paymentController.js # Stripe checkout + webhook
│ │ │ ├── productController.js # Product CRUD
│ │ │ └── userController.js # User profile
│ │ ├── middleware/
│ │ │ ├── authMiddleware.js # JWT verification
│ │ │ └── multer.js # File upload handling
│ │ ├── models/
│ │ │ ├── User.js
│ │ │ ├── Product.js
│ │ │ ├── Cart.js
│ │ │ └── Order.js
│ │ ├── routes/
│ │ │ ├── authRoutes.js
│ │ │ ├── cartRoutes.js
│ │ │ ├── orderRoutes.js
│ │ │ ├── paymentRoutes.js
│ │ │ ├── productRoutes.js
│ │ │ └── userRoutes.js
│ │ ├── templates/
│ │ │ ├── welcomeTemplate.js # Welcome email HTML
│ │ │ ├── receiptEmailTemplate.js # Receipt email HTML
│ │ │ └── receiptTemplate.js # PDF receipt template
│ │ ├── utils/
│ │ │ ├── emailService.js # Resend email sender
│ │ │ └── generateToken.js # JWT token generator
│ │ └── validations/ # (Empty — for future Zod schemas)
│ ├── .env.example # 👈 Backend env template
│ ├── app.js # Express app config + CORS
│ ├── server.js # Server entry point
│ └── package.json
│
└── .git/ # Git repository
You need accounts on the following services. All are free-tier compatible for development.
- Website: https://cloud.mongodb.com
- What to do:
- Create a free account
- Create a new Cluster (free M0 tier is enough)
- Create a database user (username + password)
- Whitelist your IP (or use
0.0.0.0/0for development) - Click "Connect" → "Connect your application" → Copy the connection string
- Replace
<password>with your database user's password
- Provides:
MONGO_URI
- Website: https://console.firebase.google.com
- What to do:
- Create a new Firebase project
- Go to Authentication → Sign-in method → Enable Google
- Go to Project Settings → General → Add a Web App
- Copy the
apiKey,authDomain, andprojectIdfrom the config - Go to Project Settings → Service Accounts → Click "Generate new private key"
- Open the downloaded JSON file and copy:
project_id→FIREBASE_PROJECT_IDprivate_key→FIREBASE_PRIVATE_KEYclient_email→FIREBASE_CLIENT_EMAIL
- Provides (Frontend):
VITE_FIREBASE_API_KEY,VITE_FIREBASE_AUTH_DOMAIN,VITE_FIREBASE_PROJECT_ID - Provides (Backend):
FIREBASE_PROJECT_ID,FIREBASE_PRIVATE_KEY,FIREBASE_CLIENT_EMAIL
- Website: https://cloudinary.com
- What to do:
- Create a free account
- Go to Dashboard → Copy the Cloud Name, API Key, and API Secret
- Provides:
CLOUDINARY_CLOUD_NAME,CLOUDINARY_API_KEY,CLOUDINARY_API_SECRET
- Website: https://stripe.com
- What to do:
- Create an account
- Go to Developers → API Keys (use Test mode keys for development)
- Copy the Secret Key (starts with
sk_xxxx_...) - For the webhook secret, see Section 11
- Provides:
STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET
- Website: https://resend.com
- What to do:
- Create a free account
- Go to API Keys → Create a new API key
- Add & verify your sending domain (or use their
onboarding@resend.devfor testing)
- Provides:
RESEND_API_KEY,RESEND_SENDER_EMAIL
git clone <repository-url>
cd "Ecommerce With Backend"cd backend
npm installThis installs these key packages:
| Package | Purpose |
|---|---|
express |
Web framework |
mongoose |
MongoDB ODM |
cors |
Cross-Origin Resource Sharing |
cookie-parser |
Parse cookies from requests |
dotenv |
Load environment variables |
jsonwebtoken |
JWT authentication |
bcryptjs |
Password hashing |
firebase-admin |
Verify Google Auth tokens |
cloudinary |
Image upload & management |
multer |
File upload middleware |
stripe |
Payment processing |
resend |
Email sending service |
puppeteer-core |
PDF receipt generation |
@sparticuz/chromium |
Chromium binary for Puppeteer |
nodemailer |
Alternative email transport |
nodemon (dev) |
Auto-restart server on changes |
cd ../frontend
npm installThis installs these key packages:
| Package | Purpose |
|---|---|
react + react-dom |
UI library |
react-router-dom |
Client-side routing |
@reduxjs/toolkit |
State management (RTK Query) |
react-redux |
React-Redux bindings |
firebase |
Firebase client SDK (Google Auth) |
@stripe/stripe-js |
Stripe frontend SDK |
@stripe/react-stripe-js |
Stripe React components |
lucide-react |
Icon library |
vite (dev) |
Build tool & dev server |
@vitejs/plugin-react |
React plugin for Vite |
Caution
Never commit .env files to Git! They contain sensitive API keys and secrets.
cd backend
cp .env.example .env
# Now edit .env with your actual values (see Section 6)cd frontend
cp .env.example .env
# Now edit .env with your actual values (see Section 7)Create a file backend/.env with these values:
# Server Port
PORT=5000
# MongoDB Atlas Connection String
# 👉 Get from: MongoDB Atlas > Connect > Connect your application
MONGO_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/<database-name>?appName=<app-name>
# JWT Secret (any random strong string)
# 👉 Generate with: openssl rand -base64 32
JWT_SECRET=your_random_secret_key_here
# Cloudinary (Image Uploads)
# 👉 Get from: Cloudinary Dashboard
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
# Stripe (Payments)
# 👉 Get from: Stripe Dashboard > Developers > API Keys (use TEST keys)
STRIPE_SECRET_KEY=sk_xxxx_xxxxxxxxxxxxxxxxxxxxxxxx
# 👉 Get from: Stripe CLI when running `stripe listen` locally (see Section 11)
STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxxxxx
# Resend (Email Service)
# 👉 Get from: Resend Dashboard > API Keys
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxx
# 👉 Your verified sender email in Resend
RESEND_SENDER_EMAIL=your-email@yourdomain.com
# Frontend URL (for CORS configuration)
FRONTEND_URL=http://localhost:5173
# Firebase Admin SDK (Google Auth token verification)
# 👉 Get from: Firebase Console > Project Settings > Service Accounts > Generate new private key
FIREBASE_PROJECT_ID=your-firebase-project-id
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-xxxxx@your-project-id.iam.gserviceaccount.com
# ⚠️ Copy the ENTIRE private key including BEGIN/END markers
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYOUR_PRIVATE_KEY_CONTENT_HERE\n-----END PRIVATE KEY-----\n"Warning
The FIREBASE_PRIVATE_KEY must be wrapped in double quotes "..." and newlines must be represented as \n (literal backslash-n). Copy it exactly from the downloaded JSON service account file.
Create a file frontend/.env with these values:
# Backend API URL
# 👉 For local development, use:
VITE_API_URL=http://localhost:5000/api
# Admin Login Credentials (for admin panel access)
# 👉 Set to whatever admin email/password you want
VITE_ADMIN_EMAIL=admin@gmail.com
VITE_ADMIN_PASSWORD=admin1234
# Firebase (Google Auth)
# 👉 Get from: Firebase Console > Project Settings > General > Your Web App > SDK config
VITE_FIREBASE_API_KEY=your_firebase_api_key
VITE_FIREBASE_AUTH_DOMAIN=your-project-id.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-firebase-project-idNote
All frontend env variables MUST start with VITE_ prefix. This is a Vite requirement — variables without this prefix won't be accessible in the browser.
cd backend
npm run dev- Runs on:
http://localhost:5000 - Uses
nodemonfor auto-restart on file changes - You should see:
Server is running on port 5000andMongoDB Connected: ...
cd frontend
npm run dev- Runs on:
http://localhost:5173 - Uses Vite with Hot Module Replacement (HMR)
cd frontend
npm run build # Creates optimized build in /dist folder
npm run preview # Preview production build locallyTip
Open two separate terminal windows/tabs — one for backend, one for frontend. Both need to be running simultaneously.
All backend routes are prefixed with /api:
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /google |
No | Login/Register via Google |
| POST | /logout |
No | Logout (clear cookie) |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /profile |
Yes | Get logged-in user profile |
| PATCH | /profile |
Yes | Update user profile |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | / |
No | Get all products (with filters) |
| GET | /:id |
No | Get single product by ID |
| POST | / |
Yes | Create product (Admin) |
| PATCH | /:id |
Yes | Update product (Admin) |
| DELETE | /:id |
Yes | Delete product (Admin) |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | / |
Yes | Add item to cart |
| GET | / |
Yes | Get user's cart |
| PATCH | / |
Yes | Update cart item quantity |
| DELETE | / |
Yes | Remove item from cart |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /my-orders |
Yes | Get logged-in user's orders |
| GET | /:orderId/receipt |
Yes | Download PDF receipt |
| GET | /receipt-by-session/:sessionId |
No | Download receipt by Stripe session |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /create-checkout-session |
Yes | Create Stripe checkout session |
| POST | /webhook |
No | Stripe webhook handler |
| GET | /verify-session/:sessionId |
No | Verify Stripe session status |
| Field | Type | Required | Notes |
|---|---|---|---|
| username | String | Yes | |
| String | Yes | Unique | |
| googleId | String | No | Unique, sparse |
| avatar | String | No | Profile picture URL |
| phone | String | No | |
| shippingAddress | Object | No | address, country, state, city, postalCode |
| Field | Type | Required | Notes |
|---|---|---|---|
| name | String | Yes | |
| price | Number | Yes | |
| category | String | Yes | Enum: tshirt, shirt, jacket, shoes |
| gender | String | Yes | Enum: man, woman, kids |
| status | String | No | Enum: "New In", "Best Seller" |
| description | String | Yes | |
| sizes | [String] | Yes | |
| colors | [Object] | No | Array of { name, hex } |
| image | String | Yes | Cloudinary URL |
| Field | Type | Required | Notes |
|---|---|---|---|
| user | ObjectId | Yes | References User |
| items | [Object] | Yes | Array of { product, quantity, size, color } |
| Field | Type | Required | Notes |
|---|---|---|---|
| user | ObjectId | Yes | References User |
| items | [Object] | Yes | Array of { product, quantity, size, color } |
| contactInfo | Object | Yes | fullName, phone, email |
| shippingInfo | Object | Yes | country, state, city, postalCode, address |
| subtotal | Number | Yes | |
| shippingCharge | Number | No | Default: 0 |
| totalAmount | Number | Yes | |
| status | String | No | Enum: Pending, Processing, Shipped, Delivered, Cancelled |
| paymentStatus | String | No | Enum: Unpaid, Paid |
| stripeSessionId | String | No | |
| orderNumber | String | No | Unique |
| paymentId | String | No |
For payments to work locally, you need to forward Stripe webhooks to your local server:
# macOS
brew install stripe/stripe-cli/stripe
# Windows (Scoop)
scoop install stripe
# Linux
# Download from: https://stripe.com/docs/stripe-cli#installstripe loginstripe listen --forward-to localhost:5000/api/payment/webhookAfter running the above command, you'll see something like:
> Ready! Your webhook signing secret is whsec_xxxxxxxxxxxxxxxxxxxxx
Copy this value and set it as STRIPE_WEBHOOK_SECRET in your backend .env file.
Important
Keep the stripe listen command running in a separate terminal while testing payments locally. This is the third terminal you need (Backend + Frontend + Stripe CLI).
The project includes a vercel.json for SPA routing:
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}- Deploy via
vercelCLI or connect the GitHub repo to Vercel Dashboard - Set all
VITE_*environment variables in Vercel project settings - The
VITE_API_URLshould point to your deployed backend URL (e.g.,https://api.yourdomain.com/api)
- Can be deployed on Render, Railway, Fly.io, or any Node.js hosting
- Set all backend env variables in the hosting platform
- Update
FRONTEND_URLto your deployed frontend URL - Update the
allowedOriginsarray inapp.jsto include your production frontend URL - For Stripe webhooks in production, create a webhook endpoint in Stripe Dashboard pointing to
https://your-backend.com/api/payment/webhook
- Check your
MONGO_URIconnection string - Ensure your IP is whitelisted in MongoDB Atlas (Network Access)
- Verify the database user credentials
- Check that
FRONTEND_URLin backend.envmatches your frontend URL exactly - Check the
allowedOriginsarray inbackend/app.js
- Ensure all 3 Firebase env variables are set in frontend
- Ensure all 3 Firebase Admin env variables are set in backend
- Check that Google sign-in is enabled in Firebase Console > Authentication
- Verify
FIREBASE_PRIVATE_KEYhas correct\nformatting
- Ensure you're using test mode keys (starts with
sk_xxxx_) - Make sure
stripe listenis running for local webhook forwarding - Check that
STRIPE_WEBHOOK_SECRETmatches the CLI output
- Verify all 3 Cloudinary env variables
- Check your Cloudinary account hasn't exceeded the free tier limit
- Verify
RESEND_API_KEYis correct - Ensure your sender domain is verified in Resend Dashboard
- For testing, use
onboarding@resend.devas sender
puppeteer-corerequires a Chromium binary- The
@sparticuz/chromiumpackage provides this - Locally, you may need to install Chromium:
npx @puppeteer/browsers install chromium
# 1. Clone the repo
git clone <repo-url>
cd "Ecommerce With Backend"
# 2. Setup Backend
cd backend
npm install
cp .env.example .env
# Edit .env with your actual values
# 3. Setup Frontend
cd ../frontend
npm install
cp .env.example .env
# Edit .env with your actual values
# 4. Start Backend (Terminal 1)
cd backend
npm run dev
# 5. Start Frontend (Terminal 2)
cd frontend
npm run dev
# 6. Start Stripe Webhook Listener (Terminal 3 — for payments)
stripe listen --forward-to localhost:5000/api/payment/webhook
# 7. Open browser
# Go to: http://localhost:5173Note
Minimum 3 terminals needed for full functionality:
- Backend server (
npm run devin/backend) - Frontend dev server (
npm run devin/frontend) - Stripe webhook listener (
stripe listen --forward-to ...)
Last Updated: June 27, 2026