πͺ GRAVITY SHOP
A full-stack 3D e-commerce platform built with Next.js, Three.js, and Stripe.
Gravity Shop is a production-grade e-commerce storefront that combines WebGL-powered 3D product visualization with a complete checkout and admin management system. Customers browse products rendered in interactive 3D scenes, add items to a cart, and complete purchases through Stripe Checkout. Administrators manage products, users, orders, inventory, and store settings through a protected dashboard.
The application is server-rendered with Next.js 14 App Router, backed by MongoDB Atlas, and secured with JWT authentication verified cryptographically at the Edge middleware layer.
- 3D Product Visualization β Interactive product scenes built with React Three Fiber and Drei
- Product Browsing β Grid layout with category filtering and real-time search
- Search Palette β Command-palette-style search with keyboard navigation (
Ctrl+K) - Shopping Cart β Slide-out cart drawer with quantity management and live totals
- Cart Animations β Fly-to-cart micro-animations using Framer Motion
- Stripe Checkout β Secure payment flow via Stripe Checkout Sessions
- User Accounts β Registration, login, and order history
- Responsive Design β Glassmorphism UI with gradient backgrounds and dark theme
- Product Management β Create, edit, and delete products with image and 3D model uploads
- Inventory Control β Real-time stock levels with low-stock alerts
- Order Management β View, filter, and update order statuses
- User Management β Search, paginate, toggle roles, activate/deactivate accounts
- Analytics β Revenue charts, top-selling products, monthly trends (Recharts)
- Store Settings β Business configuration persisted to MongoDB
- JWT Authentication β Issued on login/register, stored as HTTP-only cookies
- Edge Middleware Protection β Cryptographic JWT verification via
joseon all/adminroutes - Webhook Signature Validation β Stripe webhook payloads verified with
constructEvent() - Rate Limiting β Sliding-window limiter on sensitive endpoints via Upstash Redis
- Password Hashing β bcrypt with salt rounds
- Stripe Checkout Sessions β Server-side session creation with line items from database
- Webhook Fulfillment β Automatic order status transition and inventory decrement on payment
- Atomic Transactions β MongoDB transactions wrap fulfillment to prevent partial updates
- Idempotent Processing β Duplicate webhook deliveries are safely ignored
| Layer | Technology | Purpose |
|---|---|---|
| Framework | Next.js 14 (App Router) | Server/client rendering, API routes, middleware |
| Language | TypeScript 5 | Type safety across the stack |
| UI Library | React 18 | Component architecture |
| 3D Engine | Three.js + React Three Fiber + Drei | WebGL product visualization |
| Animation | Framer Motion + GSAP | Page transitions and micro-animations |
| Styling | Tailwind CSS 3 | Utility-first CSS |
| State | Zustand | Client-side cart and auth state |
| Database | MongoDB Atlas + Mongoose 9 | Document storage and ODM |
| Payments | Stripe SDK | Checkout sessions and webhook processing |
| Media | Cloudinary | Image and 3D model (GLB) hosting |
| Cache | Upstash Redis | Rate limiting |
| Auth | jsonwebtoken + jose + bcryptjs | Token signing, edge verification, password hashing |
| Charts | Recharts | Admin analytics visualization |
| Icons | Lucide React | UI iconography |
graph TB
subgraph Client
Browser["Browser"]
R3F["React Three Fiber"]
Zustand["Zustand Store"]
end
subgraph Edge
MW["Middleware (jose JWT)"]
end
subgraph "Next.js Server"
Pages["App Router Pages"]
API["API Routes"]
Auth["Auth API"]
Checkout["Checkout API"]
Webhook["Stripe Webhook"]
AdminAPI["Admin API"]
end
subgraph "External Services"
MongoDB["MongoDB Atlas"]
Stripe["Stripe"]
Cloudinary["Cloudinary"]
Redis["Upstash Redis"]
end
Browser --> MW
MW --> Pages
MW --> API
Browser --> R3F
Browser --> Zustand
Auth --> MongoDB
AdminAPI --> MongoDB
AdminAPI --> Cloudinary
Checkout --> Stripe
Checkout --> MongoDB
Webhook --> MongoDB
API --> Redis
gravity-shop/
βββ app/
β βββ (admin)/ # Admin route group
β β βββ analytics/page.tsx # Revenue & sales dashboard
β β βββ inventory/page.tsx # Stock management
β β βββ orders/page.tsx # Order management
β β βββ products/page.tsx # Product CRUD
β β βββ settings/page.tsx # Store configuration
β β βββ users/page.tsx # User management
β β βββ layout.tsx # Admin sidebar layout
β β βββ page.tsx # Admin dashboard home
β βββ (user)/
β β βββ account/page.tsx # User profile & orders
β β βββ layout.tsx
β βββ api/
β β βββ admin/
β β β βββ analytics/ # GET aggregated stats
β β β βββ inventory/ # GET/PATCH stock levels
β β β βββ orders/ # GET/PATCH orders
β β β βββ products/ # GET/POST products
β β β βββ settings/ # GET/PUT store settings
β β β βββ upload/ # POST file uploads
β β β βββ users/ # GET users, PATCH user by ID
β β βββ auth/
β β β βββ login/ # POST credentials
β β β βββ register/ # POST new account
β β βββ checkout/ # POST Stripe session
β β βββ health/ # GET service status
β β βββ products/ # GET public products
β β βββ search/ # GET search results
β β βββ webhooks/stripe/ # POST Stripe events
β βββ product/[id]/page.tsx # Product detail page
β βββ layout.tsx # Root layout
β βββ page.tsx # Homepage
β βββ robots.ts # SEO robots
β βββ sitemap.ts # SEO sitemap
βββ components/
β βββ admin/ # AdminSidebar, ProductDataGrid, ProductUploadModal, GlowingChart
β βββ animations/ # CartFlyAnimation
β βββ auth/ # AuthModal
β βββ canvas/ # Scene, FloatingProduct, Environment
β βββ cart/ # CartDrawer, CartItemCard, CartScene, CartSummary
β βββ product/ # ProductCard3D, ProductGrid, ProductDetails, ProductViewer, etc.
β βββ ui/ # Navbar, Hero, SearchPalette, GlassPanel, MagneticCursor, FloatingGradientBackground
βββ lib/
β βββ db/connect.ts # MongoDB connection singleton
β βββ models/
β β βββ User.ts # User schema (name, email, password, role, isActive)
β β βββ Product.ts # Product schema (name, slug, price, stock, images, model3d)
β β βββ Order.ts # Order schema (items, status, stripeSessionId)
β β βββ Setting.ts # Settings schema (key-value store by category)
β βββ api-error.ts # Structured error handling
β βββ cloudinary.ts # Upload helper
β βββ env.ts # Environment validation
β βββ logger.ts # Server-side logger
β βββ rate-limit.ts # Upstash rate limiter
βββ store/
β βββ useAppStore.ts # Zustand store (cart, auth, UI state)
βββ middleware.ts # Edge JWT verification for /admin routes
βββ next.config.mjs
βββ tailwind.config.ts
βββ tsconfig.json
βββ package.json
# Clone the repository
git clone https://github.com/ashish7802/Gravity-Shop.git
cd Gravity-Shop
# Install dependencies
npm install --legacy-peer-depsNote: The
--legacy-peer-depsflag is required due to peer dependency conflicts between React 18 and@react-three/drei.
Create a .env.local file in the project root with the following variables:
# MongoDB
MONGODB_URI=
# Authentication
JWT_SECRET=
# Stripe
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
# Cloudinary
CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=
# Upstash Redis
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
β οΈ Important: Never commit.env.localto version control. The.gitignorealready excludes it.
# Start the development server
npm run devOpen http://localhost:3000 in your browser.
# Build for production
npm run build
# Start the production server
npm start- Create a Stripe account.
- Copy your Publishable Key and Secret Key from the Stripe Dashboard β Developers β API Keys.
- Set up a webhook endpoint pointing to
https://your-domain.com/api/webhooks/stripe. - Subscribe to the
checkout.session.completedevent. - Copy the Webhook Signing Secret and add it to
STRIPE_WEBHOOK_SECRET.
# For local testing with Stripe CLI
stripe listen --forward-to localhost:3000/api/webhooks/stripe- Create a Cloudinary account.
- Navigate to Dashboard β Settings β Access Keys.
- Copy
Cloud Name,API Key, andAPI Secretinto your environment variables. - Product images upload to
gravity-shop/images/. - 3D models (GLB files) upload to
gravity-shop/models/.
- Create a MongoDB Atlas cluster.
- Create a database user with read/write permissions.
- Whitelist your IP address (or use
0.0.0.0/0for development). - Copy the connection string into
MONGODB_URI. - The application automatically creates these collections on first use:
usersproductsorderssettings
Access the admin dashboard at /admin after logging in with an admin account.
To create the first admin user, register a normal account and then update the role directly in MongoDB:
db.users.updateOne(
{ email: "your-email@example.com" },
{ $set: { role: "admin" } }
)| Page | Route | Functionality |
|---|---|---|
| Dashboard | /admin |
Overview with quick stats |
| Products | /admin/products |
CRUD with image/model uploads |
| Inventory | /admin/inventory |
Stock levels and low-stock alerts |
| Orders | /admin/orders |
Status management and filtering |
| Users | /admin/users |
Search, pagination, role toggle, activation |
| Analytics | /admin/analytics |
Revenue charts, top products, trends |
| Settings | /admin/settings |
Store, payment, media, email config |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/auth/register |
Public | Create a new user account |
POST |
/api/auth/login |
Public | Authenticate and receive JWT |
GET |
/api/products |
Public | List all products |
GET |
/api/search |
Public | Full-text product search |
POST |
/api/checkout |
User | Create a Stripe Checkout Session |
POST |
/api/webhooks/stripe |
Stripe | Handle payment webhooks |
GET |
/api/health |
Public | Service connectivity status |
GET |
/api/admin/products |
Admin | List products (admin view) |
POST |
/api/admin/products |
Admin | Create a new product |
GET |
/api/admin/orders |
Admin | List all orders |
PATCH |
/api/admin/orders |
Admin | Update order status |
GET |
/api/admin/inventory |
Admin | Get inventory levels |
PATCH |
/api/admin/inventory |
Admin | Update stock quantities |
GET |
/api/admin/users |
Admin | List users with pagination |
PATCH |
/api/admin/users/[id] |
Admin | Update user role or status |
GET |
/api/admin/analytics |
Admin | Aggregated business metrics |
GET |
/api/admin/settings |
Admin | Read store settings |
PUT |
/api/admin/settings |
Admin | Update store settings |
POST |
/api/admin/upload |
Admin | Upload images or 3D models |
- User submits credentials to
/api/auth/login. - Server verifies password hash with bcrypt.
- Server signs a JWT containing
userId,email, androle. - Token is returned and stored as an HTTP-only cookie.
All routes matching /admin/* and /api/admin/* are intercepted by Edge Middleware that:
- Extracts the JWT from cookies
- Cryptographically verifies the signature using
jose(jwtVerify) - Validates token expiration
- Checks that
role === "admin" - Returns
401or403for unauthorized requests
Stripe webhook payloads are verified using stripe.webhooks.constructEvent() with the webhook signing secret before any database mutations occur.
Sensitive endpoints are protected by a sliding-window rate limiter (10 requests / 10 seconds) powered by Upstash Redis.
- Dynamic Imports β Three.js canvas components are loaded with
next/dynamicto avoid blocking initial page render - Lazy 3D Engine β The WebGL renderer only initializes when 3D components scroll into view
- MongoDB Connection Pooling β Singleton connection pattern prevents connection exhaustion in serverless
- Aggregation Pipelines β Analytics queries use
$lookupinstead of per-document queries - Atomic Transactions β Stripe fulfillment uses
mongoose.startSession()withwithTransaction()to prevent partial writes - Image Optimization β Product images served through Cloudinary CDN with automatic format selection
- SEO β Auto-generated
robots.txtandsitemap.xmlroutes
- Push the repository to GitHub.
- Import the project in Vercel.
- Set the Install Command to
npm install --legacy-peer-deps. - Add all environment variables in Vercel Project Settings.
- Deploy.
graph LR
A["git push"] --> B["GitHub"]
B --> C["Vercel Build"]
C --> D["Edge Network"]
D --> E["Live Site"]
E --> F["MongoDB Atlas"]
E --> G["Stripe"]
E --> H["Cloudinary"]
E --> I["Upstash Redis"]
- Register a Stripe webhook endpoint pointing to
https://your-domain.vercel.app/api/webhooks/stripe. - Subscribe to
checkout.session.completed. - Update
STRIPE_WEBHOOK_SECRETwith the production signing secret.
Screenshots of the storefront, product pages, and admin dashboard can be added here.
| View | Screenshot |
|---|---|
| Homepage | Coming soon |
| Product Detail (3D) | Coming soon |
| Cart Drawer | Coming soon |
| Admin Dashboard | Coming soon |
| Admin Products | Coming soon |
| Admin Analytics | Coming soon |
- No Email Notifications β Order confirmations and shipping updates are not sent via email. The settings page includes an email configuration section for future integration.
- No Guest Checkout β Users must register or log in before purchasing.
- No Wishlist β There is no saved-items or favorites feature.
- No Multi-Currency β Stripe sessions are created in a single currency.
- No Image Cropping β Uploaded images are stored as-is without client-side cropping.
- GLB Model Dependency β 3D product previews require a GLB model URL in the product record; products without one display a static image fallback.
- Email notifications via SendGrid or Resend
- Guest checkout flow
- Wishlist and saved items
- Product reviews and ratings
- Multi-currency support
- Order tracking with shipping integration
- Bulk product import (CSV)
- Client-side image cropping before upload
This project is licensed under the MIT License.
Built with Next.js, Three.js, and Stripe