The Billing App calculates the final bill amount for a user after applying various discounts based on their user type (Employee, Affiliate, or Customer) and discount on bill amount. Additionally, the service supports real time currency conversion for bills by integrating with an external exchange rate API.
- Dynamic discount calculation based on user type using the Strategy Design Pattern.
- Additional discounts on bills over certain amounts.
- Realtime currency conversion for the final bill amount using an external API.
- Easily extendable architecture to add new user type, discount strategies or currency conversion logic.
-
Billing Controller & Service:
BillingControllerhandles billing API request.BillingServicedoes the overall billing process, including discounts and currency conversion.
-
Discount Strategy Factory:
- Implements the Strategy Design Pattern to dynamically choose the correct discount strategy based on the user type.
- User types supported:
EMPLOYEE,AFFILIATE, andCUSTOMER. - Using Factory and Strategy design pattern enables scalability of new user type and discount rules.
-
Discount Strategies:
- EmployeeDiscount: 30% discount on non-grocery items.
- AffiliateDiscount: 10% discount on non-grocery items.
- CustomerLoyaltyDiscount: 5% discount on non-grocery items for customers associated for more than 2 years.
-
Currency Exchange Rate Service:
- Integrates with an ExchangeRate-API to fetch currency conversion rates.
- Used Pair API to get conversion rate between two currencies.
-
Resilient and Modular Design:
- Ensures separation of concerns between billing logic, discount calculation, and currency conversion.
- Log information for debugging and monitoring purposes.
-
Authentication & Authorization:
- Just for this demo application implemented ImMemoryUserDetail providing three users
USER,ADMIN, andGUEST. - API is accessible only for
USER,ADMINusers only. GUESTuser will get 403 Unauthorised error (Added to demonstrate authorization).
- Just for this demo application implemented ImMemoryUserDetail providing three users
-
Strategy Pattern:
- Used for selecting the discount calculation logic dynamically based on the user type.
-
Factory Pattern:
- Encapsulates the creation logic of discount strategies in
DiscountStrategyFactory.
- Encapsulates the creation logic of discount strategies in
-
Separation of Concerns:
- The project cleanly separates concerns across services and components to ensure maintainability and testability.
- Java 17
- Spring Boot 3.0
- Spring Security for authentication and authorization
- Lombok for reducing boilerplate code
- JUnit 5 and Mockito for testing
- SLF4J for logging
- Java 17 or later
- An IDE (e.g., IntelliJ IDEA, Eclipse, or VS Code)
- Postman or cURL for testing APIs
- Clone the repository:
git clone https://github.com/avidee007/billing-app cd billing-app - Update application properties:
- Configure the following property in the
src/main/resources/application.propertiesfile:app.currency.exchange.api.key=<API_KEY>
- Configure the following property in the
- Build the project:
./gradlew build
- Run the application:
./gradlew bootRun
The application will be available at http://localhost:8080/billing-service.
Endpoint: POST /api/v1/calculate
Request Body:
{
"userType": "EMPLOYEE",
"tenure": 4,
"totalAmount": 700,
"originalCurrency": "AED",
"targetCurrency": "INR",
"items": [
{
"category": "OTHER",
"price": 500
},
{
"category": "GROCERIES",
"price": 200
}
]
}Response:
{
"finalAmount": 12104.251,
"currency": "INR"
}- Import the Postman collection into Postman.
- Send the request to the
/api/v1/calculateendpoint.
curl -X POST http://localhost:8080/billing-service/api/v1/calculate \
-H "Content-Type: application/json" \
-H "Authorization: Basic dXNlcjpwYXNzd29yZA=="
-d '{
"userType": "EMPLOYEE",
"tenure": 1,
"totalAmount": 700,
"originalCurrency": "AED",
"targetCurrency": "INR",
"items": [
{
"category": "OTHER",
"price": 500
},
{
"category": "GROCERIES",
"price": 200
},
]
}'- Before running tests update api key else one integration test will fail.
- Run unit tests using Gradlew:
./gradlew test
UML class diagram and plantUml code for UML diagram can be found in here.


