Skip to content

Commit c2060a6

Browse files
committed
Amazon order checkout flow
1 parent 12175ec commit c2060a6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1715
-4
lines changed

README.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ Various Low Level Object-Oriented System Design problems are discussed in this s
1212
10. Chat application
1313
11. Notification system
1414
12. Leetcode / Hackerrank like online judge
15+
13. IMDB
16+
14. Amazon order checkout flow
1517

1618

1719
# Planned (In no particular order)
1820
1. File System
1921
2. Social media news feed
20-
3. Amazon order management
21-
4. Payment system
22+
3. Skyscanner Flights
23+
4. Stripe
2224
5. LinkedIn Job board
2325
6. API Rate Limiter
2426
7. Git version control
@@ -28,9 +30,18 @@ Various Low Level Object-Oriented System Design problems are discussed in this s
2830
11. Splitwise
2931
12. Elevator system
3032
13. Traffic control system
31-
14. IMDB
33+
14. Badge Swipe / Access system
3234
15. In-memory database
3335
16. Database Sharding Simulation
3436
17. Online food delivery fleet
3537
18. Vending machine
36-
19. Badge Swipe / Access system
38+
19. Airbnb
39+
20. Airport Management System
40+
21. Uber ride matching system
41+
22. Stack Overflow
42+
23. Zerodha
43+
24. Rule Engine
44+
25. PubSub system
45+
26. Task Management System
46+
27. RedBus
47+
28.

src/com/lld/amazon/Main.java

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package com.lld.amazon;
2+
3+
import com.lld.amazon.constant.*;
4+
import com.lld.amazon.exception.PricingException;
5+
import com.lld.amazon.model.*;
6+
import com.lld.amazon.service.*;
7+
import com.lld.amazon.service.impl.*;
8+
9+
import java.time.LocalDateTime;
10+
import java.util.ArrayList;
11+
import java.util.Collections;
12+
import java.util.List;
13+
14+
public class Main {
15+
16+
private static void test1(PricingService pricingService, OrderService orderService, Customer customer,
17+
List<KV> customerPreferences) throws PricingException {
18+
Catalogue catalogue = new Catalogue();
19+
catalogue.addProduct(getProduct1(pricingService));
20+
21+
HomePage home = new HomePage();
22+
home.addCatalogue(catalogue);
23+
24+
HomePageService homePageService = new HomePageServiceImpl();
25+
List<Catalogue> catalogues = homePageService.chooseCatalogue(home);
26+
if (catalogues.isEmpty()) {
27+
throw new RuntimeException("Invalid test! No catalogue found");
28+
}
29+
30+
List<Product> customerChosenProducts = homePageService.chooseProducts(catalogues);
31+
Product product = customerChosenProducts.get(0);
32+
33+
System.out.println(product.getTitle());
34+
for (ProductVariety variety: product.getVarieties()) {
35+
System.out.println("Total amount: " + variety.getPricing().getTotalAmount());
36+
}
37+
38+
CartService cartService = new CartServiceImpl(pricingService, orderService, customer, customerPreferences);
39+
Cart cart = cartService.addToCart(customer, product, product.getVarieties().get(0), 2);
40+
System.out.println("Cart cost: " + cart.getCartCost());
41+
42+
// Customer can opt-in for any delivery option while checking out
43+
// The default is standard delivery
44+
DeliveryOption deliveryOption = new DeliveryOption(DeliveryType.ONE_DAY_DELIVERY,
45+
new DeliveryETA(LocalDateTime.now().plusDays(1)));
46+
47+
Order order = cartService.checkout(cart, new PaymentMethod(
48+
PaymentMethodType.CASH_ON_DELIVERY, Collections.emptyList()),
49+
customer.getProfile().getDefaultDeliveryAddress(), deliveryOption
50+
);
51+
52+
System.out.println("Order total: " + order.getOrderTotal());
53+
54+
List<OrderItemDelivery> orderItemDeliveries = order.getOrderItemDeliveries();
55+
for (OrderItemDelivery delivery: orderItemDeliveries) {
56+
System.out.println(delivery.getItem().getProduct().getTitle() + " " + delivery.getItem().getChosenVariety().getTitleSuffix()
57+
+ " has ETA by date: " + delivery.getDeliveryETA().getETAHumanReadable());
58+
}
59+
60+
Payment payment = orderService.pay(order);
61+
System.out.println("Payment status: " + payment.getPaymentStatus());
62+
}
63+
64+
private static Product getProduct1(PricingService pricingService) throws PricingException {
65+
String title1 = "Redmi 13C (Starshine Green, 4GB RAM, 128GB Storage) " +
66+
"| Powered by 4G MediaTek Helio G85 | 90Hz Display | " +
67+
"50MP AI Triple Camera";
68+
String desc1 = "Processor: High performance MediaTek G85 ; Enhance gaming " +
69+
"with 1GHz GPU | 8GB of RAM including 4GB virtual | 6.74\" HD+ 90Hz " +
70+
"display with Corning Gorilla Glass 3 Protection | 50MP AI Triple " +
71+
"camera |Fast Side fingerprint | 5000mAh Battery";
72+
Seller seller = new Seller("Cloudtail");
73+
74+
PricingGroup baseGroup = pricingService.registerPricingGroup(PricingGroups.BASE, PricingGroupType.ITEM_LEVEL, true);
75+
PricingGroup taxGroup = pricingService.registerPricingGroup(PricingGroups.TAX, PricingGroupType.ITEM_LEVEL, false);
76+
PricingGroup discountGroup = pricingService.registerPricingGroup(PricingGroups.DISCOUNT, PricingGroupType.ITEM_LEVEL, false);
77+
78+
// Base price
79+
pricingService.registerPricingLineItemWithAmount(baseGroup, PricingLineItems.BASE_AMOUNT,
80+
new Money(11000D, CurrencySymbol.INR), null);
81+
82+
// Tax
83+
pricingService.registerPricingLineItemWithPercentage(taxGroup, PricingLineItems.CGST,
84+
2.5D, new Money(CurrencySymbol.INR), baseGroup);
85+
pricingService.registerPricingLineItemWithPercentage(taxGroup, PricingLineItems.SGST,
86+
2.5D, new Money(CurrencySymbol.INR), baseGroup);
87+
88+
// Discount
89+
pricingService.registerPricingLineItemWithPercentage(discountGroup, PricingLineItems.INSTANT_DISCOUNT,
90+
-10D, new Money(CurrencySymbol.INR), baseGroup);
91+
pricingService.registerPricingLineItemWithAmount(discountGroup, PricingLineItems.NEW_USER_DISCOUNT,
92+
new Money(-50D, CurrencySymbol.INR), baseGroup);
93+
94+
Pricing pricing = new Pricing();
95+
pricing.addPricingGroup(baseGroup);
96+
pricing.addPricingGroup(taxGroup);
97+
pricing.addPricingGroup(discountGroup);
98+
99+
ProductVarietyMetadata varietyMetadata = new ProductVarietyMetadata();
100+
101+
// Product variety specific metadata
102+
varietyMetadata.addMetadata("Colour", "Green");
103+
varietyMetadata.addMetadata("RAM Memory Installed Size", "4 GB");
104+
varietyMetadata.addMetadata("CPU Model", "Snapdragon");
105+
varietyMetadata.addMetadata("Memory Storage Capacity", "128 GB");
106+
107+
ProductVariety variety1 = new ProductVariety(pricing, varietyMetadata, seller);
108+
109+
Product product1 = new Product(title1, desc1, List.of(variety1));
110+
111+
// Top level product metadata irrespective of any variety
112+
product1.addMetadata("Brand", "Xiaomi");
113+
product1.addMetadata("Operating System", "MIUI 14, Android 13.0");
114+
115+
product1.addPromise("Promise 1", "7 days Service Centre Replacement");
116+
product1.addPromise("Promise 2", "Free Delivery");
117+
product1.addPromise("Promise 3", "1 year Warranty Care");
118+
product1.addPromise("Promise 4", "1 year Warranty");
119+
product1.addPromise("Promise 5", "Pay on Delivery");
120+
product1.addPromise("Promise 6", "Top Brand");
121+
product1.addPromise("Promise 7", "Amazon Delivered");
122+
123+
return product1;
124+
}
125+
126+
public static void main(String[] args) throws PricingException {
127+
CustomerProfile customerProfile = new CustomerProfile(CurrencySymbol.INR); // Put addresses in the profile
128+
Customer customer = new Customer("test", "test@test.com", customerProfile);
129+
130+
List<KV> customerPreferences = new ArrayList<>();
131+
customerPreferences.add(new KV(CustomerPreferenceKeys.CURRENCY, CurrencySymbol.INR));
132+
133+
// Initialize dependencies here
134+
PricingService pricingService = new PricingServiceImpl();
135+
ETAService etaService = new ETAServiceImpl();
136+
OrderService orderService = new OrderServiceImpl(etaService);
137+
138+
test1(pricingService, orderService, customer, customerPreferences);
139+
}
140+
}

src/com/lld/amazon/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Design Amazon order checkout flow
2+
3+
<b>Date: 08-08-2024</b>
4+
5+
1. A user should be able to browse catalogues of products.
6+
2. A product might have multiple varieties
7+
3. The system should support different components of item and cart level pricing.
8+
The fare / price schema should be flexible
9+
4. Multiple delivery options, payment methods should be supported
10+
11+
12+
# TODO
13+
1. Support Billing
14+
2. Support order flow using state machine
15+
3. Support product level review and ratings
16+
4. Design the warehouse and procurement flow of products
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.lld.amazon.constant;
2+
3+
public enum CurrencySymbol {
4+
INR("INR"),
5+
USD("USD");
6+
private final String val;
7+
CurrencySymbol(String symbol) {
8+
this.val = symbol;
9+
}
10+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.lld.amazon.constant;
2+
3+
public class CustomerPreferenceKeys {
4+
public static final String CURRENCY = "currency";
5+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.lld.amazon.constant;
2+
3+
public enum DeliveryType {
4+
STANDARD_DELIVERY,
5+
SAME_DAY_DELIVERY,
6+
ONE_DAY_DELIVERY,
7+
TWO_DAY_DELIVERY,
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.lld.amazon.constant;
2+
3+
public enum OfferType {
4+
CASHBACK,
5+
BANK_OFFER,
6+
PARTNER_OFFER,
7+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.lld.amazon.constant;
2+
3+
public enum OrderState {
4+
ORDER_PLACED,
5+
READY_TO_DISPATCH,
6+
SHIPPED_BY_SELLER,
7+
PICKED_UP_BY_COURIER_PARTNER,
8+
IN_TRANSIT,
9+
DELIVERED,
10+
CANCELLED,
11+
MISSING,
12+
RETURNED,
13+
REFUNDED,
14+
EXCHANGED,
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.lld.amazon.constant;
2+
3+
public enum PaymentMethodType {
4+
DEBIT_CARD,
5+
CREDIT_CARD,
6+
CASH_ON_DELIVERY,
7+
UPI,
8+
NET_BANKING,
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.lld.amazon.constant;
2+
3+
public enum PaymentStatus {
4+
TO_BE_INITIATED,
5+
IN_PROGRESS,
6+
SUCCESS,
7+
FAILED,
8+
CANCELED,
9+
}

0 commit comments

Comments
 (0)