A production-ready REST API for a multi-role e-commerce platform built with Spring Boot 3, PostgreSQL, JWT Authentication, and Stripe Payments
- Overview
- Features
- Tech Stack
- Architecture
- Project Structure
- Prerequisites
- Setup & Installation
- Configuration
- API Endpoints
- Database Schema
- Security Features
- Default Credentials
- Contributing
- License
ShopSphere Backend (SB-Ecom) is a comprehensive, enterprise-grade e-commerce REST API built with Spring Boot 3 and Java 21. It supports three distinct user roles — Admin, Seller, and User — each with their own scoped access and capabilities.
The API handles everything from product and category management to shopping carts, order processing, Stripe payments, and real-time analytics. It is backed by PostgreSQL on AWS RDS and secured with stateless JWT authentication via httpOnly cookies.
- JWT (JSON Web Token) based authentication
- Role-based access control (RBAC)
- Secure password hashing with BCrypt
- User registration and login
- Cookie-based JWT token management
- Create, read, update, and delete products
- Category-based product organization
- Product search and filtering
- Advanced pagination and sorting
- Image upload and management
- Product inventory tracking
- User registration and profile management
- Address management (multiple addresses per user)
- User role management (ADMIN, USER, SELLER)
- Account settings and preferences
- Add/remove products from cart
- Update product quantities
- Real-time cart total calculation
- Cart persistence
- Order creation and processing
- Order tracking and status updates
- Order history and details
- Order item management
- Stripe integration — create payment intents and confirm payments
- Payment status tracking per order
httpOnlycookie-based JWT for XSS protection
- Admin: full product, category, order, seller, and analytics management
- Seller: manage own products and view own orders (DB-level filtered, paginated)
- Analytics endpoint: total revenue, order count, product count, user count
- Auto-seeded default roles and accounts on startup via
DataSeeder
| Technology | Version | Purpose |
|---|---|---|
| Java | 21 | Programming Language |
| Spring Boot | 3.4.1 | Framework |
| Spring Security | 3.4.1 | Authentication & Authorization |
| Spring Data JPA | 3.4.1 | Database ORM |
| Spring Validation | 3.4.1 | Input Validation |
| Technology | Version | Purpose |
|---|---|---|
| PostgreSQL | Latest | Primary Database (RDS) |
| H2 | Latest | Testing Database |
| Library | Version | Purpose |
|---|---|---|
| JJWT | 0.12.5 | JWT token generation & validation |
| Stripe Java SDK | 31.3.0 | Payment intent creation |
| Lombok | 1.18.36 | Reduce boilerplate code |
| ModelMapper | 3.2.4 | DTO ↔ Entity mapping |
| Maven | 3.8+ | Build & dependency management |
- Amazon RDS (PostgreSQL) — managed cloud database
- Local image storage — uploaded product images stored in
images/directory
The application follows a 3-tier layered architecture:
┌─────────────────────────────────────────┐
│ Controller Layer (REST APIs) │
│ Handles HTTP requests & responses │
└──────────────┬──────────────────────────┘
│
┌──────────────▼──────────────────────────┐
│ Service Layer (Business Logic) │
│ Implements core application logic │
└──────────────┬──────────────────────────┘
│
┌──────────────▼──────────────────────────┐
│ Repository Layer (Data Access) │
│ Interacts with Database via JPA │
└──────────────┬──────────────────────────┘
│
┌──────────────▼──────────────────────────┐
│ Database (PostgreSQL/H2) │
│ Persistent Data Storage │
└─────────────────────────────────────────┘
ecom-spring/
├── src/
│ ├── main/
│ │ ├── java/com/ecommerce/sb_ecom/
│ │ │ ├── SbEcomApplication.java # Main Spring Boot Application
│ │ │ └── project/
│ │ │ ├── config/ # Configuration Classes
│ │ │ │ ├── AppConfig.java
│ │ │ │ ├── AppConstant.java
│ │ │ │ └── WebMvcConfig.java
│ │ │ │
│ │ │ ├── controller/ # REST API Controllers
│ │ │ │ ├── ProductController.java
│ │ │ │ ├── CategoryController.java
│ │ │ │ ├── CartController.java
│ │ │ │ ├── OrderController.java
│ │ │ │ ├── AddressController.java
│ │ │ │ └── AuthController.java
│ │ │ │
│ │ │ ├── service/ # Service Layer
│ │ │ │ ├── ProductService.java
│ │ │ │ ├── ProductServiceImp.java
│ │ │ │ ├── CartService.java
│ │ │ │ ├── CartServiceImp.java
│ │ │ │ ├── OrderService.java
│ │ │ │ ├── OrderServiceImp.java
│ │ │ │ └── ... (other services)
│ │ │ │
│ │ │ ├── repositories/ # Data Access Layer
│ │ │ │ ├── ProductRepository.java
│ │ │ │ ├── CategoryRepository.java
│ │ │ │ ├── CartRepository.java
│ │ │ │ ├── OrderRepository.java
│ │ │ │ └── ... (other repositories)
│ │ │ │
│ │ │ ├── model/ # Entity Models
│ │ │ │ ├── Product.java
│ │ │ │ ├── Category.java
│ │ │ │ ├── User.java
│ │ │ │ ├── Cart.java
│ │ │ │ ├── CartItem.java
│ │ │ │ ├── Order.java
│ │ │ │ ├── OrderItem.java
│ │ │ │ ├── Address.java
│ │ │ │ ├── Payment.java
│ │ │ │ ├── Role.java
│ │ │ │ └── AppRole.java
│ │ │ │
│ │ │ ├── payload/ # DTOs & Response Objects
│ │ │ │ ├── ProductDTO.java
│ │ │ │ ├── CategoryDTO.java
│ │ │ │ ├── CartDTO.java
│ │ │ │ ├── OrderDTO.java
│ │ │ │ ├── AddressDTO.java
│ │ │ │ ├── ProductResponse.java
│ │ │ │ ├── APIResponse.java
│ │ │ │ └── ... (other DTOs)
│ │ │ │
│ │ │ ├── security/ # Security Configuration
│ │ │ │ ├── WebSecurityConfig.java
│ │ │ │ ├── jwt/
│ │ │ │ │ ├── JwtUtils.java
│ │ │ │ │ ├── AuthTokenFilter.java
│ │ │ │ │ └── AuthEntryPointJwt.java
│ │ │ │ ├── services/
│ │ │ │ │ ├── UserDetailsServiceImp.java
│ │ │ │ │ └── UserDetailsImp.java
│ │ │ │ └── request/
│ │ │ │ └── LoginRequest.java
│ │ │ │
│ │ │ ├── exceptions/ # Exception Handling
│ │ │ │ ├── APIException.java
│ │ │ │ ├── ResourceNotFoundException.java
│ │ │ │ └── MyGlobalExceptionHandler.java
│ │ │ │
│ │ │ └── util/ # Utility Classes
│ │ │ └── AuthUtil.java
│ │ │
│ │ └── resources/
│ │ ├── application.properties # Main Configuration
│ │ └── application-test.properties # Test Configuration
│ │
│ └── test/ # Unit & Integration Tests
│ ├── java/
│ └── resources/
│
├── images/ # Image Storage Directory
│
├── pom.xml # Maven Dependencies
├── mvnw & mvnw.cmd # Maven Wrapper
├── target/ # Build Output
└── README.md # Project Documentation
Before you begin, ensure you have the following installed:
- Java 21 or higher
java -version
- Maven 3.8+
mvn -version
- PostgreSQL 12+ (or use Amazon RDS)
- Git
- Node.js & npm (for frontend integration)
git clone https://github.com/yourusername/ecom-spring.git
cd ecom-springEdit src/main/resources/application.properties:
# PostgreSQL Configuration
spring.datasource.url=jdbc:postgresql://your-host:5432/your-database
spring.datasource.username=your-username
spring.datasource.password=your-password
spring.datasource.driver-class-name=org.postgresql.DriverIn application.properties, update your JWT secret:
spring.app.jwtSecret=your-super-secret-key-min-32-characters-long
spring.app.jwtExpirationMs=3600000
spring.app.jwtCookieName=springBootEcommvn clean installmvn spring-boot:runOr run the JAR file:
java -jar target/sb-ecom-0.0.1-SNAPSHOT.jarThe application will start on http://localhost:5000
# Server Configuration
server.port=5000
# Database Configuration
spring.datasource.url=jdbc:postgresql://ecom.cpq4iaua6gyt.eu-north-1.rds.amazonaws.com:5432/ecom
spring.datasource.username=postgres
spring.datasource.password=****
# JPA/Hibernate Configuration
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
# JWT Configuration
spring.app.jwtSecret=mySecretKey123912738aopsgjnspkmndfsopkvajoirjg94gf2opfng2moknm
spring.app.jwtExpirationMs=3000000
spring.app.jwtCookieName=springBootEcom
# Image Storage Configuration
image.base.url=http://ecom-env.eba-f5y6srgx.eu-north-1.elasticbeanstalk.com/images/a.png
image.storage.path=images/
# Frontend Configuration
frontend.url=http://localhost:3000/All endpoints are prefixed with
/api
| Method | Endpoint | Access | Description |
|---|---|---|---|
POST |
/auth/signin |
Public | Login — returns JWT cookie |
POST |
/auth/signup |
Public | Register new user |
POST |
/auth/signout |
Authenticated | Logout — clears JWT cookie |
GET |
/auth/user |
Authenticated | Get current user info |
GET |
/auth/sellers |
Admin | List all sellers (paginated) |
| Method | Endpoint | Access | Description |
|---|---|---|---|
GET |
/public/product |
Public | List products (filter, sort, paginate) |
GET |
/public/categories/{id}/products |
Public | Products by category |
GET |
/public/products/Keyword/{kw} |
Public | Search by keyword |
POST |
/admin/categories/{id}/product |
Admin/Seller | Create product |
PUT |
/admin/products/{id} |
Admin/Seller | Update product |
DELETE |
/admin/products/{id} |
Admin/Seller | Delete product |
PUT |
/admin/products/{id}/image |
Admin/Seller | Upload product image |
GET |
/admin/products |
Admin | All products (paginated) |
GET |
/seller/products |
Seller | Seller's own products (paginated) |
| Method | Endpoint | Access | Description |
|---|---|---|---|
GET |
/public/categories |
Public | List all categories (paginated) |
POST |
/admin/categories |
Admin | Create category |
PUT |
/admin/categories/{id} |
Admin | Update category |
DELETE |
/admin/categories/{id} |
Admin | Delete category |
| Method | Endpoint | Access | Description |
|---|---|---|---|
GET |
/carts/users/cart |
User | Get current user's cart |
POST |
/carts/products/{id}/quantity/{qty} |
User | Add product to cart |
PUT |
/carts/{cartId}/products/{id}/quantity/{op} |
User | Update quantity |
DELETE |
/carts/{cartId}/products/{id} |
User | Remove product from cart |
| Method | Endpoint | Access | Description |
|---|---|---|---|
POST |
/order/users/payments/{method} |
User | Place an order |
GET |
/order/users/orders |
User | Get logged-in user's orders |
POST |
/order/stripe-client-secret |
User | Create Stripe payment intent |
GET |
/admin/orders |
Admin | All orders (paginated) |
GET |
/seller/orders |
Seller | Seller's orders (paginated) |
PUT |
/admin/orders/{id}/status |
Admin/Seller | Update order status |
| Method | Endpoint | Access | Description |
|---|---|---|---|
GET |
/users/addresses |
User | Get user's addresses |
POST |
/addresses |
User | Add new address |
PUT |
/addresses/{id} |
User | Update address |
DELETE |
/addresses/{id} |
User | Delete address |
| Method | Endpoint | Access | Description |
|---|---|---|---|
GET |
/admin/app/analytics |
Admin | Revenue, orders, products, users count |
User (1) ----< (Many) Cart
|
+--< (Many) Address
|
+--< (Many) Order
|
+--< (Many) Role
|
+--< (Many) Product (as seller)
Product (1) ----< (Many) CartItem
|
+----< (Many) OrderItem
|
+----< (1) Category
Cart (1) ----< (Many) CartItem
Order (1) ----< (Many) OrderItem
|
+----< (1) Payment
| Table | Purpose |
|---|---|
users |
User accounts and profiles |
products |
Product catalog |
categories |
Product categories |
cart |
Shopping carts |
cart_items |
Items in cart |
orders |
Customer orders |
order_items |
Items in orders |
addresses |
User delivery addresses |
payments |
Payment transactions |
roles |
User roles (ADMIN, USER, SELLER) |
user_role |
User-Role mapping |
- JWT Tokens for stateless authentication
- BCrypt password encryption
- Cookie-based token storage
- Token Refresh mechanism
- Role-Based Access Control (RBAC)
- ADMIN: Full system access
- SELLER: Manage own products
- USER: Browse and purchase products
- Method-level security using
@PreAuthorize - URL pattern-based authorization
- Secure password hashing (min 8 characters)
- CORS configuration for frontend integration
- Exception handling with proper HTTP status codes
- Validation of all user inputs
- Protection against SQL injection (using JPA)
- HTTPS ready configuration
- Stateless JWT — tokens stored in
httpOnlycookies (XSS-safe) - BCrypt password hashing
- JWT expiry configurable via
spring.app.jwtExpirationMs
- Role-Based Access Control (RBAC)
ROLE_ADMIN— full system accessROLE_SELLER— manage own products and view own ordersROLE_USER— browse, cart, checkout, view own orders
- Method-level security via
@PreAuthorizeannotations - URL pattern-based rules in
WebSecurityConfig - Ownership checks on address and cart endpoints
- File upload validation — whitelist of allowed image extensions, path traversal prevention
Seeded automatically on first startup via DataSeeder:
| Role | Username | Password |
|---|---|---|
| Admin | admin |
password |
| Seller | seller |
password |
| User | user1 |
password |
⚠️ Change these credentials before deploying to production.
We welcome contributions! Here's how you can help:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- Follow Google Java Style Guide
- Use meaningful variable/method names
- Add comments for complex logic
- Write unit tests for new features
- Keep commits small and focused
This project is licensed under the MIT License - see the LICENSE file for details.
For issues, questions, or suggestions:
- Create an Issue on GitHub
- Email: support@example.com
- Discord: Join Our Community
- Stripe payment integration
- Role-based access control (Admin / Seller / User)
- Seller-scoped order and product management
- User order history endpoint
- Analytics dashboard endpoint
- Email notifications on order placement
- Product reviews & ratings
- Coupon & discount system
- Wishlist feature
- Real-time notifications (WebSocket)