Vending Machine System Design - Complete Low-Level Design Guide
Design a scalable Vending Machine System using Java and Spring Boot. Learn requirement analysis, UML class diagrams, inventory management, payment processing, state machine design, SOLID principles, design patterns, concurrency, and enterprise architecture.
Introduction
The Vending Machine is one of the classic Low-Level Design (LLD) interview problems because it demonstrates object-oriented design, state management, inventory handling, payment processing, and hardware interaction.
Vending machines are commonly found in:
- Airports
- Railway Stations
- Shopping Malls
- Corporate Offices
- Hospitals
- Schools
- Universities
Every day, millions of users purchase products such as snacks and beverages using cash, cards, or digital wallets.
A vending machine appears simple, but internally it must manage:
- Product Inventory
- Payment Validation
- Coin and Cash Handling
- Change Calculation
- Product Dispensing
- State Transitions
- Error Handling
- Machine Maintenance
In this article, we'll design a production-ready Vending Machine System using Java and Spring Boot while following SOLID principles and enterprise design practices.
Problem Statement
Design a vending machine that supports:
- Display Products
- Select Product
- Accept Payment
- Dispense Product
- Return Change
- Cancel Transaction
- Refund Payment
- Refill Inventory
- Machine Maintenance
Functional Requirements
The system should allow users to:
- View products
- Select product
- Insert coins
- Insert cash
- Pay using card
- Pay using QR code
- Receive product
- Receive change
- Cancel purchase
- Get refund
Administrators should:
- Add products
- Refill products
- Refill cash
- View inventory
- View sales reports
- Enable maintenance mode
Non-Functional Requirements
The system should be:
- Highly Available
- Thread Safe
- Secure
- Maintainable
- Extensible
- Fault Tolerant
- Easy to Monitor
Actors
Actors include:
- Customer
- Administrator
- Vending Machine
- Payment Gateway
- Inventory System
High-Level Architecture
flowchart TD
CUSTOMER["Customer"]
MACHINE["Vending Machine Controller"]
PRODUCT["Product Management Service"]
INVENTORY["Inventory Tracking Service"]
PAYMENT["Payment Gateway"]
CHANGE["Change Calculation Engine"]
DISPENSE["Dispensing Hardware Unit"]
DATABASE["System Database"]
CUSTOMER --> MACHINE
MACHINE --> PRODUCT
MACHINE --> INVENTORY
MACHINE --> PAYMENT
MACHINE --> CHANGE
MACHINE --> DISPENSE
MACHINE --> DATABASE
Core Components
The vending machine consists of:
- Vending Machine
- Product
- Product Slot
- Inventory
- Payment
- Coin
- Cash
- Card Payment
- Change Calculator
- Dispenser
Domain Model
classDiagram
class VendingMachine
class Product
class Inventory
class Payment
class ProductSlot
class Coin
class Cash
class Card
class Dispenser
VendingMachine --> Inventory
Inventory --> ProductSlot
ProductSlot --> Product
Payment --> Coin
Payment --> Cash
Payment --> Card
VendingMachine --> Dispenser
Entity Responsibilities
Vending Machine
Responsible for:
- Managing transactions
- Product selection
- Payment processing
- Dispensing products
Product
Stores:
- Product ID
- Name
- Price
- Category
Product Slot
Stores:
- Slot Number
- Product
- Quantity
Inventory
Responsible for:
- Stock Management
- Refill Operations
- Availability Check
Payment
Stores:
- Payment Type
- Amount
- Status
Dispenser
Responsible for:
- Product Dispensing
- Delivery Confirmation
Product Categories
Snacks
Drinks
Chocolate
Coffee
Sandwich
Water
Product Status
Available
Out Of Stock
Reserved
Expired
Purchase Workflow
sequenceDiagram
participant Customer
participant Machine
participant Payment
participant Dispenser
Customer->>Machine: Select Product
Machine->>Payment: Validate Payment
Payment-->>Machine: Success
Machine->>Dispenser: Dispense Product
Dispenser-->>Customer: Product Delivered
Machine Workflow
flowchart LR
DISPLAY["Product Display Screen"]
SELECT["Product Selection"]
PAYMENT["Payment Processing"]
DISPENSE["Dispensing Mechanism"]
CHANGE["Change Return Module"]
DONE["Transaction Complete"]
DISPLAY --> SELECT --> PAYMENT --> DISPENSE --> CHANGE --> DONE
Payment Methods
Supported methods:
- Coins
- Cash
- Credit Card
- Debit Card
- UPI
- QR Code
- NFC
Coin Types
5¢
10¢
25¢
50¢
$1
Change Calculation
Example:
Product Price:
$2.75
Customer Pays:
$5.00
Change:
$2.25
The system should return the minimum number of coins and notes while considering available inventory.
Cancel Transaction
flowchart LR
PAYMENT["Payment Process Started"]
CANCEL["Cancel Request"]
REFUND["Refund Processing"]
STATE["System Idle State"]
PAYMENT --> CANCEL --> REFUND --> STATE
Product Dispensing
flowchart LR
PAYMENT["Payment Confirmed"]
MOTOR["Motor Control System"]
DISPENSE["Product Dispensing Unit"]
CUSTOMER["Customer Delivery"]
PAYMENT --> MOTOR --> DISPENSE --> CUSTOMER
Machine States
Idle
Product Selected
Waiting For Payment
Dispensing
Returning Change
Out Of Service
Maintenance
Inventory Management
Inventory tracks:
- Product Quantity
- Low Stock
- Expiry Date
- Refill Date
Administrators receive alerts when stock is low.
Design Patterns
Singleton
Machine Configuration
Only one configuration instance.
Factory Pattern
Payment Factory
Creates:
- Cash Payment
- Coin Payment
- Card Payment
- QR Payment
Strategy Pattern
Payment Processing
Different payment providers implement different strategies.
State Pattern
Machine States
Idle
↓
Selection
↓
Payment
↓
Dispensing
↓
Idle
Observer Pattern
Inventory Notifications
Subscribers:
- Inventory Dashboard
- Refill Service
- Maintenance Team
SOLID Principles
SRP
Payment handles payments.
Inventory manages stock.
Dispenser controls product delivery.
OCP
New payment methods can be added without modifying existing logic.
LSP
Every payment type behaves as a Payment implementation.
ISP
Separate interfaces:
- Payment
- Inventory
- Dispensing
DIP
Machine depends on interfaces instead of concrete payment implementations.
Concurrency
Potential issues:
- Two customers selecting the last product simultaneously.
- Duplicate dispensing.
- Concurrent inventory updates.
Solutions:
- Transactions
- Optimistic Locking
- Atomic Inventory Updates
- Thread-safe inventory management
Database Design
Product
Inventory
Transaction
Payment
CoinInventory
CashInventory
MachineLog
Spring Boot Layers
flowchart LR
Controller
-->
Service
-->
Repository
-->
Database
REST APIs
GET /products
POST /purchase
POST /payment
POST /cancel
POST /refund
POST /inventory/refill
GET /inventory
Enterprise Architecture
flowchart TD
CLIENT["Mobile App"]
GATEWAY["API Gateway"]
SERVICE["Vending Machine Service"]
INVENTORY["Inventory Service"]
PAYMENT["Payment Service"]
NOTIFICATION["Notification Service"]
DATABASE["PostgreSQL DB"]
CACHE["Redis Cache"]
STREAM["Kafka Event Stream"]
CLIENT --> GATEWAY --> SERVICE
SERVICE --> INVENTORY
SERVICE --> PAYMENT
SERVICE --> NOTIFICATION
SERVICE --> DATABASE
SERVICE --> CACHE
SERVICE --> STREAM
Redis can cache product inventory and machine state.
Kafka can publish events such as:
- ProductSelected
- PaymentCompleted
- ProductDispensed
- RefundProcessed
- InventoryLow
- MachineMaintenanceRequired
Scaling Considerations
Large vending machine networks may include:
- Thousands of Machines
- Multiple Cities
- Real-Time Inventory
- Remote Monitoring
Scaling techniques:
- IoT Device Management
- Redis
- Kafka
- Horizontal Scaling
- Monitoring Dashboard
- Event Streaming
Future Enhancements
Potential features:
- AI Product Recommendation
- Face Recognition Payments
- Loyalty Programs
- Dynamic Pricing
- Smart Inventory Prediction
- Voice Assistant
- Mobile App Ordering
- Remote Machine Diagnostics
- QR-Based Pickup
- Energy Optimization
Common Mistakes
❌ Hardcoded payment logic.
❌ Ignoring machine states.
❌ No inventory synchronization.
❌ No change calculation strategy.
❌ Tight coupling between payment and dispensing.
❌ No transaction rollback.
Interview Questions
- How would you calculate change efficiently?
- How would you prevent selling the last product twice?
- Which design patterns are useful?
- How would you support new payment methods?
- How would you monitor thousands of vending machines?
- How would Redis improve this system?
- How would you design inventory management?
- How would you support remote diagnostics?
- How would you implement refunds?
- How would you scale this system globally?
Summary
The Vending Machine System is a classic LLD problem that combines inventory management, payment processing, state transitions, hardware interaction, and object-oriented design.
A production-ready implementation should include:
- Rich domain entities
- Layered Spring Boot architecture
- SOLID principles
- Factory, Strategy, State, Singleton, and Observer patterns
- Secure payment processing
- Accurate change calculation
- Thread-safe inventory management
- REST APIs
- Redis for caching machine state
- Kafka for event publishing
- Monitoring and remote management
Mastering this design prepares you for advanced LLD problems such as Parking Lot, ATM, Smart Locker, Retail POS, Self-Checkout Systems, and IoT Device Management, where state management, inventory, concurrency, and extensibility are key design considerations.