Machine Coding Problem

E-commerce Cart & Checkout

macoAllcommercepromotion-enginetax-logic
Commonly Asked By:AmazonWalmartShopifyeBay

Functional Scope (In-Scope)

  • Snapshot Pricing Protection: Freezes the unit cost at the precise millisecond of cart insertion, mitigating mid-checkout pricing shifts.
  • Tiered Promotion Application: Supports standard percentage discounts and item-specific bulk triggers with custom priority weights.
  • Modular Tax & Shipping Estimators: Calculates location-based jurisdictional taxes and volumetric freight surcharges dynamically.
  • Session Cart Merge Pipelines: Safely reconciles anonymous guest cart items into authenticated user balances on login.

Explicit Boundaries (Out-of-Scope)

  • Direct ACH/Credit Payment Routing: Payments are captured via simulated gateway tokens without card validations or bank routing handshakes.
  • Physical Warehouse Fulfillment: Excludes packing logistics, barcode labels creation, and delivery vehicle dispatching.

Production reference implementations demonstrating snapshot pricing, promotions, and atomic inventory checkout in Java and Python:

// ─── JAVA BLUEPRINT ──────────────────────────────────────────────────────────
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

enum TaxCategory {
    PHYSICAL_GOODS, DIGITAL_GOODS, FOOD, MEDICINE
}

class Product {
    private final String productId;
    private final String name;
    private final double weightKg;
    private final double basePrice;
    private volatile double livePrice;
    private final TaxCategory taxCategory;

    public Product(String productId, String name, double weightKg, double basePrice, TaxCategory taxCategory) {
        this.productId = productId;
        this.name = name;
        this.weightKg = weightKg;
        this.basePrice = basePrice;
        this.livePrice = basePrice;
        this.taxCategory = taxCategory;
    }

    public String getProductId() { return productId; }
    public String getName() { return name; }
    public double getWeightKg() { return weightKg; }
    public double getBasePrice() { return basePrice; }
    public double getLivePrice() { return livePrice; }
    public void setLivePrice(double livePrice) { this.livePrice = livePrice; }
    public TaxCategory getTaxCategory() { return taxCategory; }
}

class CartItem {
    private final String productId;
    private int quantity;
    private final double snapshotPrice; // Snapshot pricing pattern

    public CartItem(String productId, int quantity, double snapshotPrice) {
        this.productId = productId;
        this.quantity = quantity;
        this.snapshotPrice = snapshotPrice;
    }

    public String getProductId() { return productId; }
    public int getQuantity() { return quantity; }
    public void setQuantity(int quantity) { this.quantity = quantity; }
    public double getSnapshotPrice() { return snapshotPrice; }
}

class Cart {
    private final String cartId;
    private final String userId; // Null if guest/anonymous
    private final Map<String, CartItem> items = new ConcurrentHashMap<>();

    public Cart(String cartId, String userId) {
        this.cartId = cartId;
        this.userId = userId;
    }

    public String getCartId() { return cartId; }
    public String getUserId() { return userId; }
    public Collection<CartItem> getItems() { return items.values(); }

    public void addItem(Product product, int quantity) {
        items.compute(product.getProductId(), (id, currentItem) -> {
            if (currentItem == null) {
                return new CartItem(id, quantity, product.getLivePrice());
            } else {
                currentItem.setQuantity(currentItem.getQuantity() + quantity);
                return currentItem;
            }
        });
    }

    public void removeItem(String productId) {
        items.remove(productId);
    }
}

interface Promotion {
    String getCode();
    int getPriority(); // Prioritized application order
    double apply(double currentSubtotal, Collection<CartItem> items);
}

class PercentagePromo implements Promotion {
    private final String code;
    private final double discountPercentage;
    private final int priority;

    public PercentagePromo(String code, double discountPercentage, int priority) {
        this.code = code;
        this.discountPercentage = discountPercentage;
        this.priority = priority;
    }

    @Override
    public String getCode() { return code; }
    @Override
    public int getPriority() { return priority; }
    @Override
    public double apply(double currentSubtotal, Collection<CartItem> items) {
        return currentSubtotal * (1.0 - (discountPercentage / 100.0));
    }
}

class BulkDiscountPromo implements Promotion {
    private final String code;
    private final String targetProductId;
    private final int minQty;
    private final double discountPerItem;
    private final int priority;

    public BulkDiscountPromo(String code, String targetProductId, int minQty, double discountPerItem, int priority) {
        this.code = code;
        this.targetProductId = targetProductId;
        this.minQty = minQty;
        this.discountPerItem = discountPerItem;
        this.priority = priority;
    }

    @Override
    public String getCode() { return code; }
    @Override
    public int getPriority() { return priority; }
    @Override
    public double apply(double currentSubtotal, Collection<CartItem> items) {
        double totalDiscount = 0.0;
        for (CartItem item : items) {
            if (item.getProductId().equals(targetProductId) && item.getQuantity() >= minQty) {
                totalDiscount += item.getQuantity() * discountPerItem;
            }
        }
        return Math.max(0.0, currentSubtotal - totalDiscount);
    }
}

class TaxCalculator {
    private final Map<String, Map<TaxCategory, Double>> taxRules = new ConcurrentHashMap<>();

    public void addRule(String jurisdiction, TaxCategory category, double rate) {
        taxRules.computeIfAbsent(jurisdiction, k -> new ConcurrentHashMap<>()).put(category, rate);
    }

    public double calculateTax(String jurisdiction, TaxCategory category, double amount) {
        Map<TaxCategory, Double> rules = taxRules.get(jurisdiction);
        if (rules == null) return 0.0;
        double rate = rules.getOrDefault(category, 0.0);
        return amount * rate;
    }
}

class ShippingEstimator {
    public double estimateShipping(String destinationZip, double totalWeightKg) {
        double baseRate = 5.00;
        double weightSurcharge = totalWeightKg * 1.50;
        // Surcharge based on zip length
        double zipFactor = destinationZip.length() * 0.50;
        return baseRate + weightSurcharge + zipFactor;
    }
}

class OrderService {
    private final ConcurrentHashMap<String, AtomicInteger> inventory = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, ReentrantLock> productLocks = new ConcurrentHashMap<>();

    public void addInventory(String productId, int qty) {
        inventory.put(productId, new AtomicInteger(qty));
    }

    // High performance fine-grained locking with deadlock prevention
    public String placeOrder(Cart cart, String jurisdiction, String promoCode, Map<String, Product> productCatalog, TaxCalculator taxCalculator, ShippingEstimator shippingEstimator, List<Promotion> activePromos) {
        if (cart.getItems().isEmpty()) {
            throw new IllegalArgumentException("Cart is empty.");
        }

        // Sort items by Product ID to guarantee a global lock acquisition order (prevents deadlocks)
        List<CartItem> sortedItems = cart.getItems().stream()
            .sorted(Comparator.comparing(CartItem::getProductId))
            .collect(Collectors.toList());

        List<ReentrantLock> locksToAcquire = new ArrayList<>();
        for (CartItem item : sortedItems) {
            locksToAcquire.add(productLocks.computeIfAbsent(item.getProductId(), k -> new ReentrantLock()));
        }

        // Acquire locks in sorted sequence
        for (ReentrantLock lock : locksToAcquire) {
            lock.lock();
        }

        try {
            // 1. Double-check stock under lock
            for (CartItem item : sortedItems) {
                AtomicInteger stock = inventory.get(item.getProductId());
                if (stock == null || stock.get() < item.getQuantity()) {
                    throw new IllegalStateException("Insufficient inventory for product: " + item.getProductId());
                }
            }

            // 2. Deduct inventory atomically
            for (CartItem item : sortedItems) {
                inventory.get(item.getProductId()).addAndGet(-item.getQuantity());
            }

            // 3. Compute Subtotal based on Snapshot prices
            double subtotal = 0.0;
            double totalWeight = 0.0;
            for (CartItem item : sortedItems) {
                subtotal += item.getSnapshotPrice() * item.getQuantity();
                Product p = productCatalog.get(item.getProductId());
                if (p != null) {
                    totalWeight += p.getWeightKg() * item.getQuantity();
                }
            }

            // 4. Apply promo
            double discountedSubtotal = subtotal;
            if (promoCode != null) {
                Optional<Promotion> promoOpt = activePromos.stream()
                    .filter(p -> p.getCode().equalsIgnoreCase(promoCode))
                    .findFirst();
                if (promoOpt.isPresent()) {
                    discountedSubtotal = promoOpt.get().apply(subtotal, cart.getItems());
                }
            }

            // 5. Compute Tax proportionally split across items
            double tax = 0.0;
            for (CartItem item : sortedItems) {
                Product p = productCatalog.get(item.getProductId());
                if (p != null) {
                    double itemShare = (item.getSnapshotPrice() * item.getQuantity()) / subtotal;
                    double itemDiscountedPrice = discountedSubtotal * itemShare;
                    tax += taxCalculator.calculateTax(jurisdiction, p.getTaxCategory(), itemDiscountedPrice);
                }
            }

            // 6. Estimating shipping
            double shipping = shippingEstimator.estimateShipping(jurisdiction, totalWeight);
            double grandTotal = discountedSubtotal + tax + shipping;

            return "ORDER-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase() + " | Paid: $" + Math.round(grandTotal * 100.0) / 100.0;
        } finally {
            // Release locks in reverse order
            for (int i = locksToAcquire.size() - 1; i >= 0; i--) {
                locksToAcquire.get(i).unlock();
            }
        }
    }

    // Merge Guest Cart into User's Auth Cart
    public void mergeCarts(Cart guestCart, Cart userCart) {
        for (CartItem item : guestCart.getItems()) {
            userCart.getItems().stream()
                .filter(x -> x.getProductId().equals(item.getProductId()))
                .findFirst()
                .ifPresentOrElse(
                    existing -> existing.setQuantity(existing.getQuantity() + item.getQuantity()),
                    () -> userCart.addItem(new Product(item.getProductId(), "Product", 0, item.getSnapshotPrice(), TaxCategory.PHYSICAL_GOODS), item.getQuantity())
                );
        }
    }
}

public class Main {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== STARTING E-COMMERCE CART & CHECKOUT SIMULATION ===");
        OrderService orderService = new OrderService();
        TaxCalculator taxCalculator = new TaxCalculator();
        ShippingEstimator shippingEstimator = new ShippingEstimator();

        // 1. Setup tax rates
        taxCalculator.addRule("NY-10001", TaxCategory.PHYSICAL_GOODS, 0.08); // 8%
        taxCalculator.addRule("NY-10001", TaxCategory.DIGITAL_GOODS, 0.04);  // 4%
        taxCalculator.addRule("NY-10001", TaxCategory.FOOD, 0.00);           // Tax free food

        // 2. Catalog & Inventory Setup
        Map<String, Product> catalog = new ConcurrentHashMap<>();
        Product ps5 = new Product("prod-ps5", "PlayStation 5", 4.5, 499.99, TaxCategory.PHYSICAL_GOODS);
        Product milk = new Product("prod-milk", "Organic Milk", 1.0, 3.49, TaxCategory.FOOD);
        
        catalog.put(ps5.getProductId(), ps5);
        catalog.put(milk.getProductId(), milk);

        orderService.addInventory("prod-ps5", 2); // Extremely hot item: Only 2 units!
        orderService.addInventory("prod-milk", 100);

        List<Promotion> promotions = List.of(
            new PercentagePromo("SAVE10", 10.0, 1),
            new BulkDiscountPromo("MILKLOVE", "prod-milk", 3, 0.50, 2)
        );

        // 3. Guest cart merge test
        System.out.println("--- Testing Anonymous Cart Merging ---");
        Cart guestCart = new Cart("cart-guest", null);
        guestCart.addItem(milk, 2);

        Cart userCart = new Cart("cart-user", "user-789");
        userCart.addItem(milk, 1);

        orderService.mergeCarts(guestCart, userCart);
        System.out.println("  User cart items after merging guest cart:");
        for (CartItem ci : userCart.getItems()) {
            System.out.println("    Product: " + ci.getProductId() + ", Qty: " + ci.getQuantity() + ", Snapshot Price: $" + ci.getSnapshotPrice());
        }

        // 4. Concurrency Checkout Test (High contention on limited stock)
        System.out.println("\n--- Concurrent Checkout Race ---");
        ExecutorService executor = Executors.newFixedThreadPool(5);
        CountDownLatch latch = new CountDownLatch(1);

        Runnable checkoutUserA = () -> {
            try {
                latch.await();
                Cart cartA = new Cart("cart-A", "user-A");
                cartA.addItem(ps5, 2); // Wants all remaining stock!
                String receipt = orderService.placeOrder(cartA, "NY-10001", "SAVE10", catalog, taxCalculator, shippingEstimator, promotions);
                System.out.println("  [SUCCESS] User A checkout succeeded: " + receipt);
            } catch (Exception e) {
                System.out.println("  [FAILED] User A checkout failed: " + e.getMessage());
            }
        };

        Runnable checkoutUserB = () -> {
            try {
                latch.await();
                Cart cartB = new Cart("cart-B", "user-B");
                cartB.addItem(ps5, 1); // Wants 1 unit
                String receipt = orderService.placeOrder(cartB, "NY-10001", "SAVE10", catalog, taxCalculator, shippingEstimator, promotions);
                System.out.println("  [SUCCESS] User B checkout succeeded: " + receipt);
            } catch (Exception e) {
                System.out.println("  [FAILED] User B checkout failed: " + e.getMessage());
            }
        };

        executor.submit(checkoutUserA);
        executor.submit(checkoutUserB);

        latch.countDown();
        executor.shutdown();
        executor.awaitTermination(2, TimeUnit.SECONDS);

        System.out.println("=== E-COMMERCE CART & CHECKOUT SIMULATION COMPLETE ===");
    }
}