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..c0e4d5da9
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/brand/BrandFacade.java
@@ -0,0 +1,18 @@
+package com.loopers.application.brand;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+@RequiredArgsConstructor
+@Component
+public class BrandFacade {
+  private final BrandService brandService;
+
+  public BrandInfo getBrandDetail(long id) {
+    Brand brand = brandService.getBrand(id);
+    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..5a2ae251c
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/brand/BrandInfo.java
@@ -0,0 +1,16 @@
+package com.loopers.application.brand;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+
+public record BrandInfo(Long id, String name, String story) {
+  public static BrandInfo from(Brand model) {
+    if (model == null) throw new CoreException(ErrorType.NOT_FOUND, "유저정보를 찾을수 없습니다.");
+    return new BrandInfo(
+        model.getId(),
+        model.getName(),
+        model.getStory()
+    );
+  }
+}
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..1685623a2
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/like/LikeInfo.java
@@ -0,0 +1,10 @@
+package com.loopers.application.like;
+
+public record LikeInfo(long likeCount, boolean isLiked) {
+  public static LikeInfo from(long likeCount, boolean isLiked) {
+    return new LikeInfo(
+        likeCount,
+        isLiked
+    );
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/order/CreateOrderCommand.java b/apps/commerce-api/src/main/java/com/loopers/application/order/CreateOrderCommand.java
new file mode 100644
index 000000000..61aa9f7e3
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/order/CreateOrderCommand.java
@@ -0,0 +1,22 @@
+package com.loopers.application.order;
+
+import com.loopers.interfaces.api.order.OrderCreateV1Dto;
+
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public record CreateOrderCommand(Long userId, Map<Long, Long> orderItemInfo) {
+  public record ItemCommand(Long productId, Map<Long, Long> quantity) {
+  }
+
+  public static CreateOrderCommand from(Long userId, OrderCreateV1Dto.OrderRequest request) {
+    return new CreateOrderCommand(
+        userId,
+        request.items().stream()
+            .collect(Collectors.toMap(
+                OrderCreateV1Dto.OrderItemRequest::productId,
+                OrderCreateV1Dto.OrderItemRequest::quantity,
+                Long::sum
+            )));
+  }
+}
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..b6e1cd950
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/order/OrderFacade.java
@@ -0,0 +1,60 @@
+package com.loopers.application.order;
+
+import com.loopers.domain.order.CreateOrderService;
+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.product.ProductStockService;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserPointService;
+import com.loopers.domain.user.UserService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+
+@RequiredArgsConstructor
+@Component
+public class OrderFacade {
+  private final UserService userService;
+  private final PointService pointService;
+  private final ProductService productService;
+  private final OrderService orderService;
+  private final CreateOrderService createOrderService;
+
+  private final ProductStockService productStockService;
+  private final UserPointService userPointService;
+
+  @Transactional(readOnly = true)
+  public Page<Order> getOrderList(Long userId,
+                                  String sortType,
+                                  int page,
+                                  int size) {
+    return orderService.getOrders(userId, sortType, page, size);
+  }
+  
+  @Transactional(readOnly = true)
+  public OrderInfo getOrderDetail(Long orderId) {
+    Order order = orderService.getOrder(orderId);
+    return OrderInfo.from(order);
+  }
+
+  @Transactional
+  public OrderInfo createOrder(CreateOrderCommand command) {
+
+    Map<Long, Long> quantityMap = command.orderItemInfo();
+    User user = userService.getActiveUser(command.userId());
+    List<Product> productList = productService.getExistingProducts(quantityMap.keySet());
+
+    productStockService.deduct(productList, quantityMap);
+    userPointService.use(user, productList, quantityMap);
+
+    Order savedOrder = createOrderService.save(user, productList, quantityMap);
+    return OrderInfo.from(savedOrder);
+  }
+}
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..95d20d92b
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/order/OrderInfo.java
@@ -0,0 +1,23 @@
+package com.loopers.application.order;
+
+import com.loopers.domain.order.Order;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+
+import java.math.BigDecimal;
+import java.time.ZonedDateTime;
+import java.util.List;
+
+public record OrderInfo(long id, String status, BigDecimal totalPrice
+    , ZonedDateTime orderAt, List<OrderItemInfo> orderItemInfo) {
+  public static OrderInfo from(Order model) {
+    if (model == null) throw new CoreException(ErrorType.NOT_FOUND, "주문정보를 찾을수 없습니다.");
+    return new OrderInfo(
+        model.getId(),
+        model.getStatus().name(),
+        model.getTotalPrice(),
+        model.getOrderAt(),
+        OrderItemInfo.from(model.getOrderItems())
+    );
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/order/OrderItemInfo.java b/apps/commerce-api/src/main/java/com/loopers/application/order/OrderItemInfo.java
new file mode 100644
index 000000000..92a66aa2f
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/order/OrderItemInfo.java
@@ -0,0 +1,24 @@
+package com.loopers.application.order;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.loopers.domain.order.OrderItem;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+public record OrderItemInfo(Long id, long quantity
+    , @JsonSerialize(using = ToStringSerializer.class) BigDecimal unitPrice,
+                            @JsonSerialize(using = ToStringSerializer.class) BigDecimal totalPrice) {
+  public static List<OrderItemInfo> from(List<OrderItem> model) {
+    if (model == null) throw new CoreException(ErrorType.NOT_FOUND, "주문상세정보를 찾을수 없습니다.");
+    return model.stream().map(item -> new OrderItemInfo(
+        item.getId(),
+        item.getQuantity(),
+        item.getUnitPrice(),
+        item.getTotalPrice()
+    )).toList();
+  }
+}
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 92b3efd79..8a85275ff 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
@@ -1,10 +1,8 @@
 package com.loopers.application.point;
 
 import com.loopers.domain.point.PointService;
-import com.loopers.domain.user.UserModel;
+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 lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Component;
 
@@ -16,14 +14,13 @@ public class PointFacade {
   private final UserService userService;
   private final PointService pointService;
 
-  public BigDecimal getPoint(String userId) {
-    UserModel user = userService.getUser(userId);
-    return pointService.getAmount(user.getUserId());
+  public BigDecimal getPoint(Long userId) {
+    User user = userService.getActiveUser(userId);
+    return user.getPoint().getAmount();
   }
 
-  public BigDecimal charge(String userId, BigDecimal chargeAmt) {
-    UserModel user = userService.getUser(userId);
-    if (user == null) throw new CoreException(ErrorType.NOT_FOUND, "유저정보를 찾을수 없습니다.");
+  public BigDecimal charge(Long userId, BigDecimal chargeAmt) {
+    User user = userService.getActiveUser(userId);
     return pointService.charge(user, chargeAmt);
   }
 
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/point/PointInfo.java b/apps/commerce-api/src/main/java/com/loopers/application/point/PointInfo.java
index ff51218d9..ca76d1644 100644
--- a/apps/commerce-api/src/main/java/com/loopers/application/point/PointInfo.java
+++ b/apps/commerce-api/src/main/java/com/loopers/application/point/PointInfo.java
@@ -1,11 +1,11 @@
 package com.loopers.application.point;
 
-import com.loopers.domain.point.PointModel;
+import com.loopers.domain.point.Point;
 
 import java.math.BigDecimal;
 
 public record PointInfo(String userId, BigDecimal amount) {
-  public static PointInfo from(PointModel model) {
+  public static PointInfo from(Point model) {
     if (model == null) return null;
     return new PointInfo(
         model.getUser().getUserId(),
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/product/ProductDetailInfo.java b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductDetailInfo.java
new file mode 100644
index 000000000..fadaa5cc8
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductDetailInfo.java
@@ -0,0 +1,24 @@
+package com.loopers.application.product;
+
+import com.loopers.application.brand.BrandInfo;
+import com.loopers.application.like.LikeInfo;
+import com.loopers.domain.product.Product;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+
+import java.math.BigDecimal;
+
+public record ProductDetailInfo(Long id, String name, BigDecimal price, long stock
+    , BrandInfo brandInfo, LikeInfo likeInfo) {
+  public static ProductDetailInfo from(Product model, boolean isLiked) {
+    if (model == null) throw new CoreException(ErrorType.NOT_FOUND, "상품정보를 찾을수 없습니다.");
+    return new ProductDetailInfo(
+        model.getId(),
+        model.getName(),
+        model.getPrice(),
+        model.getStock(),
+        BrandInfo.from(model.getBrand()),
+        LikeInfo.from(model.getLikeCount(), isLiked)
+    );
+  }
+}
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..2a9a97eff
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductFacade.java
@@ -0,0 +1,32 @@
+package com.loopers.application.product;
+
+import com.loopers.domain.like.LikeService;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@RequiredArgsConstructor
+@Component
+public class ProductFacade {
+  private final ProductService productService;
+  private final LikeService likeService;
+
+  @Transactional(readOnly = true)
+  public Page<Product> getProductList(Long brandId,
+                                      String sortType,
+                                      int page,
+                                      int size) {
+    return productService.getProducts(brandId, sortType, page, size);
+  }
+
+  @Transactional(readOnly = true)
+  public ProductDetailInfo getProductDetail(long userId, long productId) {
+    Product product = productService.getProduct(productId);
+    boolean isLiked = likeService.isLiked(userId, productId);
+    return ProductDetailInfo.from(product, isLiked);
+  }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/user/UserFacade.java b/apps/commerce-api/src/main/java/com/loopers/application/user/UserFacade.java
index f4e3e79c3..9e7703061 100644
--- a/apps/commerce-api/src/main/java/com/loopers/application/user/UserFacade.java
+++ b/apps/commerce-api/src/main/java/com/loopers/application/user/UserFacade.java
@@ -1,6 +1,6 @@
 package com.loopers.application.user;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
 import com.loopers.domain.user.UserService;
 import com.loopers.interfaces.api.user.UserCreateV1Dto;
 import lombok.RequiredArgsConstructor;
@@ -12,12 +12,12 @@ public class UserFacade {
   private final UserService userService;
 
   public UserInfo join(UserCreateV1Dto.UserRequest requestDto) {
-    UserModel user = userService.join(UserModel.create(requestDto.userId(), requestDto.email(), requestDto.birthday(), requestDto.gender()));
+    User user = userService.join(User.create(requestDto.userId(), requestDto.email(), requestDto.birthday(), requestDto.gender()));
     return UserInfo.from(user);
   }
 
   public UserInfo getUser(String userId) {
-    UserModel user = userService.getUser(userId);
+    User user = userService.getUser(userId);
     return UserInfo.from(user);
   }
 
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/user/UserInfo.java b/apps/commerce-api/src/main/java/com/loopers/application/user/UserInfo.java
index df777bb86..16b11be7d 100644
--- a/apps/commerce-api/src/main/java/com/loopers/application/user/UserInfo.java
+++ b/apps/commerce-api/src/main/java/com/loopers/application/user/UserInfo.java
@@ -1,11 +1,11 @@
 package com.loopers.application.user;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
 import com.loopers.support.error.CoreException;
 import com.loopers.support.error.ErrorType;
 
 public record UserInfo(String userId, String email, String birthday, String gender) {
-  public static UserInfo from(UserModel model) {
+  public static UserInfo from(User model) {
     if (model == null) throw new CoreException(ErrorType.NOT_FOUND, "유저정보를 찾을수 없습니다.");
     return new UserInfo(
         model.getUserId(),
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..39067ec5a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/brand/Brand.java
@@ -0,0 +1,32 @@
+package com.loopers.domain.brand;
+
+import com.loopers.domain.BaseEntity;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import lombok.Getter;
+
+@Entity
+@Table(name = "brand")
+@Getter
+public class Brand extends BaseEntity {
+  private String name;
+  private String story;
+
+  protected Brand() {
+    this.name = "";
+    this.story = "";
+  }
+
+  private Brand(String name, String story) {
+    this.name = name;
+    this.story = story;
+  }
+
+  public static Brand create(String name, String story) {
+    if (name.isBlank()) {
+      throw new IllegalArgumentException("브랜드명은 비어있을 수 없습니다.");
+    }
+    return new Brand(name, story);
+  }
+
+}
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..ceb5791f4
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/brand/BrandRepository.java
@@ -0,0 +1,10 @@
+package com.loopers.domain.brand;
+
+import java.util.Optional;
+
+public interface BrandRepository {
+  Optional<Brand> findById(Long id);
+
+  Brand save(Brand brand);
+
+}
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..0e05dead6
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/brand/BrandService.java
@@ -0,0 +1,27 @@
+package com.loopers.domain.brand;
+
+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 BrandService {
+
+  private final BrandRepository brandRepository;
+
+  @Transactional(readOnly = true)
+  public Brand getBrand(Long id) {
+    if (id == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "ID가 없습니다.");
+    }
+    return brandRepository.findById(id).orElse(null);
+  }
+
+  public Brand save(Brand brand) {
+    return brandRepository.save(brand);
+  }
+
+}
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..7015ee53d
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/like/Like.java
@@ -0,0 +1,43 @@
+package com.loopers.domain.like;
+
+import com.loopers.domain.BaseEntity;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.user.User;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.persistence.*;
+import lombok.Getter;
+
+@Entity
+@Table(name = "likes", uniqueConstraints = {
+    @UniqueConstraint(columnNames = {"ref_user_id", "ref_product_id"})
+})
+@Getter
+public class Like extends BaseEntity {
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "ref_user_Id", nullable = false)
+  private User user;
+
+  @ManyToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "ref_product_Id", nullable = false)
+  private Product product;
+
+  protected Like() {
+  }
+
+  private Like(User user, Product product) {
+    this.user = user;
+    this.product = product;
+  }
+
+  public static Like create(User user, Product product) {
+    if (user == null || user.getId() == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "사용자ID는 비어있을 수 없습니다.");
+    }
+    if (product == null || product.getId() == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "상품ID는 비어있을 수 없습니다.");
+    }
+    return new Like(user, product);
+  }
+
+}
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..b0a87fb3a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/like/LikeRepository.java
@@ -0,0 +1,21 @@
+package com.loopers.domain.like;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+import java.util.Optional;
+
+public interface LikeRepository {
+
+  Optional<Like> findById(Long userId, Long productid);
+
+  Like save(Like like);
+
+  long remove(Long userId, Long productId);
+
+  boolean isLiked(Long userId, Long productId);
+
+  long getLikeCount(Long productId);
+
+  Page<Like> getLikedProducts(Long userId, Pageable pageable);
+}
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..01610a251
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/like/LikeService.java
@@ -0,0 +1,74 @@
+
+package com.loopers.domain.like;
+
+import com.loopers.domain.product.Product;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.*;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Optional;
+
+@RequiredArgsConstructor
+@Component
+public class LikeService {
+
+  private final LikeRepository likeRepository;
+
+  @Transactional
+  public Like save(Like like) {
+    Long userId = like.getUser().getId();
+    Long productId = like.getProduct().getId();
+    Optional<Like> existingLike = likeRepository.findById(userId, productId);
+
+    if (existingLike.isPresent()) {
+      return existingLike.get();
+    }
+    return likeRepository.save(like);
+  }
+
+
+  @Transactional
+  public long remove(Long userId, Long productId) {
+    return likeRepository.remove(userId, productId);
+  }
+
+  @Transactional
+  public boolean isLiked(Long userId, Long productId) {
+    return likeRepository.isLiked(userId, productId);
+  }
+
+  public Page<Product> getLikedProducts(
+      Long userId,
+      String sortType,
+      int page,
+      int size
+  ) {
+    if (userId == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "ID가 없습니다.");
+    }
+    Sort sort = this.getSortBySortType(sortType);
+    Pageable pageable = PageRequest.of(page, size, sort);
+    Page<Like> likePage = likeRepository.getLikedProducts(userId, pageable);
+    List<Product> likedProducts = likePage.getContent().stream().map(Like::getProduct).toList();
+    return new PageImpl<>(likedProducts, pageable, likePage.getTotalElements());
+  }
+
+  private Sort getSortBySortType(String sortType) {
+    if (sortType == null) sortType = "latest";
+    Sort latestSort = Sort.by("createdAt").descending();
+    switch (sortType.toLowerCase()) {
+      case "latest":
+        return latestSort;
+      case "price_asc":
+        return Sort.by("price").ascending().and(latestSort);
+      case "likes_desc":
+        return Sort.by("likesCount").descending().and(latestSort);
+      default:
+        return latestSort;
+    }
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/order/CreateOrderService.java b/apps/commerce-api/src/main/java/com/loopers/domain/order/CreateOrderService.java
new file mode 100644
index 000000000..4780d71b3
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/CreateOrderService.java
@@ -0,0 +1,41 @@
+
+package com.loopers.domain.order;
+
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductRepository;
+import com.loopers.domain.user.User;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@RequiredArgsConstructor
+@Component
+public class CreateOrderService {
+  private final ProductRepository productRepository;
+  private final OrderRepository orderRepository;
+
+  public Order save(User user, List<Product> productList, Map<Long, Long> quantityMap) {
+
+    List<OrderItem> orderItems = new ArrayList<>();
+
+    BigDecimal totalPrice = productList.stream().map(product -> {
+      long quantity = quantityMap.get(product.getId());
+      BigDecimal unitPrice = product.getPrice();
+      BigDecimal itemTotalPrice = unitPrice.multiply(new BigDecimal(quantity));
+
+      OrderItem orderItem = OrderItem.create(product.getId(), quantity, unitPrice);
+      orderItems.add(orderItem);
+
+      return itemTotalPrice;
+    }).reduce(BigDecimal.ZERO, BigDecimal::add);
+
+    Order order = Order.create(user.getId(), OrderStatus.PAID, totalPrice, orderItems);
+    return orderRepository.save(order);
+  }
+
+}
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..157f231b7
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/Order.java
@@ -0,0 +1,78 @@
+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.*;
+import lombok.Getter;
+
+import java.math.BigDecimal;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+@Entity
+@Table(name = "orders")
+@Getter
+public class Order extends BaseEntity {
+
+  private Long refUserId;
+
+  private OrderStatus status;
+
+  BigDecimal totalPrice;
+
+  ZonedDateTime orderAt;
+
+  @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
+  @JoinColumn(name = "ref_order_id")
+  private List<OrderItem> orderItems = new ArrayList<>();
+
+  public void setOrderItems(List<OrderItem> orderItems) {
+    if (orderItems == null || orderItems.isEmpty()) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "주문 상세내역이 없습니다.");
+    }
+    this.orderItems = orderItems;
+  }
+
+  protected Order() {
+  }
+
+  private Order(long refUserId, OrderStatus status, BigDecimal totalPrice, List<OrderItem> orderItems) {
+    this.refUserId = refUserId;
+    this.status = status;
+    this.totalPrice = totalPrice;
+    this.orderAt = ZonedDateTime.now();
+    this.orderItems = orderItems;
+  }
+
+  public static Order create(long refUserId, OrderStatus status, BigDecimal totalPrice, List<OrderItem> orderItems) {
+    if (status == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "상태 정보는 비어있을 수 없습니다.");
+    }
+    if (totalPrice.compareTo(BigDecimal.ZERO) < 0) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "총가격은 음수일수 없습니다.");
+    }
+    return new Order(refUserId, status, totalPrice, orderItems);
+  }
+
+  public void cancel() {
+    if (status == OrderStatus.CANCELLED) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "이미 취소된 주문입니다.");
+    }
+    this.status = OrderStatus.CANCELLED;
+  }
+
+  public void preparing() {
+    if (status == OrderStatus.PENDING) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "결재대기중 주문입니다.");
+    }
+    if (status == OrderStatus.PREPARING) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "이미 준비중인 주문입니다.");
+    }
+    if (status.compare(OrderStatus.PREPARING) > 0) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "상품준비 완료된 주문입니다.");
+    }
+    this.status = OrderStatus.PREPARING;
+  }
+}
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..17c324510
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderItem.java
@@ -0,0 +1,42 @@
+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.Getter;
+
+import java.math.BigDecimal;
+
+@Entity
+@Table(name = "order_item")
+@Getter
+public class OrderItem extends BaseEntity {
+
+  private long refProductId;
+
+  private long quantity;
+
+  private BigDecimal unitPrice;
+
+  private BigDecimal totalPrice;
+
+  protected OrderItem() {
+  }
+
+  private OrderItem(long refProductId, long quantity, BigDecimal unitPrice, BigDecimal totalPrice) {
+    this.refProductId = refProductId;
+    this.quantity = quantity;
+    this.unitPrice = unitPrice;
+    this.totalPrice = totalPrice;
+  }
+
+  public static OrderItem create(long refProductId, long quantity, BigDecimal unitPrice) {
+    if (unitPrice.compareTo(BigDecimal.ZERO) < 0) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "가격은 음수일수 없습니다.");
+    }
+    BigDecimal totalPrice = unitPrice.multiply(new BigDecimal(quantity));
+    return new OrderItem(refProductId, quantity, unitPrice, totalPrice);
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderPreparer.java b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderPreparer.java
new file mode 100644
index 000000000..6a4a29d5a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderPreparer.java
@@ -0,0 +1,35 @@
+
+package com.loopers.domain.order;
+
+import com.loopers.domain.point.Point;
+import com.loopers.domain.product.Product;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+@RequiredArgsConstructor
+@Component
+public class OrderPreparer {
+  public static List<Product> verifyProductStockDeductable(List<Product> products, Map<Long, Long> quantityMap) {
+    products.forEach(i -> i.deductStock(quantityMap.get(i.getId())));
+    return products;
+  }
+  public static List<Product> verifyProductStockAddable(List<Product> products, Map<Long, Long> quantityMap) {
+    products.forEach(i -> i.addStock(quantityMap.get(i.getId())));
+    return products;
+  }
+
+  public static BigDecimal getTotalAmt(Point point, List<Product> products, Map<Long, Long> quantityMap) {
+    return products.stream()
+        .map(product -> {
+          Long productId = product.getId();
+          Long quantity = quantityMap.getOrDefault(productId, 0L);
+          return product.getPrice().multiply(BigDecimal.valueOf(quantity));
+        })
+        .reduce(BigDecimal.ZERO, BigDecimal::add);
+  }
+
+}
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..4ba06bc61
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderRepository.java
@@ -0,0 +1,15 @@
+package com.loopers.domain.order;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+import java.util.Optional;
+
+public interface OrderRepository {
+  Optional<Order> findById(Long id);
+
+  Page<Order> findByUserId(Long userId, Pageable pageable);
+
+  Order save(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..e02487b7b
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderService.java
@@ -0,0 +1,66 @@
+
+package com.loopers.domain.order;
+
+import com.loopers.application.order.CreateOrderCommand;
+import com.loopers.domain.product.ProductRepository;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@RequiredArgsConstructor
+@Component
+public class OrderService {
+  private final ProductRepository productRepository;
+  private final OrderRepository orderRepository;
+
+  public Page<Order> getOrders(
+      Long userId,
+      String sortType,
+      int page,
+      int size
+  ) {
+    Sort sort = this.getSortBySortType(sortType);
+    Pageable pageable = PageRequest.of(page, size, sort);
+    Page<Order> orders = null;
+    if (userId == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "유저 정보가 없습니다.");
+    }
+    orders = orderRepository.findByUserId(userId, pageable);
+    return orders;
+  }
+
+  @Transactional(readOnly = true)
+  public Order getOrder(Long id) {
+    if (id == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "ID가 없습니다.");
+    }
+    return orderRepository.findById(id).orElse(null);
+  }
+
+  public Order save(Order order) {
+    return orderRepository.save(order);
+  }
+
+  private Sort getSortBySortType(String sortType) {
+    if (sortType == null) sortType = "latest";
+    Sort latestSort = Sort.by("createdAt").descending();
+    switch (sortType.toLowerCase()) {
+      case "latest":
+        return latestSort;
+      case "price":
+        return Sort.by("status").descending();
+      default:
+        return latestSort;
+    }
+  }
+
+}
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..8dd95ef7e
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderStatus.java
@@ -0,0 +1,27 @@
+package com.loopers.domain.order;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor
+public enum OrderStatus {
+  PENDING("결제 대기", 10),
+  PAID("결제 완료", 20),
+  PREPARING("상품 준비 중", 30),
+  SHIPPED("배송 중", 40),
+  DELIVERED("배송 완료", 50),
+  CANCELLED("주문 취소", 90),
+  REFUNDED("환불 완료", 100);
+
+  private final String description;
+  @Getter(AccessLevel.NONE)
+  private final int sequence;
+
+  public Integer compare(OrderStatus other) {
+    return Integer.compare(this.sequence, other.sequence);
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/point/PointModel.java b/apps/commerce-api/src/main/java/com/loopers/domain/point/Point.java
similarity index 67%
rename from apps/commerce-api/src/main/java/com/loopers/domain/point/PointModel.java
rename to apps/commerce-api/src/main/java/com/loopers/domain/point/Point.java
index db3321685..84ecc6696 100644
--- a/apps/commerce-api/src/main/java/com/loopers/domain/point/PointModel.java
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/point/Point.java
@@ -1,7 +1,7 @@
 package com.loopers.domain.point;
 
 import com.loopers.domain.BaseEntity;
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
 import com.loopers.support.error.CoreException;
 import com.loopers.support.error.ErrorType;
 import jakarta.persistence.*;
@@ -13,33 +13,33 @@
 @Entity
 @Table(name = "point")
 @Getter
-public class PointModel extends BaseEntity {
+public class Point extends BaseEntity {
   private BigDecimal amount;
 
   @OneToOne
-  @JoinColumn(name = "userId", unique = true, nullable = false)
-  private UserModel user;
+  @JoinColumn(name = "ref_user_Id", unique = true, nullable = false)
+  private User user;
 
-  public void setUser(UserModel user) {
+  public void setUser(User user) {
     this.user = user;
     if (user.getPoint() != this) {
       user.setPoint(this);
     }
   }
 
-  protected PointModel() {
+  protected Point() {
     this.amount = BigDecimal.ZERO;
   }
 
-  private PointModel(UserModel user, BigDecimal amount) {
-    Objects.requireNonNull(user, "UserModel must not be null for PointModel creation.");
+  private Point(User user, BigDecimal amount) {
+    Objects.requireNonNull(user, "유저 정보가 없습니다.");
 
     this.setUser(user);
     this.amount = amount;
   }
 
-  public static PointModel create(UserModel user, BigDecimal amount) {
-    return new PointModel(user, amount);
+  public static Point create(User user, BigDecimal amount) {
+    return new Point(user, amount);
   }
 
   public void charge(BigDecimal amountToChange) {
@@ -54,7 +54,7 @@ public void use(BigDecimal amountToChange) {
       throw new CoreException(ErrorType.BAD_REQUEST, "차감 금액은 0보다 커야 합니다.");
     }
     if (this.amount.compareTo(amountToChange) < 0) {
-      throw new CoreException(ErrorType.BAD_REQUEST, "잔액이 부족합니다.");
+      throw new CoreException(ErrorType.INSUFFICIENT_POINT, "포인트가 부족합니다.");
     }
     this.amount = this.amount.subtract(amountToChange);
   }
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/point/PointRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/point/PointRepository.java
index 35d2dc95c..0524bc7ac 100644
--- a/apps/commerce-api/src/main/java/com/loopers/domain/point/PointRepository.java
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/point/PointRepository.java
@@ -6,12 +6,13 @@
 import java.util.Optional;
 
 public interface PointRepository {
+  Optional<Point> findByUserId(Long userId);
 
-  Optional<PointModel> findByUserId(String userId);
+  Optional<Point> findByUserId(String userId);
 
   @Lock(LockModeType.PESSIMISTIC_WRITE)
-  Optional<PointModel> findByUserIdForUpdate(String userId);
+  Optional<Point> findByUserIdForUpdate(Long userId);
 
-  PointModel save(PointModel point);
+  Point save(Point point);
 
 }
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 9554dcac0..9482ade25 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,7 +1,7 @@
 
 package com.loopers.domain.point;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
 import com.loopers.support.error.CoreException;
 import com.loopers.support.error.ErrorType;
 import lombok.RequiredArgsConstructor;
@@ -18,20 +18,37 @@ public class PointService {
   private final PointRepository pointRepository;
 
   @Transactional(readOnly = true)
-  public BigDecimal getAmount(String userId) {
+  public Point getAvailablePoints(Long userId) {
     return pointRepository.findByUserId(userId)
-        .map(PointModel::getAmount)
+        .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "포인트 정보를 찾을 수 없습니다."));
+  }
+
+  @Transactional(readOnly = true)
+  public BigDecimal getAmount(Long userId) {
+    return pointRepository.findByUserId(userId)
+        .map(Point::getAmount)
         .orElse(null);
   }
 
   @Transactional
-  public BigDecimal charge(UserModel user, BigDecimal chargeAmt) {
-    Optional<PointModel> pointOpt = pointRepository.findByUserIdForUpdate(user.getUserId());
-    if (pointOpt.isEmpty()) {
+  public BigDecimal charge(User user, BigDecimal chargeAmt) {
+    Optional<Point> pointOpt = pointRepository.findByUserIdForUpdate(user.getId());
+    if (!pointOpt.isPresent()) {
       throw new CoreException(ErrorType.NOT_FOUND, "현재 포인트 정보를 찾을수 없습니다.");
     }
     pointOpt.get().charge(chargeAmt);
     pointRepository.save(pointOpt.get());
-    return getAmount(user.getUserId());
+    return getAmount(user.getId());
+  }
+
+  @Transactional
+  public BigDecimal use(User user, BigDecimal useAmt) {
+    Optional<Point> pointOpt = pointRepository.findByUserIdForUpdate(user.getId());
+    if (!pointOpt.isPresent()) {
+      throw new CoreException(ErrorType.NOT_FOUND, "현재 포인트 정보를 찾을수 없습니다.");
+    }
+    pointOpt.get().use(useAmt);
+    pointRepository.save(pointOpt.get());
+    return getAmount(user.getId());
   }
 }
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..0a536113f
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/Product.java
@@ -0,0 +1,73 @@
+package com.loopers.domain.product;
+
+import com.loopers.domain.BaseEntity;
+import com.loopers.domain.brand.Brand;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.persistence.*;
+import lombok.Getter;
+
+import java.math.BigDecimal;
+
+@Entity
+@Table(name = "product")
+@Getter
+public class Product extends BaseEntity {
+  private String name;
+
+  @ManyToOne(fetch = FetchType.LAZY) // 지연 로딩 설정 (성능상 권장)
+  @JoinColumn(name = "ref_brand_Id")
+  private Brand brand;
+
+  private BigDecimal price;
+  private long stock;
+
+  @Transient
+  private long likeCount;
+
+  public void setBrand(Brand brand) {
+    this.brand = brand;
+  }
+
+  public void setLikeCount(long likeCount) {
+    this.likeCount = likeCount;
+  }
+
+  protected Product() {
+    this.stock = 0;
+  }
+
+  private Product(Brand brand, String name, BigDecimal price, long stock) {
+    this.setBrand(brand);
+    this.name = name;
+    this.price = price;
+    this.stock = stock;
+  }
+
+  public static Product create(Brand brand, String name, BigDecimal price, long stock) {
+    if (price.compareTo(BigDecimal.ZERO) < 0) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "가격은 음수 일수 없습니다.");
+    }
+    if (stock < 0) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "재고는 0보다 커야 합니다.");
+    }
+    return new Product(brand, name, price, stock);
+  }
+
+  public void deductStock(long quantity) {
+    if (quantity <= 0) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "수량은 0보다 커야 합니다.");
+    }
+    if (this.stock < quantity) {
+      throw new CoreException(ErrorType.INSUFFICIENT_STOCK, "재고가 부족합니다.");
+    }
+    this.stock -= quantity;
+  }
+
+  public void addStock(long quantity) {
+    if (quantity <= 0) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "수량은 0보다 커야 합니다.");
+    }
+    this.stock += quantity;
+  }
+}
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..ae1031751
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductRepository.java
@@ -0,0 +1,23 @@
+package com.loopers.domain.product;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+public interface ProductRepository {
+  Optional<Product> findById(Long id);
+
+  List<Product> findAllById(Set<Long> id);
+
+  Page<Product> findByBrandId(Long brandId, Pageable pageable);
+
+  Page<Product> findAll(Pageable pageable);
+
+  Product save(Product product);
+
+  List<Product> save(List<Product> products);
+
+}
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..15a98b75c
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductService.java
@@ -0,0 +1,100 @@
+
+package com.loopers.domain.product;
+
+import com.loopers.domain.like.LikeRepository;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@RequiredArgsConstructor
+@Component
+public class ProductService {
+
+  private final ProductRepository productRepository;
+  private final LikeRepository likeRepository;
+
+  @Transactional(readOnly = true)
+  public Page<Product> getProducts(
+      Long brandId,
+      String sortType,
+      int page,
+      int size
+  ) {
+    Sort sort = this.getSortBySortType(sortType);
+    Pageable pageable = PageRequest.of(page, size, sort);
+    Page<Product> products = null;
+    if (brandId != null) {
+      products = productRepository.findByBrandId(brandId, pageable);
+    } else {
+      products = productRepository.findAll(pageable);
+    }
+    return products;
+  }
+
+  @Transactional(readOnly = true)
+  public Product getProduct(Long id) {
+    if (id == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "ID가 없습니다.");
+    }
+    Optional<Product> product = productRepository.findById(id);
+    return product.orElse(null);
+  }
+
+  @Transactional(readOnly = true)
+  public List<Product> getExistingProducts(Set<Long> productIds) {
+
+    if (productIds == null || productIds.isEmpty()) {
+      return Collections.emptyList();
+    }
+    Set<Long> uniqueIds = new HashSet<>(productIds);
+    List<Product> products = productRepository.findAllById(productIds);
+
+    if (products.size() != uniqueIds.size()) {
+      Set<Long> foundIds = products.stream()
+          .map(Product::getId)
+          .collect(Collectors.toSet());
+
+      uniqueIds.removeAll(foundIds);
+      throw new CoreException(
+          ErrorType.NOT_FOUND,
+          "다음 상품 ID들은 찾을 수 없습니다: " + uniqueIds.toString()
+      );
+    }
+    return products;
+  }
+
+  @Transactional
+  public Product save(Product product) {
+    return productRepository.save(product);
+  }
+
+  @Transactional
+  public List<Product> save(List<Product> product) {
+    return productRepository.save(product);
+  }
+
+  private Sort getSortBySortType(String sortType) {
+    if (sortType == null) sortType = "latest";
+    Sort latestSort = Sort.by("createdAt").descending();
+    switch (sortType.toLowerCase()) {
+      case "latest":
+        return latestSort;
+      case "price_asc":
+        return Sort.by("price").ascending().and(latestSort);
+      case "likes_desc":
+        return Sort.by("likesCount").descending().and(latestSort);
+      default:
+        return latestSort;
+    }
+  }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductStockService.java b/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductStockService.java
new file mode 100644
index 000000000..800226bbc
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductStockService.java
@@ -0,0 +1,27 @@
+
+package com.loopers.domain.product;
+
+import com.loopers.domain.order.OrderPreparer;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+
+@RequiredArgsConstructor
+@Component
+public class ProductStockService {
+  private final ProductRepository productService;
+
+  public void deduct(List<Product> products, Map<Long, Long> quantityMap) {
+    List<Product> deductedProducts = OrderPreparer.verifyProductStockDeductable(products, quantityMap);
+    productService.save(deductedProducts);
+  }
+
+  public void add(List<Product> products, Map<Long, Long> quantityMap) {
+    List<Product> addedProducts = OrderPreparer.verifyProductStockAddable(products, quantityMap);
+    productService.save(addedProducts);
+  }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/user/UserModel.java b/apps/commerce-api/src/main/java/com/loopers/domain/user/User.java
similarity index 78%
rename from apps/commerce-api/src/main/java/com/loopers/domain/user/UserModel.java
rename to apps/commerce-api/src/main/java/com/loopers/domain/user/User.java
index 500eae5ef..61c8167c0 100644
--- a/apps/commerce-api/src/main/java/com/loopers/domain/user/UserModel.java
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/user/User.java
@@ -1,7 +1,7 @@
 package com.loopers.domain.user;
 
 import com.loopers.domain.BaseEntity;
-import com.loopers.domain.point.PointModel;
+import com.loopers.domain.point.Point;
 import com.loopers.support.error.CoreException;
 import com.loopers.support.error.ErrorType;
 import jakarta.persistence.*;
@@ -15,26 +15,26 @@
 @Entity
 @Table(name = "user")
 @Getter
-public class UserModel extends BaseEntity {
+public class User extends BaseEntity {
   private String userId;
   private String email;
   private LocalDate birthday;
   private String gender;
 
   @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
-  private PointModel point;
+  private Point point;
 
-  public void setPoint(PointModel point) {
+  public void setPoint(Point point) {
     this.point = point;
     if (point.getUser() != this) {
       point.setUser(this);
     }
   }
 
-  protected UserModel() {
+  protected User() {
   }
 
-  private UserModel(String userId, String email, String birthday, String gender) {
+  private User(String userId, String email, String birthday, String gender) {
 
     if (!Pattern.compile("^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]{1,10}$").matcher(userId).matches()) {
       throw new CoreException(
@@ -67,11 +67,11 @@ private UserModel(String userId, String email, String birthday, String gender) {
     this.email = email;
     this.birthday = LocalDate.parse(birthday);
     this.gender = gender;
-    this.point = PointModel.create(this, BigDecimal.TEN);
+    this.point = Point.create(this, BigDecimal.TEN);
   }
 
-  public static UserModel create(String userId, String email, String birthday, String gender) {
-    return new UserModel(userId, email, birthday, gender);
+  public static User create(String userId, String email, String birthday, String gender) {
+    return new User(userId, email, birthday, gender);
   }
 
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/user/UserPointService.java b/apps/commerce-api/src/main/java/com/loopers/domain/user/UserPointService.java
new file mode 100644
index 000000000..c29759ccf
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/user/UserPointService.java
@@ -0,0 +1,28 @@
+
+package com.loopers.domain.user;
+
+import com.loopers.domain.order.OrderPreparer;
+import com.loopers.domain.point.Point;
+import com.loopers.domain.point.PointRepository;
+import com.loopers.domain.point.PointService;
+import com.loopers.domain.product.Product;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+@RequiredArgsConstructor
+@Component
+public class UserPointService {
+
+  private final PointService pointService;
+
+
+  public void use(User user, List<Product> productList, Map<Long, Long> quantityMap) {
+    BigDecimal totalAmt = OrderPreparer.getTotalAmt(user.getPoint(), productList, quantityMap);
+    pointService.use(user, totalAmt);
+  }
+}
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 b7f64a18f..2ac424125 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
@@ -3,9 +3,12 @@
 import java.util.Optional;
 
 public interface UserRepository {
-  UserModel save(UserModel user);
+  User save(User user);
 
   boolean existsByUserId(String userId);
 
-  Optional<UserModel> findByUserId(String userId);
+  Optional<User> findById(Long id);
+
+  Optional<User> findByUserId(String userId);
+
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/user/UserService.java b/apps/commerce-api/src/main/java/com/loopers/domain/user/UserService.java
index dbb459db6..7481cf1cb 100644
--- a/apps/commerce-api/src/main/java/com/loopers/domain/user/UserService.java
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/user/UserService.java
@@ -7,8 +7,6 @@
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Optional;
-
 @RequiredArgsConstructor
 @Component
 public class UserService {
@@ -16,7 +14,7 @@ public class UserService {
   private final UserRepository userRepository;
 
   @Transactional
-  public UserModel join(UserModel user) {
+  public User join(User user) {
     if (userRepository.existsByUserId(user.getUserId())) {
       throw new CoreException(ErrorType.BAD_REQUEST, "이미 가입된 ID 입니다.");
     }
@@ -24,11 +22,27 @@ public UserModel join(UserModel user) {
   }
 
   @Transactional(readOnly = true)
-  public UserModel getUser(String userId) {
-    //Ask: userId도 UserModel 안에 넣어서 왔으면, userId Model에서 검증 가능
-    if (userId == null || userId.isBlank()) {
-      throw new CoreException(ErrorType.BAD_REQUEST, "ID가 없습니다.");
+  public User getUser(Long userId) {
+    if (userId == null) {
+      throw new CoreException(ErrorType.NOT_FOUND, "ID가 없습니다.");
+    }
+    return userRepository.findById(userId).orElse(null);
+  }
+
+  @Transactional(readOnly = true)
+  public User getUser(String userId) {
+    if (userId == null) {
+      throw new CoreException(ErrorType.NOT_FOUND, "ID가 없습니다.");
     }
     return userRepository.findByUserId(userId).orElse(null);
   }
+
+  @Transactional(readOnly = true)
+  public User getActiveUser(Long userId) {
+    if (userId == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "ID가 없습니다.");
+    }
+    return userRepository.findById(userId)
+        .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "사용자 정보를 찾을 수 없습니다."));
+  }
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/brand/BrandJpaRepository.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/brand/BrandJpaRepository.java
new file mode 100644
index 000000000..5ca589a5a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/brand/BrandJpaRepository.java
@@ -0,0 +1,12 @@
+package com.loopers.infrastructure.brand;
+
+import com.loopers.domain.brand.Brand;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface BrandJpaRepository extends JpaRepository<Brand, Long> {
+  Optional<Brand> findById(Long id);
+
+  Brand save(Brand brand);
+}
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..60f26343a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/brand/BrandRepositoryImpl.java
@@ -0,0 +1,24 @@
+package com.loopers.infrastructure.brand;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@RequiredArgsConstructor
+@Component
+public class BrandRepositoryImpl implements BrandRepository {
+  private final BrandJpaRepository jpaRepository;
+
+  @Override
+  public Optional<Brand> findById(Long id) {
+    return jpaRepository.findById(id);
+  }
+
+  @Override
+  public Brand save(Brand brand) {
+    return jpaRepository.save(brand);
+  }
+}
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..1008e0adb
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/like/LikeJpaRepository.java
@@ -0,0 +1,30 @@
+package com.loopers.infrastructure.like;
+
+import com.loopers.domain.like.Like;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.Optional;
+
+public interface LikeJpaRepository extends JpaRepository<Like, Long> {
+  Optional<Like> findByUserIdAndProductId(Long userId, Long productId);
+
+  Like save(Like like);
+
+  long deleteByUserIdAndProductId(Long userId, Long productId);
+
+  boolean existsByUserIdAndProductId(Long userId, Long productId);
+
+  long countByProductId(Long productId);
+
+  @Query(
+      value = "SELECT l FROM Like l JOIN FETCH l.product p WHERE l.user.id = :userId",
+      countQuery = "SELECT COUNT(l) FROM Like l WHERE l.user.id = :userId"
+  )
+  Page<Like> getLikedProducts(@Param("userId") Long userId, Pageable pageable);
+
+  //Page<Like> getLikedProducts(@Param("userId") Long userId, Pageable pageable);
+}
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..74507560e
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/like/LikeRepositoryImpl.java
@@ -0,0 +1,49 @@
+package com.loopers.infrastructure.like;
+
+import com.loopers.domain.like.Like;
+import com.loopers.domain.like.LikeRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@RequiredArgsConstructor
+@Component
+@Primary
+public class LikeRepositoryImpl implements LikeRepository {
+  private final LikeJpaRepository jpaRepository;
+
+  @Override
+  public Optional<Like> findById(Long userId, Long productId) {
+    return jpaRepository.findByUserIdAndProductId(userId, productId);
+  }
+
+  @Override
+  public Like save(Like like) {
+    return jpaRepository.save(like);
+  }
+
+  @Override
+  public long remove(Long userId, Long productId) {
+    return jpaRepository.deleteByUserIdAndProductId(userId, productId);
+  }
+
+  @Override
+  public boolean isLiked(Long userId, Long productId) {
+    return jpaRepository.existsByUserIdAndProductId(userId, productId);
+  }
+
+  @Override
+  public long getLikeCount(Long productId) {
+    return jpaRepository.countByProductId(productId);
+  }
+
+  @Override
+  public Page<Like> getLikedProducts(Long userId, Pageable pageable) {
+    return jpaRepository.getLikedProducts(userId, pageable);
+  }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/order/OrderJpaRepository.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/order/OrderJpaRepository.java
new file mode 100644
index 000000000..2d9c05f07
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/order/OrderJpaRepository.java
@@ -0,0 +1,15 @@
+package com.loopers.infrastructure.order;
+
+import com.loopers.domain.order.Order;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface OrderJpaRepository extends JpaRepository<Order, Long> {
+  Optional<Order> findById(Long id);
+
+  Page<Order> findByRefUserId(Long userId, Pageable pageable);
+
+}
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..3e29c2a90
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/order/OrderRepositoryImpl.java
@@ -0,0 +1,32 @@
+package com.loopers.infrastructure.order;
+
+import com.loopers.domain.order.Order;
+import com.loopers.domain.order.OrderRepository;
+import com.loopers.domain.product.ProductRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@RequiredArgsConstructor
+@Component
+public class OrderRepositoryImpl implements OrderRepository {
+  private final OrderJpaRepository jpaRepository;
+
+  @Override
+  public Optional<Order> findById(Long id) {
+    return jpaRepository.findById(id);
+  }
+
+  @Override
+  public Page<Order> findByUserId(Long userId, Pageable pageable) {
+    return jpaRepository.findByRefUserId(userId, pageable);
+  }
+
+  @Override
+  public Order save(Order order) {
+    return jpaRepository.save(order);
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/point/PointJpaRepository.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/point/PointJpaRepository.java
index 2c436109d..a5a85c432 100644
--- a/apps/commerce-api/src/main/java/com/loopers/infrastructure/point/PointJpaRepository.java
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/point/PointJpaRepository.java
@@ -1,18 +1,21 @@
 package com.loopers.infrastructure.point;
 
-import com.loopers.domain.point.PointModel;
+import com.loopers.domain.point.Point;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.Param;
 
 import java.util.Optional;
 
-public interface PointJpaRepository extends JpaRepository<PointModel, Long> {
+public interface PointJpaRepository extends JpaRepository<Point, Long> {
   boolean existsByUserUserId(String userId);
 
-  Optional<PointModel> findByUserUserId(String userId);
+  Optional<Point> findByUserUserId(String userId);
+
+  Optional<Point> findByUserId(Long userId);
+
+  @Query("SELECT p FROM Point p WHERE p.user.id = :userId")
+  Optional<Point> findByUserIdForUpdate(@Param("userId") Long userId);
 
-  @Query("SELECT p FROM PointModel p WHERE p.user.userId = :userId")
-  Optional<PointModel> findByUserUserIdForUpdate(@Param("userId") String userId);
 
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/point/PointRepositoryImpl.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/point/PointRepositoryImpl.java
index cce08040d..b9ef6bf0e 100644
--- a/apps/commerce-api/src/main/java/com/loopers/infrastructure/point/PointRepositoryImpl.java
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/point/PointRepositoryImpl.java
@@ -1,6 +1,6 @@
 package com.loopers.infrastructure.point;
 
-import com.loopers.domain.point.PointModel;
+import com.loopers.domain.point.Point;
 import com.loopers.domain.point.PointRepository;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Component;
@@ -13,18 +13,22 @@ public class PointRepositoryImpl implements PointRepository {
   private final PointJpaRepository jpaRepository;
 
   @Override
-  public PointModel save(PointModel point) {
+  public Point save(Point point) {
     return jpaRepository.save(point);
   }
 
   @Override
-  public Optional<PointModel> findByUserId(String userId) {
-    return jpaRepository.findByUserUserId(userId);
+  public Optional<Point> findByUserId(Long userId) {
+    return jpaRepository.findByUserId(userId);
   }
 
   @Override
-  public Optional<PointModel> findByUserIdForUpdate(String userId) {
-    return jpaRepository.findByUserUserIdForUpdate(userId);
+  public Optional<Point> findByUserId(String userId) {
+    return jpaRepository.findByUserUserId(userId);
   }
 
+  @Override
+  public Optional<Point> findByUserIdForUpdate(Long userId) {
+    return jpaRepository.findByUserIdForUpdate(userId);
+  }
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/product/ProductJpaRepository.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/product/ProductJpaRepository.java
new file mode 100644
index 000000000..e2119e400
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/product/ProductJpaRepository.java
@@ -0,0 +1,32 @@
+package com.loopers.infrastructure.product;
+
+import com.loopers.domain.product.Product;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface ProductJpaRepository extends JpaRepository<Product, Long> {
+  Optional<Product> findById(Long id);
+
+  List<Product> findAllById(Iterable<Long> id);
+
+  Page<Product> findByBrandId(Long brandId, Pageable pageable);
+
+  List<Product> save(List<Product> product);
+
+//  @Query(value = """
+//          SELECT new com.loopers.api.product.dto.Product(
+//              p,
+//              COUNT(l.id)
+//          )
+//          FROM Product p
+//          LEFT JOIN Like l ON l.product = p
+//          GROUP BY p
+//          ORDER BY p.id DESC
+//      """,
+//      countQuery = "SELECT COUNT(p.id) FROM Product p")
+  // Page<Product> findAllWithLikeCount(Pageable pageable);
+}
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..584ac2a5c
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/product/ProductRepositoryImpl.java
@@ -0,0 +1,48 @@
+package com.loopers.infrastructure.product;
+
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+@RequiredArgsConstructor
+@Component
+public class ProductRepositoryImpl implements ProductRepository {
+  private final ProductJpaRepository jpaRepository;
+
+  @Override
+  public Optional<Product> findById(Long id) {
+    return jpaRepository.findById(id);
+  }
+
+  @Override
+  public List<Product> findAllById(Set<Long> id) {
+    return jpaRepository.findAllById(id);
+  }
+
+  @Override
+  public Page<Product> findByBrandId(Long brandId, Pageable pageable) {
+    return jpaRepository.findByBrandId(brandId, pageable);
+  }
+
+  @Override
+  public Page<Product> findAll(Pageable pageable) {
+    return jpaRepository.findAll(pageable);
+  }
+
+  @Override
+  public Product save(Product product) {
+    return jpaRepository.save(product);
+  }
+
+  @Override
+  public List<Product> save(List<Product> products) {
+    return jpaRepository.saveAll(products);
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/user/UserJpaRepository.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/user/UserJpaRepository.java
index bd867ae25..015978561 100644
--- a/apps/commerce-api/src/main/java/com/loopers/infrastructure/user/UserJpaRepository.java
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/user/UserJpaRepository.java
@@ -1,11 +1,14 @@
 package com.loopers.infrastructure.user;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
 import org.springframework.data.jpa.repository.JpaRepository;
 
 import java.util.Optional;
 
-public interface UserJpaRepository extends JpaRepository<UserModel, Long> {
+public interface UserJpaRepository extends JpaRepository<User, Long> {
   boolean existsByUserId(String userId);
-  Optional<UserModel> findByUserId(String userId);
+
+  Optional<User> findById(Long id);
+
+  Optional<User> findByUserId(String id);
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/user/UserRepositoryImpl.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/user/UserRepositoryImpl.java
index 3e33c3ff7..e4e85f02d 100644
--- a/apps/commerce-api/src/main/java/com/loopers/infrastructure/user/UserRepositoryImpl.java
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/user/UserRepositoryImpl.java
@@ -1,6 +1,6 @@
 package com.loopers.infrastructure.user;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
 import com.loopers.domain.user.UserRepository;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Component;
@@ -13,7 +13,7 @@ public class UserRepositoryImpl implements UserRepository {
   private final UserJpaRepository jpaRepository;
 
   @Override
-  public UserModel save(UserModel user) {
+  public User save(User user) {
     return jpaRepository.save(user);
   }
 
@@ -23,7 +23,12 @@ public boolean existsByUserId(String userId) {
   }
 
   @Override
-  public Optional<UserModel> findByUserId(String userId) {
+  public Optional<User> findById(Long userId) {
+    return jpaRepository.findById(userId);
+  }
+
+  @Override
+  public Optional<User> findByUserId(String userId) {
     return jpaRepository.findByUserId(userId);
   }
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderCreateV1Dto.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderCreateV1Dto.java
new file mode 100644
index 000000000..0ef09e8b2
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderCreateV1Dto.java
@@ -0,0 +1,35 @@
+package com.loopers.interfaces.api.order;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.loopers.application.order.OrderInfo;
+import com.loopers.application.order.OrderItemInfo;
+
+import java.math.BigDecimal;
+import java.time.ZonedDateTime;
+import java.util.List;
+
+public class OrderCreateV1Dto {
+  public record OrderItemRequest(long productId, long quantity) {
+  }
+
+  public record OrderRequest(List<OrderItemRequest> items) {
+  }
+
+  public record OrderResponse(long id, String status
+      , @JsonSerialize(using = ToStringSerializer.class) BigDecimal totalPrice
+      , @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") ZonedDateTime orderAt
+      , List<OrderItemInfo> orderItemInfo) {
+    public static OrderResponse from(OrderInfo info) {
+      if (info == null) return null;
+      return new OrderResponse(
+          info.id(),
+          info.status(),
+          info.totalPrice(),
+          info.orderAt(),
+          info.orderItemInfo()
+      );
+    }
+  }
+}
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..ddaf2bc04
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1ApiSpec.java
@@ -0,0 +1,55 @@
+package com.loopers.interfaces.api.order;
+
+import com.loopers.domain.order.Order;
+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;
+import jakarta.validation.Valid;
+import org.springframework.data.domain.Page;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Tag(name = "Order V1 API", description = "Loopers 예시 API 입니다.")
+public interface OrderV1ApiSpec {
+  @Operation(
+      summary = "주문 목록 조회",
+      description = "사용자 ID로 주문 목록 조회합니다."
+  )
+  @Valid
+  ApiResponse<Page<Order>> getOrderList(
+      @Schema(name = "사용자 ID", description = "조회할 사용자의 ID")
+      @RequestHeader(value = "X-USER-ID", required = false) Long userId,
+      @RequestParam(name = "sortType", defaultValue = "latest") String sortType,
+      @RequestParam(name = "page", defaultValue = "0") int page,
+      @RequestParam(name = "size", defaultValue = "20") int size
+  );
+
+  @Operation(
+      summary = "주문 요청",
+      description = "ID로 주문를 충전합니다."
+  )
+  @Valid
+  ApiResponse<OrderCreateV1Dto.OrderResponse> createOrder(
+      @Schema(name = "사용자 ID", description = "충전할 사용자의 ID")
+      @RequestHeader(value = "X-USER-ID", required = false) Long userId
+      , @RequestBody OrderCreateV1Dto.OrderRequest request
+  );
+
+
+  @Operation(
+      summary = "주문 상세조회",
+      description = "주문 ID로 주문 상세조회합니다."
+  )
+  @Valid
+  ApiResponse<OrderCreateV1Dto.OrderResponse> getOrderDetail(
+      @Schema(name = "사용자 ID", description = "조회할 사용자의 ID")
+      @RequestHeader(value = "X-USER-ID", required = false) Long userId
+      , 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..b42521578
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1Controller.java
@@ -0,0 +1,51 @@
+package com.loopers.interfaces.api.order;
+
+import com.loopers.application.order.CreateOrderCommand;
+import com.loopers.application.order.OrderFacade;
+import com.loopers.application.order.OrderInfo;
+import com.loopers.domain.order.Order;
+import com.loopers.interfaces.api.ApiResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.web.bind.annotation.*;
+
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/api/v1/orders")
+public class OrderV1Controller implements OrderV1ApiSpec {
+
+  private final OrderFacade orderFacade;
+
+  @GetMapping("")
+  @Override
+  public ApiResponse<Page<Order>> getOrderList(
+      @RequestHeader(value = "X-USER-ID", required = false) Long userId,
+      @RequestParam(name = "sortType", defaultValue = "latest") String sortType,
+      @RequestParam(name = "page", defaultValue = "0") int page,
+      @RequestParam(name = "size", defaultValue = "20") int size
+  ) {
+    Page<Order> info = orderFacade.getOrderList(userId, sortType, page, size);
+    return ApiResponse.success(info);
+  }
+
+  @PostMapping("")
+  @Override
+  public ApiResponse<OrderCreateV1Dto.OrderResponse> createOrder(@RequestHeader(value = "X-USER-ID", required = false) Long userId
+      , @RequestBody OrderCreateV1Dto.OrderRequest request
+  ) {
+    CreateOrderCommand command = CreateOrderCommand.from(userId, request);
+    OrderInfo info = orderFacade.createOrder(command);
+    OrderCreateV1Dto.OrderResponse response = OrderCreateV1Dto.OrderResponse.from(info);
+    return ApiResponse.success(response);
+  }
+
+  @GetMapping("/{orderId}")
+  @Override
+  public ApiResponse<OrderCreateV1Dto.OrderResponse> getOrderDetail(@RequestHeader(value = "X-USER-ID", required = false) Long userId
+      , @PathVariable(value = "orderId") Long orderId
+  ) {
+    OrderInfo info = orderFacade.getOrderDetail(orderId);
+    OrderCreateV1Dto.OrderResponse response = OrderCreateV1Dto.OrderResponse.from(info);
+    return ApiResponse.success(response);
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/point/PointV1ApiSpec.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/point/PointV1ApiSpec.java
index 7e86ed59c..47b7660c9 100644
--- a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/point/PointV1ApiSpec.java
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/point/PointV1ApiSpec.java
@@ -19,7 +19,7 @@ public interface PointV1ApiSpec {
   @Valid
   ApiResponse<BigDecimal> getPoint(
       @Schema(name = "사용자 ID", description = "조회할 사용자의 ID")
-      @RequestHeader(value = "X-USER-ID", required = false) String userId
+      @RequestHeader(value = "X-USER-ID", required = false) Long userId
   );
 
   @Operation(
@@ -29,7 +29,7 @@ ApiResponse<BigDecimal> getPoint(
   @Valid
   ApiResponse<BigDecimal> charge(
       @Schema(name = "사용자 ID", description = "충전할 사용자의 ID")
-      @RequestHeader(value = "X-USER-ID", required = false) String userId
+      @RequestHeader(value = "X-USER-ID", required = false) Long userId
       , @RequestBody BigDecimal amount
   );
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/point/PointV1Controller.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/point/PointV1Controller.java
index 211efbe2a..5adeadb43 100644
--- a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/point/PointV1Controller.java
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/point/PointV1Controller.java
@@ -16,14 +16,14 @@ public class PointV1Controller implements PointV1ApiSpec {
 
   @GetMapping("")
   @Override
-  public ApiResponse<BigDecimal> getPoint(@RequestHeader(value = "X-USER-ID", required = false) String userId
+  public ApiResponse<BigDecimal> getPoint(@RequestHeader(value = "X-USER-ID", required = false) Long userId
   ) {
     return ApiResponse.success(pointFacade.getPoint(userId));
   }
 
   @PostMapping("/charge")
   @Override
-  public ApiResponse<BigDecimal> charge(@RequestHeader(value = "X-USER-ID", required = false) String userId
+  public ApiResponse<BigDecimal> charge(@RequestHeader(value = "X-USER-ID", required = false) Long userId
       , @RequestBody BigDecimal amount
   ) {
     return ApiResponse.success(pointFacade.charge(userId, amount));
diff --git a/apps/commerce-api/src/main/java/com/loopers/support/error/ErrorType.java b/apps/commerce-api/src/main/java/com/loopers/support/error/ErrorType.java
index 5d142efbf..8bb2324d6 100644
--- a/apps/commerce-api/src/main/java/com/loopers/support/error/ErrorType.java
+++ b/apps/commerce-api/src/main/java/com/loopers/support/error/ErrorType.java
@@ -7,13 +7,17 @@
 @Getter
 @RequiredArgsConstructor
 public enum ErrorType {
-    /** 범용 에러 */
-    INTERNAL_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), "일시적인 오류가 발생했습니다."),
-    BAD_REQUEST(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.getReasonPhrase(), "잘못된 요청입니다."),
-    NOT_FOUND(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.getReasonPhrase(), "존재하지 않는 요청입니다."),
-    CONFLICT(HttpStatus.CONFLICT, HttpStatus.CONFLICT.getReasonPhrase(), "이미 존재하는 리소스입니다.");
+  /**
+   * 범용 에러
+   */
+  INTERNAL_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), "일시적인 오류가 발생했습니다."),
+  BAD_REQUEST(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.getReasonPhrase(), "잘못된 요청입니다."),
+  NOT_FOUND(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.getReasonPhrase(), "존재하지 않는 요청입니다."),
+  CONFLICT(HttpStatus.CONFLICT, HttpStatus.CONFLICT.getReasonPhrase(), "이미 존재하는 리소스입니다."),
 
-    private final HttpStatus status;
-    private final String code;
-    private final String message;
+  INSUFFICIENT_STOCK(HttpStatus.BAD_REQUEST, "INSUFFICIENT_STOCK", "요청하신 상품의 재고가 부족합니다."),
+  INSUFFICIENT_POINT(HttpStatus.BAD_REQUEST, "INSUFFICIENT_POINT", "사용 가능한 포인트가 부족합니다.");
+  private final HttpStatus status;
+  private final String code;
+  private final String message;
 }
diff --git a/apps/commerce-api/src/test/java/com/loopers/application/order/OrderFacadeIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/application/order/OrderFacadeIntegrationTest.java
new file mode 100644
index 000000000..a2121e2ef
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/application/order/OrderFacadeIntegrationTest.java
@@ -0,0 +1,168 @@
+package com.loopers.application.order;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.order.Order;
+import com.loopers.domain.order.OrderItem;
+import com.loopers.domain.order.OrderStatus;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.user.User;
+import com.loopers.infrastructure.brand.BrandJpaRepository;
+import com.loopers.infrastructure.order.OrderJpaRepository;
+import com.loopers.infrastructure.user.UserJpaRepository;
+import com.loopers.interfaces.api.order.OrderCreateV1Dto;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertThrows;
+
+
+@SpringBootTest
+class OrderFacadeIntegrationTest {
+  @Autowired
+  private OrderFacade orderFacade;
+  @MockitoSpyBean
+  private UserJpaRepository userJpaRepository;
+  @MockitoSpyBean
+  private BrandJpaRepository brandJpaRepository;
+  @MockitoSpyBean
+  private ProductService productService;
+
+  @MockitoSpyBean
+  private OrderJpaRepository orderJpaRepository;
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  User savedUser;
+  List<Product> savedProducts;
+  Order savedOrder;
+
+  @BeforeEach
+  void setup() {
+    // arrange
+    User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+    savedUser = userJpaRepository.save(user);
+    List<Brand> brandList = List.of(Brand.create("레이브", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.")
+        , Brand.create("마뗑킴", "마뗑킴은 트렌디하면서도 편안함을 더한 디자인을 선보입니다. 일상에서 조화롭게 적용할 수 있는 자연스러운 패션 문화를 지향합니다."));
+    List<Brand> savedBrandList = brandList.stream().map((brand) -> brandJpaRepository.save(brand)).toList();
+
+    List<Product> productList = List.of(Product.create(savedBrandList.get(0), "Wild Faith Rose Sweatshirt", new BigDecimal(8), 10)
+        , Product.create(savedBrandList.get(0), "Flower Pattern Fleece Jacket", new BigDecimal(4), 10)
+        , Product.create(savedBrandList.get(1), "Flower Pattern Fleece Jacket", new BigDecimal(178_000), 20)
+    );
+    savedProducts = productService.save(productList);
+    List<OrderItem> orderItems = new ArrayList<>();
+    orderItems.add(OrderItem.create(productList.get(0).getId(), 2L, new BigDecimal(5_000)));
+    Order order = Order.create(1, OrderStatus.PENDING, new BigDecimal(10_000), orderItems);
+    savedOrder = orderJpaRepository.save(order);
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("주문목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=0, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_주문목록조회() {
+      // act
+      Page<Order> ordersPage = orderFacade.getOrderList(savedUser.getId(), "latest", 0, 20);
+      List<Order> orders = ordersPage.getContent();
+      // assert
+      assertThat(orders).isNotEmpty().hasSize(1);
+    }
+  }
+
+  @DisplayName("주문을 조회할 때,")
+  @Nested
+  class Get {
+    @DisplayName("존재하는 상품 ID를 주면, 해당 상품 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_상품ID() {
+      // arrange
+      // act
+      OrderInfo result = orderFacade.getOrderDetail(savedOrder.getId());
+
+      // assert
+      assertThat(result.id()).isEqualTo(savedOrder.getId());
+      assertThat(result.status()).isEqualTo(savedOrder.getStatus().toString());
+      assertThat(result.totalPrice()).isEqualByComparingTo(savedOrder.getTotalPrice());
+    }
+
+    @DisplayName("존재하지 않는 상품 ID를 주면, 예외가 반환된다.")
+    @Test
+    void 실패_존재하지_않는_상품ID() {
+      // arrange
+      // act
+      // assert
+      assertThrows(CoreException.class, () -> {
+        orderFacade.getOrderDetail(0L);
+      });
+    }
+  }
+
+  @DisplayName("주문을 생성할 때,")
+  @Nested
+  class Post {
+    @DisplayName("10재고가 있는 8원의 상품 1건 주문시, 기본 포인트10으로 결재가 된다.")
+    @Test
+    void 성공_단건주문생성() {
+      List<OrderCreateV1Dto.OrderItemRequest> items = new ArrayList<>();
+      items.add(new OrderCreateV1Dto.OrderItemRequest(savedProducts.get(0).getId(), 1));
+      OrderCreateV1Dto.OrderRequest request = new OrderCreateV1Dto.OrderRequest(items);
+      CreateOrderCommand orderCommand = CreateOrderCommand.from(savedUser.getId(), request);
+      // act
+      OrderInfo savedOrder = orderFacade.createOrder(orderCommand);
+      // assert
+      assertThat(savedOrder).isNotNull();
+      assertThat(savedOrder.totalPrice()).isEqualByComparingTo(savedProducts.get(0).getPrice());
+      assertThat(savedOrder.orderItemInfo()).hasSize(1);
+    }
+
+    @DisplayName("10재고가 있는 8원의 상품 20건 주문시, 재고 없음 오류가 발생한다.")
+    @Test
+    void 실패_재고없음오류() {
+      List<OrderCreateV1Dto.OrderItemRequest> items = new ArrayList<>();
+      items.add(new OrderCreateV1Dto.OrderItemRequest(savedProducts.get(0).getId(), 20));
+      OrderCreateV1Dto.OrderRequest request = new OrderCreateV1Dto.OrderRequest(items);
+      CreateOrderCommand orderCommand = CreateOrderCommand.from(savedUser.getId(), request);
+      // act
+      // assert
+      assertThrows(CoreException.class, () -> orderFacade.createOrder(orderCommand)).getErrorType().equals(ErrorType.INSUFFICIENT_STOCK);
+    }
+
+    @DisplayName("10재고가 있는 4원의 상품 3건 주문시, 포인트 부족 오류가 발생한다.")
+    @Test
+    void 실패_포인트부족오류() {
+      long productId = savedProducts.get(1).getId();
+      long quantity = 3L;
+      List<OrderCreateV1Dto.OrderItemRequest> items = new ArrayList<>();
+      items.add(new OrderCreateV1Dto.OrderItemRequest(productId, quantity));
+      OrderCreateV1Dto.OrderRequest request = new OrderCreateV1Dto.OrderRequest(items);
+      CreateOrderCommand orderCommand = CreateOrderCommand.from(savedUser.getId(), request);
+      // act
+      // assert
+      CoreException actualException = assertThrows(CoreException.class,
+          () -> orderFacade.createOrder(orderCommand));
+      assertThat(actualException.getErrorType()).isEqualTo(ErrorType.INSUFFICIENT_POINT);
+      Product deductedProduct = productService.getProduct(productId);
+      assertThat(deductedProduct.getStock()).isEqualTo(10);
+    }
+  }
+
+}
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..f31a3d8f2
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/application/product/ProductFacadeIntegrationTest.java
@@ -0,0 +1,122 @@
+package com.loopers.application.product;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.user.User;
+import com.loopers.infrastructure.brand.BrandJpaRepository;
+import com.loopers.infrastructure.product.ProductJpaRepository;
+import com.loopers.infrastructure.user.UserJpaRepository;
+import com.loopers.support.error.CoreException;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import static com.loopers.domain.product.ProductAssertions.assertProduct;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertThrows;
+
+
+@SpringBootTest
+class ProductFacadeIntegrationTest {
+  @Autowired
+  private ProductFacade productFacade;
+  @MockitoSpyBean
+  private UserJpaRepository userJpaRepository;
+  @MockitoSpyBean
+  private BrandJpaRepository brandJpaRepository;
+  @MockitoSpyBean
+  private ProductService productService;
+
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  User savedUser;
+  List<Product> savedProducts;
+
+  @BeforeEach
+  void setup() {
+    // arrange
+    User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+    savedUser = userJpaRepository.save(user);
+    List<Brand> brandList = List.of(Brand.create("레이브", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.")
+        , Brand.create("마뗑킴", "마뗑킴은 트렌디하면서도 편안함을 더한 디자인을 선보입니다. 일상에서 조화롭게 적용할 수 있는 자연스러운 패션 문화를 지향합니다."));
+    List<Brand> savedBrandList = brandList.stream().map((brand) -> brandJpaRepository.save(brand)).toList();
+
+    List<Product> productList = List.of(Product.create(savedBrandList.get(0), "Wild Faith Rose Sweatshirt", new BigDecimal(80_000), 10)
+        , Product.create(savedBrandList.get(0), "Flower Pattern Fleece Jacket", new BigDecimal(178_000), 20)
+        , Product.create(savedBrandList.get(1), "Flower Pattern Fleece Jacket", new BigDecimal(178_000), 20)
+    );
+    savedProducts = productService.save(productList);
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("상품목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=0, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_상품목록조회() {
+      // act
+      Page<Product> productsPage = productFacade.getProductList(null, "latest", 0, 20);
+      List<Product> products = productsPage.getContent();
+      // assert
+      assertThat(products).isNotEmpty().hasSize(3);
+    }
+
+    @DisplayName("브랜드ID 검색조건 포함시, 해당 브랜드의 상품 목록이 조회된다.")
+    @Test
+    void 성공_상품목록조회_브랜드ID() {
+      // arrange
+      // act
+      Page<Product> productsPage = productFacade.getProductList(savedProducts.get(0).getId(), null, 0, 20);
+      List<Product> productList = productsPage.getContent();
+
+      // assert
+      assertThat(productList).isNotEmpty().hasSize(2);
+
+      assertProduct(productList.get(0), savedProducts.get(1));
+      assertProduct(productList.get(1), savedProducts.get(0));
+    }
+  }
+
+  @DisplayName("상품을 조회할 때,")
+  @Nested
+  class Get {
+    @DisplayName("존재하는 상품 ID를 주면, 해당 상품 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_상품ID() {
+      // arrange
+      // act
+      ProductDetailInfo result = productFacade.getProductDetail(savedUser.getId(), savedProducts.get(0).getId());
+
+      // assert
+      assertThat(result.name()).isEqualTo(savedProducts.get(0).getName());
+    }
+
+    @DisplayName("존재하지 않는 상품 ID를 주면, 예외가 반환된다.")
+    @Test
+    void 실패_존재하지_않는_상품ID() {
+      // arrange
+      // act
+      // assert
+      assertThrows(CoreException.class, () -> {
+        productFacade.getProductDetail(savedUser.getId(), (long) 100);
+      });
+    }
+  }
+
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandAssertions.java b/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandAssertions.java
new file mode 100644
index 000000000..bdf45dac1
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandAssertions.java
@@ -0,0 +1,15 @@
+package com.loopers.domain.brand;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class BrandAssertions {
+  public static void assertBrand(Brand actual, Brand expected) {
+    assertThat(actual).isNotNull();
+    assertThat(expected).isNotNull();
+    assertThat(actual.getId()).isEqualTo(expected.getId());
+    assertThat(actual.getName()).isEqualTo(expected.getName());
+    assertThat(actual.getStory()).isEqualTo(expected.getStory());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandModelTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandModelTest.java
new file mode 100644
index 000000000..57e57f3da
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandModelTest.java
@@ -0,0 +1,49 @@
+package com.loopers.domain.brand;
+
+import com.loopers.domain.product.Product;
+import com.loopers.support.error.CoreException;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+import java.math.BigDecimal;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class BrandModelTest {
+  Brand brand;
+  String validMsg = "";
+
+  @DisplayName("브랜드 모델을 생성할 때, ")
+  @Nested
+  class Create_Brand {
+    @DisplayName("브랜드명과 스토리가 모두 주어지면, 정상적으로 생성된다.")
+    @Test
+    void 성공_Brand_객체생성() {
+      //given
+      brand = Brand.create("레이브", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.");
+
+      //assert
+      assertThat(brand).isNotNull();
+      assertThat(brand.getName()).isEqualTo("레이브");
+      assertThat(brand.getStory()).isEqualTo("레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.");
+    }
+  }
+
+  @Nested
+  class Valid_Brand {
+    @BeforeEach
+    void setup() {
+      validMsg = "브랜드명은 비어있을 수 없습니다.";
+    }
+
+    @Test
+    void 실패_이름_오류() {
+      assertThatThrownBy(() -> {
+        brand = Brand.create("", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.");
+      }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining(validMsg);
+    }
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandServiceIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandServiceIntegrationTest.java
new file mode 100644
index 000000000..1a7346003
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandServiceIntegrationTest.java
@@ -0,0 +1,76 @@
+package com.loopers.domain.brand;
+
+import com.loopers.infrastructure.brand.BrandJpaRepository;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+@SpringBootTest
+class BrandServiceIntegrationTest {
+  @Autowired
+  private BrandService brandService;
+
+  @MockitoSpyBean
+  private BrandJpaRepository brandJpaRepository;
+
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  Brand brand;
+
+  @BeforeEach
+  void setup() {
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("브랜드를 조회할 때,")
+  @Nested
+  class Get {
+    @DisplayName("존재하는 브랜드 ID를 주면, 해당 브랜드 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_브랜드ID() {
+      // arrange
+      List<Brand> brands = List.of(Brand.create("레이브", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.")
+          , Brand.create("마뗑킴", "마뗑킴은 트렌디하면서도 편안함을 더한 디자인을 선보입니다. 일상에서 조화롭게 적용할 수 있는 자연스러운 패션 문화를 지향합니다."));
+      List<Brand> savedBrands = brands.stream().map((brand) -> brandJpaRepository.save(brand)).toList();
+
+      // act
+      Brand result = brandService.getBrand(savedBrands.get(0).getId());
+
+      // assert
+      assertBrand(result, savedBrands.get(0));
+    }
+
+    @DisplayName("존재하지 않는 브랜드 ID를 주면, NOT_FOUND 예외가 발생한다.")
+    @Test
+    void 실패_존재하지_않는_브랜드ID() {
+      // arrange
+
+      // act
+      Brand result = brandService.getBrand((long) 1);
+
+      // assert
+      assertThat(result).isNull();
+    }
+  }
+
+  public static void assertBrand(Brand actual, Brand expected) {
+    assertThat(actual).isNotNull();
+    assertThat(expected).isNotNull();
+    assertThat(actual.getId()).isEqualTo(expected.getId());
+    assertThat(actual.getName()).isEqualTo(expected.getName());
+    assertThat(actual.getStory()).isEqualTo(expected.getStory());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/like/FakeLikeRepository.java b/apps/commerce-api/src/test/java/com/loopers/domain/like/FakeLikeRepository.java
new file mode 100644
index 000000000..e6e6a40ec
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/like/FakeLikeRepository.java
@@ -0,0 +1,93 @@
+package com.loopers.domain.like;
+
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@RequiredArgsConstructor
+@Component
+public class FakeLikeRepository implements LikeRepository {
+  private final Map<Long, Like> list = new HashMap<>();
+
+  @Override
+  public Optional<Like> findById(Long userId, Long productId) {
+    Long id = (long) 0;
+    for (Long key : list.keySet()) {
+      id = key;
+      Like like = list.get(key);
+      if (like.getUser().getId() == userId
+          && like.getProduct().getId() == productId) {
+        return Optional.of(like);
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public Like save(Like entity) {
+    Long id = (long) 0;
+    for (Long key : list.keySet()) {
+      id = key;
+      Like like = list.get(key);
+      if (like.getUser().getId() == entity.getUser().getId()
+          && like.getProduct().getId() == entity.getUser().getId()) {
+        throw new CoreException(ErrorType.BAD_REQUEST, "중복 좋아요 요청입니다.");
+      }
+    }
+    id = id == (long) 0 ? 0 : id + 1;
+    list.put(id, entity);
+    return entity;
+  }
+
+  @Override
+  public long remove(Long userId, Long productId) {
+    long cnt = 0;
+    for (Long key : list.keySet()) {
+      Like like = list.get(key);
+      if (like.getUser().getId() == userId
+          && like.getProduct().getId() == productId) {
+        list.remove(key);
+        cnt++;
+      }
+    }
+    return cnt;
+  }
+
+  @Override
+  public boolean isLiked(Long userId, Long productId) {
+    for (Long key : list.keySet()) {
+      Like like = list.get(key);
+      if (like.getUser().getId() == userId
+          && like.getProduct().getId() == productId) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @Override
+  public long getLikeCount(Long productId) {
+    long cnt = 0;
+    for (Long key : list.keySet()) {
+      Like like = list.get(key);
+      if (like.getProduct().getId() == productId) {
+        cnt++;
+      }
+    }
+    return cnt;
+  }
+
+  @Override
+  public Page<Like> getLikedProducts(Long userId, Pageable pageable) {
+    return new PageImpl<>(list.values().stream().filter(i -> i.getUser().getId() == userId)
+        .collect(Collectors.toList()), pageable, list.size());
+  }
+
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeAssertions.java b/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeAssertions.java
new file mode 100644
index 000000000..0c62874c5
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeAssertions.java
@@ -0,0 +1,13 @@
+package com.loopers.domain.like;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LikeAssertions {
+  public static void assertLike(Like actual, Like expected) {
+    assertThat(actual).isNotNull();
+    assertThat(expected).isNotNull();
+    assertThat(actual.getId()).isEqualTo(expected.getId());
+    assertThat(actual.getUser().getId()).isEqualTo(expected.getUser().getId());
+    assertThat(actual.getProduct().getId()).isEqualTo(expected.getProduct().getId());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeModelTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeModelTest.java
new file mode 100644
index 000000000..a977dc616
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeModelTest.java
@@ -0,0 +1,69 @@
+package com.loopers.domain.like;
+
+import com.loopers.domain.product.Product;
+import com.loopers.domain.user.User;
+import com.loopers.support.error.CoreException;
+import org.junit.jupiter.api.BeforeEach;
+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.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class LikeModelTest {
+  Like like;
+  User mockUser = mock(User.class);
+  Product mockProduct = mock(Product.class);
+
+  @DisplayName("좋아요 모델을 생성할 때, ")
+  @Nested
+  class Create_Like {
+    @DisplayName("사용자id와 상품id가 모두 주어지면, 정상적으로 생성된다.")
+    @Test
+    void 성공_Like_객체생성() {
+      //given
+      mockUser = mock(User.class);
+      when(mockUser.getId()).thenReturn(1L);
+      mockProduct = mock(Product.class);
+      when(mockProduct.getId()).thenReturn(10L);
+      //act
+      like = Like.create(mockUser, mockProduct);
+      //assert
+      assertThat(like).isNotNull();
+      assertThat(like.getUser().getId()).isEqualTo(mockUser.getId());
+      assertThat(like.getProduct().getId()).isEqualTo(mockProduct.getId());
+    }
+  }
+
+  @Nested
+  class Valid_Like {
+    @BeforeEach
+    void setup() {
+      mockUser = mock(User.class);
+      when(mockUser.getId()).thenReturn(1L);
+      mockProduct = mock(Product.class);
+      when(mockProduct.getId()).thenReturn(10L);
+    }
+
+    @Test
+    void 실패_사용자ID_오류() {
+      //given
+      when(mockUser.getId()).thenReturn(null);
+      assertThatThrownBy(() -> {
+        like = Like.create(mockUser, mockProduct);
+      }).isInstanceOf(CoreException.class).hasMessageContaining("사용자ID는 비어있을 수 없습니다.");
+    }
+
+    @Test
+    void 실패_상품ID_오류() {
+      //given
+      when(mockProduct.getId()).thenReturn(null);
+      assertThatThrownBy(() -> {
+        like = Like.create(mockUser, mockProduct);
+      }).isInstanceOf(CoreException.class).hasMessageContaining("상품ID는 비어있을 수 없습니다.");
+    }
+  }
+}
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..ccb7fbeab
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeServiceIntegrationTest.java
@@ -0,0 +1,153 @@
+package com.loopers.domain.like;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.user.User;
+import com.loopers.infrastructure.brand.BrandJpaRepository;
+import com.loopers.infrastructure.like.LikeJpaRepository;
+import com.loopers.infrastructure.product.ProductJpaRepository;
+import com.loopers.infrastructure.user.UserJpaRepository;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.domain.Page;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Optional;
+
+import static com.loopers.domain.like.LikeAssertions.assertLike;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+
+@SpringBootTest
+class LikeServiceIntegrationTest {
+  @Autowired
+  private LikeService likeService;
+
+  @MockitoSpyBean
+  private LikeJpaRepository likeJpaRepository;
+  @MockitoSpyBean
+  private UserJpaRepository userJpaRepository;
+  @MockitoSpyBean
+  private BrandJpaRepository brandJpaRepository;
+  @MockitoSpyBean
+  private ProductJpaRepository productJpaRepository;
+
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  User savedUser;
+  Brand savedBrand;
+  Product savedProduct;
+
+  @TestConfiguration
+  static class FakeRepositoryConfig {
+    @Bean
+    public LikeRepository likeRepository() {
+      return new FakeLikeRepository();
+    }
+  }
+
+  @BeforeEach
+  void setup() {
+    User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+    savedUser = userJpaRepository.save(user);
+    Brand brand = Brand.create("레이브", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.");
+    savedBrand = brandJpaRepository.save(brand);
+    Product product = Product.create(savedBrand, "Wild Faith Rose Sweatshirt", new BigDecimal(80_000), 10);
+    savedProduct = productJpaRepository.save(product);
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("좋아요를 조회할 때,")
+  @Nested
+  class Create {
+    @DisplayName("존재하는 좋아요 ID를 주면, 해당 좋아요 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_좋아요ID() {
+      // arrange
+
+      // act
+      Like result = likeService.save(Like.create(savedUser, savedProduct));
+      Optional<Like> savedLike = likeJpaRepository.findById(result.getId());
+      // assert
+      assertLike(result, savedLike.get());
+    }
+
+    @DisplayName("존재하지 않는 좋아요 ID를 주면, 예외가 발생하지 않는다.")
+    @Test
+    void 성공_이미_존재하는_좋아요ID() {
+      // arrange
+      Like result1 = likeService.save(Like.create(savedUser, savedProduct));
+
+      // act
+      Like result2 = likeService.save(Like.create(savedUser, savedProduct));
+
+      // assert
+      assertLike(result1, result2);
+    }
+  }
+
+  @DisplayName("좋아요를 삭제할 때,")
+  @Nested
+  class Delete {
+    @DisplayName("존재하는 좋아요를 삭제한다.")
+    @Test
+    void 성공_존재하는_좋아요ID() {
+      // arrange
+      Like result1 = likeService.save(Like.create(savedUser, savedProduct));
+
+      // act
+      likeService.remove(savedUser.getId(), savedProduct.getId());
+
+      // assert
+      verify(likeJpaRepository, times(1)).deleteByUserIdAndProductId(savedUser.getId(), savedProduct.getId());
+      //assertThrows(NotFoundException.class, () -> service.read(id));
+    }
+
+    @DisplayName("존재하지 않는 좋아요 ID를 삭제하면, 예외가 발생하지 않는다.")
+    @Test
+    void 성공_이미_삭제된_좋아요() {
+      // arrange
+      Like savedLike = likeService.save(Like.create(savedUser, savedProduct));
+
+      // act
+      likeService.remove(savedUser.getId(), savedProduct.getId());
+      Long result1 = likeService.remove(savedUser.getId(), savedProduct.getId());
+
+      // assert
+      verify(likeJpaRepository, times(3)).deleteByUserIdAndProductId(savedUser.getId(), savedProduct.getId());
+
+    }
+  }
+
+  @DisplayName("좋아요 상품목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=0, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_좋아요_상품목록조회() {
+      // arrange
+      Like savedLike = likeService.save(Like.create(savedUser, savedProduct));
+
+      // act
+      Page<Product> productsPage = likeService.getLikedProducts(savedUser.getId(), "latest", 0, 20);
+      List<Product> products = productsPage.getContent();
+
+      // assert
+      assertThat(products).isNotEmpty().hasSize(1);
+    }
+
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeServiceTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeServiceTest.java
new file mode 100644
index 000000000..729d1b8c3
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeServiceTest.java
@@ -0,0 +1,153 @@
+package com.loopers.domain.like;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.user.User;
+import com.loopers.infrastructure.brand.BrandJpaRepository;
+import com.loopers.infrastructure.product.ProductJpaRepository;
+import com.loopers.infrastructure.user.UserJpaRepository;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.domain.Page;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import static com.loopers.domain.like.LikeAssertions.assertLike;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.verify;
+
+
+@SpringBootTest
+class LikeServiceTest {
+
+  private final LikeService likeService;
+
+  @Autowired
+  public LikeServiceTest(LikeService likeService) {
+    this.likeService = likeService;
+  }
+
+  @TestConfiguration
+  static class FakeRepositoryConfig {
+
+    @Bean
+    public LikeRepository likeRepository() {
+      return new FakeLikeRepository();
+    }
+  }
+
+  @MockitoSpyBean
+  private UserJpaRepository userJpaRepository;
+  @MockitoSpyBean
+  private BrandJpaRepository brandJpaRepository;
+  @MockitoSpyBean
+  private ProductJpaRepository productJpaRepository;
+
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  User savedUser;
+  Brand savedBrand;
+  Product savedProduct;
+
+  @BeforeEach
+  void setup() {
+    User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+    savedUser = userJpaRepository.save(user);
+    Brand brand = Brand.create("레이브", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.");
+    savedBrand = brandJpaRepository.save(brand);
+    Product product = Product.create(savedBrand, "Wild Faith Rose Sweatshirt", new BigDecimal(80_000), 10);
+    savedProduct = productJpaRepository.save(product);
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("좋아요를 조회할 때,")
+  @Nested
+  class Create {
+    @DisplayName("존재하는 좋아요 ID를 주면, 해당 좋아요 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_좋아요ID() {
+      // arrange
+
+      // act
+      Like result = likeService.save(Like.create(savedUser, savedProduct));
+
+      // assert
+      assertThat(result).isNotNull();
+      assertThat(result.getUser()).isNotNull();
+    }
+
+    @DisplayName("존재하지 않는 좋아요 ID를 주면, 예외가 발생하지 않는다.")
+    @Test
+    void 성공_이미_존재하는_좋아요ID() {
+      // arrange
+      Like result1 = likeService.save(Like.create(savedUser, savedProduct));
+
+      // act
+      Like result2 = likeService.save(Like.create(savedUser, savedProduct));
+
+      // assert
+      assertLike(result1, result2);
+    }
+  }
+
+  @DisplayName("좋아요를 삭제할 때,")
+  @Nested
+  class Delete {
+    @DisplayName("존재하는 좋아요를 삭제한다.")
+    @Test
+    void 성공_존재하는_좋아요ID() {
+      // arrange
+      Like result1 = likeService.save(Like.create(savedUser, savedProduct));
+
+      // act
+      likeService.remove(savedUser.getId(), savedProduct.getId());
+      //assert
+
+    }
+
+    @DisplayName("존재하지 않는 좋아요 ID를 삭제하면, 예외가 발생하지 않는다.")
+    @Test
+    void 성공_이미_삭제된_좋아요() {
+      // arrange
+      Like result1 = likeService.save(Like.create(savedUser, savedProduct));
+
+      // act
+      likeService.remove(savedUser.getId(), savedProduct.getId());
+      likeService.remove(savedUser.getId(), savedProduct.getId());
+
+      // assert
+    }
+  }
+
+  @DisplayName("좋아요 상품목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=0, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_좋아요_상품목록조회() {
+      // arrange
+      Like savedLike = likeService.save(Like.create(savedUser, savedProduct));
+
+      // act
+      Page<Product> productsPage = likeService.getLikedProducts(savedUser.getId(), "latest", 0, 20);
+      List<Product> products = productsPage.getContent();
+
+      // assert
+      assertThat(products).isNotEmpty().hasSize(1);
+    }
+
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderAssertions.java b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderAssertions.java
new file mode 100644
index 000000000..65a876a15
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderAssertions.java
@@ -0,0 +1,15 @@
+package com.loopers.domain.order;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class OrderAssertions {
+  public static void assertOrder(Order actual, Order expected) {
+    assertThat(actual).isNotNull();
+    assertThat(expected).isNotNull();
+    assertThat(actual.getId()).isEqualTo(expected.getId());
+    assertThat(actual.getRefUserId()).isEqualTo(expected.getRefUserId());
+    assertThat(actual.getStatus()).isEqualTo(expected.getStatus());
+    assertThat(actual.getTotalPrice()).isEqualByComparingTo(expected.getTotalPrice());
+    assertThat(actual.getOrderAt()).isEqualTo(expected.getOrderAt());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderModelTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderModelTest.java
new file mode 100644
index 000000000..82d2f1d60
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderModelTest.java
@@ -0,0 +1,99 @@
+package com.loopers.domain.order;
+
+import com.loopers.support.error.CoreException;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertThrows;
+
+class OrderModelTest {
+  Order order;
+  List<OrderItem> orderItems;
+
+  @DisplayName("주문 모델을 생성할 때, ")
+  @Nested
+  class Create_Order {
+    @DisplayName("사용자ID, 상태, 지불금액,총금액, 주문일자가 모두 주어지면, 정상적으로 생성된다.")
+    @Test
+    void 성공_Order_객체생성() {
+      orderItems = new ArrayList<>();
+      order = Order.create(1, OrderStatus.PENDING, new BigDecimal(10_000), orderItems);
+      assertThat(order.getRefUserId()).isEqualTo(1);
+      assertThat(order.getStatus()).isEqualTo(OrderStatus.PENDING);
+
+    }
+  }
+
+  @DisplayName("주문 모델을 생성할 때, 검증")
+  @Nested
+  class Valid_Order {
+
+    @Test
+    void 실패_총가격_음수오류() {
+      assertThrows(CoreException.class, () -> {
+        order = Order.create(1, OrderStatus.PENDING, new BigDecimal(-10_000), orderItems);
+      });
+    }
+  }
+
+  @DisplayName("주문 확인후, 상품준비중 상태로 변경")
+  @Nested
+  class Valid_상품준비중 {
+    @Test
+    void 실패_주문확인_결재전오류() {
+      order = Order.create(1, OrderStatus.PENDING, new BigDecimal(10_000), orderItems);
+      assertThatThrownBy(() -> {
+        order.preparing();
+      }).isInstanceOf(CoreException.class).hasMessageContaining("결재대기중");
+    }
+
+    @Test
+    void 실패_주문확인_상품준비중오류() {
+      order = Order.create(1, OrderStatus.PREPARING, new BigDecimal(10_000), orderItems);
+      assertThatThrownBy(() -> {
+        order.preparing();
+      }).isInstanceOf(CoreException.class).hasMessageContaining("이미 준비중");
+    }
+
+    @Test
+    void 실패_주문확인_상품준비완료오류() {
+      order = Order.create(1, OrderStatus.SHIPPED, new BigDecimal(10_000), orderItems);
+      assertThatThrownBy(() -> {
+        order.preparing();
+      }).isInstanceOf(CoreException.class).hasMessageContaining("상품준비 완료");
+    }
+
+    @Test
+    void 성공_상품준비중() {
+      order = Order.create(1, OrderStatus.PAID, new BigDecimal(10_000), orderItems);
+      order.preparing();
+      assertThat(order.getStatus()).isEqualTo(OrderStatus.PREPARING);
+    }
+  }
+
+  @DisplayName("상품 모델을 생성후, 주문취소")
+  @Nested
+  class Valid_주문취소 {
+    @Test
+    void 실패_주문취소_이미취소된주문오류() {
+      order = Order.create(1, OrderStatus.CANCELLED, new BigDecimal(10_000), orderItems);
+      assertThrows(CoreException.class, () -> {
+        order.preparing();
+      });
+    }
+
+    @Test
+    void 성공_주문취소() {
+      order = Order.create(1, OrderStatus.PENDING, new BigDecimal(10_000), orderItems);
+      order.cancel();
+      assertThat(order.getStatus()).isEqualTo(OrderStatus.CANCELLED);
+    }
+  }
+}
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..a3e21b571
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderServiceIntegrationTest.java
@@ -0,0 +1,120 @@
+package com.loopers.domain.order;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductService;
+import com.loopers.infrastructure.brand.BrandJpaRepository;
+import com.loopers.infrastructure.product.ProductJpaRepository;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import static com.loopers.domain.brand.BrandAssertions.assertBrand;
+import static com.loopers.domain.product.ProductAssertions.assertProduct;
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+@SpringBootTest
+@Transactional
+class OrderServiceIntegrationTest {
+  @Autowired
+  private ProductService productService;
+
+  @MockitoSpyBean
+  private BrandJpaRepository brandJpaRepository;
+  @MockitoSpyBean
+  private ProductJpaRepository productJpaRepository;
+
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  List<Brand> savedBrands;
+  List<Product> savedProducts;
+
+  @BeforeEach
+  void setup() {
+    List<Brand> brandList = List.of(Brand.create("레이브", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.")
+        , Brand.create("마뗑킴", "마뗑킴은 트렌디하면서도 편안함을 더한 디자인을 선보입니다. 일상에서 조화롭게 적용할 수 있는 자연스러운 패션 문화를 지향합니다."));
+    savedBrands = brandList.stream().map((brand) -> brandJpaRepository.save(brand)).toList();
+
+    List<Product> productList = List.of(Product.create(savedBrands.get(0), "Wild Faith Rose Sweatshirt", new BigDecimal(80_000), 10)
+        , Product.create(savedBrands.get(0), "Flower Pattern Fleece Jacket", new BigDecimal(178_000), 20)
+        , Product.create(savedBrands.get(1), "Flower Pattern Fleece Jacket", new BigDecimal(178_000), 20)
+    );
+    savedProducts = productList.stream().map((product) -> productJpaRepository.save(product)).toList();
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("상품목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=0, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_상품목록조회() {
+      // arrange
+
+      // act
+      Page<Product> productsPage = productService.getProducts(null, "latest", 0, 20);
+      List<Product> products = productsPage.getContent();
+      // assert
+      assertThat(products).isNotEmpty().hasSize(3);
+    }
+
+    @DisplayName("브랜드ID 검색조건 포함시, 해당 브랜드의 상품 목록이 조회된다.")
+    @Test
+    void 성공_상품목록조회_브랜드ID() {
+      // arrange
+
+      // act
+      Page<Product> productsPage = productService.getProducts(savedProducts.get(0).getId(), null, 0, 20);
+      List<Product> productList = productsPage.getContent();
+
+      // assert
+      assertThat(productList).isNotEmpty().hasSize(2);
+
+      assertProduct(productList.get(0), savedProducts.get(1));
+      assertProduct(productList.get(1), savedProducts.get(0));
+    }
+  }
+
+  @DisplayName("상품을 조회할 때,")
+  @Nested
+  class Get {
+    @DisplayName("존재하는 상품 ID를 주면, 해당 상품 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_상품ID() {
+      // arrange
+      // act
+      Product result = productService.getProduct(savedProducts.get(0).getId());
+
+      // assert
+      assertProduct(result, savedProducts.get(0));
+      assertBrand(result.getBrand(), savedBrands.get(0));
+    }
+
+    @DisplayName("존재하지 않는 상품 ID를 주면, null이 반환된다.")
+    @Test
+    void 실패_존재하지_않는_상품ID() {
+      // arrange
+
+      // act
+      Product result = productService.getProduct((long) 1000);
+
+      // assert
+      assertThat(result).isNull();
+    }
+  }
+
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/point/PointServiceIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/point/PointServiceIntegrationTest.java
index ac000465c..c86ebaea9 100644
--- a/apps/commerce-api/src/test/java/com/loopers/domain/point/PointServiceIntegrationTest.java
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/point/PointServiceIntegrationTest.java
@@ -1,6 +1,6 @@
 package com.loopers.domain.point;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
 import com.loopers.infrastructure.point.PointJpaRepository;
 import com.loopers.infrastructure.user.UserJpaRepository;
 import com.loopers.support.error.CoreException;
@@ -49,11 +49,11 @@ class Get {
     void 성공_존재하는_유저ID() {
       // arrange
       BigDecimal JOIN_POINT = BigDecimal.TEN;
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userJpaRepository.save(userModel);
+      User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      User saved = userJpaRepository.save(user);
 
       // act
-      BigDecimal pointAmt = pointService.getAmount(userModel.getUserId());
+      BigDecimal pointAmt = pointService.getAmount(saved.getId());
 
       // assert(회원가입시, 기본포인트 10)
       assertAll(
@@ -66,10 +66,10 @@ class Get {
     @Test
     void 실패_존재하지않는_유저ID() {
       // arrange (등록된 회원 없음)
-      String userId = "userId";
+      Long id = 5L;
 
       // act
-      BigDecimal pointAmt = pointService.getAmount(userId);
+      BigDecimal pointAmt = pointService.getAmount(id);
 
       // assert
       assertThat(pointAmt).isNull();
@@ -84,11 +84,11 @@ class Charge {
     @Test
     void 실패_존재하지않는_유저ID() {
       // arrange (등록된 회원 없음)
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
 
       // act, assert
       assertThatThrownBy(() -> {
-        pointService.charge(userModel, BigDecimal.TEN);
+        pointService.charge(user, BigDecimal.TEN);
       }).isInstanceOf(CoreException.class).hasMessageContaining("현재 포인트 정보를 찾을수 없습니다.");
 
     }
@@ -98,11 +98,11 @@ class Charge {
     void 성공_존재하는_유저ID() {
       // arrange
       BigDecimal JOIN_POINT = BigDecimal.TEN;
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userJpaRepository.save(userModel);
-      Optional<UserModel> savedUserModel = userJpaRepository.findByUserId(userModel.getUserId());
+      User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      User savedUser = userJpaRepository.save(user);
+
       // act
-      BigDecimal pointAmt = pointService.charge(savedUserModel.get(), BigDecimal.TEN);
+      BigDecimal pointAmt = pointService.charge(savedUser, BigDecimal.TEN);
 
       // assert(회원가입시, 기본포인트 10)
       assertAll(
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/point/PointModelTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/point/PointTest.java
similarity index 60%
rename from apps/commerce-api/src/test/java/com/loopers/domain/point/PointModelTest.java
rename to apps/commerce-api/src/test/java/com/loopers/domain/point/PointTest.java
index 02bcd0387..29d6b647a 100644
--- a/apps/commerce-api/src/test/java/com/loopers/domain/point/PointModelTest.java
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/point/PointTest.java
@@ -1,6 +1,6 @@
 package com.loopers.domain.point;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
 import com.loopers.support.error.CoreException;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
@@ -12,13 +12,13 @@
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-class PointModelTest {
-  UserModel userModel;
-  PointModel pointModel;
+class PointTest {
+  User user;
+  Point point;
 
   @BeforeEach
   void setup() {
-    userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
+    user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
   }
 
   @DisplayName("포인트 충전")
@@ -28,24 +28,24 @@ class Charge {
     @Test
     void 실패_포인트충전_0() {
       // arrange
-      pointModel = PointModel.create(userModel, BigDecimal.ZERO);
+      point = Point.create(user, BigDecimal.ZERO);
 
       // act, assert
       assertThatThrownBy(() -> {
-        pointModel.charge(BigDecimal.ZERO);
+        point.charge(BigDecimal.ZERO);
       }).isInstanceOf(CoreException.class).hasMessageContaining("충전 금액은 0보다 커야 합니다.");
     }
 
     @Test
     void 성공_포인트충전() {
       // arrange
-      pointModel = PointModel.create(userModel, new BigDecimal(20));
+      point = Point.create(user, new BigDecimal(20));
 
       // act
-      pointModel.charge(new BigDecimal(5));
+      point.charge(new BigDecimal(5));
 
       // assert
-      assertThat(pointModel.getAmount()).isEqualTo(new BigDecimal(25));
+      assertThat(point.getAmount()).isEqualTo(new BigDecimal(25));
     }
   }
 
@@ -55,24 +55,24 @@ class Use {
     @Test
     void 실패_포인트사용() {
       // arrange
-      pointModel = PointModel.create(userModel, BigDecimal.ZERO);
+      point = Point.create(user, BigDecimal.ZERO);
 
       // act, assert
       assertThatThrownBy(() -> {
-        pointModel.use(BigDecimal.TEN);
-      }).isInstanceOf(CoreException.class).hasMessageContaining("잔액이 부족합니다.");
+        point.use(BigDecimal.TEN);
+      }).isInstanceOf(CoreException.class).hasMessageContaining("포인트가 부족합니다.");
     }
 
     @Test
     void 성공_포인트사용() {
       // arrange
-      pointModel = PointModel.create(userModel, new BigDecimal(20));
+      point = Point.create(user, new BigDecimal(20));
 
       // act
-      pointModel.use(new BigDecimal(5));
+      point.use(new BigDecimal(5));
 
       // assert
-      assertThat(pointModel.getAmount()).isEqualTo(new BigDecimal(15));
+      assertThat(point.getAmount()).isEqualTo(new BigDecimal(15));
     }
   }
 
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductAssertions.java b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductAssertions.java
new file mode 100644
index 000000000..2c437632d
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductAssertions.java
@@ -0,0 +1,18 @@
+package com.loopers.domain.product;
+
+import com.loopers.domain.brand.Brand;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ProductAssertions {
+  public static void assertProduct(Product actual, Product expected) {
+    assertThat(actual).isNotNull();
+    assertThat(expected).isNotNull();
+    assertThat(actual.getId()).isEqualTo(expected.getId());
+    assertThat(actual.getName()).isEqualTo(expected.getName());
+    assertThat(actual.getPrice()).isEqualByComparingTo(expected.getPrice());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductModelTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductModelTest.java
new file mode 100644
index 000000000..cf44ba293
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductModelTest.java
@@ -0,0 +1,87 @@
+package com.loopers.domain.product;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.support.error.CoreException;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+import java.math.BigDecimal;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertThrows;
+
+class ProductModelTest {
+  Brand brand = Brand.create("레이브", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.");
+  Product product;
+  String validMsg = "";
+
+  @DisplayName("상품 모델을 생성할 때, ")
+  @Nested
+  class Create_Product {
+    @DisplayName("브랜드모델, 상품명, 가격, 재고, 예약재고가 모두 주어지면, 정상적으로 생성된다.")
+    @Test
+    void 성공_Product_객체생성() {
+      product = Product.create(brand, "Wild Faith Rose Sweatshirt", new BigDecimal(80_000), 10);
+      assertThat(product).isNotNull();
+      assertThat(product.getName()).isEqualTo("Wild Faith Rose Sweatshirt");
+      assertThat(product.getPrice()).isEqualTo(new BigDecimal(80_000));
+      assertThat(product.getStock()).isEqualTo(10);
+    }
+  }
+
+  @DisplayName("상품 모델을 생성할 때, 검증")
+  @Nested
+  class Valid_Product {
+    @BeforeEach
+    void setup() {
+      validMsg = "형식이 유효하지 않습니다.";
+    }
+
+    @Test
+    void 실패_가격_음수오류() {
+      assertThrows(CoreException.class, () -> {
+        product = Product.create(brand, "Wild Faith Rose Sweatshirt", new BigDecimal(-1000), 0);
+      });
+    }
+
+    @Test
+    void 실패_재고_음수오류() {
+      assertThrows(CoreException.class, () -> {
+        product = Product.create(brand, "Wild Faith Rose Sweatshirt", new BigDecimal(80_000), -1);
+      });
+    }
+
+  }
+
+  @DisplayName("상품 모델을 생성후, 재고 예약")
+  @Nested
+  class Valid_재고차감 {
+    @BeforeEach
+    void setup() {
+      product = Product.create(brand, "Wild Faith Rose Sweatshirt", new BigDecimal(1000), 10);
+    }
+
+    @Test
+    void 실패_예약재고0_차감오류() {
+      assertThrows(CoreException.class, () -> {
+        product.deductStock(0);
+      });
+    }
+
+    @Test
+    void 실패_예약재고20_차감오류() {
+      assertThrows(CoreException.class, () -> {
+        product.deductStock(20);
+      });
+    }
+
+    @Test
+    void 성공_재고예약() {
+      product.deductStock(2);
+      assertThat(product.getStock()).isEqualTo(8);
+    }
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductServiceIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductServiceIntegrationTest.java
new file mode 100644
index 000000000..b1693262e
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductServiceIntegrationTest.java
@@ -0,0 +1,118 @@
+package com.loopers.domain.product;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.infrastructure.brand.BrandJpaRepository;
+import com.loopers.infrastructure.product.ProductJpaRepository;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Page;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import static com.loopers.domain.brand.BrandAssertions.assertBrand;
+import static com.loopers.domain.product.ProductAssertions.assertProduct;
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+@SpringBootTest
+@Transactional
+class ProductServiceIntegrationTest {
+  @Autowired
+  private ProductService productService;
+
+  @MockitoSpyBean
+  private BrandJpaRepository brandJpaRepository;
+  @MockitoSpyBean
+  private ProductJpaRepository productJpaRepository;
+
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  List<Brand> savedBrands;
+  List<Product> savedProducts;
+
+  @BeforeEach
+  void setup() {
+    List<Brand> brandList = List.of(Brand.create("레이브", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.")
+        , Brand.create("마뗑킴", "마뗑킴은 트렌디하면서도 편안함을 더한 디자인을 선보입니다. 일상에서 조화롭게 적용할 수 있는 자연스러운 패션 문화를 지향합니다."));
+    savedBrands = brandList.stream().map((brand) -> brandJpaRepository.save(brand)).toList();
+
+    List<Product> productList = List.of(Product.create(savedBrands.get(0), "Wild Faith Rose Sweatshirt", new BigDecimal(80_000), 10)
+        , Product.create(savedBrands.get(0), "Flower Pattern Fleece Jacket", new BigDecimal(178_000), 20)
+        , Product.create(savedBrands.get(1), "Flower Pattern Fleece Jacket", new BigDecimal(178_000), 20)
+    );
+    savedProducts = productList.stream().map((product) -> productJpaRepository.save(product)).toList();
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("상품목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=0, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_상품목록조회() {
+      // arrange
+
+      // act
+      Page<Product> productsPage = productService.getProducts(null, "latest", 0, 20);
+      List<Product> products = productsPage.getContent();
+      // assert
+      assertThat(products).isNotEmpty().hasSize(3);
+    }
+
+    @DisplayName("브랜드ID 검색조건 포함시, 해당 브랜드의 상품 목록이 조회된다.")
+    @Test
+    void 성공_상품목록조회_브랜드ID() {
+      // arrange
+
+      // act
+      Page<Product> productsPage = productService.getProducts(savedProducts.get(0).getId(), null, 0, 20);
+      List<Product> productList = productsPage.getContent();
+
+      // assert
+      assertThat(productList).isNotEmpty().hasSize(2);
+
+      assertProduct(productList.get(0), savedProducts.get(1));
+      assertProduct(productList.get(1), savedProducts.get(0));
+    }
+  }
+
+  @DisplayName("상품을 조회할 때,")
+  @Nested
+  class Get {
+    @DisplayName("존재하는 상품 ID를 주면, 해당 상품 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_상품ID() {
+      // arrange
+      // act
+      Product result = productService.getProduct(savedProducts.get(0).getId());
+
+      // assert
+      assertProduct(result, savedProducts.get(0));
+      assertBrand(result.getBrand(), savedBrands.get(0));
+    }
+
+    @DisplayName("존재하지 않는 상품 ID를 주면, null이 반환된다.")
+    @Test
+    void 실패_존재하지_않는_상품ID() {
+      // arrange
+
+      // act
+      Product result = productService.getProduct((long) 1000);
+
+      // assert
+      assertThat(result).isNull();
+    }
+  }
+
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/user/UserServiceIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserServiceIntegrationTest.java
index a3a300d5c..7cc9e69a0 100644
--- a/apps/commerce-api/src/test/java/com/loopers/domain/user/UserServiceIntegrationTest.java
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserServiceIntegrationTest.java
@@ -39,15 +39,15 @@ class Join {
     @Test
     void 성공_회원가입() {
       // arrange
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
 
       // act
-      userService.join(userModel);
+      userService.join(user);
 
       // assert
       assertAll(
-          () -> verify(userJpaRepository, times(1)).save(userModel),
-          () -> assertThrows(CoreException.class, () -> userService.join(userModel))
+          () -> verify(userJpaRepository, times(1)).save(user),
+          () -> assertThrows(CoreException.class, () -> userService.join(user))
       );
     }
 
@@ -55,15 +55,15 @@ class Join {
     @Test
     void 실패_이미_가입된ID() {
       // arrange
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userService.join(userModel);
+      User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      userService.join(user);
 
       // act
-      verify(userJpaRepository, times(1)).save(userModel);
+      verify(userJpaRepository, times(1)).save(user);
       assertThatThrownBy(() -> {
-        userService.join(userModel);
+        userService.join(user);
       }).isInstanceOf(CoreException.class).hasMessageContaining("이미 가입된 ID 입니다.");
-      verify(userJpaRepository, times(1)).save(userModel);
+      verify(userJpaRepository, times(1)).save(user);
     }
   }
 
@@ -74,19 +74,19 @@ class Get {
     @Test
     void 성공_존재하는_유저ID() {
       // arrange
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userService.join(userModel);
+      User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      userService.join(user);
 
       // act
-      UserModel result = userService.getUser(userModel.getUserId());
+      User result = userService.getUser(user.getUserId());
 
       // assert
       assertAll(
           () -> assertThat(result).isNotNull(),
-          () -> assertThat(result.getUserId()).isEqualTo(userModel.getUserId()),
-          () -> assertThat(result.getEmail()).isEqualTo(userModel.getEmail()),
-          () -> assertThat(result.getBirthday()).isEqualTo(userModel.getBirthday()),
-          () -> assertThat(result.getGender()).isEqualTo(userModel.getGender())
+          () -> assertThat(result.getUserId()).isEqualTo(user.getUserId()),
+          () -> assertThat(result.getEmail()).isEqualTo(user.getEmail()),
+          () -> assertThat(result.getBirthday()).isEqualTo(user.getBirthday()),
+          () -> assertThat(result.getGender()).isEqualTo(user.getGender())
       );
     }
 
@@ -94,10 +94,10 @@ class Get {
     @Test
     void 실패_존재하지_않는_유저ID() {
       // arrange
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
 
       // act
-      UserModel result = userService.getUser(userModel.getUserId());
+      User result = userService.getUser(user.getUserId());
 
       // assert
       assertThat(result).isNull();
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/user/UserModelTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserTest.java
similarity index 72%
rename from apps/commerce-api/src/test/java/com/loopers/domain/user/UserModelTest.java
rename to apps/commerce-api/src/test/java/com/loopers/domain/user/UserTest.java
index 159dbdde4..91eb7b75f 100644
--- a/apps/commerce-api/src/test/java/com/loopers/domain/user/UserModelTest.java
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserTest.java
@@ -9,8 +9,8 @@
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
-class UserModelTest {
-  UserModel userModel;
+class UserTest {
+  User user;
   String validMsg = "";
 
   @DisplayName("회원가입-단위테스트1")
@@ -24,28 +24,28 @@ void setup() {
     @Test
     void 실패_ID_숫자만() {
       assertThatThrownBy(() -> {
-        userModel = UserModel.create("12345", "user1@test.XXX", "1999-01-01", "F");
+        user = User.create("12345", "user1@test.XXX", "1999-01-01", "F");
       }).isInstanceOf(CoreException.class).hasMessageContaining(validMsg);
     }
 
     @Test
     void 실패_ID_문자만() {
       assertThatThrownBy(() -> {
-        userModel = UserModel.create("hello", "user1@test.XXX", "1999-01-01", "F");
+        user = User.create("hello", "user1@test.XXX", "1999-01-01", "F");
       }).isInstanceOf(CoreException.class).hasMessageContaining(validMsg);
     }
 
     @Test
     void 실패_ID_특수문자() {
       assertThatThrownBy(() -> {
-        userModel = UserModel.create("12345!", "user1@test.XXX", "1999-01-01", "F");
+        user = User.create("12345!", "user1@test.XXX", "1999-01-01", "F");
       }).isInstanceOf(CoreException.class).hasMessageContaining(validMsg);
     }
 
     @Test
     void 실패_ID_10자이상오류() {
       assertThatThrownBy(() -> {
-        userModel = UserModel.create("12345678910", "user1@test.XXX", "1999-01-01", "F");
+        user = User.create("12345678910", "user1@test.XXX", "1999-01-01", "F");
       }).isInstanceOf(CoreException.class).hasMessageContaining(validMsg);
     }
   }
@@ -61,14 +61,14 @@ void setup() {
     @Test
     void 실패_이메일_기호없음() {
       assertThatThrownBy(() -> {
-        userModel = UserModel.create("user1", "user1test.XXX", "1999-01-01", "F");
+        user = User.create("user1", "user1test.XXX", "1999-01-01", "F");
       }).isInstanceOf(CoreException.class).hasMessageContaining(validMsg);
     }
 
     @Test
     void 실패_이메일_한글포함() {
       assertThatThrownBy(() -> {
-        userModel = UserModel.create("user1", "ㄱuser1@test.XXX", "1999-01-01", "F");
+        user = User.create("user1", "ㄱuser1@test.XXX", "1999-01-01", "F");
       }).isInstanceOf(CoreException.class).hasMessageContaining(validMsg);
     }
   }
@@ -85,22 +85,22 @@ void setup() {
     @Test
     void 실패_생년월일_형식오류() {
       assertThatThrownBy(() -> {
-        userModel = UserModel.create("user1", "user1@test.XXX", "19990101", "F");
+        user = User.create("user1", "user1@test.XXX", "19990101", "F");
       }).isInstanceOf(CoreException.class).hasMessageContaining(validMsg);
     }
 
     @Test
     void 실패_생년월일_날짜오류() {
       assertThatThrownBy(() -> {
-        userModel = UserModel.create("user1", "user1@test.XXX", "1999-13-01", "F");
+        user = User.create("user1", "user1@test.XXX", "1999-13-01", "F");
       }).isInstanceOf(CoreException.class).hasMessageContaining(validMsg);
     }
   }
 
   @Test
   void 성공_User_객체생성() {
-    userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-    assertThat(userModel).isNotNull();
-    assertThat(userModel.getUserId()).isEqualTo("user1");
+    user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+    assertThat(user).isNotNull();
+    assertThat(user.getUserId()).isEqualTo("user1");
   }
 }
diff --git a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/PointV1ApiE2ETest.java b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/PointV1ApiE2ETest.java
index 4914412f7..d1730a77f 100644
--- a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/PointV1ApiE2ETest.java
+++ b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/PointV1ApiE2ETest.java
@@ -1,6 +1,7 @@
 package com.loopers.interfaces.api;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserService;
 import com.loopers.infrastructure.user.UserJpaRepository;
 import com.loopers.utils.DatabaseCleanUp;
 import org.junit.jupiter.api.AfterEach;
@@ -22,17 +23,17 @@
 public class PointV1ApiE2ETest {
 
   private final TestRestTemplate testRestTemplate;
-  private final UserJpaRepository userJpaRepository;
+  private final UserService userService;
   private final DatabaseCleanUp databaseCleanUp;
 
   @Autowired
   public PointV1ApiE2ETest(
       TestRestTemplate testRestTemplate,
-      UserJpaRepository userJpaRepository,
+      UserService userService,
       DatabaseCleanUp databaseCleanUp
   ) {
     this.testRestTemplate = testRestTemplate;
-    this.userJpaRepository = userJpaRepository;
+    this.userService = userService;
     this.databaseCleanUp = databaseCleanUp;
   }
 
@@ -50,12 +51,12 @@ class Get {
       //given
       BigDecimal JOIN_POINT = BigDecimal.TEN;
 
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userJpaRepository.save(userModel);
+      User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      User savedUser = userService.join(user);
 
       //when
       HttpHeaders headers = new HttpHeaders();
-      headers.set("X-USER-ID", userModel.getUserId());
+      headers.set("X-USER-ID", savedUser.getId().toString());
 
       String url = "/api/v1/user/point";
       ParameterizedTypeReference<ApiResponse<BigDecimal>> resType = new ParameterizedTypeReference<>() {
@@ -93,11 +94,11 @@ class Charge {
       //given
       BigDecimal CHARGE_POINT = BigDecimal.TEN;
 
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userJpaRepository.save(userModel);
+      User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      User savedUser = userService.join(user);
 
       HttpHeaders headers = new HttpHeaders();
-      headers.set("X-USER-ID", userModel.getUserId());
+      headers.set("X-USER-ID", savedUser.getId().toString());
 
       //when
       String url = "/api/v1/user/point/charge";
@@ -116,7 +117,7 @@ class Charge {
     void 실패_ID없음_400() {
       //given
       HttpHeaders headers = new HttpHeaders();
-      headers.set("X-USER-ID", "user1");
+      headers.set("X-USER-ID", "2");
 
       //when
       String url = "/api/v1/user/point/charge";
diff --git a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/UserV1ApiE2ETest.java b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/UserV1ApiE2ETest.java
index 6c5952457..21fcb759e 100644
--- a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/UserV1ApiE2ETest.java
+++ b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/UserV1ApiE2ETest.java
@@ -1,9 +1,8 @@
 package com.loopers.interfaces.api;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
 import com.loopers.domain.user.UserService;
 import com.loopers.interfaces.api.user.UserCreateV1Dto;
-import com.loopers.support.error.CoreException;
 import com.loopers.utils.DatabaseCleanUp;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.DisplayName;
@@ -93,11 +92,11 @@ class Get {
     @Test
     void 성공_정보조회() {
       //given
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userService.join(userModel);
+      User user = User.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      userService.join(user);
 
       //when
-      String url = ENDPOINT_GET.apply(userModel.getUserId());
+      String url = ENDPOINT_GET.apply(user.getUserId());
       ParameterizedTypeReference<ApiResponse<UserCreateV1Dto.UserResponse>> resType = new ParameterizedTypeReference<>() {
       };
       ResponseEntity<ApiResponse<UserCreateV1Dto.UserResponse>> res = testRestTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(null), resType);
@@ -105,7 +104,7 @@ class Get {
       //then
       assertThat(res.getStatusCode()).isEqualTo(HttpStatus.OK);
       assertThat(res.getBody().data().userId()).isNotNull();
-      assertThat(res.getBody().data().userId()).isEqualTo(userModel.getUserId());
+      assertThat(res.getBody().data().userId()).isEqualTo(user.getUserId());
     }
 
     @DisplayName("E2E테스트2")
