The Bazaar Orders API is a Spring Boot microservice responsible for orchestrating checkout transactions, processing secure payments, managing order life cycles, tracking delivery statuses, and handling product/seller review systems within the Bazaar ecosystem.
- Core Features
- System Architecture
- Technology Stack
- Database Schema
- Environment Configuration
- Getting Started
- API Reference
- Background & Scheduled Jobs
- Checkout & Multi-Seller Order Orchestration:
- Groups items in the checkout request by seller and automatically creates separate orders for each.
- Consolidates orders under a single
OrderPaymententity with a unique external reference. - Integrates with Mercado Pago API to generate unified payment preferences and transaction flow.
- Order Lifecycle Management:
- Provides paginated purchase records for buyers and sales records for sellers.
- Enforces strict state transitions when updating order statuses (e.g., pending, paid, shipped, delivered, cancelled).
- Tracks detailed order status transitions via a history ledger.
- Unified Review & Feedback System:
- Allows customers to submit rating and written reviews for both overall orders (evaluating sellers) and individual order items (evaluating products).
- Computes and exposes real-time seller reputations (average rating, total counts).
- Asynchronous Communication:
- Leverages RabbitMQ to publish events and handle messaging tasks, such as stock notifications or inter-service communications.
- Observability & Analytics:
- Exposes comprehensive dashboard metrics for administrators: transaction volume, status counts, daily metrics, and category-specific order analytics.
- Monitored using an integrated OpenTelemetry agent for tracing and Prometheus/Grafana metric exports.
The Orders API operates behind a routing API Gateway, trusting it to perform authentication checks and inject downstream headers:
graph TD
Client([Client / App Mobile]) --> |HTTP Requests| Gateway[API Gateway]
Gateway -->|Forwards with X-User-Id & X-User-Role headers| OrdersService[Orders Microservice]
subgraph Orders Service Internals
OrdersService --> |Reads/Writes| PostgreSQL[(PostgreSQL Database)]
OrderPaymentCleanupScheduler[OrderPaymentCleanupScheduler] --> |Purges expired/failed checkouts| PostgreSQL
RabbitMQProducer[RabbitMQProducer] --> |Publishes events| RabbitMQ[RabbitMQ Broker]
end
OrdersService -->|Creates Payment Preferences| MercadoPago[Mercado Pago API]
MercadoPago -->|Webhook/IPN Notifications| OrdersService
OrdersService -->|HTTP REST Client| CatalogService[Catalog Microservice]
OrdersService -->|HTTP REST Client| UserService[User Microservice]
OrdersService -->|HTTP REST Client| CartService[Cart Microservice]
OrderPaymentCleanupScheduler -->|Restores Stock| CatalogService
Note
Authorization is established by trusting the Gateway injected headers, specifically X-User-Id for the user context and X-User-Role for role permissions (USER, ADMIN).
- Framework: Spring Boot 4.0.6, Spring Security, Spring WebMVC, Spring Actuator, Spring Data JPA
- Language: Java 21
- Database: PostgreSQL 15
- Database Migrations: Flyway Database Migration
- Caching: Spring Cache with Caffeine Provider
- Payment Broker: Mercado Pago Java SDK (v2.9.2)
- Messaging Service: Spring AMQP / RabbitMQ
- Monitoring & Observability: OpenTelemetry JVM Agent, Slf4j, Spring Boot Actuator, Micrometer
- Testing Tools: JUnit 5, Spring WebTestClient, Testcontainers (PostgreSQL integration), Mockito
Database migrations are managed automatically via Flyway scripts (src/main/resources/db/migration):
order_payments: Manages the payments created with Mercado Pago. Stores unique external references, payment status, and timestamps.orders: Links checkout records to their respective buyers (user_id), sellers (seller_id), delivery addresses, current statuses, and payment IDs.order_items: Line items containing the product reference, price, quantity, and product category.order_status_history: Holds status transition trails for auditing order lifecycles.order_reviews: Captures buyer ratings (1 to 5) and feedback directed towards the seller.order_item_reviews: Captures buyer reviews for individual items/products bought in an order, enforced by a unique buyer-to-item constraint.
To configure the application, create a .env file in the root directory based on the .env.example template:
cp .env.example .env| Variable | Description | Default / Example |
|---|---|---|
| Server Settings | ||
PORT |
Local port of the Spring Boot application | 8080 |
HOST |
Bind address of the service | 0.0.0.0 |
ENVIRONMENT |
Running environment mode (local, production, stress) |
local |
| Database | ||
DATABASE_HOST |
Host address of the PostgreSQL database | database-host |
DATABASE_NAME |
Database name | database-name |
DATABASE_PORT |
Database port | 5432 |
DATABASE_USER |
PostgreSQL user | postgres |
DATABASE_PASSWORD |
PostgreSQL password | your-secure-password |
EXPOSE_PORT |
Docker host-mapped port for PostgreSQL | 9000 |
| API Endpoints | ||
API_USER_URL |
Base URL routing for User microservice | http://localhost:8080 |
API_CATALOG_URL |
Base URL routing for Catalog microservice | http://localhost:8081 |
API_CART_URL |
Base URL routing for Cart microservice | http://localhost:8082 |
| Mercado Pago | ||
MP_API_KEY |
Mercado Pago API Integration Credentials | (From Mercado Pago Console) |
MP_WEBHOOK_URL |
Public webhook callback URL (HTTPS required) | https://your-domain.ngrok-free.app |
SUCCESS_BACK_URL |
Redirect URL after a successful transaction | https://bazaar.com/checkout/success |
FAILURE_BACK_URL |
Redirect URL after a failed transaction | https://bazaar.com/checkout/failure |
PENDING_BACK_URL |
Redirect URL when payment is pending | https://bazaar.com/checkout/pending |
| Ngrok Config | ||
NGROK_AUTHTOKEN |
Auth token for tunneling webhook notifications locally | (Optional) |
| RabbitMQ | ||
RABBITMQ_ADDRESSES |
Endpoint addresses for RabbitMQ broker | amqp://guest:guest@localhost:5672/ |
| Telemetry (Grafana) | ||
OTEL_SERVICE_NAME |
Service label reported in OpenTelemetry traces | orders-service |
OTEL_EXPORTER_OTLP_PROTOCOL |
Protocol for exporting OpenTelemetry records | http/protobuf |
OTEL_EXPORTER_OTLP_ENDPOINT |
Telemetry collector server address | http://otel-collector:4317 |
OTEL_EXPORTER_OTLP_HEADERS |
Header properties injected into OTEL requests | (Optional) |
- Java Development Kit (JDK) 21
- Maven 3.9+ (or use the provided
mvnwwrapper) - Docker & Docker Compose
To launch the microservice alongside PostgreSQL and RabbitMQ, execute the following:
- Create the shared network (if not already existing):
docker network create bazaar-network
- Build and start the containers:
docker-compose up --build
- Stop the environment:
docker-compose down -v
For development, you can spin up the PostgreSQL database and RabbitMQ in Docker, and run the Spring Boot app locally:
- Start PostgreSQL dependency:
docker-compose up postgres-orders -d
- Start RabbitMQ dependency:
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management
- Compile and run the Spring Boot app:
./mvnw spring-boot:run
Run the test suite, which uses Testcontainers to instantiate isolated PostgreSQL containers:
./mvnw clean testTo execute stress testing using k6 performance configurations:
- Configure the stress environment variables in
.env:- Set
ENVIRONMENTtostress. - Set
RABBITMQ_ADDRESSEStoamqp://guest:guest@rabbitmq:5672/.
- Set
- Run the service in test mode:
docker compose -f docker-compose.test.yml up --build
- Shutdown the test infrastructure:
docker compose -f docker-compose.test.yml down -v
Interactive API documentation (Swagger UI) is available once the application runs at:
- Swagger UI:
http://localhost:8080/swagger-ui.html - OpenAPI Definition JSON:
http://localhost:8080/v3/api-docs
Or if you use the service in the cloud, it is available at:
- Swagger UI:
https://api-orders-x0wn.onrender.com/swagger-ui/index.html - OpenAPI Definition JSON:
https://api-orders-x0wn.onrender.com/v3/api-docs
The service runs an automated scheduler, the OrderPaymentCleanupScheduler, which periodically wakes up (every 10 minutes) to release inventory and clean up abandoned payment sessions:
- Abandoned Payments: Detects
OrderPaymenttransactions left in aPENDINGstate longer than the configured timeout (defaulting to 30 minutes). Releases/restores the product quantities back into stock via the Catalog API client and cleans up the transaction records. - Rejected Payments: Scans for
REJECTEDpayments. Restores the corresponding product stock and purges the records to prevent database bloating.