Production-style Node.js/Express backend for an e-commerce platform with role-based access control, JWT auth, Google OAuth, cart/order flow, file uploads, and Razorpay payments.
- Role-aware API: user, seller, admin
- JWT access tokens + refresh tokens stored in httpOnly cookies
- Google OAuth 2.0 login via Passport
- Razorpay checkout + signature verification
- Image upload pipeline (category icons, product images)
- Centralized logging with Winston + MongoDB transport
- Node.js, Express
- MongoDB + Mongoose
- JWT (access + refresh)
- Passport Google OAuth 2.0
- Razorpay
- Multer for uploads
- Winston logging (console, file, MongoDB)
routes/API routesmodels/Mongoose modelsmiddleware/auth + role checksconfig/app configuration (Passport strategy)upload/file uploads (served as static assets)logs/error logs
npm installCreate a .env file at the project root.
PORT=3000
ACCESS_TOKEN_KEY=your_access_token_secret
REFRESH_TOKEN_KEY=your_refresh_token_secret
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
RAZORPAY_KEY_ID=your_razorpay_key_id
RAZORPAY_KEY_SECRET=your_razorpay_key_secret
EXCHANGE_RATE_API_KEY=your_exchange_rate_api_keyThis project connects to mongodb://localhost:27017/learn-ecommerce by default. Ensure MongoDB is running locally, or update the connection string in index.js if you want to use a remote database.
node index.jsIf you use nodemon:
nodemon index.js- Access tokens are JWTs returned from
/api/user/registerand/api/user/login. - Send the access token in the
Authorizationheader asBearer <token>.
- Refresh tokens are issued alongside access tokens and stored in an httpOnly cookie named
refreshToken. - Use
/api/auth/refreshto rotate tokens. This invalidates the previous refresh token.
- Google OAuth uses Passport (
config/passport.js). - Flow:
- Frontend hits
/api/auth/google. - Google redirects to
/api/auth/google/callback. - Server creates or updates user, issues tokens, sets refresh cookie, and redirects back to the frontend with
tokenin the query string.
- Frontend hits
Defined in the user model:
user(default)selleradmin
Role checks are enforced using the checkRole middleware for protected routes.
auth.middleware.js: Verifies JWT access token and attachesreq.user.checkRole.middleware.js: Role-based authorization guard.multer: Handles product/category image uploads with size/type validation.- Error middleware: Centralized error handling with structured logs.
Flow:
- Client calls
/api/order/checkoutto create a Razorpay order. - Client opens Razorpay Checkout using the returned
orderId. - On success, client calls
/api/order/paymentVerifywith the Razorpay signature. - Server verifies the signature, creates the order, and clears the cart.
The HTML test harness is available at razorpay.html for local integration testing.
- Category icons:
/upload/category/<filename> - Product images:
/upload/products/<filename>
Files are stored under upload/ and served as static assets by Express.
POST /api/user/registerRegister user with email/passwordPOST /api/user/loginLogin userGET /api/userGet current user (auth required)GET /api/auth/googleStart Google OAuthGET /api/auth/google/callbackGoogle OAuth callbackPOST /api/auth/refreshRotate refresh/access tokensPOST /api/auth/logoutClear refresh token
POST /api/categoryCreate category (admin, image upload)GET /api/categoryList categories
POST /api/productsCreate product (seller, image upload)GET /api/productsList products (pagination, filters)GET /api/products/suggestionsSearch suggestionsGET /api/products/:idProduct detailsDELETE /api/products/:idDelete product (admin or seller owner)
POST /api/cart/:productIdAdd product to cartGET /api/cartGet cartPATCH /api/cart/increase/:productIdIncrease quantityPATCH /api/cart/decrease/:productIdDecrease quantityPATCH /api/cart/remove/:productIdRemove product
POST /api/order/checkoutCreate Razorpay orderPOST /api/order/paymentVerifyVerify payment + place orderGET /api/orderGet current user ordersPATCH /api/order/status/:orderIdUpdate order status (admin)
- Winston logger logs to console,
logs/errors.log, and MongoDB. - Unhandled exceptions and promise rejections are captured and logged.
- Central error middleware returns a safe 500 response for unexpected errors.
- Set
secure: truefor cookies in production. - Shorten access token TTL and enable HTTPS.
- Use a production-ready MongoDB connection string.
ISC