Skip to content

About

Production-grade eCommerce backend built with Java, Spring Boot, JPA, Redis, Kafka, OAuth2, Spring Cloud, Docker, Kubernetes and AWS.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

80 Commits

Folders and files

Repository files navigation

Ecommerce Engine

A Spring Boot based e-commerce backend built as a learning project to explore modern backend development concepts, including REST APIs, microservices, Redis caching, database persistence, projections, external API integration, payment gateways, and Spring Cloud service discovery.


πŸ—οΈ Architecture

The project is gradually being evolved from a simple Spring Boot application into a microservices-based e-commerce system.

                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚       Client        β”‚
                         β”‚   Postman / Web UI  β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                                    β–Ό
                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚   Product Service   β”‚
                         β”‚     Port: 9000      β”‚
                         β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                                β”‚       β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       └─────────────┐
                    β–Ό                                 β–Ό
             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚    Redis    β”‚                    β”‚    MySQL    β”‚
             β”‚    Cache    β”‚                    β”‚  Database   β”‚
             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
                    β–Ό
             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚   Fake Store API β”‚
             β”‚ External Product β”‚
             β”‚      Source      β”‚
             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜


             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚  Payment Service β”‚
             β”‚                  β”‚
             β”‚  Stripe / Razorpay
             β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
                      β–Ό
               Payment Gateway


             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚ Service Discoveryβ”‚
             β”‚     Eureka       β”‚
             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Technologies

Backend

  • Java 17
  • Spring Boot 3.5.x
  • Spring MVC
  • Spring Data JPA
  • Hibernate
  • Spring Security
  • Spring Data Redis
  • Spring Cloud
  • Netflix Eureka

Database & Storage

  • MySQL
  • Redis
  • Flyway

External Services

  • Fake Store API
  • Stripe
  • Razorpay

Build & Development

  • Maven
  • IntelliJ IDEA
  • Postman
  • Git / GitHub

πŸ“¦ Project Structure

Ecommerce-engine/
β”‚
β”œβ”€β”€ ProductService/
β”‚   β”‚
β”‚   β”œβ”€β”€ src/main/java/
β”‚   β”‚   └── com/Ashim/CommerceEngine/
β”‚   β”‚       β”‚
β”‚   β”‚       β”œβ”€β”€ productService/
β”‚   β”‚       β”‚   β”œβ”€β”€ controllers/
β”‚   β”‚       β”‚   β”œβ”€β”€ services/
β”‚   β”‚       β”‚   β”œβ”€β”€ repositories/
β”‚   β”‚       β”‚   β”œβ”€β”€ models/
β”‚   β”‚       β”‚   β”œβ”€β”€ dtos/
β”‚   β”‚       β”‚   β”œβ”€β”€ projections/
β”‚   β”‚       β”‚   └── exceptions/
β”‚   β”‚       β”‚
β”‚   β”‚       └── ProductServiceApplication.java
β”‚   β”‚
β”‚   └── src/main/resources/
β”‚       β”œβ”€β”€ application.properties
β”‚       └── db/migration/
β”‚
β”œβ”€β”€ PaymentService/
β”‚   β”‚
β”‚   └── src/main/java/
β”‚       └── com/ashim/PaymentService/
β”‚           β”œβ”€β”€ controller/
β”‚           β”œβ”€β”€ services/
β”‚           β”œβ”€β”€ paymentGateway/
β”‚           └── models/
β”‚
β”œβ”€β”€ ServiceDiscovery/
β”‚   └── Eureka Server
β”‚
└── README.md

πŸ›οΈ Product Service

The Product Service is the main e-commerce service.

It provides APIs for:

  • Creating products
  • Fetching products
  • Updating products
  • Deleting products
  • Pagination
  • Product summaries
  • Category management
  • External product integration
  • Redis caching

πŸ”Œ Product API

Get Product

GET /products/{id}

Example:

GET http://localhost:9000/products/20

Get Product Summary

Returns only selected product fields using a JPA projection.

GET /products/summary

Example response:

[
  {
    "title": "iPhone 14",
    "price": 69999
  },
  {
    "title": "MacBook Air M3",
    "price": 114999
  }
]

Instead of loading the complete Product entity, the database returns only the required fields.


πŸ“„ Pagination

Products can be retrieved using pagination.

GET /products?pageNumber=0&pageSize=10

Spring Data's Pageable and Page are used to implement pagination.


πŸ—„οΈ Database

The application uses MySQL for persistent storage.

Main entities include:

  • Product
  • Category
  • User
  • Order
  • Payment

Example relationship:

Category
   β”‚
   └─── 1 : N ─── Products

πŸ”„ Database Migration

Flyway is used for database versioning.

Migration files are stored under:

src/main/resources/db/migration/

Example:

V1__create_product_tables.sql
V2__create_category_tables.sql
V3__add_indexes.sql
V4__insert_initial_data.sql

Flyway keeps track of which migrations have already been executed.


⚑ Redis Caching

Redis is used as a cache for product data.

The basic flow is:

Client
  β”‚
  β–Ό
Product Service
  β”‚
  β–Ό
Check Redis
  β”‚
  β”œβ”€β”€ Cache HIT ──────► Return Product
  β”‚
  └── Cache MISS
          β”‚
          β–Ό
      Fake Store API
          β”‚
          β–Ό
      Store in Redis
          β”‚
          β–Ό
      Return Product

For example:

Product product =
        (Product) redisTemplate
                .opsForHash()
                .get("products", "products_" + productId);

If the product is present in Redis, the external API call can be avoided.

This significantly reduces response time.


🌐 Fake Store API Integration

The project also demonstrates integration with an external REST API.

RestTemplate is used to communicate with Fake Store API.

Example:

FakeStoreProductDto product =
        restTemplate.getForObject(
            "https://fakestoreapi.com/products/" + productId,
            FakeStoreProductDto.class
        );

The application uses an abstraction:

ProductService
      β”‚
      β”œβ”€β”€ SelfProductService
      β”‚       └── MySQL
      β”‚
      └── FakeStoreProductService
              └── Fake Store API

This demonstrates programming to an interface and allows different implementations of the same business operation.


πŸ” JPA Projection

The project demonstrates Spring Data JPA interface-based projections.

Example:

public interface ProductWithTitleAndPrice {

    String getTitle();

    Double getPrice();
}

Repository:

@Query("""
       SELECT p.title AS title,
              p.price AS price
       FROM Product p
       """)
List<ProductWithTitleAndPrice> findAllProjectedBy();

Instead of retrieving the entire entity:

Product
 β”œβ”€β”€ id
 β”œβ”€β”€ title
 β”œβ”€β”€ price
 β”œβ”€β”€ description
 β”œβ”€β”€ image
 β”œβ”€β”€ category
 β”œβ”€β”€ createdAt
 └── updatedAt

the database returns only:

title
price

This is useful when the client needs only a subset of fields.


πŸ’³ Payment Service

Payment processing is separated into its own service.

The Payment Service follows the Gateway/Strategy approach.

PaymentController
       β”‚
       β–Ό
PaymentService
       β”‚
       β–Ό
PaymentGateway
       β”‚
       β”œβ”€β”€ StripePaymentGateway
       β”‚
       └── RazorpayPaymentGateway

The application does not directly depend on Stripe or Razorpay in the business layer.

Instead, it depends on:

PaymentGateway

This makes it possible to change the payment provider without changing the core payment service.


πŸ’° Stripe Payment Flow

The current Stripe implementation creates a Payment Link.

The flow is:

Client
  β”‚
  β”‚  Create Order
  β–Ό
Order Service
  β”‚
  β”‚ orderId
  β–Ό
Payment Service
  β”‚
  β–Ό
StripePaymentGateway
  β”‚
  β”œβ”€β”€ Create Price
  β”‚
  β”œβ”€β”€ Create Payment Link
  β”‚
  β–Ό
Stripe
  β”‚
  β–Ό
Payment URL
  β”‚
  β–Ό
Client

The Stripe integration uses:

StripeClient

A price is created:

PriceCreateParams priceParams =
        PriceCreateParams.builder()
                .setCurrency("inr")
                .setUnitAmount(100000L)
                .setProductData(
                        PriceCreateParams.ProductData.builder()
                                .setName("iphone_charger")
                                .build()
                )
                .build();

Then:

Price price = stripeClient
        .prices()
        .create(priceParams);

A Payment Link is then created using the generated price:

PaymentLinkCreateParams paymentLinkParams =
        PaymentLinkCreateParams.builder()
                .addLineItem(
                        PaymentLinkCreateParams.LineItem.builder()
                                .setPrice(price.getId())
                                .setQuantity(1L)
                                .build()
                )
                .build();

Finally:

PaymentLink paymentLink =
        stripeClient.paymentLinks()
                .create(paymentLinkParams);

The URL is returned to the client:

return paymentLink.getUrl();

πŸ” Payment Idempotency

Payment systems must be designed carefully because clients can retry requests.

For example:

POST /payments

could be sent twice because of:

  • Network timeout
  • Browser retry
  • Client retry
  • Load balancer retry
  • Application retry

Without idempotency:

Request 1 β†’ Payment created
Request 2 β†’ Another payment created

This can result in duplicate charges.

The intended design is:

Client
   β”‚
   β”‚ orderId / idempotency key
   β–Ό
Payment Service
   β”‚
   β”œβ”€β”€ Check existing payment
   β”‚
   β”œβ”€β”€ Already processed?
   β”‚       └── Return existing result
   β”‚
   └── Otherwise
           β”‚
           β–Ό
       Payment Gateway

The orderId is created before initiating payment and is used to associate the payment with the order.


πŸ”” Stripe Webhooks

Payment completion should not rely only on the browser redirect.

The payment provider can notify the backend through a webhook.

Customer
   β”‚
   β–Ό
Stripe Checkout
   β”‚
   β”‚ Payment
   β–Ό
Stripe
   β”‚
   β”‚ Webhook
   β–Ό
Payment Service
   β”‚
   β–Ό
Verify Event
   β”‚
   β–Ό
Update Payment Status

This allows the backend to receive the actual payment event independently of the user's browser.


πŸ”Ž Service Discovery

The project also introduces Spring Cloud Netflix Eureka.

The architecture becomes:

                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                 β”‚  Eureka Server    β”‚
                 β”‚ Service Discovery β”‚
                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚            β”‚            β”‚
             β–Ό            β–Ό            β–Ό
      Product Service  Payment      User Service
                       Service

Services register themselves with Eureka.

Instead of hardcoding service locations:

http://localhost:9000
http://localhost:8080

services can discover each other through service names.


πŸ” Configuration & Secrets

Environment-specific configuration is kept outside the committed source code.

Example:

DB_URL
DB_USERNAME
DB_PASSWORD

STRIPE_API_KEY

SERVER_PORT

The .env file is intentionally excluded from Git:

.env

Never commit:

  • Database passwords
  • Stripe secret keys
  • API keys
  • OAuth secrets
  • JWT secrets

πŸ§ͺ Running the Project

Prerequisites

Install:

  • Java 17
  • Maven
  • MySQL
  • Redis
  • Git

1. Clone

git clone https://github.com/ashim-roy/Ecommerce-engine.git
cd Ecommerce-engine

2. Configure Environment Variables

Create a local .env / environment configuration containing the required values.

Example:

SERVER_PORT=9000

DB_URL=jdbc:mysql://localhost:3306/productservice
DB_USERNAME=<your-db-user>
DB_PASSWORD=<your-db-password>

JPA_SHOW_SQL=true
DDL_AUTO=update
FLYWAY_BASELINE_ON_MIGRATE=true

Do not commit this file.


▢️ Start Redis

Verify Redis:

redis-server --version

Test the connection:

redis-cli ping

Expected:

PONG

▢️ Start Product Service

Run:

mvn spring-boot:run

The Product Service runs on:

http://localhost:9000

▢️ Start Payment Service

Run the Payment Service separately.

Example:

http://localhost:<payment-service-port>

▢️ Start Service Discovery

Start the Eureka Server separately.

Once running, services register themselves with Eureka.


🧠 Concepts Covered

This project is primarily a learning project and demonstrates several important backend engineering concepts:

Spring Boot

  • Dependency Injection
  • IoC
  • REST Controllers
  • Service Layer
  • Repository Layer
  • Configuration
  • Exception Handling

Spring Data JPA

  • Entity Mapping
  • JpaRepository
  • JPQL
  • Pagination
  • Projections
  • DTOs
  • Repository queries

Redis

  • Caching
  • Cache Hit / Cache Miss
  • RedisTemplate
  • Redis Hashes

Microservices

  • Service separation
  • Payment Service
  • Product Service
  • Service Discovery
  • Eureka

Payment Systems

  • Payment Gateway abstraction
  • Stripe integration
  • Payment Links
  • Webhooks
  • Idempotency
  • Order ID based payment tracking

Software Design

  • Programming to an Interface
  • Strategy / Gateway pattern
  • DTO pattern
  • Projection
  • Separation of concerns

πŸ“š Learning Goals

The project is being developed incrementally to understand how a production-style e-commerce backend evolves.

The progression is roughly:

Spring Boot
     ↓
REST APIs
     ↓
JPA + MySQL
     ↓
DTOs
     ↓
Pagination
     ↓
Projections
     ↓
External API Integration
     ↓
Redis Caching
     ↓
Payment Service
     ↓
Stripe Integration
     ↓
Payment Webhooks
     ↓
Idempotency
     ↓
Microservices
     ↓
Eureka Service Discovery

🚧 Future Improvements

Potential next steps include:

  • API Gateway
  • OpenFeign
  • Circuit Breaker / Resilience4j
  • Centralized Configuration
  • Kafka
  • Distributed tracing
  • Centralized logging
  • Docker
  • Kubernetes
  • CI/CD
  • Order Service
  • Inventory Service
  • Notification Service
  • Complete payment state machine
  • Production-grade idempotency
  • Automated integration tests

πŸ‘¨β€πŸ’» Author

Ashim Roy

Backend Engineer | Java | Spring Boot | Microservices | Distributed Systems


⭐ Purpose

This repository is primarily a hands-on backend engineering and microservices learning project, with the goal of understanding how individual Spring Boot concepts fit together to form a scalable e-commerce system.


### One thing I would change before you commit this

I deliberately **didn't put your actual DB credentials, Stripe keys, or other secrets** anywhere in the README. Keep those local/environment-specific.

Also, your current project has evolved quite a bitβ€”from the original Product Service into **Product + Payment + Service Discovery + Redis**, so this README reflects the architecture we're actually building rather than describing it as just a CRUD Spring Boot application.

About

Production-grade eCommerce backend built with Java, Spring Boot, JPA, Redis, Kafka, OAuth2, Spring Cloud, Docker, Kubernetes and AWS.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages