diff --git a/apps/commerce-api/src/main/java/com/loopers/application/brand/BrandFacade.java b/apps/commerce-api/src/main/java/com/loopers/application/brand/BrandFacade.java
new file mode 100644
index 000000000..f425920b8
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/brand/BrandFacade.java
@@ -0,0 +1,24 @@
+package com.loopers.application.brand;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandService;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@RequiredArgsConstructor
+@Component
+public class BrandFacade {
+
+    private final BrandService brandService;
+
+    @Transactional(readOnly = true)
+    public BrandInfo getBrand(Long brandId) {
+        Brand brand = brandService.findBrandById(brandId)
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "브랜드를 찾을 수 없습니다."));
+        return BrandInfo.from(brand);
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/brand/BrandInfo.java b/apps/commerce-api/src/main/java/com/loopers/application/brand/BrandInfo.java
new file mode 100644
index 000000000..f79e326b6
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/brand/BrandInfo.java
@@ -0,0 +1,18 @@
+package com.loopers.application.brand;
+
+import com.loopers.domain.brand.Brand;
+
+public record BrandInfo(
+        Long id,
+        String name,
+        String description
+) {
+    public static BrandInfo from(Brand brand) {
+        return new BrandInfo(
+                brand.getId(),
+                brand.getName(),
+                brand.getDescription()
+        );
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleFacade.java b/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleFacade.java
deleted file mode 100644
index 552a9ad62..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleFacade.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.loopers.application.example;
-
-import com.loopers.domain.example.ExampleModel;
-import com.loopers.domain.example.ExampleService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Component;
-
-@RequiredArgsConstructor
-@Component
-public class ExampleFacade {
-    private final ExampleService exampleService;
-
-    public ExampleInfo getExample(Long id) {
-        ExampleModel example = exampleService.getExample(id);
-        return ExampleInfo.from(example);
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleInfo.java b/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleInfo.java
deleted file mode 100644
index 877aba96c..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/application/example/ExampleInfo.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.loopers.application.example;
-
-import com.loopers.domain.example.ExampleModel;
-
-public record ExampleInfo(Long id, String name, String description) {
-    public static ExampleInfo from(ExampleModel model) {
-        return new ExampleInfo(
-            model.getId(),
-            model.getName(),
-            model.getDescription()
-        );
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/like/LikeCommand.java b/apps/commerce-api/src/main/java/com/loopers/application/like/LikeCommand.java
new file mode 100644
index 000000000..cda6224dd
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/like/LikeCommand.java
@@ -0,0 +1,11 @@
+package com.loopers.application.like;
+
+public class LikeCommand {
+
+    public record LikeProductCommand(
+            String loginId,
+            Long productId
+    ) {
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/like/LikeFacade.java b/apps/commerce-api/src/main/java/com/loopers/application/like/LikeFacade.java
new file mode 100644
index 000000000..c35d181e3
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/like/LikeFacade.java
@@ -0,0 +1,101 @@
+package com.loopers.application.like;
+
+import com.loopers.application.product.ProductInfo;
+import com.loopers.domain.brand.BrandService;
+import com.loopers.domain.like.LikeService;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserService;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@RequiredArgsConstructor
+@Component
+public class LikeFacade {
+
+    private final UserService userService;
+    private final LikeService likeService;
+    private final ProductService productService;
+    private final BrandService brandService;
+
+    @Transactional
+    public LikeInfo recordLike(LikeCommand.LikeProductCommand command) {
+        User user = userService.findUserByLoginId(command.loginId())
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "사용자를 찾을 수 없습니다."));
+
+        boolean wasCreated = likeService.recordLikeIfAbsent(user.getId(), command.productId());
+
+        Product product;
+        if (wasCreated) {
+            product = productService.increaseLikeCount(command.productId());
+        } else {
+            product = productService.findProductById(command.productId())
+                    .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "상품을 찾을 수 없습니다."));
+        }
+
+        return LikeInfo.from(
+                product.getId(),
+                product.getLikeCount().getCount()
+        );
+    }
+
+    @Transactional
+    public LikeInfo cancelLike(LikeCommand.LikeProductCommand command) {
+        User user = userService.findUserByLoginId(command.loginId())
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "사용자를 찾을 수 없습니다."));
+
+        boolean wasDeleted = likeService.cancelLikeIfPresent(user.getId(), command.productId());
+
+        Product product;
+        if (wasDeleted) {
+            product = productService.decreaseLikeCount(command.productId());
+        } else {
+            product = productService.findProductById(command.productId())
+                    .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "상품을 찾을 수 없습니다."));
+        }
+
+        return LikeInfo.from(
+                product.getId(),
+                product.getLikeCount().getCount()
+        );
+    }
+
+    @Transactional(readOnly = true)
+    public List<ProductInfo> getLikedProducts(String loginId) {
+        User user = userService.findUserByLoginId(loginId)
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "사용자를 찾을 수 없습니다."));
+
+        List<Long> productIds = likeService.findLikedProductIds(user.getId());
+
+        if (productIds.isEmpty()) {
+            throw new CoreException(ErrorType.NOT_FOUND, "좋아요한 상품이 없습니다.");
+        }
+
+        List<Product> products = productIds.stream()
+                .map(productService::findProductById)
+                .filter(Optional::isPresent)
+                .map(Optional::get)
+                .toList();
+
+        List<Long> brandIds = products.stream()
+                .map(Product::getBrandId)
+                .collect(Collectors.toSet())
+                .stream()
+                .toList();
+
+        Map<Long, String> brandNamesMap = brandService.findBrandNamesByIds(brandIds);
+
+        return products.stream()
+                .map(product -> ProductInfo.from(product, brandNamesMap.get(product.getBrandId())))
+                .toList();
+    }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/like/LikeInfo.java b/apps/commerce-api/src/main/java/com/loopers/application/like/LikeInfo.java
new file mode 100644
index 000000000..d24f8aa7d
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/like/LikeInfo.java
@@ -0,0 +1,11 @@
+package com.loopers.application.like;
+
+public record LikeInfo(
+        Long productId,
+        Integer likeCount
+) {
+    public static LikeInfo from(Long productId, Integer likeCount) {
+        return new LikeInfo(productId, likeCount);
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/order/OrderCommand.java b/apps/commerce-api/src/main/java/com/loopers/application/order/OrderCommand.java
new file mode 100644
index 000000000..0b39d2957
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/order/OrderCommand.java
@@ -0,0 +1,36 @@
+package com.loopers.application.order;
+
+import com.loopers.domain.order.Delivery;
+import java.util.List;
+
+public class OrderCommand {
+
+    public record CreateOrderCommand(
+            String loginId,
+            List<OrderItemCommand> orderItems,
+            DeliveryCommand delivery
+    ) {
+    }
+
+    public record OrderItemCommand(
+            Long productId,
+            Integer quantity
+    ) {
+    }
+
+    public record DeliveryCommand(
+            String receiverName,
+            String receiverPhoneNumber,
+            String address,
+            String addressDetail
+    ) {
+        public static Delivery toDelivery(DeliveryCommand deliveryCommand) {
+            return Delivery.createDelivery(
+                    deliveryCommand.receiverName(),
+                    deliveryCommand.receiverPhoneNumber(),
+                    deliveryCommand.address(),
+                    deliveryCommand.addressDetail()
+            );
+        }
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/order/OrderFacade.java b/apps/commerce-api/src/main/java/com/loopers/application/order/OrderFacade.java
new file mode 100644
index 000000000..030e4c76a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/order/OrderFacade.java
@@ -0,0 +1,74 @@
+package com.loopers.application.order;
+
+import com.loopers.domain.order.Delivery;
+import com.loopers.domain.order.Order;
+import com.loopers.domain.order.OrderService;
+import com.loopers.domain.point.PointService;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserService;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@RequiredArgsConstructor
+@Component
+public class OrderFacade {
+
+    private final UserService userService;
+    private final ProductService productService;
+    private final OrderService orderService;
+    private final PointService pointService;
+
+    @Transactional
+    public OrderInfo createOrder(OrderCommand.CreateOrderCommand createOrderCommand) {
+        User user = userService.findUserByLoginId(createOrderCommand.loginId())
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "사용자를 찾을 수 없습니다."));
+
+        Delivery delivery = OrderCommand.DeliveryCommand.toDelivery(createOrderCommand.delivery());
+        Order order = orderService.createOrder(user.getId(), delivery);
+
+        int totalPrice = 0;
+        for (OrderCommand.OrderItemCommand orderItemCommand : createOrderCommand.orderItems()) {
+            Product product = productService.findProductById(orderItemCommand.productId())
+                    .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "상품을 찾을 수 없습니다."));
+
+            orderService.createOrderItem(order, product, orderItemCommand.quantity());
+            totalPrice += orderService.addTotalPrice(order, product.getPrice().getPrice(), orderItemCommand.quantity());
+
+            productService.reduceStock(product.getId(), orderItemCommand.quantity());
+        }
+
+        pointService.deductPoint(user.getId(), totalPrice);
+
+        orderService.saveOrder(order);
+        return OrderInfo.from(order, order.getOrderItems(), delivery);
+    }
+
+    @Transactional
+    public List<OrderInfo> getOrdersInfo(String loginId) {
+        User user = userService.findUserByLoginId(loginId)
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "사용자를 찾을 수 없습니다."));
+
+        List<Order> orders = orderService.findOrdersByUserId(user.getId());
+
+        return orders.stream()
+                .map(order -> OrderInfo.from(order, order.getOrderItems(), order.getDelivery()))
+                .toList();
+    }
+
+    @Transactional
+    public OrderInfo getOrderInfo(String loginId, Long orderId) {
+        User user = userService.findUserByLoginId(loginId)
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "사용자를 찾을 수 없습니다."));
+
+        Order order = orderService.findOrderByIdAndUserId(orderId, user.getId())
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "주문을 찾을 수 없습니다."));
+
+        return OrderInfo.from(order, order.getOrderItems(), order.getDelivery());
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/order/OrderInfo.java b/apps/commerce-api/src/main/java/com/loopers/application/order/OrderInfo.java
new file mode 100644
index 000000000..013d6ad61
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/order/OrderInfo.java
@@ -0,0 +1,60 @@
+package com.loopers.application.order;
+
+import com.loopers.domain.order.Delivery;
+import com.loopers.domain.order.Order;
+import com.loopers.domain.order.OrderItem;
+import java.util.List;
+
+public record OrderInfo(
+        Long orderId,
+        String orderStatus,
+        List<OrderItemInfo> orderItems,
+        DeliveryInfo delivery
+) {
+
+    public static OrderInfo from(Order order, List<OrderItem> orderItems, Delivery delivery) {
+        List<OrderItemInfo> itemInfos = orderItems.stream()
+                .map(OrderItemInfo::from)
+                .toList();
+
+        return new OrderInfo(
+                order.getId(),
+                order.getOrderStatus().getDescription(),
+                itemInfos,
+                DeliveryInfo.from(delivery)
+        );
+    }
+
+    public record OrderItemInfo(
+            Long productId,
+            String productName,
+            Integer quantity,
+            Integer price
+    ) {
+        public static OrderItemInfo from(OrderItem orderItem) {
+            return new OrderItemInfo(
+                    orderItem.getProductId(),
+                    orderItem.getProductName(),
+                    orderItem.getQuantity(),
+                    orderItem.getPrice()
+            );
+        }
+    }
+
+    public record DeliveryInfo(
+            String receiverName,
+            String receiverPhone,
+            String address,
+            String addressDetail
+    ) {
+        public static DeliveryInfo from(Delivery delivery) {
+            return new DeliveryInfo(
+                    delivery.getReceiverName(),
+                    delivery.getReceiverPhoneNumber(),
+                    delivery.getBaseAddress(),
+                    delivery.getDetailAddress()
+            );
+        }
+    }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/point/PointFacade.java b/apps/commerce-api/src/main/java/com/loopers/application/point/PointFacade.java
index 00564838a..3594d5e95 100644
--- a/apps/commerce-api/src/main/java/com/loopers/application/point/PointFacade.java
+++ b/apps/commerce-api/src/main/java/com/loopers/application/point/PointFacade.java
@@ -28,7 +28,7 @@ public PointInfo getPointInfo(String loginId) {
         User user = userService.findUserByLoginId(loginId)
                 .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, loginId + " 사용자를 찾을 수 없습니다."));
 
-        Point point = pointService.getPointByUserId(user.getId())
+        Point point = pointService.findPointByUserId(user.getId())
                 .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, loginId + " 사용자의 포인트 정보를 찾을 수 없습니다."));
 
         return PointInfo.from(point);
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/product/ProductCommand.java b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductCommand.java
new file mode 100644
index 000000000..c78f51cf0
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductCommand.java
@@ -0,0 +1,13 @@
+package com.loopers.application.product;
+
+public class ProductCommand {
+
+    public record GetProductsCommand(
+            Long brandId,
+            ProductSort sort,
+            int page,
+            int size
+    ) {
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/product/ProductFacade.java b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductFacade.java
new file mode 100644
index 000000000..27b4dbcc8
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductFacade.java
@@ -0,0 +1,60 @@
+package com.loopers.application.product;
+
+import com.loopers.domain.brand.BrandService;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductService;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@RequiredArgsConstructor
+@Component
+public class ProductFacade {
+
+    private final ProductService productService;
+    private final BrandService brandService;
+
+    @Transactional(readOnly = true)
+    public List<ProductInfo> getProducts(ProductCommand.GetProductsCommand command) {
+        List<Product> products;
+
+        if (ProductSort.LATEST.equals(command.sort())) {
+            products = productService.findProductsByLatestWithBrandName(
+                    command.brandId(), command.page(), command.size());
+        } else if (ProductSort.PRICE_ASC.equals(command.sort())) {
+            products = productService.findProductsByPriceAscWithBrandName(
+                    command.brandId(), command.page(), command.size());
+        } else if (ProductSort.LIKES_DESC.equals(command.sort())) {
+            products = productService.findProductsByLikesDescWithBrandName(
+                    command.brandId(), command.page(), command.size());
+        } else {
+            throw new CoreException(ErrorType.BAD_REQUEST, "지원하지 않는 정렬 기준입니다: " + command.sort());
+        }
+
+        Set<Long> brandIds = products.stream()
+                .map(Product::getBrandId)
+                .collect(Collectors.toSet());
+
+        Map<Long, String> brandNamesMap = brandService.findBrandNamesByIds(brandIds.stream().toList());
+
+        return products.stream()
+                .map(product -> ProductInfo.from(product, brandNamesMap.get(product.getBrandId())))
+                .toList();
+    }
+
+    @Transactional(readOnly = true)
+    public ProductInfo getProduct(Long productId) {
+        Product product = productService.findProductById(productId)
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "상품을 찾을 수 없습니다."));
+        String brandName = brandService.findBrandNameById(product.getBrandId());
+
+        return ProductInfo.from(product, brandName);
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/product/ProductInfo.java b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductInfo.java
new file mode 100644
index 000000000..fd21829de
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductInfo.java
@@ -0,0 +1,26 @@
+package com.loopers.application.product;
+
+import com.loopers.domain.product.Product;
+
+public record ProductInfo(
+        Long id,
+        String name,
+        Long brandId,
+        String brandName,
+        Integer price,
+        Integer likeCount,
+        Integer stock
+) {
+    public static ProductInfo from(Product product, String brandName) {
+        return new ProductInfo(
+                product.getId(),
+                product.getName(),
+                product.getBrandId(),
+                brandName,
+                product.getPrice().getPrice(),
+                product.getLikeCount().getCount(),
+                product.getStock().getQuantity()
+        );
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/product/ProductSort.java b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductSort.java
new file mode 100644
index 000000000..bcc2c3f68
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductSort.java
@@ -0,0 +1,32 @@
+package com.loopers.application.product;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.Arrays;
+import lombok.Getter;
+
+@Getter
+public enum ProductSort {
+    LATEST("latest", "최신순"),
+    PRICE_ASC("price_asc", "가격 오름차순"),
+    LIKES_DESC("likes_desc", "좋아요 내림차순");
+
+    private final String value;
+    private final String description;
+
+    ProductSort(String value, String description) {
+        this.value = value;
+        this.description = description;
+    }
+
+    public static ProductSort fromValue(String value) {
+        if (value == null) {
+            return LATEST;
+        }
+        return Arrays.stream(ProductSort.values())
+                .filter(sort -> sort.value.equals(value))
+                .findFirst()
+                .orElseThrow(() -> new CoreException(ErrorType.BAD_REQUEST, "지원하지 않는 정렬 기준입니다: " + value));
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/brand/Brand.java b/apps/commerce-api/src/main/java/com/loopers/domain/brand/Brand.java
new file mode 100644
index 000000000..670d6d1dd
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/brand/Brand.java
@@ -0,0 +1,20 @@
+package com.loopers.domain.brand;
+
+import com.loopers.domain.BaseEntity;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import lombok.Getter;
+
+@Entity
+@Table(name = "brands")
+@Getter
+public class Brand extends BaseEntity {
+
+    @Column(nullable = false)
+    private String name;
+
+    @Column(nullable = false)
+    private String description;
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/brand/BrandRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/brand/BrandRepository.java
new file mode 100644
index 000000000..2c03690ab
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/brand/BrandRepository.java
@@ -0,0 +1,16 @@
+package com.loopers.domain.brand;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface BrandRepository {
+
+    Optional<Brand> findById(Long brandId);
+
+    Map<Long, String> findBrandNamesByIds(List<Long> brandIds);
+
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/brand/BrandService.java b/apps/commerce-api/src/main/java/com/loopers/domain/brand/BrandService.java
new file mode 100644
index 000000000..75f9152ec
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/brand/BrandService.java
@@ -0,0 +1,30 @@
+package com.loopers.domain.brand;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class BrandService {
+
+    private final BrandRepository brandRepository;
+
+    public Optional<Brand> findBrandById(Long brandId) {
+        return brandRepository.findById(brandId);
+    }
+
+    public String findBrandNameById(Long brandId) {
+        Brand brand = brandRepository.findById(brandId)
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "브랜드를 찾을 수 없습니다."));
+        return brand.getName();
+    }
+
+    public Map<Long, String> findBrandNamesByIds(List<Long> brandIds) {
+        return brandRepository.findBrandNamesByIds(brandIds);
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleModel.java b/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleModel.java
deleted file mode 100644
index c588c4a8a..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleModel.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.loopers.domain.example;
-
-import com.loopers.domain.BaseEntity;
-import com.loopers.support.error.CoreException;
-import com.loopers.support.error.ErrorType;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Table;
-
-@Entity
-@Table(name = "example")
-public class ExampleModel extends BaseEntity {
-
-    private String name;
-    private String description;
-
-    protected ExampleModel() {}
-
-    public ExampleModel(String name, String description) {
-        if (name == null || name.isBlank()) {
-            throw new CoreException(ErrorType.BAD_REQUEST, "이름은 비어있을 수 없습니다.");
-        }
-        if (description == null || description.isBlank()) {
-            throw new CoreException(ErrorType.BAD_REQUEST, "설명은 비어있을 수 없습니다.");
-        }
-
-        this.name = name;
-        this.description = description;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void update(String newDescription) {
-        if (newDescription == null || newDescription.isBlank()) {
-            throw new CoreException(ErrorType.BAD_REQUEST, "설명은 비어있을 수 없습니다.");
-        }
-        this.description = newDescription;
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleRepository.java
deleted file mode 100644
index 3625e5662..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleRepository.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.loopers.domain.example;
-
-import java.util.Optional;
-
-public interface ExampleRepository {
-    Optional<ExampleModel> find(Long id);
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleService.java b/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleService.java
deleted file mode 100644
index c0e8431e8..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/domain/example/ExampleService.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.loopers.domain.example;
-
-import com.loopers.support.error.CoreException;
-import com.loopers.support.error.ErrorType;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-@RequiredArgsConstructor
-@Component
-public class ExampleService {
-
-    private final ExampleRepository exampleRepository;
-
-    @Transactional(readOnly = true)
-    public ExampleModel getExample(Long id) {
-        return exampleRepository.find(id)
-            .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "[id = " + id + "] 예시를 찾을 수 없습니다."));
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/like/Like.java b/apps/commerce-api/src/main/java/com/loopers/domain/like/Like.java
new file mode 100644
index 000000000..83c20b0b1
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/like/Like.java
@@ -0,0 +1,37 @@
+package com.loopers.domain.like;
+
+import com.loopers.domain.BaseEntity;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import jakarta.persistence.UniqueConstraint;
+import lombok.Getter;
+
+@Entity
+@Table(
+        name = "likes",
+        uniqueConstraints = {
+                @UniqueConstraint(name = "uk_user_product", columnNames = {"user_id", "product_id"})
+        }
+)
+@Getter
+public class Like extends BaseEntity {
+
+    @Column(name = "user_id", nullable = false)
+    private Long userId;
+
+    @Column(name = "product_id", nullable = false)
+    private Long productId;
+
+    protected Like() {
+    }
+
+    private Like(Long userId, Long productId) {
+        this.userId = userId;
+        this.productId = productId;
+    }
+
+    public static Like createLike(Long userId, Long productId) {
+        return new Like(userId, productId);
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/like/LikeRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/like/LikeRepository.java
new file mode 100644
index 000000000..48e4bb0ea
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/like/LikeRepository.java
@@ -0,0 +1,19 @@
+package com.loopers.domain.like;
+
+import java.util.List;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface LikeRepository {
+    void saveLike(Like like);
+
+    void delete(Long userId, Long productId);
+
+    boolean saveIfAbsent(Long userId, Long productId);
+
+    boolean deleteIfPresent(Long userId, Long productId);
+
+    List<Long> findProductIdsByUserId(Long userId);
+
+    boolean existsByUserIdAndProductId(Long userId, Long productId);
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/like/LikeService.java b/apps/commerce-api/src/main/java/com/loopers/domain/like/LikeService.java
new file mode 100644
index 000000000..4c4a51344
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/like/LikeService.java
@@ -0,0 +1,44 @@
+package com.loopers.domain.like;
+
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@RequiredArgsConstructor
+
+@Service
+public class LikeService {
+
+    private final LikeRepository likeRepository;
+
+    public void recordLike(Long userId, Long productId) {
+        if (likeRepository.existsByUserIdAndProductId(userId, productId)) {
+            return;
+        }
+        likeRepository.saveLike(Like.createLike(userId, productId));
+    }
+
+    public void cancelLike(Long userId, Long productId) {
+        if (!likeRepository.existsByUserIdAndProductId(userId, productId)) {
+            return;
+        }
+        likeRepository.delete(userId, productId);
+    }
+
+    public boolean recordLikeIfAbsent(Long userId, Long productId) {
+        return likeRepository.saveIfAbsent(userId, productId);
+    }
+
+    public boolean cancelLikeIfPresent(Long userId, Long productId) {
+        return likeRepository.deleteIfPresent(userId, productId);
+    }
+
+    public List<Long> findLikedProductIds(Long userId) {
+        return likeRepository.findProductIdsByUserId(userId);
+    }
+
+    public boolean existsByUserIdAndProductId(Long userId, Long productId) {
+        return likeRepository.existsByUserIdAndProductId(userId, productId);
+    }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/order/Delivery.java b/apps/commerce-api/src/main/java/com/loopers/domain/order/Delivery.java
new file mode 100644
index 000000000..2203acf57
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/Delivery.java
@@ -0,0 +1,82 @@
+package com.loopers.domain.order;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Embeddable;
+import lombok.AccessLevel;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Embeddable
+@Getter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+public class Delivery {
+
+    @Column(nullable = false)
+    private String receiverName;
+
+    @Column(nullable = false)
+    private String receiverPhoneNumber;
+
+    @Column(nullable = false)
+    private String baseAddress;
+
+    @Column(nullable = false)
+    private String detailAddress;
+
+    @Builder
+    private Delivery(String receiverName, String receiverPhoneNumber, String baseAddress, String detailAddress) {
+        validate(receiverName, receiverPhoneNumber, baseAddress, detailAddress);
+        this.receiverName = receiverName;
+        this.receiverPhoneNumber = receiverPhoneNumber;
+        this.baseAddress = baseAddress;
+        this.detailAddress = detailAddress;
+    }
+
+    public static Delivery createDelivery(String receiverName, String receiverPhoneNumber, String baseAddress,
+                                          String detailAddress) {
+        return Delivery.builder()
+                .receiverName(receiverName)
+                .receiverPhoneNumber(receiverPhoneNumber)
+                .baseAddress(baseAddress)
+                .detailAddress(detailAddress)
+                .build();
+    }
+
+    private void validate(String receiverName, String receiverPhoneNumber, String baseAddress, String detailAddress) {
+        validateReceiverName(receiverName);
+        validateReceiverPhoneNumber(receiverPhoneNumber);
+        validateBaseAddress(baseAddress);
+        validateDetailAddress(detailAddress);
+    }
+
+    private void validateReceiverName(String receiverName) {
+        if (receiverName == null || receiverName.isBlank()) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "수령인 이름은 필수입니다.");
+        }
+    }
+
+    private void validateReceiverPhoneNumber(String receiverPhoneNumber) {
+        if (receiverPhoneNumber == null || receiverPhoneNumber.isBlank()) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "수령인 핸드폰번호는 필수입니다.");
+        }
+
+        if (!receiverPhoneNumber.matches("^\\d{3}-\\d{4}-\\d{4}$")) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "핸드폰 번호는 xxx-xxxx-xxxx 형식이어야 합니다.");
+        }
+    }
+
+    private void validateBaseAddress(String baseAddress) {
+        if (baseAddress == null || baseAddress.isBlank()) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "주소는 필수입니다.");
+        }
+    }
+
+    private void validateDetailAddress(String detailAddress) {
+        if (detailAddress == null || detailAddress.isBlank()) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "상세 주소는 필수입니다.");
+        }
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/order/Order.java b/apps/commerce-api/src/main/java/com/loopers/domain/order/Order.java
new file mode 100644
index 000000000..06314da39
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/Order.java
@@ -0,0 +1,112 @@
+package com.loopers.domain.order;
+
+import com.loopers.domain.BaseEntity;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.persistence.AttributeOverride;
+import jakarta.persistence.AttributeOverrides;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Embedded;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+import java.util.ArrayList;
+import java.util.List;
+import lombok.Builder;
+import lombok.Getter;
+
+@Entity
+@Table(name = "orders")
+@Getter
+@Builder
+public class Order extends BaseEntity {
+
+    private Long userId;
+
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
+    @JoinColumn(name = "order_id")
+    @Builder.Default
+    List<OrderItem> orderItems = new ArrayList<>();
+
+    private Integer totalPrice;
+
+    @Enumerated(EnumType.STRING)
+    @Column(nullable = false)
+    private OrderStatus orderStatus;
+
+    @Embedded
+    @AttributeOverrides({
+            @AttributeOverride(name = "receiverName", column = @Column(name = "receiver_name", nullable = false)),
+            @AttributeOverride(name = "receiverPhoneNumber", column = @Column(name = "phone_number", nullable = false)),
+            @AttributeOverride(name = "baseAddress", column = @Column(name = "base_address", nullable = false)),
+            @AttributeOverride(name = "detailAddress", column = @Column(name = "detail_address", nullable = false))
+    })
+    private Delivery delivery;
+
+    public Order() {
+    }
+
+    private Order(Long userId, List<OrderItem> orderItems, Integer totalPrice,
+                 OrderStatus orderStatus, Delivery delivery) {
+        this.userId = userId;
+        this.orderItems = orderItems;
+        this.totalPrice = totalPrice;
+        this.orderStatus = orderStatus;
+        this.delivery = delivery;
+    }
+
+    public static Order createOrder(Long userId, Delivery delivery) {
+        validateCreateOrder(userId, delivery);
+        return Order.builder()
+                .userId(userId)
+                .totalPrice(0)
+                .orderStatus(OrderStatus.CREATED)
+                .delivery(delivery)
+                .build();
+    }
+
+    public void addOrderItem(OrderItem orderItem) {
+        validateOrderItem(orderItem);
+        orderItems.add(orderItem);
+    }
+
+    public int addPrice(int price) {
+        validatePrice(price);
+        this.totalPrice += price;
+        return this.totalPrice;
+    }
+
+    private static void validateCreateOrder(Long userId, Delivery delivery) {
+        validateUserId(userId);
+        validateDelivery(delivery);
+    }
+
+    private static void validateUserId(Long userId) {
+        if (userId == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "사용자 ID는 필수입니다.");
+        }
+    }
+
+    private static void validateDelivery(Delivery delivery) {
+        if (delivery == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "배송 정보는 필수입니다.");
+        }
+    }
+
+    private void validateOrderItem(OrderItem orderItem) {
+        if (orderItem == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "주문 상품은 필수입니다.");
+        }
+    }
+
+    private void validatePrice(int price) {
+        if (price <= 0) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "가격은 0보다 커야 합니다.");
+        }
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderItem.java b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderItem.java
new file mode 100644
index 000000000..d22215808
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderItem.java
@@ -0,0 +1,81 @@
+package com.loopers.domain.order;
+
+import com.loopers.domain.BaseEntity;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import lombok.Builder;
+import lombok.Getter;
+
+@Entity
+@Table(name = "order_items")
+@Getter
+public class OrderItem extends BaseEntity {
+
+    private Long productId;
+
+    private String productName;
+
+    private Integer price;
+
+    private Integer quantity;
+
+    @Builder
+    private OrderItem(Long productId, String productName, Integer price, Integer quantity) {
+        validate(productId, productName, price, quantity);
+        this.productId = productId;
+        this.productName = productName;
+        this.price = price;
+        this.quantity = quantity;
+    }
+
+    public OrderItem() {
+    }
+
+    public static OrderItem createOrderItem(Long productId, String productName, Integer price, Integer quantity) {
+        return OrderItem.builder()
+                .productId(productId)
+                .productName(productName)
+                .price(price)
+                .quantity(quantity)
+                .build();
+    }
+
+    private void validate(Long productId, String productName, Integer price, Integer quantity) {
+        validateProductId(productId);
+        validateProductName(productName);
+        validatePrice(price);
+        validateQuantity(quantity);
+    }
+
+    private void validateProductId(Long productId) {
+        if (productId == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "상품 ID는 필수입니다.");
+        }
+    }
+
+    private void validateProductName(String productName) {
+        if (productName == null || productName.isBlank()) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "상품명은 필수입니다.");
+        }
+    }
+
+    private void validatePrice(Integer price) {
+        if (price == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "가격은 필수입니다.");
+        }
+        if (price <= 0) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "가격은 0보다 커야 합니다.");
+        }
+    }
+
+    private void validateQuantity(Integer quantity) {
+        if (quantity == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "수량은 필수입니다.");
+        }
+        if (quantity <= 0) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "수량은 0보다 커야 합니다.");
+        }
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderRepository.java
new file mode 100644
index 000000000..9b968be3b
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderRepository.java
@@ -0,0 +1,13 @@
+package com.loopers.domain.order;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface OrderRepository {
+    
+    List<Order> findOrdersByUserId(Long userId);
+
+    Optional<Order> findByIdAndUserId(Long orderId, Long userId);
+
+    void saveOrder(Order order);
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderService.java b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderService.java
new file mode 100644
index 000000000..8b9da8668
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderService.java
@@ -0,0 +1,53 @@
+package com.loopers.domain.order;
+
+import com.loopers.domain.product.Product;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.List;
+import java.util.Optional;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class OrderService {
+
+    private final OrderRepository orderRepository;
+
+    public Order createOrder(Long userId, Delivery delivery) {
+        return Order.createOrder(userId, delivery);
+    }
+
+    public void createOrderItem(Order order, Product product, Integer quantity) {
+        OrderItem orderItem = OrderItem.createOrderItem(
+                product.getId(),
+                product.getName(),
+                product.getPrice().getPrice(),
+                quantity
+        );
+
+        order.addOrderItem(orderItem);
+    }
+
+    public int addTotalPrice(Order order, int price, int quantity) {
+        return order.addPrice(price * quantity);
+    }
+
+    public void saveOrder(Order order) {
+        orderRepository.saveOrder(order);
+    }
+
+    public List<Order> findOrdersByUserId(Long userId) {
+        List<Order> orders = orderRepository.findOrdersByUserId(userId);
+
+        if (orders.isEmpty()) {
+            throw new CoreException(ErrorType.NOT_FOUND, "해당 사용자의 주문 내역이 없습니다.");
+        }
+
+        return orders;
+    }
+
+    public Optional<Order> findOrderByIdAndUserId(Long orderId, Long userId) {
+        return orderRepository.findByIdAndUserId(orderId, userId);
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderStatus.java b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderStatus.java
new file mode 100644
index 000000000..ebb7befed
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderStatus.java
@@ -0,0 +1,18 @@
+package com.loopers.domain.order;
+
+import lombok.Getter;
+
+@Getter
+public enum OrderStatus {
+    CREATED("주문 생성"),
+    PAID("결제 완료"),
+    CANCELED("주문 취소"),
+    COMPLETED("주문 완료");
+
+    private final String description;
+
+    OrderStatus(String description) {
+        this.description = description;
+    }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/point/Point.java b/apps/commerce-api/src/main/java/com/loopers/domain/point/Point.java
index 48c1aed32..582bc0707 100644
--- a/apps/commerce-api/src/main/java/com/loopers/domain/point/Point.java
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/point/Point.java
@@ -46,4 +46,16 @@ public void charge(Integer amount) {
 
         this.amount += amount;
     }
+
+    public boolean hasSufficientAmount(int amount) {
+        return this.amount >= amount;
+    }
+
+    public void deduct(int amount) {
+        if (amount <= 0) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "차감 금액은 0보다 커야 합니다.");
+        }
+
+        this.amount -= amount;
+    }
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/point/PointService.java b/apps/commerce-api/src/main/java/com/loopers/domain/point/PointService.java
index fd52dce67..5de46e8df 100644
--- a/apps/commerce-api/src/main/java/com/loopers/domain/point/PointService.java
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/point/PointService.java
@@ -1,5 +1,7 @@
 package com.loopers.domain.point;
 
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
 import java.util.Optional;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
@@ -27,7 +29,18 @@ public Point chargePoint(Long userId, Integer chargePoint) {
     }
 
     @Transactional(readOnly = true)
-    public Optional<Point> getPointByUserId(Long userId) {
+    public Optional<Point> findPointByUserId(Long userId) {
         return pointRepository.findByUserId(userId);
     }
+
+    public void deductPoint(Long userId, int amount) {
+        Point point = pointRepository.findByUserId(userId)
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "포인트를 찾을 수 없습니다."));
+
+        if (!point.hasSufficientAmount(amount)) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "포인트가 충분하지 않습니다.");
+        }
+
+        point.deduct(amount);
+    }
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/product/LikeCount.java b/apps/commerce-api/src/main/java/com/loopers/domain/product/LikeCount.java
new file mode 100644
index 000000000..767ec1889
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/LikeCount.java
@@ -0,0 +1,50 @@
+package com.loopers.domain.product;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Embeddable;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Embeddable
+@Getter
+@NoArgsConstructor
+public class LikeCount {
+
+    @Column(nullable = false)
+    private Integer count;
+
+    @Builder
+    private LikeCount(Integer count) {
+        validate(count);
+        this.count = count;
+    }
+
+    public static LikeCount createLikeCount(Integer count) {
+        return LikeCount.builder()
+                .count(count)
+                .build();
+    }
+
+    public void increase() {
+        this.count++;
+    }
+
+    public void decrease() {
+        if (this.count <= 0) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "좋아요 수는 0보다 작을 수 없습니다.");
+        }
+        this.count--;
+    }
+
+    private void validate(Integer count) {
+        if (count == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "좋아요 수는 필수입니다.");
+        }
+        if (count < 0) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "좋아요 수는 0 이상이어야 합니다.");
+        }
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/product/Price.java b/apps/commerce-api/src/main/java/com/loopers/domain/product/Price.java
new file mode 100644
index 000000000..67871e04a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/Price.java
@@ -0,0 +1,39 @@
+package com.loopers.domain.product;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Embeddable;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Embeddable
+@Getter
+@NoArgsConstructor
+public class Price {
+
+    @Column(nullable = false)
+    private Integer price;
+
+    @Builder
+    private Price(Integer price) {
+        validate(price);
+        this.price = price;
+    }
+
+    public static Price createPrice(Integer price) {
+        return Price.builder()
+                .price(price)
+                .build();
+    }
+
+    private void validate(Integer price) {
+        if (price == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "가격은 필수입니다.");
+        }
+        if (price <= 0) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "가격은 0보다 커야 합니다.");
+        }
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/product/Product.java b/apps/commerce-api/src/main/java/com/loopers/domain/product/Product.java
new file mode 100644
index 000000000..931aa19a0
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/Product.java
@@ -0,0 +1,119 @@
+package com.loopers.domain.product;
+
+import com.loopers.domain.BaseEntity;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.persistence.AttributeOverride;
+import jakarta.persistence.AttributeOverrides;
+import jakarta.persistence.Column;
+import jakarta.persistence.Embedded;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import lombok.Builder;
+import lombok.Getter;
+
+@Entity
+@Table(name = "products")
+@Getter
+public class Product extends BaseEntity {
+
+    @Column(nullable = false)
+    private String name;
+
+    @Column(nullable = false)
+    private Long brandId;
+
+    @Embedded
+    @AttributeOverrides({
+            @AttributeOverride(name = "price", column = @Column(name = "price", nullable = false, unique = true))
+    })
+    private Price price;
+
+    @Embedded
+    @AttributeOverrides({
+            @AttributeOverride(name = "count", column = @Column(name = "like_count", nullable = false, unique = true))
+    })
+    private LikeCount likeCount;
+
+    @Embedded
+    @AttributeOverrides({
+            @AttributeOverride(name = "quantity", column = @Column(name = "stock", nullable = false, unique = true))
+    })
+    private Stock stock;
+
+    private boolean isDeleted;
+
+    @Builder
+    private Product(String name, Long brandId, Price price, LikeCount likeCount, Stock stock) {
+        validate(name, brandId, price, likeCount, stock);
+        this.name = name;
+        this.brandId = brandId;
+        this.price = price;
+        this.likeCount = likeCount;
+        this.stock = stock;
+        this.isDeleted = false;
+    }
+
+    public Product() {
+    }
+
+    public static Product createProduct(String name, Long brandId, Price price, LikeCount likeCount, Stock stock) {
+        return Product.builder()
+                .name(name)
+                .brandId(brandId)
+                .price(price)
+                .likeCount(likeCount)
+                .stock(stock)
+                .build();
+    }
+
+    public void reduceStock(Integer quantity) {
+        this.stock.reduceQuantity(quantity);
+    }
+
+    public void increaseLikeCount() {
+        this.likeCount.increase();
+    }
+
+    public void decreaseLikeCount() {
+        this.likeCount.decrease();
+    }
+
+    private void validate(String name, Long brandId, Price price, LikeCount likeCount, Stock stock) {
+        validateName(name);
+        validateBrandId(brandId);
+        validatePrice(price);
+        validateLikeCount(likeCount);
+        validateStock(stock);
+    }
+
+    private void validateName(String name) {
+        if (name == null || name.isBlank()) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "상품명은 필수입니다.");
+        }
+    }
+
+    private void validateBrandId(Long brandId) {
+        if (brandId == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "브랜드 ID는 필수입니다.");
+        }
+    }
+
+    private void validatePrice(Price price) {
+        if (price == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "가격은 필수입니다.");
+        }
+    }
+
+    private void validateLikeCount(LikeCount likeCount) {
+        if (likeCount == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "좋아요 수는 필수입니다.");
+        }
+    }
+
+    private void validateStock(Stock stock) {
+        if (stock == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "재고는 필수입니다.");
+        }
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductRepository.java
new file mode 100644
index 000000000..b379f10f9
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductRepository.java
@@ -0,0 +1,16 @@
+package com.loopers.domain.product;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface ProductRepository {
+
+    Optional<Product> findById(Long productId);
+
+    List<Product> findProductsByLatestWithBrandName(Long brandId, int page, int size);
+
+    List<Product> findProductsByPriceAscWithBrandName(Long brandId, int page, int size);
+
+    List<Product> findProductsByLikesDescWithBrandName(Long brandId, int page, int size);
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductService.java b/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductService.java
new file mode 100644
index 000000000..9a0765245
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductService.java
@@ -0,0 +1,51 @@
+package com.loopers.domain.product;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.List;
+import java.util.Optional;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class ProductService {
+
+    private final ProductRepository productRepository;
+
+    public void reduceStock(Long productId, Integer quantity) {
+        Product product = productRepository.findById(productId)
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "상품을 찾을 수 없습니다."));
+        product.reduceStock(quantity);
+    }
+
+    public Optional<Product> findProductById(Long productId) {
+        return productRepository.findById(productId);
+    }
+
+    public List<Product> findProductsByLatestWithBrandName(Long brandId, int page, int size) {
+        return productRepository.findProductsByLatestWithBrandName(brandId, page, size);
+    }
+
+    public List<Product> findProductsByPriceAscWithBrandName(Long brandId, int page, int size) {
+        return productRepository.findProductsByPriceAscWithBrandName(brandId, page, size);
+    }
+
+    public List<Product> findProductsByLikesDescWithBrandName(Long brandId, int page, int size) {
+        return productRepository.findProductsByLikesDescWithBrandName(brandId, page, size);
+    }
+
+    public Product increaseLikeCount(Long productId) {
+        Product product = productRepository.findById(productId)
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "상품을 찾을 수 없습니다."));
+        product.increaseLikeCount();
+        return product;
+    }
+
+    public Product decreaseLikeCount(Long productId) {
+        Product product = productRepository.findById(productId)
+                .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "상품을 찾을 수 없습니다."));
+        product.decreaseLikeCount();
+        return product;
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/product/Stock.java b/apps/commerce-api/src/main/java/com/loopers/domain/product/Stock.java
new file mode 100644
index 000000000..e8419cd4e
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/Stock.java
@@ -0,0 +1,51 @@
+package com.loopers.domain.product;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Embeddable;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Embeddable
+@Getter
+@NoArgsConstructor
+public class Stock {
+
+    @Column(nullable = false)
+    private Integer quantity;
+
+    @Builder
+    private Stock(Integer quantity) {
+        validate(quantity);
+        this.quantity = quantity;
+    }
+
+    public static Stock createStock(Integer quantity) {
+        return Stock.builder()
+                .quantity(quantity)
+                .build();
+    }
+
+    public void reduceQuantity(Integer quantity) {
+        if (quantity == null || quantity <= 0) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "차감할 재고 수량은 1 이상이어야 합니다.");
+        }
+
+        if (this.quantity < quantity) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "재고가 부족합니다.");
+        }
+
+        this.quantity -= quantity;
+    }
+
+    private void validate(Integer quantity) {
+        if (quantity == null) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "재고 수량은 필수입니다.");
+        }
+        if (quantity < 0) {
+            throw new CoreException(ErrorType.BAD_REQUEST, "재고 수량은 0 이상이어야 합니다.");
+        }
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/user/UserRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/user/UserRepository.java
index d0017b1c6..4ae239d01 100644
--- a/apps/commerce-api/src/main/java/com/loopers/domain/user/UserRepository.java
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/user/UserRepository.java
@@ -10,4 +10,5 @@ public interface UserRepository {
     boolean existsByEmail(String email);
 
     Optional<User> findByLoginId(String loginId);
+
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/brand/BrandRepositoryImpl.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/brand/BrandRepositoryImpl.java
new file mode 100644
index 000000000..8193bc793
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/brand/BrandRepositoryImpl.java
@@ -0,0 +1,26 @@
+package com.loopers.infrastructure.brand;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandRepository;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Repository;
+
+@RequiredArgsConstructor
+@Repository
+public class BrandRepositoryImpl implements BrandRepository {
+
+    @Override
+    public Optional<Brand> findById(Long brandId) {
+        return Optional.empty();
+    }
+
+    @Override
+    public Map<Long, String> findBrandNamesByIds(List<Long> brandIds) {
+        return new HashMap<>();
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleJpaRepository.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleJpaRepository.java
deleted file mode 100644
index ce6d3ead0..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleJpaRepository.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.loopers.infrastructure.example;
-
-import com.loopers.domain.example.ExampleModel;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface ExampleJpaRepository extends JpaRepository<ExampleModel, Long> {}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleRepositoryImpl.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleRepositoryImpl.java
deleted file mode 100644
index 37f2272f0..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/infrastructure/example/ExampleRepositoryImpl.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.loopers.infrastructure.example;
-
-import com.loopers.domain.example.ExampleModel;
-import com.loopers.domain.example.ExampleRepository;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Component;
-
-import java.util.Optional;
-
-@RequiredArgsConstructor
-@Component
-public class ExampleRepositoryImpl implements ExampleRepository {
-    private final ExampleJpaRepository exampleJpaRepository;
-
-    @Override
-    public Optional<ExampleModel> find(Long id) {
-        return exampleJpaRepository.findById(id);
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/like/LikeJpaRepository.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/like/LikeJpaRepository.java
new file mode 100644
index 000000000..078547f37
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/like/LikeJpaRepository.java
@@ -0,0 +1,22 @@
+package com.loopers.infrastructure.like;
+
+import com.loopers.domain.like.Like;
+import java.util.List;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+public interface LikeJpaRepository extends JpaRepository<Like, Long> {
+    boolean existsByUserIdAndProductId(Long userId, Long productId);
+
+    @Query("SELECT l.productId FROM Like l WHERE l.userId = :userId")
+    List<Long> findProductIdsByUserId(@Param("userId") Long userId);
+
+    void deleteByUserIdAndProductId(Long userId, Long productId);
+
+    @Modifying(clearAutomatically = true)
+    @Query("DELETE FROM Like l WHERE l.userId = :userId AND l.productId = :productId")
+    int deleteByUserIdAndProductIdAndReturnCount(@Param("userId") Long userId, @Param("productId") Long productId);
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/like/LikeRepositoryImpl.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/like/LikeRepositoryImpl.java
new file mode 100644
index 000000000..36d666153
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/like/LikeRepositoryImpl.java
@@ -0,0 +1,59 @@
+package com.loopers.infrastructure.like;
+
+import com.loopers.domain.like.Like;
+import com.loopers.domain.like.LikeRepository;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.stereotype.Repository;
+
+@RequiredArgsConstructor
+@Repository
+public class LikeRepositoryImpl implements LikeRepository {
+
+    private final LikeJpaRepository likeJpaRepository;
+
+    @Override
+    public void saveLike(Like like) {
+        try {
+            likeJpaRepository.save(like);
+        } catch (DataIntegrityViolationException e) {
+            throw new CoreException(ErrorType.CONFLICT, "이미 좋아요가 등록된 상품입니다.");
+        }
+    }
+
+    @Override
+    public void delete(Long userId, Long productId) {
+        likeJpaRepository.deleteByUserIdAndProductId(userId, productId);
+    }
+
+    @Override
+    public boolean saveIfAbsent(Long userId, Long productId) {
+        try {
+            Like like = Like.createLike(userId, productId);
+            likeJpaRepository.save(like);
+            return true;
+        } catch (DataIntegrityViolationException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean deleteIfPresent(Long userId, Long productId) {
+        int deletedCount = likeJpaRepository.deleteByUserIdAndProductIdAndReturnCount(userId, productId);
+        return deletedCount > 0;
+    }
+
+    @Override
+    public List<Long> findProductIdsByUserId(Long userId) {
+        return likeJpaRepository.findProductIdsByUserId(userId);
+    }
+
+    @Override
+    public boolean existsByUserIdAndProductId(Long userId, Long productId) {
+        return likeJpaRepository.existsByUserIdAndProductId(userId, productId);
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/order/OrderRepositoryImpl.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/order/OrderRepositoryImpl.java
new file mode 100644
index 000000000..ce744750c
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/order/OrderRepositoryImpl.java
@@ -0,0 +1,27 @@
+package com.loopers.infrastructure.order;
+
+import com.loopers.domain.order.Order;
+import com.loopers.domain.order.OrderRepository;
+import java.util.List;
+import java.util.Optional;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class OrderRepositoryImpl implements OrderRepository {
+
+    @Override
+    public List<Order> findOrdersByUserId(Long userId) {
+        return List.of();
+    }
+
+    @Override
+    public Optional<Order> findByIdAndUserId(Long orderId, Long userId) {
+        return Optional.empty();
+    }
+
+    @Override
+    public void saveOrder(Order order) {
+
+    }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/product/ProductRepositoryImpl.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/product/ProductRepositoryImpl.java
new file mode 100644
index 000000000..0dd1d87ea
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/product/ProductRepositoryImpl.java
@@ -0,0 +1,31 @@
+package com.loopers.infrastructure.product;
+
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductRepository;
+import java.util.List;
+import java.util.Optional;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class ProductRepositoryImpl implements ProductRepository {
+
+    @Override
+    public Optional<Product> findById(Long productId) {
+        return Optional.empty();
+    }
+
+    @Override
+    public List<Product> findProductsByLatestWithBrandName(Long brandId, int page, int size) {
+        return null;
+    }
+
+    @Override
+    public List<Product> findProductsByPriceAscWithBrandName(Long brandId, int page, int size) {
+        return null;
+    }
+
+    @Override
+    public List<Product> findProductsByLikesDescWithBrandName(Long brandId, int page, int size) {
+        return null;
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/brand/BrandV1ApiSpec.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/brand/BrandV1ApiSpec.java
new file mode 100644
index 000000000..7fa33e256
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/brand/BrandV1ApiSpec.java
@@ -0,0 +1,22 @@
+package com.loopers.interfaces.api.brand;
+
+import com.loopers.interfaces.api.ApiResponse;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+@Tag(name = "Brand V1 API", description = "Brand V1 API 입니다.")
+public interface BrandV1ApiSpec {
+
+    @Operation(
+            summary = "브랜드 정보 조회",
+            description = "브랜드 ID로 브랜드 정보를 조회합니다."
+    )
+    ApiResponse<BrandV1Dto.BrandResponse> getBrand(
+            @Schema(name = "브랜드 ID", description = "조회할 브랜드의 ID")
+            @Parameter(name = "brandId", description = "브랜드 ID", required = true)
+            Long brandId
+    );
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/brand/BrandV1Controller.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/brand/BrandV1Controller.java
new file mode 100644
index 000000000..a445f129b
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/brand/BrandV1Controller.java
@@ -0,0 +1,30 @@
+package com.loopers.interfaces.api.brand;
+
+import com.loopers.application.brand.BrandFacade;
+import com.loopers.application.brand.BrandInfo;
+import com.loopers.interfaces.api.ApiResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/api/v1/brands")
+public class BrandV1Controller implements BrandV1ApiSpec {
+
+    private final BrandFacade brandFacade;
+
+    @GetMapping("/{brandId}")
+    @Override
+    public ApiResponse<BrandV1Dto.BrandResponse> getBrand(
+            @PathVariable Long brandId
+    ) {
+        BrandInfo brandInfo = brandFacade.getBrand(brandId);
+        BrandV1Dto.BrandResponse response = BrandV1Dto.BrandResponse.from(brandInfo);
+
+        return ApiResponse.success(response);
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/brand/BrandV1Dto.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/brand/BrandV1Dto.java
new file mode 100644
index 000000000..5288bdea3
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/brand/BrandV1Dto.java
@@ -0,0 +1,21 @@
+package com.loopers.interfaces.api.brand;
+
+import com.loopers.application.brand.BrandInfo;
+
+public class BrandV1Dto {
+
+    public record BrandResponse(
+            Long id,
+            String name,
+            String description
+    ) {
+        public static BrandResponse from(BrandInfo info) {
+            return new BrandResponse(
+                    info.id(),
+                    info.name(),
+                    info.description()
+            );
+        }
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1ApiSpec.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1ApiSpec.java
deleted file mode 100644
index 219e3101e..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1ApiSpec.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.loopers.interfaces.api.example;
-
-import com.loopers.interfaces.api.ApiResponse;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.tags.Tag;
-
-@Tag(name = "Example V1 API", description = "Loopers 예시 API 입니다.")
-public interface ExampleV1ApiSpec {
-
-    @Operation(
-        summary = "예시 조회",
-        description = "ID로 예시를 조회합니다."
-    )
-    ApiResponse<ExampleV1Dto.ExampleResponse> getExample(
-        @Schema(name = "예시 ID", description = "조회할 예시의 ID")
-        Long exampleId
-    );
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Controller.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Controller.java
deleted file mode 100644
index 917376016..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Controller.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.loopers.interfaces.api.example;
-
-import com.loopers.application.example.ExampleFacade;
-import com.loopers.application.example.ExampleInfo;
-import com.loopers.interfaces.api.ApiResponse;
-import lombok.RequiredArgsConstructor;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RequiredArgsConstructor
-@RestController
-@RequestMapping("/api/v1/examples")
-public class ExampleV1Controller implements ExampleV1ApiSpec {
-
-    private final ExampleFacade exampleFacade;
-
-    @GetMapping("/{exampleId}")
-    @Override
-    public ApiResponse<ExampleV1Dto.ExampleResponse> getExample(
-        @PathVariable(value = "exampleId") Long exampleId
-    ) {
-        ExampleInfo info = exampleFacade.getExample(exampleId);
-        ExampleV1Dto.ExampleResponse response = ExampleV1Dto.ExampleResponse.from(info);
-        return ApiResponse.success(response);
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Dto.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Dto.java
deleted file mode 100644
index 4ecf0eea5..000000000
--- a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/example/ExampleV1Dto.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.loopers.interfaces.api.example;
-
-import com.loopers.application.example.ExampleInfo;
-
-public class ExampleV1Dto {
-    public record ExampleResponse(Long id, String name, String description) {
-        public static ExampleResponse from(ExampleInfo info) {
-            return new ExampleResponse(
-                info.id(),
-                info.name(),
-                info.description()
-            );
-        }
-    }
-}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1ApiSpec.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1ApiSpec.java
new file mode 100644
index 000000000..8b6bd62fe
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1ApiSpec.java
@@ -0,0 +1,42 @@
+package com.loopers.interfaces.api.like;
+
+import com.loopers.interfaces.api.ApiResponse;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+@Tag(name = "Like V1 API", description = "Like V1 API 입니다.")
+public interface LikeV1ApiSpec {
+
+    @Operation(
+            summary = "상품 좋아요 등록",
+            description = "상품 ID로 상품에 좋아요를 등록합니다."
+    )
+    ApiResponse<LikeV1Dto.LikeResponse> likeProduct(
+            @Parameter(name = "X-USER-ID", description = "로그인 ID", required = true)
+            String loginId,
+            @Parameter(name = "productId", description = "상품 ID", required = true)
+            Long productId
+    );
+
+    @Operation(
+            summary = "상품 좋아요 취소",
+            description = "상품 ID로 상품의 좋아요를 취소합니다."
+    )
+    ApiResponse<LikeV1Dto.LikeResponse> cancelLikeProduct(
+            @Parameter(name = "X-USER-ID", description = "로그인 ID", required = true)
+            String loginId,
+            @Parameter(name = "productId", description = "상품 ID", required = true)
+            Long productId
+    );
+
+    @Operation(
+            summary = "내가 좋아요 한 상품 목록 조회",
+            description = "로그인 ID로 내가 좋아요 한 상품 목록을 조회합니다."
+    )
+    ApiResponse<LikeV1Dto.LikedProductListResponse> getLikedProducts(
+            @Parameter(name = "X-USER-ID", description = "로그인 ID", required = true)
+            String loginId
+    );
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1Controller.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1Controller.java
new file mode 100644
index 000000000..9eac75208
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1Controller.java
@@ -0,0 +1,62 @@
+package com.loopers.interfaces.api.like;
+
+import com.loopers.application.like.LikeCommand;
+import com.loopers.application.like.LikeFacade;
+import com.loopers.application.like.LikeInfo;
+import com.loopers.application.product.ProductInfo;
+import com.loopers.interfaces.api.ApiResponse;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/api/v1/like")
+public class LikeV1Controller implements LikeV1ApiSpec {
+
+    private final LikeFacade likeFacade;
+
+    @PostMapping("/products/{productId}")
+    @Override
+    public ApiResponse<LikeV1Dto.LikeResponse> likeProduct(
+            @RequestHeader("X-USER-ID") String loginId,
+            @PathVariable Long productId
+    ) {
+        LikeCommand.LikeProductCommand command = new LikeCommand.LikeProductCommand(loginId, productId);
+        LikeInfo likeInfo = likeFacade.recordLike(command);
+        LikeV1Dto.LikeResponse response = LikeV1Dto.LikeResponse.from(likeInfo);
+
+        return ApiResponse.success(response);
+    }
+
+    @DeleteMapping("/products/{productId}")
+    @Override
+    public ApiResponse<LikeV1Dto.LikeResponse> cancelLikeProduct(
+            @RequestHeader("X-USER-ID") String loginId,
+            @PathVariable Long productId
+    ) {
+        LikeCommand.LikeProductCommand command = new LikeCommand.LikeProductCommand(loginId, productId);
+        LikeInfo likeInfo = likeFacade.cancelLike(command);
+        LikeV1Dto.LikeResponse response = LikeV1Dto.LikeResponse.from(likeInfo);
+
+        return ApiResponse.success(response);
+    }
+
+    @GetMapping("/products")
+    @Override
+    public ApiResponse<LikeV1Dto.LikedProductListResponse> getLikedProducts(
+            @RequestHeader("X-USER-ID") String loginId
+    ) {
+        List<ProductInfo> productInfos = likeFacade.getLikedProducts(loginId);
+        LikeV1Dto.LikedProductListResponse response = LikeV1Dto.LikedProductListResponse.from(productInfos);
+
+        return ApiResponse.success(response);
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1Dto.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1Dto.java
new file mode 100644
index 000000000..58c9aac35
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1Dto.java
@@ -0,0 +1,54 @@
+package com.loopers.interfaces.api.like;
+
+import com.loopers.application.like.LikeInfo;
+import com.loopers.application.product.ProductInfo;
+import java.util.List;
+
+public class LikeV1Dto {
+
+    public record LikeResponse(
+            Long productId,
+            Integer likeCount
+    ) {
+        public static LikeResponse from(LikeInfo info) {
+            return new LikeResponse(
+                    info.productId(),
+                    info.likeCount()
+            );
+        }
+    }
+
+    public record LikedProductListResponse(
+            List<ProductItem> products
+    ) {
+        public static LikedProductListResponse from(List<ProductInfo> productInfos) {
+            List<ProductItem> items = productInfos.stream()
+                    .map(ProductItem::from)
+                    .toList();
+            return new LikedProductListResponse(items);
+        }
+    }
+
+    public record ProductItem(
+            Long id,
+            String name,
+            Long brandId,
+            String brandName,
+            Integer price,
+            Integer likeCount,
+            Integer stock
+    ) {
+        public static ProductItem from(ProductInfo info) {
+            return new ProductItem(
+                    info.id(),
+                    info.name(),
+                    info.brandId(),
+                    info.brandName(),
+                    info.price(),
+                    info.likeCount(),
+                    info.stock()
+            );
+        }
+    }
+}
+
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1ApiSpec.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1ApiSpec.java
new file mode 100644
index 000000000..06b926dfb
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1ApiSpec.java
@@ -0,0 +1,47 @@
+package com.loopers.interfaces.api.order;
+
+import com.loopers.interfaces.api.ApiResponse;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.List;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@Tag(name = "Order V1 API", description = "Order V1 API 입니다.")
+public interface OrderV1ApiSpec {
+
+    @Operation(
+            summary = "주문 요청",
+            description = "사용자가 주문 요청을 합니다."
+    )
+    ApiResponse<OrderV1Dto.OrderResponse> order(
+            @Schema(name = "로그인 ID", description = "주문 요청을 하는 사용자의 로그인 ID")
+            String loginId,
+
+            @Schema(name = "주문 요청 정보", description = "주문할 정보")
+            OrderV1Dto.OrderRequest orderRequest
+    );
+
+    @Operation(
+            summary = "유저 주문 목록 조회",
+            description = "사용자의 주문 목록을 조회합니다."
+    )
+    ApiResponse<List<OrderV1Dto.OrderResponse>> getOrdersInfo(
+            @Parameter(name = "loginId", description = "조회할 사용자의 로그인 ID", required = true)
+            String loginId
+    );
+
+    @Operation(
+            summary = "단일 주문 상세 조회",
+            description = "주문 ID로 단일 주문의 상세 정보를 조회합니다."
+    )
+    ApiResponse<OrderV1Dto.OrderResponse> getOrderInfo(
+            @Schema(name = "로그인 ID", description = "사용자의 로그인 ID")
+            String loginId,
+
+            @Schema(name = "주문 ID", description = "조회할 주문 ID")
+            @PathVariable Long orderId
+    );
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1Controller.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1Controller.java
new file mode 100644
index 000000000..be405e470
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1Controller.java
@@ -0,0 +1,63 @@
+package com.loopers.interfaces.api.order;
+
+import com.loopers.application.order.OrderCommand;
+import com.loopers.application.order.OrderFacade;
+import com.loopers.application.order.OrderInfo;
+import com.loopers.interfaces.api.ApiResponse;
+import jakarta.validation.Valid;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/api/v1/orders")
+public class OrderV1Controller implements OrderV1ApiSpec {
+
+    private final OrderFacade orderFacade;
+
+    @PostMapping
+    @Override
+    public ApiResponse<OrderV1Dto.OrderResponse> order(
+            @RequestHeader("X-USER-ID") String loginId,
+            @Valid @RequestBody OrderV1Dto.OrderRequest orderRequest
+    ) {
+        OrderCommand.CreateOrderCommand createOrderCommand = orderRequest.toCommand(loginId);
+        OrderInfo orderInfo = orderFacade.createOrder(createOrderCommand);
+        OrderV1Dto.OrderResponse response = OrderV1Dto.OrderResponse.from(orderInfo);
+
+        return ApiResponse.success(response);
+    }
+
+    @GetMapping
+    @Override
+    public ApiResponse<List<OrderV1Dto.OrderResponse>> getOrdersInfo(
+            @RequestHeader("X-USER-ID") String loginId
+    ) {
+        List<OrderInfo> orderInfo = orderFacade.getOrdersInfo(loginId);
+        List<OrderV1Dto.OrderResponse> response = orderInfo.stream()
+                .map(OrderV1Dto.OrderResponse::from)
+                .toList();
+
+        return ApiResponse.success(response);
+    }
+
+    @GetMapping("/{orderId}")
+    @Override
+    public ApiResponse<OrderV1Dto.OrderResponse> getOrderInfo(
+            @RequestHeader("X-USER-ID") String loginId,
+            @PathVariable Long orderId
+    ) {
+        OrderInfo orderInfo = orderFacade.getOrderInfo(loginId, orderId);
+        OrderV1Dto.OrderResponse response = OrderV1Dto.OrderResponse.from(orderInfo);
+
+        return ApiResponse.success(response);
+    }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1Dto.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1Dto.java
new file mode 100644
index 000000000..c960475c0
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1Dto.java
@@ -0,0 +1,101 @@
+package com.loopers.interfaces.api.order;
+
+import com.loopers.application.order.OrderCommand;
+import com.loopers.application.order.OrderCommand.CreateOrderCommand;
+import com.loopers.application.order.OrderInfo;
+import java.util.List;
+
+public class OrderV1Dto {
+
+    public record OrderRequest(
+            List<OrderItemRequest> orderItems,
+            DeliveryRequest delivery
+    ) {
+        public CreateOrderCommand toCommand(String loginId) {
+            List<OrderCommand.OrderItemCommand> itemCommands = orderItems.stream()
+                    .map(OrderItemRequest::toCommand)
+                    .toList();
+
+            return new OrderCommand.CreateOrderCommand(
+                    loginId,
+                    itemCommands,
+                    delivery.toCommand()
+            );
+        }
+    }
+
+    public record OrderItemRequest(
+            Long productId,
+            Integer quantity
+    ) {
+        public OrderCommand.OrderItemCommand toCommand() {
+            return new OrderCommand.OrderItemCommand(productId, quantity);
+        }
+    }
+
+    public record DeliveryRequest(
+            String receiverName,
+            String receiverPhoneNumber,
+            String address,
+            String addressDetail
+    ) {
+        public OrderCommand.DeliveryCommand toCommand() {
+            return new OrderCommand.DeliveryCommand(
+                    receiverName,
+                    receiverPhoneNumber,
+                    address,
+                    addressDetail
+            );
+        }
+    }
+
+    public record OrderResponse(
+            Long orderId,
+            String orderStatus,
+            List<OrderItemResponse> orderItems,
+            DeliveryResponse delivery
+    ) {
+        public static OrderResponse from(OrderInfo orderInfo) {
+            return new OrderResponse(
+                    orderInfo.orderId(),
+                    orderInfo.orderStatus(),
+                    orderInfo.orderItems().stream()
+                            .map(OrderItemResponse::from)
+                            .toList(),
+                    DeliveryResponse.from(orderInfo.delivery())
+            );
+        }
+    }
+
+    public record  OrderItemResponse(
+            Long productId,
+            String productName,
+            Integer quantity,
+            Integer price
+    ) {
+        public static OrderItemResponse from(OrderInfo.OrderItemInfo itemInfo) {
+            return new OrderItemResponse(
+                    itemInfo.productId(),
+                    itemInfo.productName(),
+                    itemInfo.quantity(),
+                    itemInfo.price()
+            );
+        }
+    }
+
+    public record DeliveryResponse(
+            String receiverName,
+            String receiverPhone,
+            String address,
+            String addressDetail
+    ) {
+        public static DeliveryResponse from(OrderInfo.DeliveryInfo deliveryInfo) {
+            return new DeliveryResponse(
+                    deliveryInfo.receiverName(),
+                    deliveryInfo.receiverPhone(),
+                    deliveryInfo.address(),
+                    deliveryInfo.addressDetail()
+            );
+        }
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/product/ProductV1ApiSpec.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/product/ProductV1ApiSpec.java
new file mode 100644
index 000000000..92f8b202f
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/product/ProductV1ApiSpec.java
@@ -0,0 +1,35 @@
+package com.loopers.interfaces.api.product;
+
+import com.loopers.interfaces.api.ApiResponse;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+@Tag(name = "Product V1 API", description = "Product V1 API 입니다.")
+public interface ProductV1ApiSpec {
+
+    @Operation(
+            summary = "상품 목록 조회",
+            description = "브랜드 ID, 정렬 기준, 페이지 정보를 이용하여 상품 목록을 조회합니다."
+    )
+    ApiResponse<ProductV1Dto.ProductListResponse> getProducts(
+            @Parameter(name = "brandId", description = "브랜드 ID (선택사항)", required = false)
+            Long brandId,
+            @Parameter(name = "sort", description = "정렬 기준 (latest, price_asc, likes_desc)", required = false)
+            String sort,
+            @Parameter(name = "page", description = "페이지 번호 (기본값: 0)", required = false)
+            Integer page,
+            @Parameter(name = "size", description = "페이지당 상품 수 (기본값: 20)", required = false)
+            Integer size
+    );
+
+    @Operation(
+            summary = "상품 정보 조회",
+            description = "상품 ID로 상품 정보를 조회합니다."
+    )
+    ApiResponse<ProductV1Dto.ProductResponse> getProduct(
+            @Schema(name = "상품 ID", description = "조회할 상품의 ID")
+            Long productId
+    );
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/product/ProductV1Controller.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/product/ProductV1Controller.java
new file mode 100644
index 000000000..3a8b9c8be
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/product/ProductV1Controller.java
@@ -0,0 +1,51 @@
+package com.loopers.interfaces.api.product;
+
+import com.loopers.application.product.ProductCommand;
+import com.loopers.application.product.ProductFacade;
+import com.loopers.application.product.ProductInfo;
+import com.loopers.application.product.ProductSort;
+import com.loopers.interfaces.api.ApiResponse;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/api/v1/products")
+public class ProductV1Controller implements ProductV1ApiSpec {
+
+    private final ProductFacade productFacade;
+
+    @GetMapping
+    @Override
+    public ApiResponse<ProductV1Dto.ProductListResponse> getProducts(
+            @RequestParam(required = false) Long brandId,
+            @RequestParam(required = false, defaultValue = "latest") String sort,
+            @RequestParam(required = false, defaultValue = "0") Integer page,
+            @RequestParam(required = false, defaultValue = "20") Integer size
+    ) {
+        ProductSort productSort = ProductSort.fromValue(sort);
+        ProductCommand.GetProductsCommand getProductsCommand = new ProductCommand.GetProductsCommand(
+                brandId, productSort, page, size
+        );
+        List<ProductInfo> productInfos = productFacade.getProducts(getProductsCommand);
+        ProductV1Dto.ProductListResponse response = ProductV1Dto.ProductListResponse.from(productInfos);
+
+        return ApiResponse.success(response);
+    }
+
+    @GetMapping("/{productId}")
+    @Override
+    public ApiResponse<ProductV1Dto.ProductResponse> getProduct(
+            @PathVariable Long productId
+    ) {
+        ProductInfo productInfo = productFacade.getProduct(productId);
+        ProductV1Dto.ProductResponse response = ProductV1Dto.ProductResponse.from(productInfo);
+
+        return ApiResponse.success(response);
+    }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/product/ProductV1Dto.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/product/ProductV1Dto.java
new file mode 100644
index 000000000..83a6bfc16
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/product/ProductV1Dto.java
@@ -0,0 +1,62 @@
+package com.loopers.interfaces.api.product;
+
+import com.loopers.application.product.ProductInfo;
+import java.util.List;
+
+public class ProductV1Dto {
+
+    public record ProductListResponse(
+            List<ProductItem> products
+    ) {
+        public static ProductListResponse from(List<ProductInfo> productInfos) {
+            List<ProductItem> items = productInfos.stream()
+                    .map(ProductItem::from)
+                    .toList();
+            return new ProductListResponse(items);
+        }
+    }
+
+    public record ProductItem(
+            Long id,
+            String name,
+            Long brandId,
+            String brandName,
+            Integer price,
+            Integer likeCount,
+            Integer stock
+    ) {
+        public static ProductItem from(ProductInfo info) {
+            return new ProductItem(
+                    info.id(),
+                    info.name(),
+                    info.brandId(),
+                    info.brandName(),
+                    info.price(),
+                    info.likeCount(),
+                    info.stock()
+            );
+        }
+    }
+
+    public record ProductResponse(
+            Long id,
+            String name,
+            Long brandId,
+            String brandName,
+            Integer price,
+            Integer likeCount,
+            Integer stock
+    ) {
+        public static ProductResponse from(ProductInfo info) {
+            return new ProductResponse(
+                    info.id(),
+                    info.name(),
+                    info.brandId(),
+                    info.brandName(),
+                    info.price(),
+                    info.likeCount(),
+                    info.stock()
+            );
+        }
+    }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/application/brand/BrandFacadeIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/application/brand/BrandFacadeIntegrationTest.java
new file mode 100644
index 000000000..aceda00f9
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/application/brand/BrandFacadeIntegrationTest.java
@@ -0,0 +1,89 @@
+package com.loopers.application.brand;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandService;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.Optional;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+@SpringBootTest
+class BrandFacadeIntegrationTest {
+
+    @Autowired
+    private BrandFacade brandFacade;
+
+    @MockitoSpyBean
+    private BrandService brandService;
+
+    @DisplayName("브랜드 정보를 조회할 때,")
+    @Nested
+    class GetBrand {
+
+        @DisplayName("브랜드가 존재하면 브랜드 정보가 반환된다.")
+        @Test
+        void returnsBrandInfo_whenBrandExists() {
+            // arrange
+            Long brandId = 1L;
+            Brand brand = createBrand(brandId, "브랜드명", "브랜드 설명");
+
+            doReturn(Optional.of(brand)).when(brandService).findBrandById(brandId);
+
+            // act
+            BrandInfo result = brandFacade.getBrand(brandId);
+
+            // assert
+            assertAll(
+                    () -> assertThat(result.id()).isEqualTo(1L),
+                    () -> assertThat(result.name()).isEqualTo("브랜드명"),
+                    () -> assertThat(result.description()).isEqualTo("브랜드 설명")
+            );
+
+            // verify
+            verify(brandService, times(1)).findBrandById(brandId);
+        }
+
+        @DisplayName("브랜드가 존재하지 않으면 NOT_FOUND 예외가 발생한다.")
+        @Test
+        void throwsException_whenBrandDoesNotExist() {
+            // arrange
+            Long brandId = 999L;
+
+            doReturn(Optional.empty()).when(brandService).findBrandById(brandId);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                brandFacade.getBrand(brandId);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
+            assertThat(exception.getMessage()).contains("브랜드를 찾을 수 없습니다.");
+
+            // verify
+            verify(brandService, times(1)).findBrandById(brandId);
+        }
+    }
+
+    private Brand createBrand(Long id, String name, String description) {
+        Brand brand = mock(Brand.class);
+        when(brand.getId()).thenReturn(id);
+        when(brand.getName()).thenReturn(name);
+        when(brand.getDescription()).thenReturn(description);
+        return brand;
+    }
+}
+
diff --git a/apps/commerce-api/src/test/java/com/loopers/application/like/LikeFacadeIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/application/like/LikeFacadeIntegrationTest.java
new file mode 100644
index 000000000..5b983f013
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/application/like/LikeFacadeIntegrationTest.java
@@ -0,0 +1,427 @@
+package com.loopers.application.like;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.loopers.domain.brand.BrandService;
+import com.loopers.domain.like.LikeService;
+import com.loopers.domain.product.LikeCount;
+import com.loopers.domain.product.Price;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.product.Stock;
+import com.loopers.domain.user.LoginId;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserService;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+@SpringBootTest
+class LikeFacadeIntegrationTest {
+
+    @Autowired
+    private LikeFacade likeFacade;
+
+    @MockitoSpyBean
+    private UserService userService;
+
+    @MockitoSpyBean
+    private LikeService likeService;
+
+    @MockitoSpyBean
+    private ProductService productService;
+
+    @MockitoSpyBean
+    private BrandService brandService;
+
+    @DisplayName("좋아요를 등록할 때,")
+    @Nested
+    class RecordLike {
+
+        @DisplayName("사용자와 상품이 존재하면 좋아요가 등록되고 좋아요 수가 증가한다.")
+        @Test
+        void recordsLike_whenUserAndProductExist() {
+            // arrange
+            String loginId = "testUser";
+            Long userId = 1L;
+            Long productId = 1L;
+            LikeCommand.LikeProductCommand command = new LikeCommand.LikeProductCommand(loginId, productId);
+
+            User user = createUser(userId, loginId);
+            Product product = createProduct(productId, "상품명", 1L, 10000, 10, 100);
+            Product increasedProduct = createProduct(productId, "상품명", 1L, 10000, 11, 100);
+
+            doReturn(Optional.of(user)).when(userService).findUserByLoginId(loginId);
+            doReturn(false).when(likeService).existsByUserIdAndProductId(userId, productId);
+            doReturn(Optional.of(product)).when(productService).findProductById(productId);
+            doReturn(increasedProduct).when(productService).increaseLikeCount(productId);
+
+            // act
+            LikeInfo result = likeFacade.recordLike(command);
+
+            // assert
+            assertAll(
+                    () -> assertThat(result.productId()).isEqualTo(productId),
+                    () -> assertThat(result.likeCount()).isEqualTo(11)
+            );
+
+            // verify
+            verify(userService, times(1)).findUserByLoginId(loginId);
+            verify(likeService, times(1)).existsByUserIdAndProductId(userId, productId);
+            verify(productService, times(1)).increaseLikeCount(productId);
+            verify(likeService, times(1)).recordLike(userId, productId);
+        }
+
+        @DisplayName("이미 좋아요가 등록되어 있으면 멱등하게 현재 상태를 반환한다.")
+        @Test
+        void returnsCurrentState_whenLikeAlreadyExists() {
+            // arrange
+            String loginId = "testUser";
+            Long userId = 1L;
+            Long productId = 1L;
+            LikeCommand.LikeProductCommand command = new LikeCommand.LikeProductCommand(loginId, productId);
+
+            User user = createUser(userId, loginId);
+            Product product = createProduct(productId, "상품명", 1L, 10000, 10, 100);
+
+            doReturn(Optional.of(user)).when(userService).findUserByLoginId(loginId);
+            doReturn(true).when(likeService).existsByUserIdAndProductId(userId, productId);
+            doReturn(Optional.of(product)).when(productService).findProductById(productId);
+
+            // act
+            LikeInfo result = likeFacade.recordLike(command);
+
+            // assert
+            assertAll(
+                    () -> assertThat(result.productId()).isEqualTo(productId),
+                    () -> assertThat(result.likeCount()).isEqualTo(10)
+            );
+
+            // verify
+            verify(userService, times(1)).findUserByLoginId(loginId);
+            verify(likeService, times(1)).existsByUserIdAndProductId(userId, productId);
+            verify(productService, never()).increaseLikeCount(anyLong());
+            verify(likeService, never()).recordLike(anyLong(), anyLong());
+        }
+
+        @DisplayName("사용자가 존재하지 않으면 NOT_FOUND 예외가 발생한다.")
+        @Test
+        void throwsException_whenUserDoesNotExist() {
+            // arrange
+            String loginId = "nonExistentUser";
+            Long productId = 1L;
+            LikeCommand.LikeProductCommand command = new LikeCommand.LikeProductCommand(loginId, productId);
+
+            doReturn(Optional.empty()).when(userService).findUserByLoginId(loginId);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                likeFacade.recordLike(command);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
+            assertThat(exception.getMessage()).contains("사용자를 찾을 수 없습니다.");
+
+            // verify
+            verify(userService, times(1)).findUserByLoginId(loginId);
+            verify(likeService, never()).existsByUserIdAndProductId(anyLong(), anyLong());
+            verify(productService, never()).increaseLikeCount(anyLong());
+        }
+
+        @DisplayName("상품이 존재하지 않으면 NOT_FOUND 예외가 발생한다.")
+        @Test
+        void throwsException_whenProductDoesNotExist() {
+            // arrange
+            String loginId = "testUser";
+            Long userId = 1L;
+            Long productId = 999L;
+            LikeCommand.LikeProductCommand command = new LikeCommand.LikeProductCommand(loginId, productId);
+
+            User user = createUser(userId, loginId);
+
+            doReturn(Optional.of(user)).when(userService).findUserByLoginId(loginId);
+            doReturn(false).when(likeService).existsByUserIdAndProductId(userId, productId);
+            doThrow(new CoreException(ErrorType.NOT_FOUND, "상품을 찾을 수 없습니다."))
+                    .when(productService).increaseLikeCount(productId);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                likeFacade.recordLike(command);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
+            assertThat(exception.getMessage()).contains("상품을 찾을 수 없습니다.");
+
+            // verify
+            verify(userService, times(1)).findUserByLoginId(loginId);
+            verify(likeService, times(1)).existsByUserIdAndProductId(userId, productId);
+            verify(productService, times(1)).increaseLikeCount(productId);
+            verify(likeService, never()).recordLike(anyLong(), anyLong());
+        }
+    }
+
+    @DisplayName("좋아요를 취소할 때,")
+    @Nested
+    class CancelLike {
+
+        @DisplayName("좋아요가 등록되어 있으면 좋아요가 취소되고 좋아요 수가 감소한다.")
+        @Test
+        void cancelsLike_whenLikeExists() {
+            // arrange
+            String loginId = "testUser";
+            Long userId = 1L;
+            Long productId = 1L;
+            LikeCommand.LikeProductCommand command = new LikeCommand.LikeProductCommand(loginId, productId);
+
+            User user = createUser(userId, loginId);
+            Product product = createProduct(productId, "상품명", 1L, 10000, 10, 100);
+            Product decreasedProduct = createProduct(productId, "상품명", 1L, 10000, 9, 100);
+
+            doReturn(Optional.of(user)).when(userService).findUserByLoginId(loginId);
+            doReturn(true).when(likeService).existsByUserIdAndProductId(userId, productId);
+            doReturn(Optional.of(product)).when(productService).findProductById(productId);
+            doReturn(decreasedProduct).when(productService).decreaseLikeCount(productId);
+
+            // act
+            LikeInfo result = likeFacade.cancelLike(command);
+
+            // assert
+            assertAll(
+                    () -> assertThat(result.productId()).isEqualTo(productId),
+                    () -> assertThat(result.likeCount()).isEqualTo(9)
+            );
+
+            // verify
+            verify(userService, times(1)).findUserByLoginId(loginId);
+            verify(likeService, times(1)).existsByUserIdAndProductId(userId, productId);
+            verify(productService, times(1)).decreaseLikeCount(productId);
+            verify(likeService, times(1)).cancelLike(userId, productId);
+        }
+
+        @DisplayName("이미 좋아요가 취소되어 있으면 멱등하게 현재 상태를 반환한다.")
+        @Test
+        void returnsCurrentState_whenLikeAlreadyCancelled() {
+            // arrange
+            String loginId = "testUser";
+            Long userId = 1L;
+            Long productId = 1L;
+            LikeCommand.LikeProductCommand command = new LikeCommand.LikeProductCommand(loginId, productId);
+
+            User user = createUser(userId, loginId);
+            Product product = createProduct(productId, "상품명", 1L, 10000, 10, 100);
+
+            doReturn(Optional.of(user)).when(userService).findUserByLoginId(loginId);
+            doReturn(false).when(likeService).existsByUserIdAndProductId(userId, productId);
+            doReturn(Optional.of(product)).when(productService).findProductById(productId);
+
+            // act
+            LikeInfo result = likeFacade.cancelLike(command);
+
+            // assert
+            assertAll(
+                    () -> assertThat(result.productId()).isEqualTo(productId),
+                    () -> assertThat(result.likeCount()).isEqualTo(10)
+            );
+
+            // verify
+            verify(userService, times(1)).findUserByLoginId(loginId);
+            verify(likeService, times(1)).existsByUserIdAndProductId(userId, productId);
+            verify(productService, never()).decreaseLikeCount(anyLong());
+            verify(likeService, never()).cancelLike(anyLong(), anyLong());
+        }
+
+        @DisplayName("사용자가 존재하지 않으면 NOT_FOUND 예외가 발생한다.")
+        @Test
+        void throwsException_whenUserDoesNotExist() {
+            // arrange
+            String loginId = "nonExistentUser";
+            Long productId = 1L;
+            LikeCommand.LikeProductCommand command = new LikeCommand.LikeProductCommand(loginId, productId);
+
+            doReturn(Optional.empty()).when(userService).findUserByLoginId(loginId);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                likeFacade.cancelLike(command);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
+            assertThat(exception.getMessage()).contains("사용자를 찾을 수 없습니다.");
+
+            // verify
+            verify(userService, times(1)).findUserByLoginId(loginId);
+            verify(likeService, never()).existsByUserIdAndProductId(anyLong(), anyLong());
+            verify(productService, never()).decreaseLikeCount(anyLong());
+        }
+
+        @DisplayName("상품이 존재하지 않으면 NOT_FOUND 예외가 발생한다.")
+        @Test
+        void throwsException_whenProductDoesNotExist() {
+            // arrange
+            String loginId = "testUser";
+            Long userId = 1L;
+            Long productId = 999L;
+            LikeCommand.LikeProductCommand command = new LikeCommand.LikeProductCommand(loginId, productId);
+
+            User user = createUser(userId, loginId);
+
+            doReturn(Optional.of(user)).when(userService).findUserByLoginId(loginId);
+            doReturn(false).when(likeService).existsByUserIdAndProductId(userId, productId);
+            doReturn(Optional.empty()).when(productService).findProductById(productId);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                likeFacade.cancelLike(command);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
+            assertThat(exception.getMessage()).contains("상품을 찾을 수 없습니다.");
+
+            // verify
+            verify(userService, times(1)).findUserByLoginId(loginId);
+            verify(likeService, times(1)).existsByUserIdAndProductId(userId, productId);
+            verify(productService, never()).decreaseLikeCount(anyLong());
+        }
+    }
+
+    @DisplayName("내가 좋아요한 상품 목록을 조회할 때,")
+    @Nested
+    class GetLikedProducts {
+
+        @DisplayName("좋아요한 상품이 있으면 상품 목록이 반환된다.")
+        @Test
+        void returnsProducts_whenLikedProductsExist() {
+            // arrange
+            String loginId = "testUser";
+            Long userId = 1L;
+            List<Long> productIds = List.of(1L, 2L);
+
+            User user = createUser(userId, loginId);
+            Product product1 = createProduct(1L, "상품1", 1L, 10000, 10, 100);
+            Product product2 = createProduct(2L, "상품2", 2L, 20000, 20, 200);
+
+            Map<Long, String> brandNamesMap = new HashMap<>();
+            brandNamesMap.put(1L, "브랜드1");
+            brandNamesMap.put(2L, "브랜드2");
+
+            doReturn(Optional.of(user)).when(userService).findUserByLoginId(loginId);
+            doReturn(productIds).when(likeService).findLikedProductIds(userId);
+            doReturn(Optional.of(product1)).when(productService).findProductById(1L);
+            doReturn(Optional.of(product2)).when(productService).findProductById(2L);
+            doReturn(brandNamesMap).when(brandService).findBrandNamesByIds(any());
+
+            // act
+            List<com.loopers.application.product.ProductInfo> result = likeFacade.getLikedProducts(loginId);
+
+            // assert
+            assertThat(result).hasSize(2);
+            assertAll(
+                    () -> assertThat(result.get(0).id()).isEqualTo(1L),
+                    () -> assertThat(result.get(0).name()).isEqualTo("상품1"),
+                    () -> assertThat(result.get(0).brandName()).isEqualTo("브랜드1"),
+                    () -> assertThat(result.get(1).id()).isEqualTo(2L),
+                    () -> assertThat(result.get(1).name()).isEqualTo("상품2"),
+                    () -> assertThat(result.get(1).brandName()).isEqualTo("브랜드2")
+            );
+
+            // verify
+            verify(userService, times(1)).findUserByLoginId(loginId);
+            verify(likeService, times(1)).findLikedProductIds(userId);
+            verify(brandService, times(1)).findBrandNamesByIds(any());
+        }
+
+        @DisplayName("좋아요한 상품이 없으면 NOT_FOUND 예외가 발생한다.")
+        @Test
+        void throwsException_whenNoLikedProducts() {
+            // arrange
+            String loginId = "testUser";
+            Long userId = 1L;
+
+            User user = createUser(userId, loginId);
+
+            doReturn(Optional.of(user)).when(userService).findUserByLoginId(loginId);
+            doReturn(List.of()).when(likeService).findLikedProductIds(userId);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                likeFacade.getLikedProducts(loginId);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
+            assertThat(exception.getMessage()).contains("좋아요한 상품이 없습니다.");
+
+            // verify
+            verify(userService, times(1)).findUserByLoginId(loginId);
+            verify(likeService, times(1)).findLikedProductIds(userId);
+            verify(productService, never()).findProductById(anyLong());
+            verify(brandService, never()).findBrandNamesByIds(any());
+        }
+
+        @DisplayName("사용자가 존재하지 않으면 NOT_FOUND 예외가 발생한다.")
+        @Test
+        void throwsException_whenUserDoesNotExist() {
+            // arrange
+            String loginId = "nonExistentUser";
+
+            doReturn(Optional.empty()).when(userService).findUserByLoginId(loginId);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                likeFacade.getLikedProducts(loginId);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
+            assertThat(exception.getMessage()).contains("사용자를 찾을 수 없습니다.");
+
+            // verify
+            verify(userService, times(1)).findUserByLoginId(loginId);
+            verify(likeService, never()).findLikedProductIds(anyLong());
+        }
+    }
+
+    private User createUser(Long id, String loginId) {
+        User user = mock(User.class);
+        when(user.getId()).thenReturn(id);
+        when(user.getLoginId()).thenReturn(new LoginId(loginId));
+        return user;
+    }
+
+    private Product createProduct(Long id, String name, Long brandId, Integer price, Integer likeCount, Integer stock) {
+        Product product = mock(Product.class);
+        Price priceValue = mock(Price.class);
+        LikeCount likeCountValue = mock(LikeCount.class);
+        Stock stockValue = mock(Stock.class);
+
+        when(product.getId()).thenReturn(id);
+        when(product.getName()).thenReturn(name);
+        when(product.getBrandId()).thenReturn(brandId);
+        when(product.getPrice()).thenReturn(priceValue);
+        when(product.getLikeCount()).thenReturn(likeCountValue);
+        when(product.getStock()).thenReturn(stockValue);
+        when(priceValue.getPrice()).thenReturn(price);
+        when(likeCountValue.getCount()).thenReturn(likeCount);
+        when(stockValue.getQuantity()).thenReturn(stock);
+
+        return product;
+    }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/application/product/ProductFacadeIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/application/product/ProductFacadeIntegrationTest.java
new file mode 100644
index 000000000..cc39a01ab
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/application/product/ProductFacadeIntegrationTest.java
@@ -0,0 +1,367 @@
+package com.loopers.application.product;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.loopers.domain.brand.BrandService;
+import com.loopers.domain.product.LikeCount;
+import com.loopers.domain.product.Price;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.product.Stock;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+@SpringBootTest
+class ProductFacadeIntegrationTest {
+
+    @Autowired
+    private ProductFacade productFacade;
+
+    @MockitoSpyBean
+    private ProductService productService;
+
+    @MockitoSpyBean
+    private BrandService brandService;
+
+    @DisplayName("상품 목록을 조회할 때,")
+    @Nested
+    class GetProducts {
+
+        @DisplayName("LATEST 정렬로 조회하면 최신순 상품 목록이 반환된다.")
+        @Test
+        void returnsProducts_whenSortedByLatest() {
+            // arrange
+            Long brandId = null;
+            int page = 0;
+            int size = 20;
+            ProductCommand.GetProductsCommand command = new ProductCommand.GetProductsCommand(
+                    brandId, ProductSort.LATEST, page, size
+            );
+
+            Product product1 = createProduct(1L, "상품1", 1L, 10000, 10, 100);
+            Product product2 = createProduct(2L, "상품2", 1L, 20000, 20, 200);
+            List<Product> products = List.of(product1, product2);
+
+            Map<Long, String> brandNamesMap = new HashMap<>();
+            brandNamesMap.put(1L, "브랜드1");
+
+            doReturn(products).when(productService).findProductsByLatestWithBrandName(brandId, page, size);
+            doReturn(brandNamesMap).when(brandService).findBrandNamesByIds(any());
+
+            // act
+            List<ProductInfo> result = productFacade.getProducts(command);
+
+            // assert
+            assertThat(result).hasSize(2);
+            assertAll(
+                    () -> assertThat(result.get(0).id()).isEqualTo(1L),
+                    () -> assertThat(result.get(0).name()).isEqualTo("상품1"),
+                    () -> assertThat(result.get(0).brandName()).isEqualTo("브랜드1"),
+                    () -> assertThat(result.get(1).id()).isEqualTo(2L),
+                    () -> assertThat(result.get(1).name()).isEqualTo("상품2"),
+                    () -> assertThat(result.get(1).brandName()).isEqualTo("브랜드1")
+            );
+
+            // verify
+            verify(productService, times(1)).findProductsByLatestWithBrandName(brandId, page, size);
+            verify(brandService, times(1)).findBrandNamesByIds(any());
+        }
+
+        @DisplayName("PRICE_ASC 정렬로 조회하면 가격 오름차순 상품 목록이 반환된다.")
+        @Test
+        void returnsProducts_whenSortedByPriceAsc() {
+            // arrange
+            Long brandId = null;
+            int page = 0;
+            int size = 20;
+            ProductCommand.GetProductsCommand command = new ProductCommand.GetProductsCommand(
+                    brandId, ProductSort.PRICE_ASC, page, size
+            );
+
+            Product product1 = createProduct(1L, "상품1", 1L, 10000, 10, 100);
+            Product product2 = createProduct(2L, "상품2", 2L, 20000, 20, 200);
+            List<Product> products = List.of(product1, product2);
+
+            Map<Long, String> brandNamesMap = new HashMap<>();
+            brandNamesMap.put(1L, "브랜드1");
+            brandNamesMap.put(2L, "브랜드2");
+
+            doReturn(products).when(productService).findProductsByPriceAscWithBrandName(brandId, page, size);
+            doReturn(brandNamesMap).when(brandService).findBrandNamesByIds(any());
+
+            // act
+            List<ProductInfo> result = productFacade.getProducts(command);
+
+            // assert
+            assertThat(result).hasSize(2);
+            assertAll(
+                    () -> assertThat(result.get(0).id()).isEqualTo(1L),
+                    () -> assertThat(result.get(0).brandName()).isEqualTo("브랜드1"),
+                    () -> assertThat(result.get(1).id()).isEqualTo(2L),
+                    () -> assertThat(result.get(1).brandName()).isEqualTo("브랜드2")
+            );
+
+            // verify
+            verify(productService, times(1)).findProductsByPriceAscWithBrandName(brandId, page, size);
+            verify(brandService, times(1)).findBrandNamesByIds(any());
+        }
+
+        @DisplayName("LIKES_DESC 정렬로 조회하면 좋아요 내림차순 상품 목록이 반환된다.")
+        @Test
+        void returnsProducts_whenSortedByLikesDesc() {
+            // arrange
+            Long brandId = null;
+            int page = 0;
+            int size = 20;
+            ProductCommand.GetProductsCommand command = new ProductCommand.GetProductsCommand(
+                    brandId, ProductSort.LIKES_DESC, page, size
+            );
+
+            Product product1 = createProduct(1L, "상품1", 1L, 10000, 100, 100);
+            Product product2 = createProduct(2L, "상품2", 1L, 20000, 50, 200);
+            List<Product> products = List.of(product1, product2);
+
+            Map<Long, String> brandNamesMap = new HashMap<>();
+            brandNamesMap.put(1L, "브랜드1");
+
+            doReturn(products).when(productService).findProductsByLikesDescWithBrandName(brandId, page, size);
+            doReturn(brandNamesMap).when(brandService).findBrandNamesByIds(any());
+
+            // act
+            List<ProductInfo> result = productFacade.getProducts(command);
+
+            // assert
+            assertThat(result).hasSize(2);
+            assertAll(
+                    () -> assertThat(result.get(0).id()).isEqualTo(1L),
+                    () -> assertThat(result.get(0).likeCount()).isEqualTo(100),
+                    () -> assertThat(result.get(1).id()).isEqualTo(2L),
+                    () -> assertThat(result.get(1).likeCount()).isEqualTo(50)
+            );
+
+            // verify
+            verify(productService, times(1)).findProductsByLikesDescWithBrandName(brandId, page, size);
+            verify(brandService, times(1)).findBrandNamesByIds(any());
+        }
+
+        @DisplayName("여러 brandId가 있는 경우 중복을 제거하고 한 번에 조회한다.")
+        @Test
+        void deduplicatesBrandIds_whenMultipleProductsHaveSameBrand() {
+            // arrange
+            Long brandId = null;
+            int page = 0;
+            int size = 20;
+            ProductCommand.GetProductsCommand command = new ProductCommand.GetProductsCommand(
+                    brandId, ProductSort.LATEST, page, size
+            );
+
+            Product product1 = createProduct(1L, "상품1", 1L, 10000, 10, 100);
+            Product product2 = createProduct(2L, "상품2", 1L, 20000, 20, 200);
+            Product product3 = createProduct(3L, "상품3", 2L, 30000, 30, 300);
+            List<Product> products = List.of(product1, product2, product3);
+
+            Map<Long, String> brandNamesMap = new HashMap<>();
+            brandNamesMap.put(1L, "브랜드1");
+            brandNamesMap.put(2L, "브랜드2");
+
+            doReturn(products).when(productService).findProductsByLatestWithBrandName(brandId, page, size);
+            doReturn(brandNamesMap).when(brandService).findBrandNamesByIds(any());
+
+            // act
+            List<ProductInfo> result = productFacade.getProducts(command);
+
+            // assert
+            assertThat(result).hasSize(3);
+            assertAll(
+                    () -> assertThat(result.get(0).brandName()).isEqualTo("브랜드1"),
+                    () -> assertThat(result.get(1).brandName()).isEqualTo("브랜드1"),
+                    () -> assertThat(result.get(2).brandName()).isEqualTo("브랜드2")
+            );
+
+            // verify
+            verify(productService, times(1)).findProductsByLatestWithBrandName(brandId, page, size);
+            verify(brandService, times(1)).findBrandNamesByIds(any());
+        }
+
+        @DisplayName("brandId로 필터링하면 해당 브랜드의 상품만 조회된다.")
+        @Test
+        void returnsProducts_whenFilteredByBrandId() {
+            // arrange
+            Long brandId = 1L;
+            int page = 0;
+            int size = 20;
+            ProductCommand.GetProductsCommand command = new ProductCommand.GetProductsCommand(
+                    brandId, ProductSort.LATEST, page, size
+            );
+
+            Product product1 = createProduct(1L, "상품1", 1L, 10000, 10, 100);
+            List<Product> products = List.of(product1);
+
+            Map<Long, String> brandNamesMap = new HashMap<>();
+            brandNamesMap.put(1L, "브랜드1");
+
+            doReturn(products).when(productService).findProductsByLatestWithBrandName(brandId, page, size);
+            doReturn(brandNamesMap).when(brandService).findBrandNamesByIds(any());
+
+            // act
+            List<ProductInfo> result = productFacade.getProducts(command);
+
+            // assert
+            assertThat(result).hasSize(1);
+            assertThat(result.get(0).brandId()).isEqualTo(1L);
+            assertThat(result.get(0).brandName()).isEqualTo("브랜드1");
+
+            // verify
+            verify(productService, times(1)).findProductsByLatestWithBrandName(brandId, page, size);
+            verify(brandService, times(1)).findBrandNamesByIds(any());
+        }
+
+        @DisplayName("상품이 없으면 빈 리스트가 반환된다.")
+        @Test
+        void returnsEmptyList_whenNoProductsExist() {
+            // arrange
+            Long brandId = null;
+            int page = 0;
+            int size = 20;
+            ProductCommand.GetProductsCommand command = new ProductCommand.GetProductsCommand(
+                    brandId, ProductSort.LATEST, page, size
+            );
+
+            List<Product> products = List.of();
+
+            doReturn(products).when(productService).findProductsByLatestWithBrandName(brandId, page, size);
+            doReturn(new HashMap<>()).when(brandService).findBrandNamesByIds(any());
+
+            // act
+            List<ProductInfo> result = productFacade.getProducts(command);
+
+            // assert
+            assertThat(result).isEmpty();
+
+            // verify
+            verify(productService, times(1)).findProductsByLatestWithBrandName(brandId, page, size);
+            verify(brandService, times(1)).findBrandNamesByIds(any());
+        }
+    }
+
+    @DisplayName("상품 정보를 조회할 때,")
+    @Nested
+    class GetProduct {
+
+        @DisplayName("상품이 존재하면 상품 정보가 반환된다.")
+        @Test
+        void returnsProductInfo_whenProductExists() {
+            // arrange
+            Long productId = 1L;
+            Product product = createProduct(1L, "상품1", 1L, 10000, 10, 100);
+            String brandName = "브랜드1";
+
+            doReturn(Optional.of(product)).when(productService).findProductById(productId);
+            doReturn(brandName).when(brandService).findBrandNameById(1L);
+
+            // act
+            ProductInfo result = productFacade.getProduct(productId);
+
+            // assert
+            assertAll(
+                    () -> assertThat(result.id()).isEqualTo(1L),
+                    () -> assertThat(result.name()).isEqualTo("상품1"),
+                    () -> assertThat(result.brandId()).isEqualTo(1L),
+                    () -> assertThat(result.brandName()).isEqualTo("브랜드1"),
+                    () -> assertThat(result.price()).isEqualTo(10000),
+                    () -> assertThat(result.likeCount()).isEqualTo(10),
+                    () -> assertThat(result.stock()).isEqualTo(100)
+            );
+
+            // verify
+            verify(productService, times(1)).findProductById(productId);
+            verify(brandService, times(1)).findBrandNameById(1L);
+        }
+
+        @DisplayName("상품이 존재하지 않으면 NOT_FOUND 예외가 발생한다.")
+        @Test
+        void throwsException_whenProductDoesNotExist() {
+            // arrange
+            Long productId = 999L;
+
+            doReturn(Optional.empty()).when(productService).findProductById(productId);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                productFacade.getProduct(productId);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
+            assertThat(exception.getMessage()).contains("상품을 찾을 수 없습니다.");
+
+            // verify
+            verify(productService, times(1)).findProductById(productId);
+            verify(brandService, never()).findBrandNameById(anyLong());
+        }
+
+        @DisplayName("브랜드가 존재하지 않으면 NOT_FOUND 예외가 발생한다.")
+        @Test
+        void throwsException_whenBrandDoesNotExist() {
+            // arrange
+            Long productId = 1L;
+            Product product = createProduct(1L, "상품1", 999L, 10000, 10, 100);
+
+            doReturn(Optional.of(product)).when(productService).findProductById(productId);
+            doThrow(new CoreException(ErrorType.NOT_FOUND, "브랜드를 찾을 수 없습니다."))
+                    .when(brandService).findBrandNameById(999L);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                productFacade.getProduct(productId);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
+            assertThat(exception.getMessage()).contains("브랜드를 찾을 수 없습니다.");
+
+            // verify
+            verify(productService, times(1)).findProductById(productId);
+            verify(brandService, times(1)).findBrandNameById(999L);
+        }
+    }
+
+    private Product createProduct(Long id, String name, Long brandId, Integer price, Integer likeCount, Integer stock) {
+        Product product = mock(Product.class);
+        Price priceValue = mock(Price.class);
+        LikeCount likeCountValue = mock(LikeCount.class);
+        Stock stockValue = mock(Stock.class);
+
+        when(product.getId()).thenReturn(id);
+        when(product.getName()).thenReturn(name);
+        when(product.getBrandId()).thenReturn(brandId);
+        when(product.getPrice()).thenReturn(priceValue);
+        when(product.getLikeCount()).thenReturn(likeCountValue);
+        when(product.getStock()).thenReturn(stockValue);
+        when(priceValue.getPrice()).thenReturn(price);
+        when(likeCountValue.getCount()).thenReturn(likeCount);
+        when(stockValue.getQuantity()).thenReturn(stock);
+
+        return product;
+    }
+}
+
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleModelTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleModelTest.java
deleted file mode 100644
index 44ca7576e..000000000
--- a/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleModelTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.loopers.domain.example;
-
-import com.loopers.support.error.CoreException;
-import com.loopers.support.error.ErrorType;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertAll;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class ExampleModelTest {
-    @DisplayName("예시 모델을 생성할 때, ")
-    @Nested
-    class Create {
-        @DisplayName("제목과 설명이 모두 주어지면, 정상적으로 생성된다.")
-        @Test
-        void createsExampleModel_whenNameAndDescriptionAreProvided() {
-            // arrange
-            String name = "제목";
-            String description = "설명";
-
-            // act
-            ExampleModel exampleModel = new ExampleModel(name, description);
-
-            // assert
-            assertAll(
-                () -> assertThat(exampleModel.getId()).isNotNull(),
-                () -> assertThat(exampleModel.getName()).isEqualTo(name),
-                () -> assertThat(exampleModel.getDescription()).isEqualTo(description)
-            );
-        }
-
-        @DisplayName("제목이 빈칸으로만 이루어져 있으면, BAD_REQUEST 예외가 발생한다.")
-        @Test
-        void throwsBadRequestException_whenTitleIsBlank() {
-            // arrange
-            String name = "   ";
-
-            // act
-            CoreException result = assertThrows(CoreException.class, () -> {
-                new ExampleModel(name, "설명");
-            });
-
-            // assert
-            assertThat(result.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
-        }
-
-        @DisplayName("설명이 비어있으면, BAD_REQUEST 예외가 발생한다.")
-        @Test
-        void throwsBadRequestException_whenDescriptionIsEmpty() {
-            // arrange
-            String description = "";
-
-            // act
-            CoreException result = assertThrows(CoreException.class, () -> {
-                new ExampleModel("제목", description);
-            });
-
-            // assert
-            assertThat(result.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
-        }
-    }
-}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleServiceIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleServiceIntegrationTest.java
deleted file mode 100644
index bbd5fdbe1..000000000
--- a/apps/commerce-api/src/test/java/com/loopers/domain/example/ExampleServiceIntegrationTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package com.loopers.domain.example;
-
-import com.loopers.infrastructure.example.ExampleJpaRepository;
-import com.loopers.support.error.CoreException;
-import com.loopers.support.error.ErrorType;
-import com.loopers.utils.DatabaseCleanUp;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertAll;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-@SpringBootTest
-class ExampleServiceIntegrationTest {
-    @Autowired
-    private ExampleService exampleService;
-
-    @Autowired
-    private ExampleJpaRepository exampleJpaRepository;
-
-    @Autowired
-    private DatabaseCleanUp databaseCleanUp;
-
-    @AfterEach
-    void tearDown() {
-        databaseCleanUp.truncateAllTables();
-    }
-
-    @DisplayName("예시를 조회할 때,")
-    @Nested
-    class Get {
-        @DisplayName("존재하는 예시 ID를 주면, 해당 예시 정보를 반환한다.")
-        @Test
-        void returnsExampleInfo_whenValidIdIsProvided() {
-            // arrange
-            ExampleModel exampleModel = exampleJpaRepository.save(
-                new ExampleModel("예시 제목", "예시 설명")
-            );
-
-            // act
-            ExampleModel result = exampleService.getExample(exampleModel.getId());
-
-            // assert
-            assertAll(
-                () -> assertThat(result).isNotNull(),
-                () -> assertThat(result.getId()).isEqualTo(exampleModel.getId()),
-                () -> assertThat(result.getName()).isEqualTo(exampleModel.getName()),
-                () -> assertThat(result.getDescription()).isEqualTo(exampleModel.getDescription())
-            );
-        }
-
-        @DisplayName("존재하지 않는 예시 ID를 주면, NOT_FOUND 예외가 발생한다.")
-        @Test
-        void throwsException_whenInvalidIdIsProvided() {
-            // arrange
-            Long invalidId = 999L; // Assuming this ID does not exist
-
-            // act
-            CoreException exception = assertThrows(CoreException.class, () -> {
-                exampleService.getExample(invalidId);
-            });
-
-            // assert
-            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
-        }
-    }
-}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeServiceIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeServiceIntegrationTest.java
new file mode 100644
index 000000000..23e0dde33
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeServiceIntegrationTest.java
@@ -0,0 +1,196 @@
+package com.loopers.domain.like;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.util.List;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+@SpringBootTest
+class LikeServiceIntegrationTest {
+
+    @Autowired
+    private LikeService likeService;
+
+    @MockitoSpyBean
+    private LikeRepository likeRepository;
+
+    @DisplayName("좋아요를 등록할 때,")
+    @Nested
+    class RecordLike {
+
+        @DisplayName("좋아요가 존재하지 않으면 등록된다.")
+        @Test
+        void recordsLike_whenLikeDoesNotExist() {
+            // arrange
+            Long userId = 1L;
+            Long productId = 1L;
+
+            doReturn(false).when(likeRepository).existsByUserIdAndProductId(userId, productId);
+
+            // act
+            likeService.recordLike(userId, productId);
+
+            // verify
+            verify(likeRepository, times(1)).existsByUserIdAndProductId(userId, productId);
+            verify(likeRepository, times(1)).saveLike(argThat(like ->
+                    like.getUserId().equals(userId) && like.getProductId().equals(productId)
+            ));
+
+        }
+
+        @DisplayName("이미 좋아요가 등록되어 있으면 멱등하게 동작하여 등록하지 않는다.")
+        @Test
+        void doesNotRecordLike_whenLikeAlreadyExists() {
+            // arrange
+            Long userId = 1L;
+            Long productId = 1L;
+
+            doReturn(true).when(likeRepository).existsByUserIdAndProductId(userId, productId);
+
+            // act
+            likeService.recordLike(userId, productId);
+
+            // verify
+            verify(likeRepository, times(1)).existsByUserIdAndProductId(userId, productId);
+            verify(likeRepository, never()).saveLike(any(Like.class));
+        }
+    }
+
+    @DisplayName("좋아요를 취소할 때,")
+    @Nested
+    class CancelLike {
+
+        @DisplayName("좋아요가 존재하면 취소된다.")
+        @Test
+        void cancelsLike_whenLikeExists() {
+            // arrange
+            Long userId = 1L;
+            Long productId = 1L;
+
+            doReturn(true).when(likeRepository).existsByUserIdAndProductId(userId, productId);
+
+            // act
+            likeService.cancelLike(userId, productId);
+
+            // verify
+            verify(likeRepository, times(1)).existsByUserIdAndProductId(userId, productId);
+            verify(likeRepository, times(1)).delete(userId, productId);
+        }
+
+        @DisplayName("이미 좋아요가 취소되어 있으면 멱등하게 동작하여 취소하지 않는다.")
+        @Test
+        void doesNotCancelLike_whenLikeAlreadyCancelled() {
+            // arrange
+            Long userId = 1L;
+            Long productId = 1L;
+
+            doReturn(false).when(likeRepository).existsByUserIdAndProductId(userId, productId);
+
+            // act
+            likeService.cancelLike(userId, productId);
+
+            // verify
+            verify(likeRepository, times(1)).existsByUserIdAndProductId(userId, productId);
+            verify(likeRepository, never()).delete(anyLong(), anyLong());
+        }
+    }
+
+    @DisplayName("좋아요한 상품 ID 목록을 조회할 때,")
+    @Nested
+    class FindLikedProductIds {
+
+        @DisplayName("좋아요한 상품이 있으면 상품 ID 목록이 반환된다.")
+        @Test
+        void returnsProductIds_whenLikedProductsExist() {
+            // arrange
+            Long userId = 1L;
+            List<Long> productIds = List.of(1L, 2L, 3L);
+
+            doReturn(productIds).when(likeRepository).findProductIdsByUserId(userId);
+
+            // act
+            List<Long> result = likeService.findLikedProductIds(userId);
+
+            // assert
+            assertThat(result).hasSize(3);
+            assertThat(result).containsExactlyInAnyOrder(1L, 2L, 3L);
+
+            // verify
+            verify(likeRepository, times(1)).findProductIdsByUserId(userId);
+        }
+
+        @DisplayName("좋아요한 상품이 없으면 빈 목록이 반환된다.")
+        @Test
+        void returnsEmptyList_whenNoLikedProducts() {
+            // arrange
+            Long userId = 1L;
+
+            doReturn(List.of()).when(likeRepository).findProductIdsByUserId(userId);
+
+            // act
+            List<Long> result = likeService.findLikedProductIds(userId);
+
+            // assert
+            assertThat(result).isEmpty();
+
+            // verify
+            verify(likeRepository, times(1)).findProductIdsByUserId(userId);
+        }
+    }
+
+    @DisplayName("좋아요 존재 여부를 확인할 때,")
+    @Nested
+    class ExistsByUserIdAndProductId {
+
+        @DisplayName("좋아요가 존재하면 true를 반환한다.")
+        @Test
+        void returnsTrue_whenLikeExists() {
+            // arrange
+            Long userId = 1L;
+            Long productId = 1L;
+
+            doReturn(true).when(likeRepository).existsByUserIdAndProductId(userId, productId);
+
+            // act
+            boolean result = likeService.existsByUserIdAndProductId(userId, productId);
+
+            // assert
+            assertThat(result).isTrue();
+
+            // verify
+            verify(likeRepository, times(1)).existsByUserIdAndProductId(userId, productId);
+        }
+
+        @DisplayName("좋아요가 존재하지 않으면 false를 반환한다.")
+        @Test
+        void returnsFalse_whenLikeDoesNotExist() {
+            // arrange
+            Long userId = 1L;
+            Long productId = 1L;
+
+            doReturn(false).when(likeRepository).existsByUserIdAndProductId(userId, productId);
+
+            // act
+            boolean result = likeService.existsByUserIdAndProductId(userId, productId);
+
+            // assert
+            assertThat(result).isFalse();
+
+            // verify
+            verify(likeRepository, times(1)).existsByUserIdAndProductId(userId, productId);
+        }
+    }
+}
+
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/order/DeliveryTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/order/DeliveryTest.java
new file mode 100644
index 000000000..463720654
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/order/DeliveryTest.java
@@ -0,0 +1,150 @@
+package com.loopers.domain.order;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
+import org.junit.jupiter.params.provider.ValueSource;
+
+class DeliveryTest {
+
+    @DisplayName("배송 정보를 생성할 때,")
+    @Nested
+    class CreateDelivery {
+
+        @DisplayName("모든 필드가 올바르게 주어지면 정상적으로 생성된다.")
+        @Test
+        void createsDelivery_whenAllFieldsAreValid() {
+            // arrange
+            String receiverName = "홍길동";
+            String receiverPhoneNumber = "010-1234-5678";
+            String baseAddress = "서울시 강남구";
+            String detailAddress = "테헤란로 123";
+
+            // act
+            Delivery delivery = Delivery.createDelivery(receiverName, receiverPhoneNumber, baseAddress, detailAddress);
+
+            // assert
+            assertAll(
+                    () -> assertThat(delivery.getReceiverName()).isEqualTo(receiverName),
+                    () -> assertThat(delivery.getReceiverPhoneNumber()).isEqualTo(receiverPhoneNumber),
+                    () -> assertThat(delivery.getBaseAddress()).isEqualTo(baseAddress),
+                    () -> assertThat(delivery.getDetailAddress()).isEqualTo(detailAddress)
+            );
+        }
+
+        @DisplayName("수령인 이름이 비어있으면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @NullAndEmptySource
+        @ValueSource(strings = {" ", "   "})
+        void throwsException_whenReceiverNameIsBlank(String invalidReceiverName) {
+            // arrange
+            String receiverPhoneNumber = "010-1234-5678";
+            String baseAddress = "서울시 강남구";
+            String detailAddress = "테헤란로 123";
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Delivery.createDelivery(invalidReceiverName, receiverPhoneNumber, baseAddress, detailAddress);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("수령인 이름은 필수입니다.");
+        }
+
+        @DisplayName("수령인 핸드폰번호가 비어있으면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @NullAndEmptySource
+        @ValueSource(strings = {" ", "   "})
+        void throwsException_whenReceiverPhoneNumberIsBlank(String invalidPhoneNumber) {
+            // arrange
+            String receiverName = "홍길동";
+            String baseAddress = "서울시 강남구";
+            String detailAddress = "테헤란로 123";
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Delivery.createDelivery(receiverName, invalidPhoneNumber, baseAddress, detailAddress);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("수령인 핸드폰번호는 필수입니다.");
+        }
+
+        @DisplayName("주소가 비어있으면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @NullAndEmptySource
+        @ValueSource(strings = {" ", "   "})
+        void throwsException_whenBaseAddressIsBlank(String invalidAddress) {
+            // arrange
+            String receiverName = "홍길동";
+            String receiverPhoneNumber = "010-1234-5678";
+            String detailAddress = "테헤란로 123";
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Delivery.createDelivery(receiverName, receiverPhoneNumber, invalidAddress, detailAddress);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("주소는 필수입니다.");
+        }
+
+        @DisplayName("상세 주소가 비어있으면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @NullAndEmptySource
+        @ValueSource(strings = {" ", "   "})
+        void throwsException_whenDetailAddressIsBlank(String invalidDetailAddress) {
+            // arrange
+            String receiverName = "홍길동";
+            String receiverPhoneNumber = "010-1234-5678";
+            String baseAddress = "서울시 강남구";
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Delivery.createDelivery(receiverName, receiverPhoneNumber, baseAddress, invalidDetailAddress);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("상세 주소는 필수입니다.");
+        }
+
+        @DisplayName("핸드폰 번호가 xxx-xxxx-xxxx 형식이 아니면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @ValueSource(strings = {
+                "01012345678",
+                "010-1234-567",
+                "010-123-5678",
+                "0101234-5678",
+                "010-12345678",
+                "0101234-5678",
+                "01-1234-5678",
+                "010-12345-6789",
+                "010-123-45678",
+                "0101234567",
+                "010-1234-56789",
+                "phone-number"
+        })
+        void throwsException_whenPhoneNumberFormatIsInvalid(String invalidPhoneNumber) {
+            // arrange
+            String receiverName = "홍길동";
+            String baseAddress = "서울시 강남구";
+            String detailAddress = "테헤란로 123";
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Delivery.createDelivery(receiverName, invalidPhoneNumber, baseAddress, detailAddress);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("핸드폰 번호는 xxx-xxxx-xxxx 형식이어야 합니다.");
+        }
+    }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderItemTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderItemTest.java
new file mode 100644
index 000000000..ea85d378d
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderItemTest.java
@@ -0,0 +1,149 @@
+package com.loopers.domain.order;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
+import org.junit.jupiter.params.provider.ValueSource;
+
+class OrderItemTest {
+
+    @DisplayName("주문 상품을 생성할 때,")
+    @Nested
+    class CreateOrderItem {
+
+        @DisplayName("모든 필드가 올바르게 주어지면 정상적으로 생성된다.")
+        @Test
+        void createsOrderItem_whenAllFieldsAreValid() {
+            // arrange
+            Long productId = 1L;
+            String productName = "상품명";
+            Integer price = 10000;
+            Integer quantity = 2;
+
+            // act
+            OrderItem orderItem = OrderItem.createOrderItem(productId, productName, price, quantity);
+
+            // assert
+            assertAll(
+                    () -> assertThat(orderItem.getProductId()).isEqualTo(productId),
+                    () -> assertThat(orderItem.getProductName()).isEqualTo(productName),
+                    () -> assertThat(orderItem.getPrice()).isEqualTo(price),
+                    () -> assertThat(orderItem.getQuantity()).isEqualTo(quantity)
+            );
+        }
+
+        @DisplayName("상품 ID가 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenProductIdIsNull() {
+            // arrange
+            String productName = "상품명";
+            Integer price = 10000;
+            Integer quantity = 2;
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                OrderItem.createOrderItem(null, productName, price, quantity);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("상품 ID는 필수입니다.");
+        }
+
+        @DisplayName("상품명이 비어있으면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @NullAndEmptySource
+        @ValueSource(strings = {" ", "   "})
+        void throwsException_whenProductNameIsBlank(String invalidProductName) {
+            // arrange
+            Long productId = 1L;
+            Integer price = 10000;
+            Integer quantity = 2;
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                OrderItem.createOrderItem(productId, invalidProductName, price, quantity);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("상품명은 필수입니다.");
+        }
+
+        @DisplayName("가격이 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenPriceIsNull() {
+            // arrange
+            Long productId = 1L;
+            String productName = "상품명";
+            Integer quantity = 2;
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                OrderItem.createOrderItem(productId, productName, null, quantity);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("가격은 필수입니다.");
+        }
+
+        @DisplayName("가격이 0 이하면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @ValueSource(ints = {0, -1, -100})
+        void throwsException_whenPriceIsZeroOrNegative(int invalidPrice) {
+            // arrange
+            Long productId = 1L;
+            String productName = "상품명";
+            Integer quantity = 2;
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                OrderItem.createOrderItem(productId, productName, invalidPrice, quantity);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("가격은 0보다 커야 합니다.");
+        }
+
+        @DisplayName("수량이 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenQuantityIsNull() {
+            // arrange
+            Long productId = 1L;
+            String productName = "상품명";
+            Integer price = 10000;
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                OrderItem.createOrderItem(productId, productName, price, null);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("수량은 필수입니다.");
+        }
+
+        @DisplayName("수량이 0 이하면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @ValueSource(ints = {0, -1, -100})
+        void throwsException_whenQuantityIsZeroOrNegative(int invalidQuantity) {
+            // arrange
+            Long productId = 1L;
+            String productName = "상품명";
+            Integer price = 10000;
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                OrderItem.createOrderItem(productId, productName, price, invalidQuantity);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("수량은 0보다 커야 합니다.");
+        }
+    }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderServiceIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderServiceIntegrationTest.java
new file mode 100644
index 000000000..969fa838b
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderServiceIntegrationTest.java
@@ -0,0 +1,223 @@
+package com.loopers.domain.order;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.loopers.domain.product.Price;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.Stock;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+@SpringBootTest
+class OrderServiceIntegrationTest {
+
+    @Autowired
+    private OrderService orderService;
+
+    @MockitoSpyBean
+    private OrderRepository orderRepository;
+
+    @DisplayName("주문을 생성할 때,")
+    @Nested
+    class CreateOrder {
+
+        @DisplayName("사용자 ID와 배송 정보가 주어지면 주문이 생성된다.")
+        @Test
+        void createsOrder_whenUserIdAndDeliveryAreProvided() {
+            // arrange
+            Long userId = 1L;
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+
+            // act
+            Order order = orderService.createOrder(userId, delivery);
+
+            // assert
+            assertAll(
+                    () -> assertThat(order.getUserId()).isEqualTo(userId),
+                    () -> assertThat(order.getDelivery()).isEqualTo(delivery),
+                    () -> assertThat(order.getTotalPrice()).isEqualTo(0),
+                    () -> assertThat(order.getOrderStatus()).isEqualTo(OrderStatus.CREATED),
+                    () -> assertThat(order.getOrderItems()).isEmpty()
+            );
+        }
+    }
+
+    @DisplayName("주문 상품을 생성할 때,")
+    @Nested
+    class CreateOrderItem {
+
+        @DisplayName("주문, 상품, 수량이 주어지면 주문 상품이 생성되고 주문에 추가된다.")
+        @Test
+        void createsOrderItem_whenOrderProductAndQuantityAreProvided() {
+            // arrange
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+            Order order = Order.createOrder(1L, delivery);
+            Integer price = 10000;
+            Product product = createProduct(1L, "상품명", price);
+            Integer quantity = 2;
+
+            // act
+            orderService.createOrderItem(order, product, quantity);
+
+            // assert
+            assertThat(order.getOrderItems()).hasSize(1);
+            OrderItem orderItem = order.getOrderItems().get(0);
+            assertAll(
+                    () -> assertThat(orderItem.getProductId()).isEqualTo(product.getId()),
+                    () -> assertThat(orderItem.getProductName()).isEqualTo(product.getName()),
+                    () -> assertThat(orderItem.getPrice()).isEqualTo(price),
+                    () -> assertThat(orderItem.getQuantity()).isEqualTo(quantity)
+            );
+        }
+    }
+
+    @DisplayName("총 가격을 추가할 때,")
+    @Nested
+    class AddTotalPrice {
+
+        @DisplayName("가격과 수량이 주어지면 주문의 총 가격에 추가된다.")
+        @Test
+        void addsTotalPrice_whenPriceAndQuantityAreProvided() {
+            // arrange
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+            Order order = Order.createOrder(1L, delivery);
+            int price = 10000;
+            int quantity = 2;
+
+            // act
+            orderService.addTotalPrice(order, price, quantity);
+
+            // assert
+            assertThat(order.getTotalPrice()).isEqualTo(20000);
+        }
+
+        @DisplayName("여러 번 가격을 추가하면 총액이 누적된다.")
+        @Test
+        void accumulatesTotalPrice_whenPriceIsAddedMultipleTimes() {
+            // arrange
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+            Order order = Order.createOrder(1L, delivery);
+
+            // act
+            orderService.addTotalPrice(order, 10000, 2);
+            orderService.addTotalPrice(order, 5000, 3);
+
+            // assert
+            assertThat(order.getTotalPrice()).isEqualTo(35000);
+        }
+    }
+
+    @DisplayName("사용자 ID로 주문 목록을 조회할 때,")
+    @Nested
+    class FindOrdersByUserId {
+
+        @DisplayName("주문이 존재하면 주문 목록이 반환된다.")
+        @Test
+        void returnsOrders_whenOrdersExist() {
+            // arrange
+            Long userId = 1L;
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+            Order order1 = Order.createOrder(userId, delivery);
+            Order order2 = Order.createOrder(userId, delivery);
+            List<Order> orders = List.of(order1, order2);
+
+            doReturn(orders).when(orderRepository).findOrdersByUserId(userId);
+
+            // act
+            List<Order> result = orderService.findOrdersByUserId(userId);
+
+            // assert
+            assertThat(result).hasSize(2);
+            assertThat(result).containsExactlyInAnyOrder(order1, order2);
+            verify(orderRepository, times(1)).findOrdersByUserId(userId);
+        }
+
+        @DisplayName("주문이 없으면 NOT_FOUND 예외가 발생한다.")
+        @Test
+        void throwsException_whenOrdersDoNotExist() {
+            // arrange
+            Long userId = 1L;
+            doReturn(new ArrayList<>()).when(orderRepository).findOrdersByUserId(userId);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                orderService.findOrdersByUserId(userId);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.NOT_FOUND);
+            assertThat(exception.getMessage()).contains("해당 사용자의 주문 내역이 없습니다.");
+            verify(orderRepository, times(1)).findOrdersByUserId(userId);
+        }
+    }
+
+    @DisplayName("주문 ID와 사용자 ID로 주문을 조회할 때,")
+    @Nested
+    class FindOrderByIdAndUserId {
+
+        @DisplayName("주문이 존재하면 주문이 반환된다.")
+        @Test
+        void returnsOrder_whenOrderExists() {
+            // arrange
+            Long orderId = 1L;
+            Long userId = 1L;
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+            Order order = Order.createOrder(userId, delivery);
+
+            doReturn(Optional.of(order)).when(orderRepository).findByIdAndUserId(orderId, userId);
+
+            // act
+            Optional<Order> result = orderService.findOrderByIdAndUserId(orderId, userId);
+
+            // assert
+            assertThat(result).isPresent();
+            assertThat(result.get()).isEqualTo(order);
+            verify(orderRepository, times(1)).findByIdAndUserId(orderId, userId);
+        }
+
+        @DisplayName("주문이 없으면 빈 Optional이 반환된다.")
+        @Test
+        void returnsEmpty_whenOrderDoesNotExist() {
+            // arrange
+            Long orderId = 1L;
+            Long userId = 1L;
+            doReturn(Optional.empty()).when(orderRepository).findByIdAndUserId(orderId, userId);
+
+            // act
+            Optional<Order> result = orderService.findOrderByIdAndUserId(orderId, userId);
+
+            // assert
+            assertThat(result).isEmpty();
+            verify(orderRepository, times(1)).findByIdAndUserId(orderId, userId);
+        }
+    }
+
+    private Product createProduct(Long id, String name, Integer price) {
+        Product product = mock(Product.class);
+        Price priceValue = mock(Price.class);
+        Stock stock = mock(Stock.class);
+        
+        when(product.getId()).thenReturn(id);
+        when(product.getName()).thenReturn(name);
+        when(product.getPrice()).thenReturn(priceValue);
+        when(priceValue.getPrice()).thenReturn(price);
+        when(product.getStock()).thenReturn(stock);
+        
+        return product;
+    }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderTest.java
new file mode 100644
index 000000000..827edc0c9
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderTest.java
@@ -0,0 +1,161 @@
+package com.loopers.domain.order;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+class OrderTest {
+
+    @DisplayName("주문을 생성할 때,")
+    @Nested
+    class CreateOrder {
+
+        @DisplayName("모든 필드가 올바르게 주어지면 정상적으로 생성된다.")
+        @Test
+        void createsOrder_whenAllFieldsAreValid() {
+            // arrange
+            Long userId = 1L;
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+
+            // act
+            Order order = Order.createOrder(userId, delivery);
+
+            // assert
+            assertAll(
+                    () -> assertThat(order.getUserId()).isEqualTo(userId),
+                    () -> assertThat(order.getDelivery()).isEqualTo(delivery),
+                    () -> assertThat(order.getTotalPrice()).isEqualTo(0),
+                    () -> assertThat(order.getOrderStatus()).isEqualTo(OrderStatus.CREATED),
+                    () -> assertThat(order.getOrderItems()).isEmpty()
+            );
+        }
+
+        @DisplayName("사용자 ID가 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenUserIdIsNull() {
+            // arrange
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Order.createOrder(null, delivery);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("사용자 ID는 필수입니다.");
+        }
+
+        @DisplayName("배송 정보가 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenDeliveryIsNull() {
+            // arrange
+            Long userId = 1L;
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Order.createOrder(userId, null);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("배송 정보는 필수입니다.");
+        }
+    }
+
+    @DisplayName("주문 상품을 추가할 때,")
+    @Nested
+    class AddOrderItem {
+
+        @DisplayName("주문 상품이 올바르게 주어지면 정상적으로 추가된다.")
+        @Test
+        void addsOrderItem_whenOrderItemIsValid() {
+            // arrange
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+            Order order = Order.createOrder(1L, delivery);
+            OrderItem orderItem = OrderItem.createOrderItem(1L, "상품명", 10000, 2);
+
+            // act
+            order.addOrderItem(orderItem);
+
+            // assert
+            assertThat(order.getOrderItems()).hasSize(1);
+            assertThat(order.getOrderItems().get(0)).isEqualTo(orderItem);
+        }
+
+        @DisplayName("주문 상품이 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenOrderItemIsNull() {
+            // arrange
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+            Order order = Order.createOrder(1L, delivery);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                order.addOrderItem(null);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("주문 상품은 필수입니다.");
+        }
+    }
+
+    @DisplayName("가격을 추가할 때,")
+    @Nested
+    class AddPrice {
+
+        @DisplayName("가격이 올바르게 주어지면 정상적으로 추가된다.")
+        @Test
+        void addsPrice_whenPriceIsValid() {
+            // arrange
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+            Order order = Order.createOrder(1L, delivery);
+            int price = 10000;
+
+            // act
+            order.addPrice(price);
+
+            // assert
+            assertThat(order.getTotalPrice()).isEqualTo(10000);
+        }
+
+        @DisplayName("가격을 여러 번 추가하면 총액이 누적된다.")
+        @Test
+        void accumulatesPrice_whenPriceIsAddedMultipleTimes() {
+            // arrange
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+            Order order = Order.createOrder(1L, delivery);
+
+            // act
+            order.addPrice(10000);
+            order.addPrice(5000);
+            order.addPrice(3000);
+
+            // assert
+            assertThat(order.getTotalPrice()).isEqualTo(18000);
+        }
+
+        @DisplayName("가격이 0 이하면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @ValueSource(ints = {0, -1, -100})
+        void throwsException_whenPriceIsZeroOrNegative(int invalidPrice) {
+            // arrange
+            Delivery delivery = Delivery.createDelivery("홍길동", "010-1234-5678", "서울시 강남구", "테헤란로 123");
+            Order order = Order.createOrder(1L, delivery);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                order.addPrice(invalidPrice);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("가격은 0보다 커야 합니다.");
+        }
+    }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/product/LikeCountTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/product/LikeCountTest.java
new file mode 100644
index 000000000..a2d2be3dc
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/product/LikeCountTest.java
@@ -0,0 +1,72 @@
+package com.loopers.domain.product;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+class LikeCountTest {
+
+    @DisplayName("좋아요 수를 생성할 때,")
+    @Nested
+    class CreateLikeCount {
+
+        @DisplayName("좋아요 수가 올바르게 주어지면 정상적으로 생성된다.")
+        @Test
+        void createsLikeCount_whenCountIsValid() {
+            // arrange
+            Integer count = 100;
+
+            // act
+            LikeCount likeCount = LikeCount.createLikeCount(count);
+
+            // assert
+            assertThat(likeCount.getCount()).isEqualTo(count);
+        }
+
+        @DisplayName("좋아요 수가 0이면 정상적으로 생성된다.")
+        @Test
+        void createsLikeCount_whenCountIsZero() {
+            // arrange
+            Integer count = 0;
+
+            // act
+            LikeCount likeCount = LikeCount.createLikeCount(count);
+
+            // assert
+            assertThat(likeCount.getCount()).isEqualTo(0);
+        }
+
+        @DisplayName("좋아요 수가 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenCountIsNull() {
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                LikeCount.createLikeCount(null);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("좋아요 수는 필수입니다.");
+        }
+
+        @DisplayName("좋아요 수가 음수이면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @ValueSource(ints = {-1, -100})
+        void throwsException_whenCountIsNegative(int invalidCount) {
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                LikeCount.createLikeCount(invalidCount);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("좋아요 수는 0 이상이어야 합니다.");
+        }
+    }
+}
+
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/product/PriceTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/product/PriceTest.java
new file mode 100644
index 000000000..081bf3c85
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/product/PriceTest.java
@@ -0,0 +1,59 @@
+package com.loopers.domain.product;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+class PriceTest {
+
+    @DisplayName("가격을 생성할 때,")
+    @Nested
+    class CreatePrice {
+
+        @DisplayName("가격이 올바르게 주어지면 정상적으로 생성된다.")
+        @Test
+        void createsPrice_whenPriceIsValid() {
+            // arrange
+            Integer price = 10000;
+
+            // act
+            Price priceValue = Price.createPrice(price);
+
+            // assert
+            assertThat(priceValue.getPrice()).isEqualTo(price);
+        }
+
+        @DisplayName("가격이 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenPriceIsNull() {
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Price.createPrice(null);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("가격은 필수입니다.");
+        }
+
+        @DisplayName("가격이 0 이하면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @ValueSource(ints = {0, -1, -100})
+        void throwsException_whenPriceIsZeroOrNegative(int invalidPrice) {
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Price.createPrice(invalidPrice);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("가격은 0보다 커야 합니다.");
+        }
+    }
+}
+
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductTest.java
new file mode 100644
index 000000000..4cc003941
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductTest.java
@@ -0,0 +1,139 @@
+package com.loopers.domain.product;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
+import org.junit.jupiter.params.provider.ValueSource;
+
+class ProductTest {
+
+    @DisplayName("상품을 생성할 때,")
+    @Nested
+    class CreateProduct {
+
+        @DisplayName("모든 필드가 올바르게 주어지면 정상적으로 생성된다.")
+        @Test
+        void createsProduct_whenAllFieldsAreValid() {
+            // arrange
+            String name = "상품명";
+            Long brandId = 1L;
+            Price price = Price.createPrice(10000);
+            LikeCount likeCount = LikeCount.createLikeCount(10);
+            Stock stock = Stock.createStock(100);
+
+            // act
+            Product product = Product.createProduct(name, brandId, price, likeCount, stock);
+
+            // assert
+            assertAll(
+                    () -> assertThat(product.getName()).isEqualTo(name),
+                    () -> assertThat(product.getBrandId()).isEqualTo(brandId),
+                    () -> assertThat(product.getPrice()).isEqualTo(price),
+                    () -> assertThat(product.getLikeCount()).isEqualTo(likeCount),
+                    () -> assertThat(product.getStock()).isEqualTo(stock),
+                    () -> assertThat(product.isDeleted()).isFalse()
+            );
+        }
+
+        @DisplayName("상품명이 비어있으면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @NullAndEmptySource
+        @ValueSource(strings = {" ", "   "})
+        void throwsException_whenNameIsBlank(String invalidName) {
+            // arrange
+            Long brandId = 1L;
+            Price price = Price.createPrice(10000);
+            LikeCount likeCount = LikeCount.createLikeCount(10);
+            Stock stock = Stock.createStock(100);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Product.createProduct(invalidName, brandId, price, likeCount, stock);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("상품명은 필수입니다.");
+        }
+
+        @DisplayName("브랜드 ID가 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenBrandIdIsNull() {
+            // arrange
+            String name = "상품명";
+            Price price = Price.createPrice(10000);
+            LikeCount likeCount = LikeCount.createLikeCount(10);
+            Stock stock = Stock.createStock(100);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Product.createProduct(name, null, price, likeCount, stock);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("브랜드 ID는 필수입니다.");
+        }
+
+        @DisplayName("가격이 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenPriceIsNull() {
+            // arrange
+            String name = "상품명";
+            Long brandId = 1L;
+            LikeCount likeCount = LikeCount.createLikeCount(10);
+            Stock stock = Stock.createStock(100);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Product.createProduct(name, brandId, null, likeCount, stock);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("가격은 필수입니다.");
+        }
+
+        @DisplayName("좋아요 수가 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenLikeCountIsNull() {
+            // arrange
+            String name = "상품명";
+            Long brandId = 1L;
+            Price price = Price.createPrice(10000);
+            Stock stock = Stock.createStock(100);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Product.createProduct(name, brandId, price, null, stock);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("좋아요 수는 필수입니다.");
+        }
+
+        @DisplayName("재고가 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenStockIsNull() {
+            // arrange
+            String name = "상품명";
+            Long brandId = 1L;
+            Price price = Price.createPrice(10000);
+            LikeCount likeCount = LikeCount.createLikeCount(10);
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Product.createProduct(name, brandId, price, likeCount, null);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("재고는 필수입니다.");
+        }
+    }
+}
+
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/product/StockTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/product/StockTest.java
new file mode 100644
index 000000000..4430c43f1
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/product/StockTest.java
@@ -0,0 +1,121 @@
+package com.loopers.domain.product;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+class StockTest {
+
+    @DisplayName("재고를 생성할 때,")
+    @Nested
+    class CreateStock {
+
+        @DisplayName("재고 수량이 올바르게 주어지면 정상적으로 생성된다.")
+        @Test
+        void createsStock_whenQuantityIsValid() {
+            // arrange
+            Integer quantity = 100;
+
+            // act
+            Stock stock = Stock.createStock(quantity);
+
+            // assert
+            assertThat(stock.getQuantity()).isEqualTo(quantity);
+        }
+
+        @DisplayName("재고 수량이 0이면 정상적으로 생성된다.")
+        @Test
+        void createsStock_whenQuantityIsZero() {
+            // arrange
+            Integer quantity = 0;
+
+            // act
+            Stock stock = Stock.createStock(quantity);
+
+            // assert
+            assertThat(stock.getQuantity()).isEqualTo(0);
+        }
+
+        @DisplayName("재고 수량이 null이면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenQuantityIsNull() {
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Stock.createStock(null);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("재고 수량은 필수입니다.");
+        }
+
+        @DisplayName("재고 수량이 음수이면 BAD_REQUEST가 발생한다.")
+        @ParameterizedTest
+        @ValueSource(ints = {-1, -100})
+        void throwsException_whenQuantityIsNegative(int invalidQuantity) {
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                Stock.createStock(invalidQuantity);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("재고 수량은 0 이상이어야 합니다.");
+        }
+    }
+
+    @DisplayName("재고를 차감할 때,")
+    @Nested
+    class ReduceQuantity {
+
+        @DisplayName("재고가 충분하면 정상적으로 차감된다.")
+        @Test
+        void reducesQuantity_whenStockIsSufficient() {
+            // arrange
+            Stock stock = Stock.createStock(100);
+            Integer quantity = 30;
+
+            // act
+            stock.reduceQuantity(quantity);
+
+            // assert
+            assertThat(stock.getQuantity()).isEqualTo(70);
+        }
+
+        @DisplayName("재고를 여러 번 차감하면 수량이 누적 차감된다.")
+        @Test
+        void accumulatesReduction_whenReducedMultipleTimes() {
+            // arrange
+            Stock stock = Stock.createStock(100);
+
+            // act
+            stock.reduceQuantity(20);
+            stock.reduceQuantity(30);
+
+            // assert
+            assertThat(stock.getQuantity()).isEqualTo(50);
+        }
+
+        @DisplayName("재고가 부족하면 BAD_REQUEST가 발생한다.")
+        @Test
+        void throwsException_whenStockIsInsufficient() {
+            // arrange
+            Stock stock = Stock.createStock(100);
+            Integer quantity = 150;
+
+            // act & assert
+            CoreException exception = assertThrows(CoreException.class, () -> {
+                stock.reduceQuantity(quantity);
+            });
+
+            assertThat(exception.getErrorType()).isEqualTo(ErrorType.BAD_REQUEST);
+            assertThat(exception.getMessage()).contains("재고가 부족합니다.");
+        }
+    }
+}
+
diff --git a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/ExampleV1ApiE2ETest.java b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/ExampleV1ApiE2ETest.java
deleted file mode 100644
index 1bb3dba65..000000000
--- a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/ExampleV1ApiE2ETest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.loopers.interfaces.api;
-
-import com.loopers.domain.example.ExampleModel;
-import com.loopers.infrastructure.example.ExampleJpaRepository;
-import com.loopers.interfaces.api.example.ExampleV1Dto;
-import com.loopers.utils.DatabaseCleanUp;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.web.client.TestRestTemplate;
-import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-
-import java.util.function.Function;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertAll;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
-class ExampleV1ApiE2ETest {
-
-    private static final Function<Long, String> ENDPOINT_GET = id -> "/api/v1/examples/" + id;
-
-    private final TestRestTemplate testRestTemplate;
-    private final ExampleJpaRepository exampleJpaRepository;
-    private final DatabaseCleanUp databaseCleanUp;
-
-    @Autowired
-    public ExampleV1ApiE2ETest(
-        TestRestTemplate testRestTemplate,
-        ExampleJpaRepository exampleJpaRepository,
-        DatabaseCleanUp databaseCleanUp
-    ) {
-        this.testRestTemplate = testRestTemplate;
-        this.exampleJpaRepository = exampleJpaRepository;
-        this.databaseCleanUp = databaseCleanUp;
-    }
-
-    @AfterEach
-    void tearDown() {
-        databaseCleanUp.truncateAllTables();
-    }
-
-    @DisplayName("GET /api/v1/examples/{id}")
-    @Nested
-    class Get {
-        @DisplayName("존재하는 예시 ID를 주면, 해당 예시 정보를 반환한다.")
-        @Test
-        void returnsExampleInfo_whenValidIdIsProvided() {
-            // arrange
-            ExampleModel exampleModel = exampleJpaRepository.save(
-                new ExampleModel("예시 제목", "예시 설명")
-            );
-            String requestUrl = ENDPOINT_GET.apply(exampleModel.getId());
-
-            // act
-            ParameterizedTypeReference<ApiResponse<ExampleV1Dto.ExampleResponse>> responseType = new ParameterizedTypeReference<>() {};
-            ResponseEntity<ApiResponse<ExampleV1Dto.ExampleResponse>> response =
-                testRestTemplate.exchange(requestUrl, HttpMethod.GET, new HttpEntity<>(null), responseType);
-
-            // assert
-            assertAll(
-                () -> assertTrue(response.getStatusCode().is2xxSuccessful()),
-                () -> assertThat(response.getBody().data().id()).isEqualTo(exampleModel.getId()),
-                () -> assertThat(response.getBody().data().name()).isEqualTo(exampleModel.getName()),
-                () -> assertThat(response.getBody().data().description()).isEqualTo(exampleModel.getDescription())
-            );
-        }
-
-        @DisplayName("숫자가 아닌 ID 로 요청하면, 400 BAD_REQUEST 응답을 받는다.")
-        @Test
-        void throwsBadRequest_whenIdIsNotProvided() {
-            // arrange
-            String requestUrl = "/api/v1/examples/나나";
-
-            // act
-            ParameterizedTypeReference<ApiResponse<ExampleV1Dto.ExampleResponse>> responseType = new ParameterizedTypeReference<>() {};
-            ResponseEntity<ApiResponse<ExampleV1Dto.ExampleResponse>> response =
-                testRestTemplate.exchange(requestUrl, HttpMethod.GET, new HttpEntity<>(null), responseType);
-
-            // assert
-            assertAll(
-                () -> assertTrue(response.getStatusCode().is4xxClientError()),
-                () -> assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST)
-            );
-        }
-
-        @DisplayName("존재하지 않는 예시 ID를 주면, 404 NOT_FOUND 응답을 받는다.")
-        @Test
-        void throwsException_whenInvalidIdIsProvided() {
-            // arrange
-            Long invalidId = -1L;
-            String requestUrl = ENDPOINT_GET.apply(invalidId);
-
-            // act
-            ParameterizedTypeReference<ApiResponse<ExampleV1Dto.ExampleResponse>> responseType = new ParameterizedTypeReference<>() {};
-            ResponseEntity<ApiResponse<ExampleV1Dto.ExampleResponse>> response =
-                testRestTemplate.exchange(requestUrl, HttpMethod.GET, new HttpEntity<>(null), responseType);
-
-            // assert
-            assertAll(
-                () -> assertTrue(response.getStatusCode().is4xxClientError()),
-                () -> assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND)
-            );
-        }
-    }
-}
