This project implements an Order Payment Service that integrates with Redis to publish payment status messages. It leverages Spring Boot, Redis with Lettuce, and a structured event-driven approach to notify other services about successful or failed payment transactions.
Redis (Remote Dictionary Server) is an in-memory, key-value data store known for its speed, flexibility, and scalability. It is widely used for caching, real-time messaging, session management, leaderboards, and job queuing. It is often referred to as a data structures server. What this means is that Redis provides access to mutable data structures via a set of commands, which are sent using a server-client model with TCP sockets and a simple protocol. So different processes can query and modify the same data structures in a shared way.
- Blazing Fast β Data is stored in memory, making reads/writes extremely fast.
- Supports Data Structures β Strings, Lists, Sets, Hashes, Sorted Sets, Streams, Pub/Sub, etc.
- Persistence β Data can be persisted to disk using RDB (snapshotting) or AOF (append-only file).
- Scalability β Supports clustering and replication for high availability.
- Pub/Sub Messaging β Used for real-time notifications and distributed systems.
Redis Publish/Subscribe (Pub/Sub) is often used in business applications for real-time event-driven messaging. Here are some common message types:
-
Order Processing System (E-commerce)
Message Types:- ORDER_PLACED β When a customer places an order.
- PAYMENT_SUCCESS β Payment is successful.
- PAYMENT_FAILED β Payment is declined.
- ORDER_SHIPPED β Order has been shipped.
- ORDER_DELIVERED β Order is delivered to the customer.
Use Case: Notify users in real-time about their order status.
-
Payment Processing & Fraud Detection (Fintech)
Message Types:- PAYMENT_INITIATED β When a user initiates a payment.
- PAYMENT_AUTHORIZED β When payment is authorized.
- PAYMENT_REJECTED β Payment failed due to insufficient funds or fraud detection.
- PAYMENT_REFUNDED β When a refund is issued.
- FRAUD_ALERT β When fraud is detected.
Use Case:
- Notify customers of payment transactions.
- Alert fraud detection systems to take action.
-
Notification & Alerts System
Message Types:- NEW_MESSAGE β A user receives a new message in a chat app.
- NEW_COMMENT β Someone comments on a post.
- FRIEND_REQUEST β A new friend request is received.
- PROMOTIONAL_OFFER β A business sends discounts to customers.
- SYSTEM_ALERT β A critical error occurs (e.g., server downtime alert).
Use Case:
- Real-time user notifications for chat apps like WhatsApp or Slack.
- Push notifications for social media updates.
-
Real-Time Stock Market & Trading Platforms (Finance)
Message Types:- STOCK_PRICE_UPDATE β Stock price updates every second.
- TRADE_EXECUTED β A stock trade is completed.
- MARKET_NEWS_UPDATE β News impacting the stock market.
- PORTFOLIO_ALERT β Portfolio value changes significantly.
Use Case: Stock trading apps like Robinhood use Redis for real-time price updates.
-
IoT & Real-Time Sensor Data (Smart Devices)
Message Types:- TEMPERATURE_UPDATE β Sends real-time temperature readings.
- MOTION_DETECTED β Security camera detects movement.
- DEVICE_HEALTH_CHECK β IoT device reports its health.
Use Case: Smart home automation, monitoring energy consumption, and security alerts.
Lettuce is a scalable, high-performance, and non-blocking Redis client for Java. It is also a reactive and thread-safe Redis client built on Netty
. It supports both synchronous and asynchronous (reactive) interactions with Redis.
- Supports Asynchronous & Reactive APIs (using CompletableFuture, RxJava, and Project Reactor).
- Thread-Safe Connections (multiple threads can use a single connection).
- Automatic Reconnection & Cluster Support.
- Built on Netty (High Performance, Non-Blocking IO).
- Supports Redis Pub/Sub & Redis Streams.
This project uses LettuceConnectionFactory
to configure Redis connections with shared ClientResources. This connection factory is used by RedisTemplate
to interact with Redis, enabling efficient message publishing and retrieval. The RedisPublisher
service is responsible for publishing messages to the appropriate Redis channels (PAYMENT_SUCCESS and PAYMENT_FAILED).
The Order Payment Service provides REST APIs to create and process payment transactions. The main flow involves:
- Validating the Request β Ensuring the order exists, amount is valid, etc.
- Calling Payment Gateway β Fetching transaction details (e.g., transactionId, paymentStatus).
- Persisting Order Payment β Storing payment transaction details in the database.
- Publishing Payment Status:
- If
paymentStatus = SUCCESS
, publish toPAYMENT_SUCCESS
channel. - If an exception occurs during processing, publish to
PAYMENT_FAILED
channel with an error message.
- If
The processPayment
method determines the flow based on paymentMethod (CREDIT_CARD, PAYPAL, BANK_TRANSFER), handling specific conditions for each type.
The technology used in this project are:
Spring Boot Starter Web
β Provides essential components for building RESTful APIs.Redis with Lettuce
β Message publishing
The project is organized into the following package structure:
redis-publisher-lettuce/
βββ src/main/java/com/yoanesber/spring/redis_publisher_lettuce/
β βββ πconfig/ # Configuration classes for Redis
β βββ πcontroller/ # REST controllers handling API requests
β βββ πdto/ # Data Transfer Objects for requests and responses
β βββ πentity/ # Entity classes representing Order Payment data
β βββ πservice/ # Business logic layer
β β βββ πimpl/ # Implementation of services
β βββ πredis/ # Redis-related classes (RedisPublisher)
Configuration values are stored in .env.development
and referenced in application.properties
.
Example .env.development
file content:
# Application properties
APP_PORT=8081
SPRING_PROFILES_ACTIVE=development
# Redis properties
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_USERNAME=default
REDIS_PASSWORD=your_password
REDIS_TIMEOUT=5
REDIS_CONNECT_TIMEOUT=3
REDIS_LETTUCE_SHUTDOWN_TIMEOUT=10
Example application.properties
file content:
# Application properties
spring.application.name=redis-publisher-lettuce
server.port=${APP_PORT}
spring.profiles.active=${SPRING_PROFILES_ACTIVE}
# Redis properties
spring.data.redis.host=${REDIS_HOST}
spring.data.redis.port=${REDIS_PORT}
spring.data.redis.username=${REDIS_USERNAME}
spring.data.redis.password=${REDIS_PASSWORD}
spring.data.redis.timeout=${REDIS_TIMEOUT}
spring.data.redis.connect-timeout=${REDIS_CONNECT_TIMEOUT}
spring.data.redis.lettuce.shutdown-timeout=${REDIS_LETTUCE_SHUTDOWN_TIMEOUT}
A step by step series of examples that tell you how to get a development env running.
- Clone the repository
git clone https://github.com/yoanesber/Spring-Boot-Redis-Publisher-Lettuce.git
cd Spring-Boot-Redis-Publisher-Lettuce
- Ensure Redis is installed and running:
redis-server
- (Optional) If you want to add a specific user with access to a specific channel, you can run the following command in Redis CLI:
ACL SETUSER your_user +CHANNEL~your_channel on >your_password
- Set up Redis password in
.env.development
file:
# Redis properties
REDIS_PASSWORD=your_password
- Build and run the application
mvn spring-boot:run
- Use API endpoints to test payment processing.
POST http://localhost:8081/api/v1/order-payment
- Create a new order payment and trigger payment processing.
Body Request (CREDIT_CARD):
{
"orderId":"ORD123456789",
"amount":"199.99",
"currency":"USD",
"paymentMethod":"CREDIT_CARD",
"cardNumber":"1234 5678 9012 3456",
"cardExpiry":"31/12",
"cardCvv":"123"
}
Successful Response (CREDIT_CARD):
{
"statusCode": 201,
"timestamp": "2025-03-17T08:28:53.539884900Z",
"message": "Order payment created successfully",
"data": {
"orderId": "ORD123456789",
"transactionId": "TXN1742200133539",
"paymentStatus": "SUCCESS",
"amount": 199.99,
"currency": "USD",
"paymentMethod": "CREDIT_CARD",
"createdAt": "2025-03-17T08:28:53.539884900Z"
}
}
Body Request (PAYPAL):
{
"orderId":"ORD123456789",
"amount":"199.99",
"currency":"USD",
"paymentMethod":"PAYPAL",
"paypalEmail":"[email protected]"
}
Successful Response (PAYPAL):
{
"statusCode": 201,
"timestamp": "2025-03-17T08:28:39.010745500Z",
"message": "Order payment created successfully",
"data": {
"orderId": "ORD123456789",
"transactionId": "TXN1742200119003",
"paymentStatus": "SUCCESS",
"amount": 199.99,
"currency": "USD",
"paymentMethod": "PAYPAL",
"createdAt": "2025-03-17T08:28:39.003556100Z"
}
}
Body Request (BANK_TRANSFER):
{
"orderId":"ORD123456789",
"amount":"199.99",
"currency":"USD",
"paymentMethod":"BANK_TRANSFER",
"bankAccount":"1234567890",
"bankName":"Bank of Indonesia"
}
Successful Response (BANK_TRANSFER):
{
"statusCode": 201,
"timestamp": "2025-03-17T08:28:29.806174300Z",
"message": "Order payment created successfully",
"data": {
"orderId": "ORD123456789",
"transactionId": "TXN1742200108505",
"paymentStatus": "SUCCESS",
"amount": 199.99,
"currency": "USD",
"paymentMethod": "BANK_TRANSFER",
"createdAt": "2025-03-17T08:28:28.505517700Z"
}
}
Invalid Request:
{
"orderId":"ORD123456789",
"amount":"199.99",
"currency":"USD",
"paymentMethod":"CREDITCARD",
"cardNumber":"1234 5678 9012 3456",
"cardExpiry":"31/12",
"cardCvv":"123"
}
In the JSON request above, we use "paymentMethod":"CREDITCARD"
, which should be "paymentMethod":"CREDIT_CARD"
, to test an invalid request. This ensures the API correctly validates input and returns an appropriate error response for unsupported or incorrectly formatted values.
Invalid Response:
{
"statusCode": 500,
"timestamp": "2025-03-17T09:55:11.906453600Z",
"message": "Invalid payment method: CREDITCARD",
"data": null
}
- For the Redis Subscriber implementation, check out Spring Boot Redis Subscriber with Lettuce.
- For the Redis Stream as Message Producer implementation, check out Order Payment Service with Redis Streams as Reliable Message Producer for PAYMENT_SUCCESS / PAYMENT_FAILED Events.