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..57fcb4d5b
--- /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..211f684a3
--- /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/LikeFacade.java b/apps/commerce-api/src/main/java/com/loopers/application/like/LikeFacade.java
new file mode 100644
index 000000000..72b3f3e97
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/like/LikeFacade.java
@@ -0,0 +1,28 @@
+package com.loopers.application.like;
+
+import com.loopers.domain.like.LikeService;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.user.UserService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+@RequiredArgsConstructor
+@Component
+public class LikeFacade {
+  private final UserService userService;
+  private final ProductService productService;
+  private final LikeService likeService;
+
+  public LikeInfo like(Long userId, Long productId) {
+    likeService.save(userId, productId);
+    long likeCnt = likeService.getLikeCount(productId);
+    return LikeInfo.from(likeCnt, true);
+  }
+
+  public LikeInfo unlike(Long userId, Long productId) {
+    likeService.remove(userId, productId);
+    long likeCnt = likeService.getLikeCount(productId);
+    return LikeInfo.from(likeCnt, false);
+  }
+
+}
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..ceea3a4a2
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/order/CreateOrderCommand.java
@@ -0,0 +1,20 @@
+package com.loopers.application.order;
+
+import com.loopers.interfaces.api.order.OrderCreateV1Dto;
+
+import java.util.List;
+
+public record CreateOrderCommand(Long userId, List<OrderItemCommand> orderItemCommands) {
+  public record OrderItemCommand(Long productId, Long quantity) {
+
+  }
+
+  public static CreateOrderCommand from(Long userId, OrderCreateV1Dto.OrderRequest request) {
+    return new CreateOrderCommand(
+        userId,
+        request.items().stream()
+            .map(item -> new OrderItemCommand(item.productId(), item.quantity()))
+            .toList()
+    );
+  }
+}
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..fc1afb1e3
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/order/OrderFacade.java
@@ -0,0 +1,81 @@
+package com.loopers.application.order;
+
+import com.loopers.domain.order.*;
+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 com.loopers.domain.product.ProductService;
+import com.loopers.domain.stock.StockService;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserRepository;
+import com.loopers.domain.user.UserService;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.exception.ContextedRuntimeException;
+import org.springframework.data.domain.Page;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Optional;
+
+@RequiredArgsConstructor
+@Component
+public class OrderFacade {
+  private final UserService userService;
+  private final UserRepository userRepository;
+  private final ProductService productService;
+  private final StockService stockService;
+  private final OrderService orderService;
+  private final PointService pointService;
+  private final PointRepository pointRepository;
+
+  @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) {
+
+    List<CreateOrderCommand.OrderItemCommand> orderItemCommands = command.orderItemCommands();
+    Long userId = command.userId();
+    List<Long> productIds = orderItemCommands.stream().map(CreateOrderCommand.OrderItemCommand::productId).toList();
+    List<Product> products = productService.getExistingProducts(productIds);
+
+    // 2. Command -> Domain 객체(OrderItem) 변환
+    for (CreateOrderCommand.OrderItemCommand item : orderItemCommands) {
+      stockService.deduct(item.productId(), item.quantity()); // 재고 차감
+    }
+    // 3. 주문 생성
+    List<OrderItem> orderItems = orderItemCommands.stream()
+        .map(item ->
+        {
+          Long productId = item.productId();
+          Product product = products.stream().filter(p -> p.getId().equals(productId)).findFirst()
+              .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, ""));
+          return OrderItem.create(productId, item.quantity(), product.getPrice());
+        })
+        .toList();
+    Order order = Order.create(userId, orderItems);
+    Order savedOrder = orderService.save(order);
+    savedOrder.paid();
+
+    // 4. 포인트 차감(비관적락)
+    pointService.use(userId, order.getTotalPrice().getAmount());
+    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..883d3ec00
--- /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().getAmount(),
+        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..841e6e88a
--- /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().getAmount(),
+        item.getTotalPrice().getAmount()
+    )).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..ed1f011e0 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,14 +1,14 @@
 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(),
+        model.getUser().getLoginId(),
         model.getAmount()
     );
   }
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..a7f3ae445
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductDetailInfo.java
@@ -0,0 +1,25 @@
+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.domain.stock.Stock;
+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, Stock stock, LikeInfo likeInfo) {
+    if (model == null) throw new CoreException(ErrorType.NOT_FOUND, "상품정보를 찾을수 없습니다.");
+    return new ProductDetailInfo(
+        model.getId(),
+        model.getName(),
+        model.getPrice().getAmount(),
+        stock.getAvailable(),
+        BrandInfo.from(model.getBrand()),
+        likeInfo
+    );
+  }
+}
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..b3d32032a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductFacade.java
@@ -0,0 +1,79 @@
+package com.loopers.application.product;
+
+import com.loopers.application.like.LikeInfo;
+import com.loopers.domain.like.LikeService;
+import com.loopers.domain.like.ProductIdAndLikeCount;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.stock.Stock;
+import com.loopers.domain.stock.StockService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@RequiredArgsConstructor
+@Component
+public class ProductFacade {
+  private final ProductService productService;
+  private final StockService stockService;
+  private final LikeService likeService;
+
+  @Transactional(readOnly = true)
+  public Page<ProductWithLikeCount> getProductList(Long brandId,
+                                      String sortType,
+                                      int page,
+                                      int size) {
+    Page<Product> productPage = productService.getProducts(brandId, sortType, page, size);
+    List<Product> products = productPage.getContent();
+
+    List<Long> productIds = products.stream()
+        .map(Product::getId)
+        .toList();
+
+    List<ProductIdAndLikeCount> likeCountList = likeService.getLikeCount(productIds);
+
+    // 총 좋아요 정보
+    Map<Long, Long> likeCountMap = likeCountList.stream()
+        .collect(Collectors.toMap(
+            ProductIdAndLikeCount::getProductId,
+            ProductIdAndLikeCount::getLikeCount
+        ));
+
+    //
+
+    //
+    List<ProductWithLikeCount> dtoList = products.stream()
+        .map(product -> {
+          Long productId = product.getId();
+          Long totalLikeCount = likeCountMap.getOrDefault(productId, 0L);
+
+          return new ProductWithLikeCount(
+              productId,
+              product.getName(),
+              product.getPrice().getAmount(),
+              totalLikeCount
+          );
+        })
+        .toList();
+
+    return new PageImpl<>(dtoList, productPage.getPageable(), productPage.getTotalElements());
+  }
+
+  @Transactional(readOnly = true)
+  public ProductDetailInfo getProductDetail(long userId, long productId) {
+    Product product = productService.getExistingProduct(productId);
+    Stock stock = stockService.findByProductId(productId);
+    long likeCount = likeService.getLikeCount(productId);
+    boolean isLiked = likeService.isLiked(userId, productId);
+
+    LikeInfo likeInfo = LikeInfo.from(likeCount, isLiked);
+    return ProductDetailInfo.from(product, stock, likeInfo);
+  }
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/application/product/ProductWithLikeCount.java b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductWithLikeCount.java
new file mode 100644
index 000000000..32c811df5
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/application/product/ProductWithLikeCount.java
@@ -0,0 +1,20 @@
+package com.loopers.application.product;
+
+import com.loopers.domain.product.Product;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+
+import java.math.BigDecimal;
+
+public record ProductWithLikeCount(Long id, String name, BigDecimal price
+    , long likeCount) {
+  public static ProductWithLikeCount from(Product model, long likeCount) {
+    if (model == null) throw new CoreException(ErrorType.NOT_FOUND, "상품정보를 찾을수 없습니다.");
+    return new ProductWithLikeCount(
+        model.getId(),
+        model.getName(),
+        model.getPrice().getAmount(),
+        likeCount
+    );
+  }
+}
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..33997ebcd 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,14 +1,14 @@
 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(),
+        model.getLoginId(),
         model.getEmail(),
         model.getBirthday().toString(),
         model.getGender()
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..09a7ac785
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/brand/Brand.java
@@ -0,0 +1,34 @@
+package com.loopers.domain.brand;
+
+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;
+
+@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 == null || name.isBlank()) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "브랜드명은 비어있을 수 없습니다.");
+    }
+    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..07872308a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/brand/BrandRepository.java
@@ -0,0 +1,12 @@
+package com.loopers.domain.brand;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface BrandRepository {
+  Optional<Brand> findById(Long id);
+
+  Brand save(Brand brand);
+
+  List<Brand> saveAll(List<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..8145a7216
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/brand/BrandService.java
@@ -0,0 +1,35 @@
+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;
+
+import java.util.List;
+
+@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);
+  }
+
+  @Transactional
+  public Brand save(Brand brand) {
+    return brandRepository.save(brand);
+  }
+
+  @Transactional
+  public List<Brand> saveAll(List<Brand> brands) {
+    return brandRepository.saveAll(brands);
+  }
+
+}
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..2b5212cca
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/like/Like.java
@@ -0,0 +1,46 @@
+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;
+
+  @Version
+  Long version = 0L;
+
+  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..a0eb9358a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/like/LikeRepository.java
@@ -0,0 +1,24 @@
+package com.loopers.domain.like;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface LikeRepository {
+
+  Optional<Like> findById(Long userId, Long productId);
+
+  int save(Long userId, Long productId);
+
+  void remove(Long userId, Long productId);
+
+  boolean isLiked(Long userId, Long productId);
+
+  long getLikeCount(Long productId);
+
+  Page<Like> getLikedProducts(Long userId, Pageable pageable);
+
+  List<ProductIdAndLikeCount> getLikeCountWithProductId(List<Long> productIds);
+}
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..5304fdb88
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/like/LikeService.java
@@ -0,0 +1,73 @@
+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 void save(Long userId, Long productId) {
+    Optional<Like> liked = likeRepository.findById(userId, productId);
+    if (!liked.isPresent()) {
+      likeRepository.save(userId, productId);
+    }
+  }
+
+
+  @Transactional
+  public void remove(Long userId, Long productId) {
+    likeRepository.remove(userId, productId);
+  }
+
+  @Transactional(readOnly = true)
+  public boolean isLiked(Long userId, Long productId) {
+    return likeRepository.isLiked(userId, productId);
+  }
+
+  @Transactional(readOnly = true)
+  public long getLikeCount(Long productId) {
+    return likeRepository.getLikeCount(productId);
+  }
+
+
+  @Transactional(readOnly = true)
+  public List<ProductIdAndLikeCount> getLikeCount(List<Long> productIds) {
+    return likeRepository.getLikeCountWithProductId(productIds);
+  }
+
+  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 "product_asc":
+        return Sort.by("refProductId").ascending().and(latestSort);
+      default:
+        return latestSort;
+    }
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/like/ProductIdAndLikeCount.java b/apps/commerce-api/src/main/java/com/loopers/domain/like/ProductIdAndLikeCount.java
new file mode 100644
index 000000000..003b0f1fb
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/like/ProductIdAndLikeCount.java
@@ -0,0 +1,14 @@
+package com.loopers.domain.like;
+
+import lombok.Getter;
+
+@Getter
+public class ProductIdAndLikeCount {
+  private final Long productId;
+  private final Long likeCount;
+
+  public ProductIdAndLikeCount(Long productId, Long likeCount) {
+    this.productId = productId;
+    this.likeCount = likeCount;
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/order/CurrencyCode.java b/apps/commerce-api/src/main/java/com/loopers/domain/order/CurrencyCode.java
new file mode 100644
index 000000000..01ba637ce
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/CurrencyCode.java
@@ -0,0 +1,8 @@
+package com.loopers.domain.order;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@Getter
+@RequiredArgsConstructor
+public enum CurrencyCode {USD, EUR, GBP, KRW}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/order/Money.java b/apps/commerce-api/src/main/java/com/loopers/domain/order/Money.java
new file mode 100644
index 000000000..0e3247ff1
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/Money.java
@@ -0,0 +1,79 @@
+package com.loopers.domain.order;
+
+import jakarta.persistence.Embeddable;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.Objects;
+
+@Embeddable
+@Getter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+public class Money {
+  private static final BigDecimal ZERO = BigDecimal.ZERO;
+
+  private BigDecimal amount;
+  @Enumerated(EnumType.STRING)
+  private CurrencyCode currency;
+
+  public Money(BigDecimal amount, CurrencyCode currency) {
+    // 💡 음수 검증
+    if (amount.compareTo(BigDecimal.ZERO) < 0) {
+      throw new IllegalArgumentException("금액은 음수가 될 수 없습니다.");
+    }
+
+    this.amount = amount;
+    this.currency = currency;
+  }
+
+  public Money add(Money other) {
+    if (!this.currency.equals(other.currency)) {
+      throw new IllegalArgumentException("통화가 다릅니다.");
+    }
+    return new Money(this.amount.add(other.amount), this.currency);
+  }
+
+  public Money subtract(Money other) {
+    if (!this.currency.equals(other.currency)) {
+      throw new IllegalArgumentException("통화가 다릅니다.");
+    }
+    return new Money(this.amount.subtract(other.amount), this.currency);
+  }
+
+  public Money multiply(long multiplier) {
+    BigDecimal multiplierDecimal = BigDecimal.valueOf(multiplier);
+    BigDecimal newAmount = this.amount.multiply(multiplierDecimal);
+    return new Money(newAmount, this.currency);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    Money money = (Money) o;
+    return Objects.equals(currency, money.currency) &&
+        amount.compareTo(money.amount) == 0;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(amount.stripTrailingZeros(), currency);
+  }
+
+  public boolean isZero() {
+    return this.amount.compareTo(ZERO) == 0;
+  }
+
+  public static Money wons(long amount) {
+    BigDecimal amountDecimal = BigDecimal.valueOf(amount);
+    return new Money(amountDecimal, CurrencyCode.KRW);
+  }
+
+  public static Money of(BigDecimal amount, CurrencyCode currencyCode) {
+    return new Money(amount, currencyCode);
+  }
+}
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..e6387dcd4
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/Order.java
@@ -0,0 +1,84 @@
+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.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;
+
+  private Money totalPrice;
+
+  private ZonedDateTime orderAt;
+
+  @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
+  @JoinColumn(name = "ref_order_id")
+  private List<OrderItem> orderItems = new ArrayList<>();
+
+  private 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, List<OrderItem> orderItems) {
+    this.refUserId = refUserId;
+    this.status = status;
+    this.orderAt = ZonedDateTime.now();
+    setOrderItems(orderItems);
+  }
+
+  public static Order create(long refUserId, List<OrderItem> orderItems) {
+    if (orderItems == null || orderItems.isEmpty()) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "주문 상세내역이 없습니다.");
+    }
+    return new Order(refUserId, OrderStatus.PENDING, orderItems);
+  }
+
+  public void paid() {
+    if (status == OrderStatus.PAID) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "이미 결재완료된 주문입니다.");
+    }
+    this.status = OrderStatus.PAID;
+  }
+
+  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;
+  }
+
+  public Money getTotalPrice() {
+    return orderItems.stream().map(item -> item.getTotalPrice()).reduce(Money.wons(0), Money::add);
+  }
+}
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..8a0afb233
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderItem.java
@@ -0,0 +1,58 @@
+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;
+
+@Entity
+@Table(name = "order_item")
+@Getter
+public class OrderItem extends BaseEntity {
+
+  private long refProductId;
+
+  private long quantity;
+  @Embedded
+  @AttributeOverride(
+      name = "amount",
+      column = @Column(name = "unit_price_amount")
+  )
+  @AttributeOverride(
+      name = "currency",
+      column = @Column(name = "unit_price_currency")
+  )
+  private Money unitPrice;
+
+  @Embedded
+  @AttributeOverride(
+      name = "amount",
+      column = @Column(name = "total_price_amount")
+  )
+  @AttributeOverride(
+      name = "currency",
+      column = @Column(name = "total_price_currency")
+  )
+  private Money totalPrice;
+
+  protected OrderItem() {
+  }
+
+  private OrderItem(long refProductId, long quantity, Money unitPrice) {
+    this.refProductId = refProductId;
+    this.quantity = quantity;
+    this.unitPrice = unitPrice;
+  }
+
+  public static OrderItem create(long refProductId, long quantity, Money unitPrice) {
+    if (quantity <= 0) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "수량은 0보다 커야 합니다.");
+    }
+    return new OrderItem(refProductId, quantity, unitPrice);
+  }
+
+  public Money getTotalPrice() {
+    return this.unitPrice.multiply(this.quantity);
+  }
+}
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..6acc8d16a
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderService.java
@@ -0,0 +1,61 @@
+
+package com.loopers.domain.order;
+
+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;
+
+@RequiredArgsConstructor
+@Component
+public class OrderService {
+  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);
+  }
+
+  @Transactional
+  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..f0db451db
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/order/OrderStatus.java
@@ -0,0 +1,25 @@
+package com.loopers.domain.order;
+
+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 int 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 65%
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..809f18159 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,34 @@
 @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;
+  @OneToOne(fetch = FetchType.LAZY)
+  @JoinColumn(name = "ref_user_Id", unique = true, nullable = false)
+  private User user;
 
-  public void setUser(UserModel user) {
+  public void setUser(User user) {
+    Objects.requireNonNull(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 +55,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..9bfe88f2d 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
@@ -1,17 +1,14 @@
 package com.loopers.domain.point;
 
-import jakarta.persistence.LockModeType;
-import org.springframework.data.jpa.repository.Lock;
-
 import java.util.Optional;
 
 public interface PointRepository {
+  Optional<Point> findByUserId(Long userId);
 
-  Optional<PointModel> findByUserId(String userId);
+  Optional<Point> findByUserLoginId(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..edc9aa443 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,38 @@ 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());
+    Point saved = pointRepository.save(pointOpt.get());
+    return saved.getAmount();
+  }
+
+  @Transactional
+  public BigDecimal use(Long userId, BigDecimal useAmt) {
+    Optional<Point> pointOpt = pointRepository.findByUserIdForUpdate(userId);
+    if (!pointOpt.isPresent()) {
+      throw new CoreException(ErrorType.NOT_FOUND, "현재 포인트 정보를 찾을수 없습니다.");
+    }
+    Point point = pointOpt.get();
+    point.use(useAmt);
+    Point saved = pointRepository.save(point);
+    return saved.getAmount();
   }
 }
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..9bf2740e6
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/Product.java
@@ -0,0 +1,45 @@
+package com.loopers.domain.product;
+
+import com.loopers.domain.BaseEntity;
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.order.Money;
+import com.loopers.domain.stock.Stock;
+import jakarta.persistence.*;
+import lombok.Getter;
+
+@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 Money price;
+
+  @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
+  @JoinColumn(name = "ref_stock_id", updatable = false)
+  private Stock stock;
+
+  public void setBrand(Brand brand) {
+    this.brand = brand;
+  }
+
+  protected Product() {
+
+  }
+
+  private Product(Brand brand, String name, Money price, Stock stock) {
+    this.setBrand(brand);
+    this.name = name;
+    this.price = price;
+    this.stock = stock;
+  }
+
+  public static Product create(Brand brand, String name, Money price) {
+
+    return new Product(brand, name, price, Stock.create(null, 0));
+  }
+}
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..19a9bbb86
--- /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> ids);
+
+  Page<Product> findByBrandId(Long brandId, Pageable pageable);
+
+  Page<Product> findAll(Pageable pageable);
+
+  Product save(Product product);
+
+  List<Product> saveAll(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..c05f009a3
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/product/ProductService.java
@@ -0,0 +1,110 @@
+
+package com.loopers.domain.product;
+
+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;
+
+  @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 Product getExistingProduct(Long id) {
+    if (id == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "ID가 없습니다.");
+    }
+    Optional<Product> product = productRepository.findById(id);
+    if (product.isEmpty()) {
+      throw new CoreException(ErrorType.NOT_FOUND, "상품을 찾을 수 없습니다.");
+    }
+    return product.get();
+  }
+
+  @Transactional(readOnly = true)
+  public List<Product> getExistingProducts(List<Long> productIds) {
+
+    if (productIds == null || productIds.isEmpty()) {
+      return Collections.emptyList();
+    }
+    Set<Long> uniqueIds = new HashSet<>(productIds);
+    List<Product> products = productRepository.findAllById(uniqueIds);
+
+    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> saveAll(List<Product> product) {
+    return productRepository.saveAll(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("totalPrice").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/stock/Stock.java b/apps/commerce-api/src/main/java/com/loopers/domain/stock/Stock.java
new file mode 100644
index 000000000..b196b6bf3
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/stock/Stock.java
@@ -0,0 +1,42 @@
+package com.loopers.domain.stock;
+
+import com.loopers.domain.BaseEntity;
+import com.loopers.domain.product.Product;
+import com.loopers.support.error.CoreException;
+import com.loopers.support.error.ErrorType;
+import jakarta.persistence.*;
+import lombok.Getter;
+
+@Entity
+@Table(name = "stock")
+@Getter
+public class Stock extends BaseEntity {
+  private Long refProductId;
+  private long available = 0;
+
+  protected Stock() {
+
+  }
+
+  private Stock(Long refProductId, long available) {
+    this.refProductId = refProductId;
+    this.available = available;
+  }
+
+  public static Stock create(Long refProductId, long available) {
+    if (available < 0) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "재고는 0보다 커야 합니다.");
+    }
+    return new Stock(refProductId, available);
+  }
+
+  public void deduct(long quantity) {
+    if (quantity <= 0) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "수량은 0보다 커야 합니다.");
+    }
+    if (this.available < quantity) {
+      throw new CoreException(ErrorType.INSUFFICIENT_STOCK, "재고가 부족합니다.");
+    }
+    this.available -= quantity;
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/stock/StockRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/stock/StockRepository.java
new file mode 100644
index 000000000..28044b05b
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/stock/StockRepository.java
@@ -0,0 +1,12 @@
+package com.loopers.domain.stock;
+
+import java.util.Optional;
+
+public interface StockRepository {
+  Optional<Stock> findByProductId(Long refProductId);
+
+  Optional<Stock> findByProductIdForUpdate(Long refProductId);
+
+  Stock save(Stock stock);
+
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/domain/stock/StockService.java b/apps/commerce-api/src/main/java/com/loopers/domain/stock/StockService.java
new file mode 100644
index 000000000..aa0266ef4
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/domain/stock/StockService.java
@@ -0,0 +1,34 @@
+
+package com.loopers.domain.stock;
+
+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 StockService {
+
+  private final StockRepository stockRepository;
+
+  @Transactional(readOnly = true)
+  public Stock findByProductId(Long productId) {
+    return stockRepository.findByProductId(productId)
+        .orElse(Stock.create(productId, 0));
+  }
+
+  @Transactional
+  public Stock save(Stock stock) {
+    return stockRepository.save(stock);
+  }
+
+  @Transactional
+  public Stock deduct(Long productId, long quantity) {
+    Stock stock = stockRepository.findByProductIdForUpdate(productId)
+        .orElseThrow(() -> new CoreException(ErrorType.NOT_FOUND, "상품 재고가 존재하지 않습니다."));
+    stock.deduct(quantity);
+    return stockRepository.save(stock);
+  }
+}
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 73%
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..d3bda90d5 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,11 +1,12 @@
 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.*;
 import lombok.Getter;
+import org.hibernate.annotations.DynamicUpdate;
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
@@ -15,28 +16,28 @@
 @Entity
 @Table(name = "user")
 @Getter
-public class UserModel extends BaseEntity {
-  private String userId;
+public class User extends BaseEntity {
+  private String loginId;
   private String email;
   private LocalDate birthday;
   private String gender;
 
-  @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
-  private PointModel point;
+  @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = true)
+  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 loginId, String email, String birthday, String gender) {
 
-    if (!Pattern.compile("^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]{1,10}$").matcher(userId).matches()) {
+    if (!Pattern.compile("^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]{1,10}$").matcher(loginId).matches()) {
       throw new CoreException(
           ErrorType.BAD_REQUEST,
           "아이디 형식이 잘못되었습니다.(영문 및 숫자 1~10자 이내)"
@@ -63,15 +64,15 @@ private UserModel(String userId, String email, String birthday, String gender) {
           "성별정보가 없습니다."
       );
     }
-    this.userId = userId;
+    this.loginId = loginId;
     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/UserRepository.java b/apps/commerce-api/src/main/java/com/loopers/domain/user/UserRepository.java
index b7f64a18f..f94a61c38 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,9 @@
 import java.util.Optional;
 
 public interface UserRepository {
-  UserModel save(UserModel user);
+  User save(User user);
 
-  boolean existsByUserId(String userId);
+  Optional<User> findById(Long id);
 
-  Optional<UserModel> findByUserId(String userId);
+  Optional<User> findByLoginId(String longinId);
 }
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..5ff80ad9c 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,19 +14,35 @@ public class UserService {
   private final UserRepository userRepository;
 
   @Transactional
-  public UserModel join(UserModel user) {
-    if (userRepository.existsByUserId(user.getUserId())) {
+  public User join(User user) {
+    if (userRepository.findByLoginId(user.getLoginId()).isPresent()) {
       throw new CoreException(ErrorType.BAD_REQUEST, "이미 가입된 ID 입니다.");
     }
     return userRepository.save(user);
   }
 
   @Transactional(readOnly = true)
-  public UserModel getUser(String userId) {
-    //Ask: userId도 UserModel 안에 넣어서 왔으면, userId Model에서 검증 가능
-    if (userId == null || userId.isBlank()) {
+  public User getUser(Long userId) {
+    if (userId == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "ID가 없습니다.");
+    }
+    return userRepository.findById(userId).orElse(null);
+  }
+
+  @Transactional(readOnly = true)
+  public User getUser(String loginId) {
+    if (loginId == null) {
+      throw new CoreException(ErrorType.BAD_REQUEST, "ID가 없습니다.");
+    }
+    return userRepository.findByLoginId(loginId).orElse(null);
+  }
+
+  @Transactional(readOnly = true)
+  public User getActiveUser(Long userId) {
+    if (userId == null) {
       throw new CoreException(ErrorType.BAD_REQUEST, "ID가 없습니다.");
     }
-    return userRepository.findByUserId(userId).orElse(null);
+    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..aa99ac6ca
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/brand/BrandJpaRepository.java
@@ -0,0 +1,8 @@
+package com.loopers.infrastructure.brand;
+
+import com.loopers.domain.brand.Brand;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface BrandJpaRepository extends JpaRepository<Brand, Long> {
+
+}
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..e4eb73b78
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/brand/BrandRepositoryImpl.java
@@ -0,0 +1,30 @@
+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.List;
+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);
+  }
+
+  @Override
+  public List<Brand> saveAll(List<Brand> brands) {
+    return jpaRepository.saveAll(brands);
+  }
+}
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..3d86377df
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/like/LikeJpaRepository.java
@@ -0,0 +1,43 @@
+package com.loopers.infrastructure.like;
+
+import com.loopers.domain.like.Like;
+import com.loopers.domain.like.ProductIdAndLikeCount;
+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.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface LikeJpaRepository extends JpaRepository<Like, Long> {
+  Optional<Like> findByUserIdAndProductId(Long userId, Long productId);
+
+  @Modifying
+  @Query(value = "INSERT IGNORE INTO likes (ref_user_id, ref_product_id, created_at, updated_at) VALUES (:userId, :productId, NOW(), NOW())", nativeQuery = true)
+  int save(@Param("userId") Long userId, @Param("productId") Long productId);
+
+  @Modifying
+  @Query("delete from Like l where l.user.id = :userId and l.product.id = :productId")
+  void delete(@Param("userId") Long userId, @Param("productId") 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);
+
+
+  @Query("SELECT NEW com.loopers.domain.like.ProductIdAndLikeCount(l.product.id, COUNT(l.id)) " +
+      "FROM Like l " +
+      "WHERE l.product.id IN :productIds " +
+      "GROUP BY l.product.id")
+  List<ProductIdAndLikeCount> countLikesByProductIds(@Param("productIds") List<Long> productIds);
+
+}
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..4641766f4
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/like/LikeRepositoryImpl.java
@@ -0,0 +1,56 @@
+package com.loopers.infrastructure.like;
+
+import com.loopers.domain.like.Like;
+import com.loopers.domain.like.LikeRepository;
+import com.loopers.domain.like.ProductIdAndLikeCount;
+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.List;
+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 int save(Long userId, Long productId) {
+    return jpaRepository.save(userId, productId);
+  }
+
+  @Override
+  public void remove(Long userId, Long productId) {
+    jpaRepository.delete(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);
+  }
+
+  @Override
+  public List<ProductIdAndLikeCount> getLikeCountWithProductId(List<Long> productIds) {
+    return jpaRepository.countLikesByProductIds(productIds);
+  }
+
+}
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..68e85215e
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/order/OrderJpaRepository.java
@@ -0,0 +1,11 @@
+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;
+
+public interface OrderJpaRepository extends JpaRepository<Order, Long> {
+  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..609a774e2
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/order/OrderRepositoryImpl.java
@@ -0,0 +1,31 @@
+package com.loopers.infrastructure.order;
+
+import com.loopers.domain.order.Order;
+import com.loopers.domain.order.OrderRepository;
+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..33cd00e38 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,23 @@
 package com.loopers.infrastructure.point;
 
-import com.loopers.domain.point.PointModel;
+import com.loopers.domain.point.Point;
+import jakarta.persistence.LockModeType;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Lock;
 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> {
-  boolean existsByUserUserId(String userId);
+public interface PointJpaRepository extends JpaRepository<Point, Long> {
 
-  Optional<PointModel> findByUserUserId(String userId);
+  Optional<Point> findByUserLoginId(String userId);
+
+  Optional<Point> findByUserId(Long userId);
+  
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
+  @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..6fea79b12 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) {
-    return jpaRepository.save(point);
+  public Point save(Point point) {
+    return jpaRepository.saveAndFlush(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> findByUserLoginId(String userId) {
+    return jpaRepository.findByUserLoginId(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..2d3a34309
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/product/ProductJpaRepository.java
@@ -0,0 +1,27 @@
+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;
+
+public interface ProductJpaRepository extends JpaRepository<Product, Long> {
+  Page<Product> findByBrandId(Long brandId, Pageable pageable);
+
+  List<Product> save(List<Product> product);
+
+//  @Query(value = """
+//          SELECT new com.loopers.api.product.dto.ProductView(
+//              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..089e79cc5
--- /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> saveAll(List<Product> products) {
+    return jpaRepository.saveAll(products);
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/stock/StockJpaRepository.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/stock/StockJpaRepository.java
new file mode 100644
index 000000000..6562fe6d9
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/stock/StockJpaRepository.java
@@ -0,0 +1,18 @@
+package com.loopers.infrastructure.stock;
+
+import com.loopers.domain.stock.Stock;
+import jakarta.persistence.LockModeType;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Lock;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.Optional;
+
+public interface StockJpaRepository extends JpaRepository<Stock, Long> {
+  Optional<Stock> findByRefProductId(Long productId);
+
+  @Lock(LockModeType.PESSIMISTIC_WRITE)
+  @Query("select s from Stock s where s.refProductId = :id")
+  Optional<Stock> findByProductIdForUpdate(@Param("id") Long id);
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/infrastructure/stock/StockRepositoryImpl.java b/apps/commerce-api/src/main/java/com/loopers/infrastructure/stock/StockRepositoryImpl.java
new file mode 100644
index 000000000..f6008f812
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/infrastructure/stock/StockRepositoryImpl.java
@@ -0,0 +1,29 @@
+package com.loopers.infrastructure.stock;
+
+import com.loopers.domain.stock.Stock;
+import com.loopers.domain.stock.StockRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@RequiredArgsConstructor
+@Component
+public class StockRepositoryImpl implements StockRepository {
+  private final StockJpaRepository jpaRepository;
+
+  @Override
+  public Optional<Stock> findByProductId(Long productId) {
+    return jpaRepository.findByRefProductId(productId);
+  }
+
+  @Override
+  public Optional<Stock> findByProductIdForUpdate(Long productId) {
+    return jpaRepository.findByProductIdForUpdate(productId);
+  }
+
+  @Override
+  public Stock save(Stock stock) {
+    return jpaRepository.save(stock);
+  }
+}
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..80175b640 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,11 @@
 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> {
-  boolean existsByUserId(String userId);
-  Optional<UserModel> findByUserId(String userId);
+public interface UserJpaRepository extends JpaRepository<User, Long> {
+  Optional<User> findByLoginId(String loginId);
+
 }
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..855023b6b 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,17 +13,18 @@ public class UserRepositoryImpl implements UserRepository {
   private final UserJpaRepository jpaRepository;
 
   @Override
-  public UserModel save(UserModel user) {
+  public User save(User user) {
     return jpaRepository.save(user);
   }
 
   @Override
-  public boolean existsByUserId(String userId) {
-    return jpaRepository.existsByUserId(userId);
+  public Optional<User> findById(Long userId) {
+    return jpaRepository.findById(userId);
   }
 
   @Override
-  public Optional<UserModel> findByUserId(String userId) {
-    return jpaRepository.findByUserId(userId);
+  public Optional<User> findByLoginId(String loginId) {
+    return jpaRepository.findByLoginId(loginId);
   }
+
 }
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeCreateV1Dto.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeCreateV1Dto.java
new file mode 100644
index 000000000..d4fa070ca
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeCreateV1Dto.java
@@ -0,0 +1,20 @@
+package com.loopers.interfaces.api.like;
+
+import com.loopers.application.user.UserInfo;
+
+public class LikeCreateV1Dto {
+  public record UserRequest(String userId, String email, String birthday, String gender) {
+  }
+
+  public record UserResponse(String userId, String email, String birthday, String gender) {
+    public static UserResponse from(UserInfo info) {
+      if (info == null) return null;
+      return new UserResponse(
+          info.userId(),
+          info.email(),
+          info.birthday(),
+          info.gender()
+      );
+    }
+  }
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1ApiSpec.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1ApiSpec.java
new file mode 100644
index 000000000..7a708b6f4
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1ApiSpec.java
@@ -0,0 +1,29 @@
+package com.loopers.interfaces.api.like;
+
+import com.loopers.application.like.LikeInfo;
+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 org.springframework.web.bind.annotation.PathVariable;
+
+@Tag(name = "Like V1 API", description = "Loopers 예시 API 입니다.")
+public interface LikeV1ApiSpec {
+  @Operation(
+      summary = "좋아요",
+      description = "좋아요 합니다."
+  )
+  ApiResponse<LikeInfo> like(
+      @Schema(name = "사용자 ID", description = "조회할 사용자의 ID") Long userId,
+      @PathVariable(value = "productId") Long productId
+  );
+
+  @Operation(
+      summary = "좋아요 삭제",
+      description = "좋아요를 삭제합니다."
+  )
+  ApiResponse<LikeInfo> unlike(
+      @Schema(name = "사용자 ID", description = "조회할 사용자의 ID") Long userId,
+      @PathVariable(value = "productId") Long productId
+  );
+}
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1Controller.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1Controller.java
new file mode 100644
index 000000000..fbfc7ce89
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/like/LikeV1Controller.java
@@ -0,0 +1,38 @@
+package com.loopers.interfaces.api.like;
+
+import com.loopers.application.like.LikeFacade;
+import com.loopers.application.like.LikeInfo;
+import com.loopers.interfaces.api.ApiResponse;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/api/v1/likes")
+public class LikeV1Controller implements LikeV1ApiSpec {
+
+  private final LikeFacade likeFacade;
+
+  @PostMapping("/{productId}")
+  @ResponseStatus(HttpStatus.CREATED)
+  @Override
+  public ApiResponse<LikeInfo> like(
+      @Schema(name = "사용자 ID", description = "조회할 사용자의 ID") Long userId,
+      @PathVariable(value = "productId") Long productId
+  ) {
+    LikeInfo info = likeFacade.like(userId, productId);
+    return ApiResponse.success(info);
+  }
+
+  @DeleteMapping("/{productId}")
+  @Override
+  public ApiResponse<LikeInfo> unlike(
+      @Schema(name = "사용자 ID", description = "조회할 사용자의 ID") Long userId,
+      @PathVariable(value = "productId") Long productId
+  ) {
+    LikeInfo info = likeFacade.unlike(userId, productId);
+    return ApiResponse.success(info);
+  }
+}
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..2fb536034
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderCreateV1Dto.java
@@ -0,0 +1,36 @@
+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 jakarta.validation.constraints.Positive;
+
+import java.math.BigDecimal;
+import java.time.ZonedDateTime;
+import java.util.List;
+
+public class OrderCreateV1Dto {
+  public record OrderItemRequest(@Positive long productId, @Positive 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..9474e7d9d
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1ApiSpec.java
@@ -0,0 +1,52 @@
+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;
+
+@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,
+      @PathVariable("orderId") 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..3df5b27e7
--- /dev/null
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/order/OrderV1Controller.java
@@ -0,0 +1,53 @@
+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.http.HttpStatus;
+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("")
+  @ResponseStatus(HttpStatus.CREATED)
+  @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..75e0ac9cf 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
@@ -9,21 +9,21 @@
 
 @RequiredArgsConstructor
 @RestController
-@RequestMapping("/api/v1/user/point")
+@RequestMapping("/api/v1/users/point")
 public class PointV1Controller implements PointV1ApiSpec {
 
   private final PointFacade pointFacade;
 
   @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/interfaces/api/user/UserCreateV1Dto.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/user/UserCreateV1Dto.java
index 837984c43..c658c78ab 100644
--- a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/user/UserCreateV1Dto.java
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/user/UserCreateV1Dto.java
@@ -2,8 +2,6 @@
 
 import com.loopers.application.user.UserInfo;
 
-import java.time.LocalDate;
-
 public class UserCreateV1Dto {
   public record UserRequest(String userId, String email, String birthday, String gender) {
   }
@@ -14,7 +12,7 @@ public static UserResponse from(UserInfo info) {
       return new UserResponse(
           info.userId(),
           info.email(),
-          info.birthday().toString(),
+          info.birthday(),
           info.gender()
       );
     }
diff --git a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/user/UserV1Controller.java b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/user/UserV1Controller.java
index b511e79cd..280bf2c19 100644
--- a/apps/commerce-api/src/main/java/com/loopers/interfaces/api/user/UserV1Controller.java
+++ b/apps/commerce-api/src/main/java/com/loopers/interfaces/api/user/UserV1Controller.java
@@ -9,7 +9,7 @@
 
 @RequiredArgsConstructor
 @RestController
-@RequestMapping("/api/v1/user")
+@RequestMapping("/api/v1/users")
 public class UserV1Controller implements UserV1ApiSpec {
 
   private final UserFacade userFacade;
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..05141702b 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, "INTERNAL_ERROR", "일시적인 오류가 발생했습니다."),
+  BAD_REQUEST(HttpStatus.BAD_REQUEST, "BAD_REQUEST", "잘못된 요청입니다."),
+  NOT_FOUND(HttpStatus.NOT_FOUND, "NOT_FOUND", "존재하지 않는 요청입니다."),
+  CONFLICT(HttpStatus.CONFLICT, "CONFLICT", "이미 존재하는 리소스입니다."),
 
-    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/like/LikeFacadeConcurrencyTest.java b/apps/commerce-api/src/test/java/com/loopers/application/like/LikeFacadeConcurrencyTest.java
new file mode 100644
index 000000000..e6a9c7031
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/application/like/LikeFacadeConcurrencyTest.java
@@ -0,0 +1,182 @@
+package com.loopers.application.like;
+
+import com.loopers.application.order.CreateOrderCommand;
+import com.loopers.application.order.OrderFacade;
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.brand.BrandService;
+import com.loopers.domain.like.LikeService;
+import com.loopers.domain.order.Money;
+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.ProductFixture;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.stock.Stock;
+import com.loopers.domain.stock.StockFixture;
+import com.loopers.domain.stock.StockService;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+import com.loopers.domain.user.UserRepository;
+import com.loopers.domain.user.UserService;
+import com.loopers.interfaces.api.order.OrderCreateV1Dto;
+import com.loopers.utils.DatabaseCleanUp;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+@SpringBootTest
+class LikeFacadeConcurrencyTest {
+  @Autowired
+  private LikeFacade sut;
+  @MockitoSpyBean
+  private UserRepository userRepository;
+  @MockitoSpyBean
+  private UserService userService;
+  @MockitoSpyBean
+  private PointService pointService;
+  @MockitoSpyBean
+  private BrandService brandService;
+  @MockitoSpyBean
+  private ProductService productService;
+  @MockitoSpyBean
+  private LikeService likeService;
+
+  @MockitoSpyBean
+  private OrderService orderService;
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+  List<User> savedUsers;
+  List<Brand> savedBrands;
+  List<Product> savedProducts;
+
+  @BeforeEach
+  void setup() {
+    // arrange
+    List<User> userList = List.of(UserFixture.createUserWithLoginId("user1"), UserFixture.createUserWithLoginId("user2"));
+    savedUsers = List.of(userService.join(userList.get(0)), userService.join(userList.get(1)));
+
+    List<Brand> brandList = List.of(BrandFixture.createBrand(), BrandFixture.createBrand());
+    savedBrands = brandService.saveAll(brandList);
+
+    List<Product> productList = List.of(ProductFixture.createProductWith("product1", Money.wons(1))
+        , ProductFixture.createProductWith("product2", Money.wons(4))
+        , ProductFixture.createProduct(savedBrands.get(1)));
+    savedProducts = productService.saveAll(productList);
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("동시에 좋아요해도 정상적으로 처리된다.")
+  @Test
+  void 성공_좋아요_쓰레드10() throws InterruptedException {
+    Long userId = savedUsers.get(0).getId();
+    Long productId = savedProducts.get(0).getId();
+
+    int threadCount = 10;
+    ExecutorService executor = Executors.newFixedThreadPool(threadCount);
+    CountDownLatch latch = new CountDownLatch(threadCount);
+
+    for (int i = 0; i < threadCount; i++) {
+      executor.submit(() -> {
+        try {
+          sut.like(userId, productId);
+        } catch (Exception e) {
+          System.out.println("실패: " + e.getMessage());
+        } finally {
+          latch.countDown();
+        }
+      });
+    }
+
+    latch.await();
+
+    Long likeCount = likeService.getLikeCount(productId);
+    assertThat(likeCount).isEqualTo(1);
+  }
+
+  @DisplayName("동시에 좋아요 취소해도 정상적으로 처리된다.")
+  @Test
+  void 성공_좋아요_취소_쓰레드10() throws InterruptedException {
+    Long userId = savedUsers.get(0).getId();
+    Long productId = savedProducts.get(0).getId();
+
+    int threadCount = 10;
+    ExecutorService executor = Executors.newFixedThreadPool(threadCount);
+    CountDownLatch latch = new CountDownLatch(threadCount);
+    AtomicInteger errorCount = new AtomicInteger();
+
+    for (int i = 0; i < threadCount; i++) {
+      executor.submit(() -> {
+        try {
+          sut.unlike(userId, productId);
+        } catch (Exception e) {
+          errorCount.getAndIncrement();
+          System.out.println("실패: " + e.getMessage());
+        } finally {
+          latch.countDown();
+        }
+      });
+    }
+
+    latch.await();
+    assertThat(errorCount.get()).isZero();
+    Long likeCount = likeService.getLikeCount(productId);
+    assertThat(likeCount).isZero();
+  }
+
+  @DisplayName("동일한 상품에 대해 여러명이 좋아요/싫어요를 요청해도, 상품의 좋아요 개수가 정상 반영되어야 한다.")
+  @Test
+  void 성공_동일한_상품_여러명_쓰레드10() throws InterruptedException {
+    Long productId = savedProducts.get(0).getId();
+
+    int threadCount = 10;
+    ExecutorService executor = Executors.newFixedThreadPool(threadCount);
+    CountDownLatch latch = new CountDownLatch(threadCount);
+    AtomicInteger errorCount = new AtomicInteger();
+
+    for (int i = 0; i < threadCount; i++) {
+      final int idx = i;
+      executor.submit(() -> {
+        try {
+          Long userId = savedUsers.get(idx % savedUsers.size()).getId();
+          if (idx % 2 == 0) {
+            sut.like(userId, productId);
+          } else {
+            sut.unlike(userId, productId);
+          }
+        } catch (Exception e) {
+          errorCount.incrementAndGet();
+          System.out.println("스레드 실패 (idx=" + idx + "): " + e.getMessage());
+        } finally {
+          latch.countDown();
+        }
+      });
+    }
+
+    latch.await();
+    assertThat(errorCount.get()).isZero();
+    Long likeCount = likeService.getLikeCount(productId);
+    assertThat(likeCount).isBetween(0L, (long) savedUsers.size());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/application/like/LikeFacadeIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/application/like/LikeFacadeIntegrationTest.java
new file mode 100644
index 000000000..6e42eef65
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/application/like/LikeFacadeIntegrationTest.java
@@ -0,0 +1,149 @@
+package com.loopers.application.like;
+
+import com.loopers.application.order.CreateOrderCommand;
+import com.loopers.application.order.OrderInfo;
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.brand.BrandService;
+import com.loopers.domain.like.LikeService;
+import com.loopers.domain.order.Money;
+import com.loopers.domain.order.OrderService;
+import com.loopers.domain.point.PointService;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductFixture;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.stock.Stock;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+import com.loopers.domain.user.UserRepository;
+import com.loopers.domain.user.UserService;
+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.test.context.bean.override.mockito.MockitoSpyBean;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+
+@SpringBootTest
+class LikeFacadeIntegrationTest {
+  @Autowired
+  private LikeFacade sut;
+  @MockitoSpyBean
+  private UserRepository userRepository;
+  @MockitoSpyBean
+  private UserService userService;
+  @MockitoSpyBean
+  private PointService pointService;
+  @MockitoSpyBean
+  private BrandService brandService;
+  @MockitoSpyBean
+  private ProductService productService;
+  @MockitoSpyBean
+  private LikeService likeService;
+
+  @MockitoSpyBean
+  private OrderService orderService;
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+  List<User> savedUsers;
+  List<Brand> savedBrands;
+  List<Product> savedProducts;
+
+  @BeforeEach
+  void setup() {
+    // arrange
+    List<User> userList = List.of(UserFixture.createUserWithLoginId("user1"), UserFixture.createUserWithLoginId("user2"));
+    savedUsers = List.of(userService.join(userList.get(0)), userService.join(userList.get(1)));
+
+    List<Brand> brandList = List.of(BrandFixture.createBrand(), BrandFixture.createBrand());
+    savedBrands = brandService.saveAll(brandList);
+
+    List<Product> productList = List.of(ProductFixture.createProductWith("product1", Money.wons(1))
+        , ProductFixture.createProductWith("product2", Money.wons(4))
+        , ProductFixture.createProduct(savedBrands.get(1)));
+    savedProducts = productService.saveAll(productList);
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("좋아요를 할 때,")
+  @Nested
+  class Post {
+    @DisplayName("좋아요가 성공한다.")
+    @Test
+    void 성공_좋아요() {
+      Long userId = savedUsers.get(0).getId();
+      Long productId = savedProducts.get(0).getId();
+
+      // act
+      LikeInfo savedLike = sut.like(userId, productId);
+      // assert
+      assertThat(savedLike).isNotNull();
+      assertThat(savedLike.isLiked()).isTrue();
+      assertThat(savedLike.likeCount()).isEqualTo(1);
+    }
+
+    @DisplayName("좋아요가 성공한다.")
+    @Test
+    void 성공_좋아요_중복() {
+      Long userId = savedUsers.get(0).getId();
+      Long productId = savedProducts.get(0).getId();
+      sut.like(userId, productId);
+      // act
+      LikeInfo savedLike = sut.like(userId, productId);
+      // assert
+      assertThat(savedLike).isNotNull();
+      assertThat(savedLike.isLiked()).isTrue();
+      assertThat(savedLike.likeCount()).isEqualTo(1);
+    }
+  }
+
+  @DisplayName("좋아요 취소할 때,")
+  @Nested
+  class Delete {
+    @DisplayName("좋아요 취소가 성공한다.")
+    @Test
+    void 성공_좋아요_취소() {
+      Long userId = savedUsers.get(0).getId();
+      Long productId = savedProducts.get(0).getId();
+
+      // act
+      LikeInfo savedLike = sut.unlike(userId, productId);
+      // assert
+      assertThat(savedLike).isNotNull();
+      assertThat(savedLike.isLiked()).isFalse();
+      assertThat(savedLike.likeCount()).isZero();
+    }
+
+    @DisplayName("좋아요 취소가 성공한다.")
+    @Test
+    void 성공_좋아요_취소_중복() {
+      Long userId = savedUsers.get(0).getId();
+      Long productId = savedProducts.get(0).getId();
+      sut.unlike(userId, productId);
+      // act
+      LikeInfo savedLike = sut.unlike(userId, productId);
+      // assert
+      assertThat(savedLike).isNotNull();
+      assertThat(savedLike.isLiked()).isFalse();
+      assertThat(savedLike.likeCount()).isZero();
+    }
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/application/order/OrderFacadeConcurrencyTest.java b/apps/commerce-api/src/test/java/com/loopers/application/order/OrderFacadeConcurrencyTest.java
new file mode 100644
index 000000000..af4eb4eea
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/application/order/OrderFacadeConcurrencyTest.java
@@ -0,0 +1,223 @@
+package com.loopers.application.order;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.brand.BrandService;
+import com.loopers.domain.order.Money;
+import com.loopers.domain.order.Order;
+import com.loopers.domain.order.OrderItem;
+import com.loopers.domain.order.OrderService;
+import com.loopers.domain.point.Point;
+import com.loopers.domain.point.PointService;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductFixture;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.stock.Stock;
+import com.loopers.domain.stock.StockFixture;
+import com.loopers.domain.stock.StockService;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+import com.loopers.domain.user.UserRepository;
+import com.loopers.domain.user.UserService;
+import com.loopers.interfaces.api.order.OrderCreateV1Dto;
+import com.loopers.utils.DatabaseCleanUp;
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.PersistenceContext;
+import org.hibernate.Hibernate;
+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.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+
+@SpringBootTest
+class OrderFacadeConcurrencyTest {
+  @Autowired
+  private OrderFacade sut;
+  @MockitoSpyBean
+  private UserRepository userRepository;
+  @MockitoSpyBean
+  private UserService userService;
+  @MockitoSpyBean
+  private PointService pointService;
+  @MockitoSpyBean
+  private BrandService brandService;
+  @MockitoSpyBean
+  private ProductService productService;
+  @MockitoSpyBean
+  private StockService stockService;
+
+  @MockitoSpyBean
+  private OrderService orderService;
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+  List<User> savedUsers;
+  List<Brand> savedBrands;
+  List<Product> savedProducts;
+
+  @BeforeEach
+  void setup() {
+    // 사용자 생성
+    savedUsers = List.of(
+        userService.join(UserFixture.createUserWithLoginId("user1")),
+        userService.join(UserFixture.createUserWithLoginId("user2"))
+    );
+
+    // 브랜드 생성
+    savedBrands = brandService.saveAll(List.of(
+        BrandFixture.createBrand(),
+        BrandFixture.createBrand()
+    ));
+
+    // 상품 생성
+    savedProducts = productService.saveAll(List.of(
+        ProductFixture.createProductWith("product1", Money.wons(1)),
+        ProductFixture.createProductWith("product2", Money.wons(4)),
+        ProductFixture.createProduct(savedBrands.get(1))
+    ));
+
+    // 재고 생성
+    stockService.save(StockFixture.createStockWith(savedProducts.get(0).getId(), 10));
+    stockService.save(StockFixture.createStockWith(savedProducts.get(1).getId(), 10));
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("동일한 상품에 대해 여러 주문이 동시에 요청되어도, 재고가 정상적으로 차감된다.")
+  @Test
+  void 재고_동시성_테스트() throws InterruptedException {
+    Long productId = savedProducts.get(0).getId();
+    CreateOrderCommand orderCommand = createOrderCommand(savedUsers.get(0).getId(), productId, 1);
+
+
+    int threadCount = 10;
+    ExecutorService executor = Executors.newFixedThreadPool(threadCount);
+    CountDownLatch latch = new CountDownLatch(threadCount);
+
+    for (int i = 0; i < threadCount; i++) {
+      executor.submit(() -> {
+        try {
+          sut.createOrder(orderCommand);
+        } catch (Exception e) {
+          System.out.println("실패: " + e.getMessage());
+        } finally {
+          latch.countDown();
+        }
+      });
+    }
+
+    latch.await();
+
+    Stock stock = stockService.findByProductId(productId);
+    assertThat(stock.getAvailable()).isZero();
+  }
+
+  @DisplayName("동일한 유저가 여러 주문을 동시에 수행해도, 포인트가 정상적으로 차감된다.")
+  @Test
+  void 포인트_동시성_테스트() throws InterruptedException {
+    Long userId = savedUsers.get(0).getId();
+    Long productId = savedProducts.get(1).getId();
+    CreateOrderCommand orderCommand = createOrderCommand(userId, productId, 1);
+
+    int threadCount = 10;
+    AtomicInteger errorCount = new AtomicInteger();
+    ExecutorService executor = Executors.newFixedThreadPool(threadCount);
+    CountDownLatch latch = new CountDownLatch(threadCount);
+
+    for (int i = 0; i < threadCount; i++) {
+      executor.submit(() -> {
+        try {
+          sut.createOrder(orderCommand);
+        } catch (Exception e) {
+          errorCount.incrementAndGet();
+        } finally {
+          latch.countDown();
+        }
+      });
+    }
+
+    latch.await();
+
+    // 재고 10개, 단가 4원 → 2개의 주문 성공, 나머지는 실패
+    assertThat(errorCount.get()).isEqualTo(8);
+
+    Stock stock = stockService.findByProductId(productId);
+    assertThat(stock.getAvailable()).isEqualTo(8);
+
+    BigDecimal remainingPoint = pointService.getAmount(userId);
+    assertThat(remainingPoint).isEqualByComparingTo(new BigDecimal(2));
+  }
+
+  @DisplayName("동일한 유저가 서로 다른 주문을 동시에 수행해도, 포인트가 정상적으로 차감된다.")
+  @Test
+  void 동일유저_다른상품_동시주문_포인트차감() throws InterruptedException {
+    Long userId = savedUsers.get(0).getId();
+    pointService.charge(savedUsers.get(0), new BigDecimal(30));
+    // 주문 1: 상품1, 단가 1원
+    Long productId1 = savedProducts.get(0).getId();
+    CreateOrderCommand orderCommand1 = createOrderCommand(userId, productId1, 1);
+
+    // 주문 2: 상품2, 단가 4원
+    Long productId2 = savedProducts.get(1).getId();
+    CreateOrderCommand orderCommand2 = createOrderCommand(userId, productId2, 1);
+
+    // 동시성 테스트: 상품1, 상품2를 각각 5개씩 병렬 주문
+    int threadCount = 10;
+    ExecutorService executor = Executors.newFixedThreadPool(threadCount);
+    CountDownLatch latch = new CountDownLatch(threadCount);
+    AtomicInteger errorCount = new AtomicInteger();
+
+    for (int i = 0; i < threadCount; i++) {
+      final CreateOrderCommand command = (i % 2 == 0) ? orderCommand1 : orderCommand2;
+      executor.submit(() -> {
+        try {
+          sut.createOrder(command);
+        } catch (Exception e) {
+          // 포인트 부족 등 실패 카운트
+          errorCount.incrementAndGet();
+        } finally {
+          latch.countDown();
+        }
+      });
+    }
+
+    latch.await();
+
+    // 재고 검증
+    Stock stock1 = stockService.findByProductId(productId1);
+    Stock stock2 = stockService.findByProductId(productId2);
+
+    assertThat(stock1.getAvailable()).isEqualTo(5); // 상품1
+    assertThat(stock2.getAvailable()).isEqualTo(5); // 상품2ㄴ
+
+    // 포인트 검증: 초기 포인트 10 + 충전포인트 30, 상품1 단가1 + 상품2 단가4 → 성공 주문만 차감
+    BigDecimal remainingPoint = pointService.getAmount(userId);
+    assertThat(remainingPoint).isEqualByComparingTo(new BigDecimal(15));
+
+    // 실패 건수 검증
+    assertThat(errorCount.get()).isZero();
+  }
+
+  private CreateOrderCommand createOrderCommand(Long userId, Long productId, int quantity) {
+    List<OrderCreateV1Dto.OrderItemRequest> items = List.of(
+        new OrderCreateV1Dto.OrderItemRequest(productId, quantity)
+    );
+    OrderCreateV1Dto.OrderRequest request = new OrderCreateV1Dto.OrderRequest(items);
+    return CreateOrderCommand.from(userId, request);
+  }
+}
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..730ed2dc2
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/application/order/OrderFacadeIntegrationTest.java
@@ -0,0 +1,192 @@
+package com.loopers.application.order;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.brand.BrandService;
+import com.loopers.domain.order.Money;
+import com.loopers.domain.order.Order;
+import com.loopers.domain.order.OrderItem;
+import com.loopers.domain.order.OrderService;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductFixture;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.stock.Stock;
+import com.loopers.domain.stock.StockFixture;
+import com.loopers.domain.stock.StockService;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+import com.loopers.domain.user.UserService;
+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.util.ArrayList;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+
+@SpringBootTest
+class OrderFacadeIntegrationTest {
+  @Autowired
+  private OrderFacade sut;
+  @MockitoSpyBean
+  private UserService userService;
+  @MockitoSpyBean
+  private BrandService brandService;
+  @MockitoSpyBean
+  private ProductService productService;
+  @MockitoSpyBean
+  private StockService stockService;
+  @MockitoSpyBean
+  private OrderService orderService;
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  List<User> savedUsers;
+  List<Brand> savedBrands;
+  List<Product> savedProducts;
+  Order savedOrder;
+
+  @BeforeEach
+  void setup() {
+    // 사용자 생성
+    savedUsers = List.of(
+        userService.join(UserFixture.createUserWithLoginId("user1")),
+        userService.join(UserFixture.createUserWithLoginId("user2"))
+    );
+
+    // 브랜드 생성
+    savedBrands = brandService.saveAll(List.of(
+        BrandFixture.createBrand(),
+        BrandFixture.createBrand()
+    ));
+
+    // 상품 생성
+    savedProducts = productService.saveAll(List.of(
+        ProductFixture.createProductWith("product1", Money.wons(8)),
+        ProductFixture.createProductWith("product2", Money.wons(4)),
+        ProductFixture.createProduct(savedBrands.get(1))
+    ));
+    // 재고 생성
+    stockService.save(StockFixture.createStockWith(savedProducts.get(0).getId(), 10));
+    stockService.save(StockFixture.createStockWith(savedProducts.get(1).getId(), 10));
+
+    List<OrderItem> orderItems = new ArrayList<>();
+    orderItems.add(OrderItem.create(savedProducts.get(0).getId(), 2L, Money.wons(5_000)));
+    Order order = Order.create(savedUsers.get(0).getId(), orderItems);
+    savedOrder = orderService.save(order);
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("주문목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=20, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_주문목록조회() {
+      Long userId = savedUsers.get(0).getId();
+      // act
+      Page<Order> ordersPage = sut.getOrderList(userId, "latest", 0, 20);
+      List<Order> orders = ordersPage.getContent();
+      // assert
+      assertThat(orders).isNotEmpty().hasSize(1);
+    }
+  }
+
+  @DisplayName("주문을 조회할 때,")
+  @Nested
+  class Get {
+    @DisplayName("존재하는 주문 ID를 주면, 해당 주문 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_상품ID() {
+      // arrange
+      Long orderId = savedOrder.getId();
+      // act
+      OrderInfo result = sut.getOrderDetail(orderId);
+
+      // assert
+      assertThat(result.id()).isEqualTo(savedOrder.getId());
+      assertThat(result.status()).isEqualTo(savedOrder.getStatus().toString());
+      assertThat(result.totalPrice()).isEqualByComparingTo(savedOrder.getTotalPrice().getAmount());
+    }
+
+    @DisplayName("존재하지 않는 주문 ID를 주면, 예외가 반환된다.")
+    @Test
+    void 실패_존재하지_않는_상품ID() {
+      // arrange
+      Long orderId = (long) -1;
+      // act
+      // assert
+      assertThrows(CoreException.class, () -> {
+        sut.getOrderDetail(orderId);
+      });
+    }
+  }
+
+  @DisplayName("주문을 생성할 때,")
+  @Nested
+  class Post {
+    @DisplayName("주문 성공 시, 모든 처리는 정상 반영되어야 한다.")
+    @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(savedUsers.get(0).getId(), request);
+      // act
+      OrderInfo savedOrder = sut.createOrder(orderCommand);
+      // assert
+      assertThat(savedOrder).isNotNull();
+      assertThat(savedOrder.totalPrice()).isEqualByComparingTo(savedProducts.get(0).getPrice().getAmount());
+      assertThat(savedOrder.orderItemInfo()).hasSize(1);
+    }
+
+    @DisplayName("재고가 존재하지 않거나 부족할 경우 주문은 실패해야 한다. 모두 롤백")
+    @Test
+    void 실패_재고없음오류() {
+      long productId = savedProducts.get(1).getId();
+      long quantity = 20L;
+      List<OrderCreateV1Dto.OrderItemRequest> items = new ArrayList<>();
+      items.add(new OrderCreateV1Dto.OrderItemRequest(productId, quantity));
+      OrderCreateV1Dto.OrderRequest request = new OrderCreateV1Dto.OrderRequest(items);
+      CreateOrderCommand orderCommand = CreateOrderCommand.from(savedUsers.get(0).getId(), request);
+      // act
+      // assert
+      assertThrows(CoreException.class, () -> sut.createOrder(orderCommand)).getErrorType().equals(ErrorType.INSUFFICIENT_STOCK);
+      Stock deductedStock = stockService.findByProductId(productId);
+      assertThat(deductedStock.getAvailable()).isEqualTo(10);
+    }
+
+    @DisplayName("주문 시 유저의 포인트 잔액이 부족할 경우 주문은 실패해야 한다. 모두 롤백")
+    @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(savedUsers.get(0).getId(), request);
+      // act
+      // assert
+      CoreException actualException = assertThrows(CoreException.class,
+          () -> sut.createOrder(orderCommand));
+      assertThat(actualException.getErrorType()).isEqualTo(ErrorType.INSUFFICIENT_POINT);
+      Stock deductedStock = stockService.findByProductId(productId);
+      assertThat(deductedStock.getAvailable()).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..e0ea35488
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/application/product/ProductFacadeIntegrationTest.java
@@ -0,0 +1,126 @@
+package com.loopers.application.product;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.brand.BrandRepository;
+import com.loopers.domain.like.LikeRepository;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductFixture;
+import com.loopers.domain.product.ProductRepository;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+import com.loopers.domain.user.UserRepository;
+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.transaction.annotation.Transactional;
+
+import java.util.List;
+
+import static com.loopers.domain.product.ProductAssertions.assertProduct;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+
+@SpringBootTest
+@Transactional
+class ProductFacadeIntegrationTest {
+  @Autowired
+  private ProductFacade sut;
+  @Autowired
+  private UserRepository userRepository;
+  @Autowired
+  private BrandRepository brandRepository;
+  @Autowired
+  private ProductRepository productRepository;
+  @Autowired
+  private LikeRepository likeRepository;
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  User savedUser;
+  List<Product> savedProducts;
+
+  @BeforeEach
+  void setup() {
+    // arrange
+    savedUser = userRepository.save(UserFixture.createUser());
+    List<Brand> brandList = List.of(BrandFixture.createBrand(), BrandFixture.createBrand());
+    List<Brand> savedBrands = brandRepository.saveAll(brandList);
+
+    List<Product> productList = List.of(ProductFixture.createProduct(savedBrands.get(0))
+        , ProductFixture.createProduct(savedBrands.get(0))
+        , ProductFixture.createProduct(savedBrands.get(1)));
+    savedProducts = productRepository.saveAll(productList);
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("상품목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=20, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_상품목록조회() {
+      // arrange
+      Long brandId = null;
+      likeRepository.save(savedUser.getId(), savedProducts.get(0).getId());
+      // act
+      Page<ProductWithLikeCount> productsPage = sut.getProductList(brandId, "latest", 0, 20);
+      List<ProductWithLikeCount> products = productsPage.getContent();
+      // assert
+      assertThat(products).isNotEmpty().hasSize(3);
+      assertThat(products.get(2).name()).isEqualTo(savedProducts.get(0).getName());
+      assertThat(products.get(2).likeCount()).isEqualTo(1);
+    }
+
+    @DisplayName("브랜드ID 검색조건 포함시, 해당 브랜드의 상품 목록이 조회된다.")
+    @Test
+    void 성공_상품목록조회_브랜드ID() {
+      // arrange
+      Long brandId = savedProducts.get(0).getBrand().getId();
+      // act
+      Page<ProductWithLikeCount> productsPage = sut.getProductList(brandId, null, 0, 20);
+      List<ProductWithLikeCount> resultList = productsPage.getContent();
+
+      // assert
+      assertThat(resultList).isNotEmpty().hasSize(2);
+      assertThat(resultList.get(0).name()).isEqualTo(savedProducts.get(1).getName());
+      assertThat(resultList.get(1).name()).isEqualTo(savedProducts.get(0).getName());
+    }
+  }
+
+  @DisplayName("상품을 조회할 때,")
+  @Nested
+  class Get {
+    @DisplayName("존재하는 상품 ID를 주면, 해당 상품 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_상품ID() {
+      // arrange
+      Long productId = savedProducts.get(0).getId();
+      // act
+      ProductDetailInfo result = sut.getProductDetail(savedUser.getId(), productId);
+      // assert
+      assertThat(result.name()).isEqualTo(savedProducts.get(0).getName());
+    }
+
+    @DisplayName("존재하지 않는 상품 ID를 주면, 예외가 반환된다.")
+    @Test
+    void 실패_존재하지_않는_상품ID() {
+      // arrange
+      Long productId = (long) -1;
+      // act
+      // assert
+      assertThrows(CoreException.class, () -> {
+        sut.getProductDetail(savedUser.getId(), productId);
+      });
+    }
+  }
+
+}
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..e445bac82
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandAssertions.java
@@ -0,0 +1,13 @@
+package com.loopers.domain.brand;
+
+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/BrandFixture.java b/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandFixture.java
new file mode 100644
index 000000000..9a9aabfcc
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandFixture.java
@@ -0,0 +1,45 @@
+package com.loopers.domain.brand;
+
+import org.instancio.Instancio;
+import org.instancio.Model;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.instancio.Select.field;
+
+public class BrandFixture {
+
+  private static final Model<Brand> BRAND_MODEL = Instancio.of(Brand.class)
+      .ignore(field(Brand::getId))
+      .ignore(field(Brand::getCreatedAt))
+      .ignore(field(Brand::getUpdatedAt))
+      .ignore(field(Brand::getDeletedAt))
+      .generate(field(Brand::getName), gen -> gen.string())
+      .generate(field(Brand::getStory), gen -> gen.string())
+      .toModel();
+
+  public static Brand createBrand() {
+    Brand brand = Instancio.of(BRAND_MODEL).create();
+    return brand;
+  }
+
+  /**
+   * 특정 필드만 override
+   */
+  public static Brand createBrandWith(String name, String story) {
+    Brand brand = Instancio.of(BRAND_MODEL)
+        .set(field(Brand::getName), name)
+        .set(field(Brand::getStory), story)
+        .create();
+    return brand;
+  }
+
+  public static List<Brand> createBrandList(int size) {
+    return Instancio.ofList(Brand.class)
+        .size(size)
+        .create();
+  }
+
+}
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..2191e678d
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandModelTest.java
@@ -0,0 +1,43 @@
+package com.loopers.domain.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 static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class BrandModelTest {
+  Brand brand = BrandFixture.createBrand();
+  String validMsg = "";
+
+  @DisplayName("브랜드 모델을 생성할 때, ")
+  @Nested
+  class Create_Brand {
+    @DisplayName("브랜드명과 스토리가 모두 주어지면, 정상적으로 생성된다.")
+    @Test
+    void 성공_Brand_객체생성() {
+      //given
+      Brand result = Brand.create(brand.getName(), brand.getStory());
+      //assert
+      BrandAssertions.assertBrand(brand, result);
+    }
+  }
+
+  @Nested
+  class Valid_Brand {
+    @BeforeEach
+    void setup() {
+      validMsg = "브랜드명은 비어있을 수 없습니다.";
+    }
+
+    @Test
+    void 실패_이름_오류() {
+      assertThatThrownBy(() -> {
+        Brand result = Brand.create("", brand.getStory());
+      }).isInstanceOf(CoreException.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..ba0378607
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/brand/BrandServiceIntegrationTest.java
@@ -0,0 +1,75 @@
+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 sut;
+
+  @MockitoSpyBean
+  private BrandRepository brandRepository;
+
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  List<Brand> savedBrands;
+
+  @BeforeEach
+  void setup() {
+    List<Brand> brandList = List.of(BrandFixture.createBrand(), BrandFixture.createBrand());
+    savedBrands = brandRepository.saveAll(brandList);
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("브랜드를 조회할 때,")
+  @Nested
+  class Get {
+    @DisplayName("존재하는 브랜드 ID를 주면, 해당 브랜드 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_브랜드ID() {
+      // arrange
+      Long brandId = savedBrands.get(0).getId();
+      // act
+      Brand result = sut.getBrand(brandId);
+
+      // assert
+      assertBrand(result, savedBrands.get(0));
+    }
+
+    @DisplayName("존재하지 않는 브랜드 ID를 주면, null을 반환한다.")
+    @Test
+    void 실패_존재하지_않는_브랜드ID() {
+      // arrange
+      Long brandId = (long) -1;
+      // act
+      Brand result = sut.getBrand(brandId);
+
+      // 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..4ef0dd5a4
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/like/FakeLikeRepository.java
@@ -0,0 +1,109 @@
+package com.loopers.domain.like;
+
+import com.loopers.domain.product.ProductFixture;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+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) {
+    for (Long key : list.keySet()) {
+      Like like = list.get(key);
+      if (like.getUser().getId().equals(userId)
+          && like.getProduct().getId().equals(productId)) {
+        return Optional.of(like);
+      }
+    }
+    return Optional.empty();
+  }
+
+  @Override
+  public int save(Long userId, Long productId) {
+    for (Long key : list.keySet()) {
+      Like like = list.get(key);
+      if (like.getUser().getId().equals(userId)
+          && like.getProduct().getId().equals(productId)) {
+        throw new CoreException(ErrorType.BAD_REQUEST, "중복 좋아요 요청입니다.");
+      }
+    }
+    Long id = list.keySet().stream().max(Long::compareTo).orElse(0L) + 1;
+    Like like = Like.create(UserFixture.createUser(), ProductFixture.createProduct());
+
+    list.put(id, like);
+    return 1;
+  }
+
+  @Override
+  public void remove(Long userId, Long productId) {
+    Iterator<Map.Entry<Long, Like>> iterator = list.entrySet().iterator();
+    while (iterator.hasNext()) {
+      Map.Entry<Long, Like> entry = iterator.next();
+      Like like = entry.getValue();
+      if (like.getUser().getId().equals(userId)
+          && like.getProduct().getId().equals(productId)) {
+        iterator.remove();
+      }
+    }
+  }
+
+  @Override
+  public boolean isLiked(Long userId, Long productId) {
+    for (Long key : list.keySet()) {
+      Like like = list.get(key);
+      if (like.getUser().getId().equals(userId)
+          && like.getProduct().getId().equals(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().equals(productId)) {
+        cnt++;
+      }
+    }
+    return cnt;
+  }
+
+  @Override
+  public Page<Like> getLikedProducts(Long userId, Pageable pageable) {
+    return new PageImpl<>(list.values().stream().filter(i -> i.getUser().getId().equals(userId))
+        .collect(Collectors.toList()), pageable, list.size());
+  }
+
+  @Override
+  public List<ProductIdAndLikeCount> getLikeCountWithProductId(List<Long> productIds) {
+    Map<Long, Long> likeCountsByProduct = list.values().stream()
+        .filter(like -> productIds.contains(like.getProduct().getId()))
+        .collect(Collectors.groupingBy(
+            like -> like.getProduct().getId(),
+            Collectors.counting()
+        ));
+
+    return likeCountsByProduct.entrySet().stream()
+        .map(entry -> new ProductIdAndLikeCount(
+            entry.getKey(), // Product ID
+            entry.getValue() // Like Count
+        ))
+        .collect(Collectors.toList());
+  }
+}
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..cdd88f405
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeServiceIntegrationTest.java
@@ -0,0 +1,166 @@
+package com.loopers.domain.like;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.order.Money;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+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.data.domain.Page;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+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.assertj.core.api.AssertionsForClassTypes.assertThatCode;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+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;
+
+  @BeforeEach
+  void setup() {
+    savedUser = userJpaRepository.save(UserFixture.createUser());
+    Brand brand = Brand.create("레이브", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.");
+    savedBrand = brandJpaRepository.save(brand);
+    Product product = Product.create(savedBrand, "Wild Faith Rose Sweatshirt", Money.wons(80_000));
+    savedProduct = productJpaRepository.save(product);
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("좋아요를 조회할 때,")
+  @Nested
+  class Create {
+    @DisplayName("존재하는 좋아요 ID를 주면, 좋아요 성공한다.")
+    @Test
+    void 성공_존재하는_좋아요ID() {
+      // arrange
+      Long userId = savedUser.getId();
+      Long productId = savedProduct.getId();
+      // act
+      likeService.save(userId, productId);
+      Optional<Like> savedLike = likeJpaRepository.findByUserIdAndProductId(userId, productId);
+      // assert
+      assertThat(savedLike).isPresent();
+      assertThat(savedLike.get().getUser().getId()).isEqualTo(userId);
+      assertThat(savedLike.get().getProduct().getId()).isEqualTo(productId);
+
+    }
+
+    @DisplayName("동일한 좋아요를 중복 저장해도 일관된 결과를 반환한다")
+    @Test
+    void 성공_이미_존재하는_좋아요ID() {
+      // arrange
+      Long userId = savedUser.getId();
+      Long productId = savedProduct.getId();
+
+      likeService.save(userId, productId);
+      Optional<Like> result1 = likeJpaRepository.findByUserIdAndProductId(userId, productId);
+
+      // act
+      likeService.save(userId, productId);
+      Optional<Like> result2 = likeJpaRepository.findByUserIdAndProductId(userId, productId);
+
+      // assert
+      assertThat(result1).isPresent();
+      assertThat(result2).isPresent();
+      assertLike(result1.get(), result2.get());
+    }
+  }
+
+  @DisplayName("좋아요를 삭제할 때,")
+  @Nested
+  class Delete {
+    @DisplayName("존재하는 좋아요를 삭제한다.")
+    @Test
+    void 성공_존재하는_좋아요ID() {
+      // arrange
+      Long userId = savedUser.getId();
+      Long productId = savedProduct.getId();
+
+      likeService.save(userId, productId);
+      Like like = likeJpaRepository.findByUserIdAndProductId(userId, productId).orElseThrow();
+
+      // act
+      likeService.remove(savedUser.getId(), savedProduct.getId());
+
+      // assert
+      verify(likeJpaRepository, times(1)).delete(userId, productId);
+      //assertThrows(NotFoundException.class, () -> service.read(id));
+    }
+
+    @DisplayName("존재하지 않는 좋아요 ID를 삭제하면, 예외가 발생하지 않는다.")
+    @Test
+    void 성공_이미_삭제된_좋아요() {
+      // arrange
+      Long userId = savedUser.getId();
+      Long productId = savedProduct.getId();
+
+      likeService.save(userId, productId);
+      likeService.remove(savedUser.getId(), savedProduct.getId());
+      likeJpaRepository.flush(); // 즉시 삭제 반영
+      // act
+
+      // assert
+      assertThatCode(() -> likeService.remove(userId, productId))
+          .doesNotThrowAnyException();
+    }
+  }
+
+  @DisplayName("좋아요 상품목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=20, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_좋아요_상품목록조회() {
+      // arrange
+      Long userId = savedUser.getId();
+      Long productId = savedProduct.getId();
+
+      likeService.save(userId, productId);
+
+      // 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..cf6f718c8
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/like/LikeServiceTest.java
@@ -0,0 +1,164 @@
+package com.loopers.domain.like;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.order.Money;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+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.data.domain.Page;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+import java.util.List;
+
+import static com.loopers.domain.like.LikeAssertions.assertLike;
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+@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() {
+    savedUser = userJpaRepository.save(UserFixture.createUser());
+    Brand brand = Brand.create("레이브", "레이브는 음악, 영화, 예술 등 다양한 문화에서 영감을 받아 경계 없고 자유분방한 스타일을 제안하는 패션 레이블입니다.");
+    savedBrand = brandJpaRepository.save(brand);
+    Product product = Product.create(savedBrand, "Wild Faith Rose Sweatshirt", Money.wons(80_000));
+    savedProduct = productJpaRepository.save(product);
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("좋아요를 생성할 때,")
+  @Nested
+  class Create {
+    @DisplayName("좋아요를 생성하면, 생성된 좋아요 정보를 반환한다.")
+    @Test
+    void 성공_좋아요_생성() {
+      // arrange
+      Long userId = savedUser.getId();
+      Long productId = savedProduct.getId();
+      // act
+      likeService.save(userId, productId);
+
+      // assert
+      Long result = likeService.getLikeCount(productId);
+      assertThat(result).isEqualTo(1);
+    }
+
+    @DisplayName("동일한 좋아요를 중복 생성하면, 멱등성이 보장된다.")
+    @Test
+    void 성공_중복_좋아요_멱등성() {
+      // arrange
+      Long userId = savedUser.getId();
+      Long productId = savedProduct.getId();
+      likeService.save(userId, productId);
+
+      // act
+      likeService.save(userId, productId);
+
+      // assert
+      Long result = likeService.getLikeCount(productId);
+      assertThat(result).isEqualTo(1);
+    }
+  }
+
+  @DisplayName("좋아요를 삭제할 때,")
+  @Nested
+  class Delete {
+    @DisplayName("존재하는 좋아요를 삭제한다.")
+    @Test
+    void 성공_존재하는_좋아요ID() {
+      // arrange
+      Long userId = savedUser.getId();
+      Long productId = savedProduct.getId();
+      likeService.save(userId, productId);
+
+      // act
+      likeService.remove(savedUser.getId(), savedProduct.getId());
+      //assert
+      boolean result = likeService.isLiked(savedUser.getId(), savedProduct.getId());
+      assertThat(result).isFalse();
+    }
+
+    @DisplayName("존재하지 않는 좋아요 ID를 삭제하면, 예외가 발생하지 않는다.")
+    @Test
+    void 성공_이미_삭제된_좋아요() {
+      // arrange
+      Long userId = savedUser.getId();
+      Long productId = savedProduct.getId();
+      likeService.save(userId, productId);
+
+      // act
+      likeService.remove(savedUser.getId(), productId);
+      likeService.remove(savedUser.getId(), productId);
+
+      // assert
+      boolean result = likeService.isLiked(savedUser.getId(), productId);
+      assertThat(result).isFalse();
+    }
+  }
+
+  @DisplayName("좋아요 상품목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=20, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_좋아요_상품목록조회() {
+      // arrange
+      Long userId = savedUser.getId();
+      Long productId = savedProduct.getId();
+      likeService.save(userId, productId);
+
+      // 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/MoneyFixture.java b/apps/commerce-api/src/test/java/com/loopers/domain/order/MoneyFixture.java
new file mode 100644
index 000000000..bf8a9c03f
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/order/MoneyFixture.java
@@ -0,0 +1,35 @@
+package com.loopers.domain.order;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.product.Product;
+import org.instancio.Instancio;
+import org.instancio.Model;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.instancio.Select.field;
+
+public class MoneyFixture {
+
+  private static final Model<Money> MODEL = Instancio.of(Money.class)
+      .generate(field(Money::getAmount),
+          gen -> gen.math().bigDecimal().scale(0).min(BigDecimal.ZERO))
+      .generate(field(Money::getCurrency),
+          gen -> gen.enumOf(CurrencyCode.class))
+      .toModel();
+
+  public static Money create() {
+    return Instancio.of(MODEL).create();
+  }
+
+  public static Money createWith(BigDecimal amount, CurrencyCode currency) {
+    return Instancio.of(MODEL)
+        .set(field(Money::getAmount), amount)
+        .set(field(Money::getCurrency), currency)
+        .create();
+  }
+}
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..6e38ff211
--- /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()).isEqualTo(expected.getTotalPrice());
+    assertThat(actual.getOrderAt()).isEqualTo(expected.getOrderAt());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderItemModelTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderItemModelTest.java
new file mode 100644
index 000000000..a41f50b54
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderItemModelTest.java
@@ -0,0 +1,47 @@
+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 static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+class OrderItemModelTest {
+  OrderItem orderItems;
+
+  @DisplayName("주문상세 모델을 생성할 때, ")
+  @Nested
+  class Create_Order {
+    @DisplayName("사용자ID, 상태, 지불금액,총금액, 주문일자가 모두 주어지면, 정상적으로 생성된다.")
+    @Test
+    void 성공_Order_객체생성() {
+      orderItems = OrderItem.create(1L, 2L, Money.wons(5_000));
+      assertThat(orderItems.getRefProductId()).isEqualTo(1L);
+      assertThat(orderItems.getQuantity()).isEqualTo(2L);
+      assertThat(orderItems.getUnitPrice()).isEqualTo(Money.wons(5_000));
+
+    }
+  }
+
+  @DisplayName("주문 모델을 생성할 때, 검증")
+  @Nested
+  class Valid_Order {
+
+    @Test
+    void 실패_수량_음수오류() {
+      Money unitPrice = Money.wons(5_000);
+      assertThrows(CoreException.class, () -> {
+        orderItems = OrderItem.create(1L, -2L, unitPrice);
+      });
+    }
+
+    @Test
+    void 실패_단가_음수오류() {
+      assertThrows(IllegalArgumentException.class, () -> {
+        orderItems = OrderItem.create(1L, 2L, Money.wons(-5_000));
+      });
+    }
+  }
+}
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..1b322f477
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderModelTest.java
@@ -0,0 +1,89 @@
+package com.loopers.domain.order;
+
+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.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.jupiter.api.Assertions.assertThrows;
+
+class OrderModelTest {
+  Order order;
+  List<OrderItem> orderItems = new ArrayList<>();
+
+  @BeforeEach
+  void setup() {
+    orderItems = new ArrayList<>();
+    orderItems.add(OrderItem.create(1L, 2L, Money.wons(5_000)));
+  }
+
+  @DisplayName("주문 모델을 생성할 때, ")
+  @Nested
+  class Create_Order {
+    @DisplayName("사용자ID, 상태, 지불금액,총금액, 주문일자가 모두 주어지면, 정상적으로 생성된다.")
+    @Test
+    void 성공_Order_객체생성() {
+      order = Order.create(1, orderItems);
+      assertThat(order.getRefUserId()).isEqualTo(1);
+      assertThat(order.getStatus()).isEqualTo(OrderStatus.PENDING);
+
+    }
+  }
+
+  @DisplayName("주문 확인시, 상품준비중 상태로 변경")
+  @Nested
+  class Valid_상품준비중 {
+    @Test
+    void 실패_주문확인_결제전오류() {
+      order = Order.create(1, orderItems);
+      assertThatThrownBy(() -> {
+        order.preparing();
+      }).isInstanceOf(CoreException.class).hasMessageContaining("결제대기중");
+    }
+
+    @Test
+    void 실패_주문확인_상품준비중오류() {
+      order = Order.create(1, orderItems);
+      order.paid();
+      order.preparing();
+      assertThatThrownBy(() -> {
+        order.preparing();
+      }).isInstanceOf(CoreException.class).hasMessageContaining("이미 준비중");
+    }
+
+
+    @Test
+    void 성공_상품준비중() {
+      order = Order.create(1, orderItems);
+      order.paid();
+      order.preparing();
+      assertThat(order.getStatus()).isEqualTo(OrderStatus.PREPARING);
+    }
+  }
+
+  @DisplayName("상품 모델을 생성후, 주문취소")
+  @Nested
+  class Valid_주문취소 {
+    @Test
+    void 실패_주문취소_이미취소된주문오류() {
+      order = Order.create(1, orderItems);
+      order.cancel();
+      assertThrows(CoreException.class, () -> {
+        order.cancel();
+      });
+    }
+
+    @Test
+    void 성공_주문취소() {
+      order = Order.create(1, 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..85b5e3fe2
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/order/OrderServiceIntegrationTest.java
@@ -0,0 +1,140 @@
+package com.loopers.domain.order;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.brand.BrandRepository;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductFixture;
+import com.loopers.domain.product.ProductRepository;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+import com.loopers.domain.user.UserRepository;
+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.util.ArrayList;
+import java.util.List;
+
+import static com.loopers.domain.order.OrderAssertions.assertOrder;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+
+@SpringBootTest
+@Transactional
+class OrderServiceIntegrationTest {
+  @Autowired
+  private OrderService sut;
+
+  @MockitoSpyBean
+  private UserRepository userRepository;
+
+  @MockitoSpyBean
+  private BrandRepository brandRepository;
+  @MockitoSpyBean
+  private ProductRepository productRepository;
+  @MockitoSpyBean
+  private OrderRepository orderRepository;
+
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  User savedUser;
+  List<Brand> savedBrands;
+  List<Product> savedProducts;
+  Order savedOrder;
+
+  @BeforeEach
+  void setup() {
+    savedUser = userRepository.save(UserFixture.createUser());
+    List<Brand> brandList = List.of(BrandFixture.createBrand(), BrandFixture.createBrand());
+    savedBrands = brandRepository.saveAll(brandList);
+
+    List<Product> productList = List.of(ProductFixture.createProduct(savedBrands.get(0))
+        , ProductFixture.createProduct(savedBrands.get(0))
+        , ProductFixture.createProduct(savedBrands.get(1)));
+    savedProducts = productRepository.saveAll(productList);
+
+    List<OrderItem> orderItems = new ArrayList<>();
+    orderItems.add(OrderItem.create(productList.get(0).getId(), 2L, Money.wons(5_000)));
+    Order order = Order.create(savedUser.getId(), orderItems);
+    savedOrder = orderRepository.save(order);
+
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("주문목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=20, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_상품목록조회() {
+      // arrange
+      Long userId = savedUser.getId();
+      // act
+      Page<Order> ordersPage = sut.getOrders(userId, "latest", 0, 20);
+      List<Order> orders = ordersPage.getContent();
+      // assert
+      assertThat(orders).isNotEmpty().hasSize(1);
+    }
+  }
+
+  @DisplayName("주문을 조회할 때,")
+  @Nested
+  class Get {
+    @DisplayName("존재하는 주문 ID를 주면, 해당 주문 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_주문ID() {
+      // arrange
+      Long orderId = savedOrder.getId();
+      // act
+      Order result = sut.getOrder(orderId);
+
+      // assert
+      assertOrder(result, savedOrder);
+    }
+
+    @DisplayName("존재하지 않는 상품 ID를 주면, null이 반환된다.")
+    @Test
+    void 실패_존재하지_않는_주문ID() {
+      // arrange
+      Long orderId = (long) -1;
+      // act
+      Order result = sut.getOrder(orderId);
+      // assert
+      assertThat(result).isNull();
+    }
+  }
+
+  @DisplayName("주문 생성")
+  @Nested
+  class Save {
+    @DisplayName("주문 생성을 한다.")
+    @Test
+    void 성공_주문생성() {
+      // arrange
+      List<OrderItem> orderItems = new ArrayList<>();
+      orderItems.add(OrderItem.create(savedProducts.get(0).getId(), 2L, Money.wons(5_000)));
+      Order order = Order.create(savedUser.getId(), orderItems);
+
+      // act
+      sut.save(order);
+
+      // assert
+      assertAll(
+          () -> verify(orderRepository, times(1)).save(order)
+      );
+    }
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/point/PointFixture.java b/apps/commerce-api/src/test/java/com/loopers/domain/point/PointFixture.java
new file mode 100644
index 000000000..8cd11aab9
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/point/PointFixture.java
@@ -0,0 +1,46 @@
+package com.loopers.domain.point;
+
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+import org.instancio.Instancio;
+import org.instancio.Model;
+
+import java.math.BigDecimal;
+
+import static org.instancio.Select.field;
+
+public class PointFixture {
+  private static final Model<Point> POINT_MODEL = Instancio.of(Point.class)
+      .ignore(field(Point::getId))
+      .ignore(field(Point::getCreatedAt))
+      .ignore(field(Point::getUpdatedAt))
+      .ignore(field(Point::getDeletedAt))
+      .ignore(field(Point::getUser))
+      .generate(field(Point::getAmount), gen -> gen.math().bigDecimal().min(BigDecimal.ZERO)
+      )
+      .toModel();
+
+  public static Point createPoint() {
+    Point point = Instancio.of(POINT_MODEL).create();
+    User user = UserFixture.createUser(point);
+    point.setUser(user);
+    return point;
+  }
+
+  /**
+   * 특정 필드만 override
+   */
+  public static Point createPointWith(BigDecimal amount) {
+    Point point = Instancio.of(POINT_MODEL)
+        .set(field(Point::getAmount), amount)
+        .create();
+
+    User user = UserFixture.createUser(point);
+    point.setUser(user);
+    return point;
+  }
+
+  public static Point createPoint(User user) {
+    return Point.create(user, BigDecimal.TEN);
+  }
+}
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..5367afd2d 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,8 @@
 package com.loopers.domain.point;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+import com.loopers.domain.user.UserService;
 import com.loopers.infrastructure.point.PointJpaRepository;
 import com.loopers.infrastructure.user.UserJpaRepository;
 import com.loopers.support.error.CoreException;
@@ -14,7 +16,6 @@
 import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
 
 import java.math.BigDecimal;
-import java.util.Optional;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -28,7 +29,7 @@ class PointServiceIntegrationTest {
   private PointService pointService;
 
   @Autowired
-  private UserJpaRepository userJpaRepository;
+  private UserService userService;
 
   @MockitoSpyBean
   private PointJpaRepository pointJpaRepository;
@@ -48,17 +49,16 @@ class Get {
     @Test
     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 = UserFixture.createUser();
+      User saved = userService.join(user);
 
       // act
-      BigDecimal pointAmt = pointService.getAmount(userModel.getUserId());
+      BigDecimal pointAmt = pointService.getAmount(saved.getId());
 
       // assert(회원가입시, 기본포인트 10)
       assertAll(
           () -> assertThat(pointAmt).isNotNull(),
-          () -> assertEquals(0, pointAmt.compareTo(new BigDecimal(10)))
+          () -> assertEquals(0, pointAmt.compareTo(saved.getPoint().getAmount()))
       );
     }
 
@@ -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 = UserFixture.createUser();
 
       // act, assert
       assertThatThrownBy(() -> {
-        pointService.charge(userModel, BigDecimal.TEN);
+        pointService.charge(user, BigDecimal.TEN);
       }).isInstanceOf(CoreException.class).hasMessageContaining("현재 포인트 정보를 찾을수 없습니다.");
 
     }
@@ -97,17 +97,17 @@ class Charge {
     @Test
     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());
+      BigDecimal chargeAmt = BigDecimal.TEN;
+
+      User savedUser = userService.join(UserFixture.createUser());
+
       // act
-      BigDecimal pointAmt = pointService.charge(savedUserModel.get(), BigDecimal.TEN);
+      BigDecimal pointAmt = pointService.charge(savedUser, chargeAmt);
 
       // assert(회원가입시, 기본포인트 10)
       assertAll(
           () -> assertThat(pointAmt).isNotNull(),
-          () -> assertEquals(0, pointAmt.compareTo(new BigDecimal(20)))
+          () -> assertEquals(0, pointAmt.compareTo(savedUser.getPoint().getAmount().add(chargeAmt)))
       );
     }
 
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 54%
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..c97dba985 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,7 @@
 package com.loopers.domain.point;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
 import com.loopers.support.error.CoreException;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
@@ -12,13 +13,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 = UserFixture.createUser();
   }
 
   @DisplayName("포인트 충전")
@@ -28,24 +29,29 @@ class Charge {
     @Test
     void 실패_포인트충전_0() {
       // arrange
-      pointModel = PointModel.create(userModel, BigDecimal.ZERO);
+      BigDecimal pointAmt = new BigDecimal(1);
+      BigDecimal chargeAmt = new BigDecimal(0);
+
+      point = PointFixture.createPointWith(pointAmt);
 
       // act, assert
       assertThatThrownBy(() -> {
-        pointModel.charge(BigDecimal.ZERO);
+        point.charge(chargeAmt);
       }).isInstanceOf(CoreException.class).hasMessageContaining("충전 금액은 0보다 커야 합니다.");
     }
 
     @Test
     void 성공_포인트충전() {
       // arrange
-      pointModel = PointModel.create(userModel, new BigDecimal(20));
+      BigDecimal pointAmt = new BigDecimal(1);
+      BigDecimal chargeAmt = new BigDecimal(5);
+      point = PointFixture.createPointWith(pointAmt);
 
       // act
-      pointModel.charge(new BigDecimal(5));
+      point.charge(chargeAmt);
 
       // assert
-      assertThat(pointModel.getAmount()).isEqualTo(new BigDecimal(25));
+      assertThat(point.getAmount()).isEqualTo(pointAmt.add(chargeAmt));
     }
   }
 
@@ -55,24 +61,28 @@ class Use {
     @Test
     void 실패_포인트사용() {
       // arrange
-      pointModel = PointModel.create(userModel, BigDecimal.ZERO);
+      BigDecimal pointAmt = new BigDecimal(1);
+      BigDecimal useAmt = new BigDecimal(10);
+      point = PointFixture.createPointWith(pointAmt);
 
       // act, assert
       assertThatThrownBy(() -> {
-        pointModel.use(BigDecimal.TEN);
-      }).isInstanceOf(CoreException.class).hasMessageContaining("잔액이 부족합니다.");
+        point.use(useAmt);
+      }).isInstanceOf(CoreException.class).hasMessageContaining("포인트가 부족합니다.");
     }
 
     @Test
     void 성공_포인트사용() {
       // arrange
-      pointModel = PointModel.create(userModel, new BigDecimal(20));
+      BigDecimal pointAmt = new BigDecimal(20);
+      BigDecimal useAmt = new BigDecimal(5);
+      point = PointFixture.createPointWith(pointAmt);
 
       // act
-      pointModel.use(new BigDecimal(5));
+      point.use(useAmt);
 
       // assert
-      assertThat(pointModel.getAmount()).isEqualTo(new BigDecimal(15));
+      assertThat(point.getAmount()).isEqualTo(pointAmt.subtract(useAmt));
     }
   }
 
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..99d2a1c9b
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductAssertions.java
@@ -0,0 +1,13 @@
+package com.loopers.domain.product;
+
+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()).isEqualTo(expected.getPrice());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductFixture.java b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductFixture.java
new file mode 100644
index 000000000..5528e3684
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductFixture.java
@@ -0,0 +1,70 @@
+package com.loopers.domain.product;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.order.Money;
+import com.loopers.domain.order.MoneyFixture;
+import org.instancio.Instancio;
+import org.instancio.Model;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.instancio.Select.field;
+
+public class ProductFixture {
+
+  private static final Model<Product> PRODUCT_MODEL = Instancio.of(Product.class)
+      .ignore(field(Product::getId))
+      .ignore(field(Product::getCreatedAt))
+      .ignore(field(Product::getUpdatedAt))
+      .ignore(field(Product::getDeletedAt))
+      .ignore(field(Product::getBrand))
+      .generate(field(Product::getName), gen -> gen.string())
+      .set(field(Product::getPrice), MoneyFixture.create())
+      .toModel();
+
+  public static Product createProduct() {
+    Product product = Instancio.of(PRODUCT_MODEL).create();
+    Brand brand = BrandFixture.createBrand();
+    product.setBrand(brand);
+    return product;
+  }
+
+  public static Product createProduct(Brand brand) {
+    Product product = Instancio.of(PRODUCT_MODEL).create();
+    product.setBrand(brand);
+    return product;
+  }
+
+  /**
+   * 특정 필드만 override
+   */
+  public static Product createProductWith(String name, Money price) {
+    Product stock = Instancio.of(PRODUCT_MODEL)
+        .set(field(Product::getName), name)
+        .set(field(Product::getPrice), price)
+        .create();
+    return stock;
+  }
+
+  public static Product createUserWithoutBrand() {
+    return Instancio.of(PRODUCT_MODEL).create();
+  }
+
+  public static List<Product> createProductList(int size) {
+    return Instancio.ofList(Product.class)
+        .size(size)
+        .create();
+  }
+
+  public static List<Product> createProductList(List<Brand> brandList) {
+    return IntStream.range(0, brandList.size())
+        .mapToObj(i -> Instancio.of(PRODUCT_MODEL)
+            .set(field(Product::getBrand), brandList.get(i))
+            .create()
+        )
+        .collect(Collectors.toList());
+  }
+}
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..8794019ed
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductModelTest.java
@@ -0,0 +1,48 @@
+package com.loopers.domain.product;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.order.Money;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+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;
+
+class ProductModelTest {
+  Brand brand = BrandFixture.createBrand();
+  Product product = ProductFixture.createProduct(brand);
+  String validMsg = "";
+
+  @DisplayName("상품 모델을 생성할 때, ")
+  @Nested
+  class Create_Product {
+    @DisplayName("브랜드모델, 상품명, 가격이 모두 주어지면, 정상적으로 생성된다.")
+    @Test
+    void 성공_Product_객체생성() {
+      Product result = Product.create(product.getBrand(), product.getName(), product.getPrice());
+      ProductAssertions.assertProduct(product, result);
+    }
+  }
+
+  @DisplayName("상품 모델을 생성할 때, 검증")
+  @Nested
+  class Valid_Product {
+    @BeforeEach
+    void setup() {
+      validMsg = "형식이 유효하지 않습니다.";
+    }
+
+    @Test
+    void 실패_가격_음수오류() {
+      assertThatThrownBy(() -> {
+        Product.create(product.getBrand(), product.getName(), Money.wons(-1_000));
+      }).isInstanceOf(IllegalArgumentException.class);
+    }
+  }
+}
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..f4e0cdbdf
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/product/ProductServiceIntegrationTest.java
@@ -0,0 +1,115 @@
+package com.loopers.domain.product;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.brand.BrandRepository;
+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.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 sut;
+
+  @MockitoSpyBean
+  private BrandRepository brandRepository;
+  @MockitoSpyBean
+  private ProductRepository productRepository;
+
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  List<Brand> savedBrands;
+  List<Product> savedProducts;
+
+  @BeforeEach
+  void setup() {
+    List<Brand> brandList = List.of(BrandFixture.createBrand(), BrandFixture.createBrand());
+    savedBrands = brandRepository.saveAll(brandList);
+
+    List<Product> productList = List.of(ProductFixture.createProduct(savedBrands.get(0))
+        , ProductFixture.createProduct(savedBrands.get(0))
+        , ProductFixture.createProduct(savedBrands.get(1)));
+    savedProducts = productRepository.saveAll(productList);
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("상품목록을 조회할 때,")
+  @Nested
+  class GetList {
+    @DisplayName("페이징 처리되어, 초기설정시 size=20, sort=최신순으로 목록이 조회된다.")
+    @Test
+    void 성공_상품목록조회() {
+      // arrange
+      Long brandId = null;
+      // act
+      Page<Product> productsPage = sut.getProducts(brandId, "latest", 0, 20);
+      List<Product> products = productsPage.getContent();
+      // assert
+      assertThat(products).isNotEmpty().hasSize(3);
+    }
+
+    @DisplayName("브랜드ID 검색조건 포함시, 해당 브랜드의 상품 목록이 조회된다.")
+    @Test
+    void 성공_상품목록조회_브랜드ID() {
+      // arrange
+      Long brandId = savedBrands.get(0).getId();
+      // act
+      Page<Product> productsPage = sut.getProducts(brandId, 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
+      Long productId = savedProducts.get(0).getId();
+      // act
+      Product result = sut.getProduct(productId);
+
+      // assert
+      assertProduct(result, savedProducts.get(0));
+      assertBrand(result.getBrand(), savedBrands.get(0));
+    }
+
+    @DisplayName("존재하지 않는 상품 ID를 주면, null이 반환된다.")
+    @Test
+    void 실패_존재하지_않는_상품ID() {
+      // arrange
+      Long productId = (long) -1;
+      // act
+      Product result = sut.getProduct(productId);
+
+      // assert
+      assertThat(result).isNull();
+    }
+  }
+
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockAssertions.java b/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockAssertions.java
new file mode 100644
index 000000000..a8fde045b
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockAssertions.java
@@ -0,0 +1,13 @@
+package com.loopers.domain.stock;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class StockAssertions {
+  public static void assertStock(Stock actual, Stock expected) {
+    assertThat(actual).isNotNull();
+    assertThat(expected).isNotNull();
+    assertThat(actual.getId()).isEqualTo(expected.getId());
+    assertThat(actual.getRefProductId()).isEqualTo(expected.getRefProductId());
+    assertThat(actual.getAvailable()).isEqualTo(expected.getAvailable());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockFixture.java b/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockFixture.java
new file mode 100644
index 000000000..70559d438
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockFixture.java
@@ -0,0 +1,39 @@
+package com.loopers.domain.stock;
+
+import org.instancio.Instancio;
+import org.instancio.Model;
+
+import static org.instancio.Select.field;
+
+public class StockFixture {
+
+  private static final Model<Stock> STOCK_MODEL = Instancio.of(Stock.class)
+      .ignore(field(Stock::getId))
+      .ignore(field(Stock::getCreatedAt))
+      .ignore(field(Stock::getUpdatedAt))
+      .ignore(field(Stock::getDeletedAt))
+      .generate(field(Stock::getRefProductId), gen -> gen.longs().min(0L))
+      .generate(field(Stock::getAvailable),
+          gen -> gen.longs().min(0L)
+      )
+      .toModel();
+
+  /**
+   * Stock + Point 자동 연결
+   */
+  public static Stock createStock() {
+    Stock stock = Instancio.of(STOCK_MODEL).create();
+    return stock;
+  }
+
+  /**
+   * 특정 필드만 override
+   */
+  public static Stock createStockWith(Long productId, long available) {
+    Stock stock = Instancio.of(STOCK_MODEL)
+        .set(field(Stock::getRefProductId), productId)
+        .set(field(Stock::getAvailable), available)
+        .create();
+    return stock;
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockModelTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockModelTest.java
new file mode 100644
index 000000000..28bca4e55
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockModelTest.java
@@ -0,0 +1,74 @@
+package com.loopers.domain.stock;
+
+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;
+
+class StockModelTest {
+  Stock stock;
+  String validMsg = "";
+
+  @DisplayName("상품 모델을 생성할 때, ")
+  @Nested
+  class Create_Stock {
+    @DisplayName("브랜드모델, 상품명, 가격, 재고, 예약재고가 모두 주어지면, 정상적으로 생성된다.")
+    @Test
+    void 성공_Stock_객체생성() {
+      stock = StockFixture.createStock();
+      Stock result = Stock.create(stock.getRefProductId(), stock.getAvailable());
+      StockAssertions.assertStock(stock, result);
+    }
+  }
+
+  @DisplayName("상품 모델을 생성할 때, 검증")
+  @Nested
+  class Valid_Stock {
+    @BeforeEach
+    void setup() {
+      validMsg = "형식이 유효하지 않습니다.";
+    }
+
+    @Test
+    void 실패_재고_음수오류() {
+      assertThatThrownBy(() -> {
+        stock = StockFixture.createStockWith(1L, -1000);
+        Stock.create(stock.getRefProductId(), stock.getAvailable());
+      }).isInstanceOf(CoreException.class);
+    }
+
+  }
+
+  @DisplayName("상품 모델을 생성후, 재고 예약")
+  @Nested
+  class Valid_재고차감 {
+    @BeforeEach
+    void setup() {
+      stock = StockFixture.createStock();
+    }
+
+    @Test
+    void 실패_차감재고0_차감오류() {
+      assertThatThrownBy(() -> {
+        stock.deduct(0);
+      }).isInstanceOf(CoreException.class);
+    }
+
+    @Test
+    void 실패_차감재고20_차감오류() {
+      assertThatThrownBy(() -> {
+        stock.deduct(stock.getAvailable() + 20);
+      }).isInstanceOf(CoreException.class);
+    }
+
+    @Test
+    void 성공_재고예약() {
+      stock.deduct(stock.getAvailable() - 1);
+      assertThat(stock.getAvailable()).isEqualTo(1);
+    }
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockServiceIntegrationTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockServiceIntegrationTest.java
new file mode 100644
index 000000000..a1f06dc3a
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/stock/StockServiceIntegrationTest.java
@@ -0,0 +1,88 @@
+package com.loopers.domain.stock;
+
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.brand.BrandRepository;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductFixture;
+import com.loopers.domain.product.ProductRepository;
+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 org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+@SpringBootTest
+@Transactional
+class StockServiceIntegrationTest {
+  @Autowired
+  private StockService sut;
+
+  @MockitoSpyBean
+  private BrandRepository brandRepository;
+  @MockitoSpyBean
+  private ProductRepository productRepository;
+  @MockitoSpyBean
+  private StockRepository stockRepository;
+  @Autowired
+  private DatabaseCleanUp databaseCleanUp;
+
+  List<Brand> savedBrands;
+  List<Product> savedProducts;
+  Stock savedStock;
+
+  @BeforeEach
+  void setup() {
+    List<Brand> brandList = List.of(BrandFixture.createBrand(), BrandFixture.createBrand());
+    savedBrands = brandRepository.saveAll(brandList);
+
+    List<Product> productList = List.of(ProductFixture.createProduct(savedBrands.get(0))
+        , ProductFixture.createProduct(savedBrands.get(0))
+        , ProductFixture.createProduct(savedBrands.get(1)));
+    savedProducts = productRepository.saveAll(productList);
+
+    Stock stock = StockFixture.createStockWith(savedProducts.get(0).getId(), 10);
+    savedStock = stockRepository.save(stock);
+  }
+
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("재고를 조회할 때,")
+  @Nested
+  class Get {
+    @DisplayName("존재하는 상품 ID를 주면, 해당 상품의 재고 정보를 반환한다.")
+    @Test
+    void 성공_존재하는_상품ID() {
+      // arrange
+      Long productId = savedProducts.get(0).getId();
+      // act
+      Stock result = sut.findByProductId(productId);
+
+      // assert
+      assertThat(result.getAvailable()).isEqualTo(savedStock.getAvailable());
+    }
+
+    @DisplayName("존재하지 않는 상품 ID를 주면, 재고0이 반환된다.")
+    @Test
+    void 실패_존재하지_않는_상품ID() {
+      // arrange
+      Long productId = (long) -1;
+      // act
+      Stock result = sut.findByProductId(productId);
+
+      // assert
+      assertThat(result).isNotNull();
+      assertThat(result.getAvailable()).isZero();
+    }
+  }
+
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/user/UserAssertions.java b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserAssertions.java
new file mode 100644
index 000000000..5e2f6f903
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserAssertions.java
@@ -0,0 +1,14 @@
+package com.loopers.domain.user;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class UserAssertions {
+  public static void assertUser(User actual, User expected) {
+    assertThat(actual).isNotNull();
+    assertThat(expected).isNotNull();
+    assertThat(actual.getId()).isEqualTo(expected.getId());
+    assertThat(actual.getLoginId()).isEqualTo(expected.getLoginId());
+    assertThat(actual.getEmail()).isEqualTo(expected.getEmail());
+    assertThat(actual.getGender()).isEqualTo(expected.getGender());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/user/UserFixture.java b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserFixture.java
new file mode 100644
index 000000000..bc05b9952
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserFixture.java
@@ -0,0 +1,110 @@
+package com.loopers.domain.user;
+
+import com.loopers.domain.point.Point;
+import com.loopers.domain.point.PointFixture;
+import org.instancio.Instancio;
+import org.instancio.Model;
+
+import java.time.LocalDate;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+import static org.instancio.Select.field;
+
+public class UserFixture {
+
+  private static final Model<User> USER_MODEL = Instancio.of(User.class)
+      .ignore(field(User::getId))
+      .ignore(field(User::getCreatedAt))
+      .ignore(field(User::getUpdatedAt))
+      .ignore(field(User::getDeletedAt))
+      .ignore(field(User::getPoint))
+      .set(field(User::getLoginId), generateLoginId())
+      .generate(field(User::getEmail),
+          gen -> gen.net().email()
+      )
+      .generate(field(User::getBirthday), gen -> gen.temporal()
+          .localDate()
+          .past()
+      )
+      .generate(field(User::getGender), gen ->
+          gen.oneOf("F", "M")
+      )
+      .toModel();
+
+  /**
+   * User + Point 자동 연결
+   */
+  public static User createUser() {
+    User user = Instancio.of(USER_MODEL).create();
+    Point point = PointFixture.createPoint(user);
+    user.setPoint(point);
+    return user;
+  }
+
+  public static User createUser(Point point) {
+    User user = Instancio.of(USER_MODEL).create();
+    user.setPoint(point);
+    return user;
+  }
+
+  /**
+   * 특정 필드만 override
+   */
+  public static User createUserWith(String loginId, String email, LocalDate birthday, String gender) {
+    User user = Instancio.of(USER_MODEL)
+        .set(field(User::getLoginId), loginId)
+        .set(field(User::getEmail), email)
+        .set(field(User::getBirthday), birthday)
+        .set(field(User::getGender), gender)
+        .create();
+
+    Point point = PointFixture.createPoint(user);
+    user.setPoint(point);
+    return user;
+  }
+
+  /**
+   * loginId만 override
+   */
+  public static User createUserWithLoginId(String loginId) {
+    User user = Instancio.of(USER_MODEL)
+        .set(field(User::getLoginId), loginId)
+        .create();
+    Point point = PointFixture.createPoint(user);
+    user.setPoint(point);
+    return user;
+  }
+
+  /**
+   * 연관관계 없이 User만 생성하고 싶을 때
+   */
+  public static User createUserWithoutPoint() {
+    return Instancio.of(USER_MODEL).create();
+  }
+
+  private static String generateLoginId() {
+    Random random = new Random();
+    String letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    String digits = "0123456789";
+
+    // 최소 1글자씩 확보
+    char letter = letters.charAt(random.nextInt(letters.length()));
+    char digit = digits.charAt(random.nextInt(digits.length()));
+
+    int remainingLength = random.nextInt(8) + 1; // 총 길이 2~10
+    String allChars = letters + digits;
+    StringBuilder sb = new StringBuilder();
+    sb.append(letter).append(digit);
+
+    for (int i = 2; i < remainingLength; i++) {
+      sb.append(allChars.charAt(random.nextInt(allChars.length())));
+    }
+
+    List<Character> chars = sb.chars().mapToObj(c -> (char) c).collect(Collectors.toList());
+    Collections.shuffle(chars);
+    return chars.stream().map(String::valueOf).collect(Collectors.joining());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/user/UserLazyTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserLazyTest.java
new file mode 100644
index 000000000..fb5901831
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserLazyTest.java
@@ -0,0 +1,61 @@
+package com.loopers.domain.user;
+
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.PersistenceUnitUtil;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest
+class UserLazyTest {
+  @Autowired
+  private UserRepository userRepository;
+
+  @Autowired
+  private EntityManager entityManager;
+
+  /**
+   * 테스트 유틸리티: User 엔티티 생성 및 저장
+   */
+  private User setupUserWithPoint() {
+    // 픽스처 대신 직접 생성하여 명확하게 Point가 생성됨을 보장
+    User user = User.create("testuser1", "test@email.com", "1990-01-01", "M");
+
+    // Point.create 내부에서 Point 객체가 생성되고 user.setPoint(this)를 통해 양방향 연결됨
+    // User 생성자 내부에 'this.point = Point.create(this, BigDecimal.TEN);' 로직이 있으므로 별도 setPoint 불필요
+
+    return userRepository.save(user);
+  }
+
+  @Test
+  @Transactional // 트랜잭션 내에서 조회해야 영속성 컨텍스트를 사용할 수 있습니다.
+  @DisplayName("User 조회 시 Point 필드는 로드되지 않아야 한다 (FetchType.LAZY 검증)")
+  void testPointIsLazyLoaded() {
+    // 1. Arrange: User 및 Point 데이터 저장
+    User savedUser = setupUserWithPoint();
+
+    // 2. Clear: 영속성 컨텍스트를 비워, 다음 findById가 DB에서 새로운 엔티티를 로드하도록 강제
+    // (이것이 없으면 1차 캐시의 User를 재사용할 수 있음)
+    entityManager.clear();
+
+    // 3. Act: DB에서 User 엔티티를 다시 조회
+    // 이 시점에 Point는 LAZY이므로 로드되면 안 됩니다.
+    User foundUser = userRepository.findById(savedUser.getId())
+        .orElseThrow(() -> new AssertionError("User Not Found"));
+
+    // 4. Assert: PersistenceUnitUtil을 사용하여 Point 필드의 로드 여부 검증
+    // PersistenceUnitUtil은 필드에 접근하지 않고 로딩 상태만 확인합니다.
+    PersistenceUnitUtil unitUtil = entityManager.getEntityManagerFactory().getPersistenceUnitUtil();
+
+    boolean isPointLoaded = unitUtil.isLoaded(foundUser, "point");
+
+    // 검증: LAZY 설정대로 Point 필드가 로드되지 않았어야 합니다.
+    assertThat(isPointLoaded)
+        .as("User 엔티티를 조회할 때 Point 필드는 LAZY Loading으로 인해 로드되지 않아야 합니다.")
+        .isFalse();
+  }
+}
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/UserModelTest.java
deleted file mode 100644
index 159dbdde4..000000000
--- a/apps/commerce-api/src/test/java/com/loopers/domain/user/UserModelTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.loopers.domain.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;
-
-class UserModelTest {
-  UserModel userModel;
-  String validMsg = "";
-
-  @DisplayName("회원가입-단위테스트1")
-  @Nested
-  class ValidID {
-    @BeforeEach
-    void setup() {
-      validMsg = "아이디 형식이 잘못되었습니다.(영문 및 숫자 1~10자 이내)";
-    }
-
-    @Test
-    void 실패_ID_숫자만() {
-      assertThatThrownBy(() -> {
-        userModel = UserModel.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");
-      }).isInstanceOf(CoreException.class).hasMessageContaining(validMsg);
-    }
-
-    @Test
-    void 실패_ID_특수문자() {
-      assertThatThrownBy(() -> {
-        userModel = UserModel.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");
-      }).isInstanceOf(CoreException.class).hasMessageContaining(validMsg);
-    }
-  }
-
-  @DisplayName("회원가입-단위테스트2")
-  @Nested
-  class Valid_Email {
-    @BeforeEach
-    void setup() {
-      validMsg = "이메일 형식이 잘못되었습니다.";
-    }
-
-    @Test
-    void 실패_이메일_기호없음() {
-      assertThatThrownBy(() -> {
-        userModel = UserModel.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");
-      }).isInstanceOf(CoreException.class).hasMessageContaining(validMsg);
-    }
-  }
-
-
-  @DisplayName("회원가입-단위테스트3")
-  @Nested
-  class Valid_Birthday {
-    @BeforeEach
-    void setup() {
-      validMsg = "생년월일 형식이 유효하지 않습니다.";
-    }
-
-    @Test
-    void 실패_생년월일_형식오류() {
-      assertThatThrownBy(() -> {
-        userModel = UserModel.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");
-      }).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");
-  }
-}
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..102aab462 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
@@ -11,7 +11,6 @@
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.junit.jupiter.api.Assertions.assertAll;
-import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -39,15 +38,14 @@ class Join {
     @Test
     void 성공_회원가입() {
       // arrange
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      User user = UserFixture.createUser();
 
       // 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)
       );
     }
 
@@ -55,15 +53,15 @@ class Join {
     @Test
     void 실패_이미_가입된ID() {
       // arrange
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userService.join(userModel);
+      User user = UserFixture.createUser();
+      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 +72,19 @@ class Get {
     @Test
     void 성공_존재하는_유저ID() {
       // arrange
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userService.join(userModel);
+      User user = UserFixture.createUser();
+      userService.join(user);
 
       // act
-      UserModel result = userService.getUser(userModel.getUserId());
+      User result = userService.getUser(user.getLoginId());
 
       // 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.getLoginId()).isEqualTo(user.getLoginId()),
+          () -> assertThat(result.getEmail()).isEqualTo(user.getEmail()),
+          () -> assertThat(result.getBirthday()).isEqualTo(user.getBirthday()),
+          () -> assertThat(result.getGender()).isEqualTo(user.getGender())
       );
     }
 
@@ -94,10 +92,10 @@ class Get {
     @Test
     void 실패_존재하지_않는_유저ID() {
       // arrange
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
+      User user = UserFixture.createUser();
 
       // act
-      UserModel result = userService.getUser(userModel.getUserId());
+      User result = userService.getUser(user.getLoginId());
 
       // assert
       assertThat(result).isNull();
diff --git a/apps/commerce-api/src/test/java/com/loopers/domain/user/UserTest.java b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserTest.java
new file mode 100644
index 000000000..0b6ed5b34
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/domain/user/UserTest.java
@@ -0,0 +1,89 @@
+package com.loopers.domain.user;
+
+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 org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class UserTest {
+
+  @DisplayName("회원가입-단위테스트1: ID 검증")
+  @Nested
+  class ValidID {
+
+    private final String validMsg = "아이디 형식이 잘못되었습니다.(영문 및 숫자 1~10자 이내)";
+
+    @ParameterizedTest
+    @ValueSource(strings = {"12345", "hello", "12345!", "12345678910"})
+    void 실패_ID_최소숫자1자_영문1자_이상(String loginId) {
+      User user = UserFixture.createUserWithLoginId(loginId);
+      assertThatThrownBy(() -> User.create(user.getLoginId(), user.getEmail(), user.getBirthday().toString(), user.getGender()))
+          .isInstanceOf(CoreException.class)
+          .hasMessageContaining(validMsg);
+    }
+  }
+
+  @DisplayName("회원가입-단위테스트2: 이메일 검증")
+  @Nested
+  class Valid_Email {
+
+    private final String validMsg = "이메일 형식이 잘못되었습니다.";
+
+    @Test
+    void 실패_이메일_기호없음() {
+      User user = UserFixture.createUser();
+      assertThatThrownBy(() -> User.create(user.getLoginId(), "user1test.XXX", user.getBirthday().toString(), user.getGender()))
+          .isInstanceOf(CoreException.class)
+          .hasMessageContaining(validMsg);
+    }
+
+    @Test
+    void 실패_이메일_한글포함() {
+      User user = UserFixture.createUser();
+      assertThatThrownBy(() -> User.create(user.getLoginId(), "ㄱuser1@test.XXX", user.getBirthday().toString(), user.getGender()))
+          .isInstanceOf(CoreException.class)
+          .hasMessageContaining(validMsg);
+    }
+  }
+
+  @DisplayName("회원가입-단위테스트3: 생년월일 검증")
+  @Nested
+  class Valid_Birthday {
+
+    private final String validMsg = "생년월일 형식이 유효하지 않습니다.";
+
+    @Test
+    void 실패_생년월일_형식오류() {
+      User user = UserFixture.createUser();
+      assertThatThrownBy(() -> User.create(user.getLoginId(), user.getEmail(), "19990101", user.getGender()))
+          .isInstanceOf(CoreException.class)
+          .hasMessageContaining(validMsg);
+    }
+
+    @Test
+    void 실패_생년월일_날짜오류() {
+      User user = UserFixture.createUser();
+      assertThatThrownBy(() -> User.create(user.getLoginId(), user.getEmail(), "1999-13-01", user.getGender()))
+          .isInstanceOf(CoreException.class)
+          .hasMessageContaining(validMsg);
+    }
+  }
+
+  @Test
+  @DisplayName("회원가입 성공 - 정상 User 객체 생성")
+  void 성공_User_객체생성() {
+    User user = UserFixture.createUser();
+    User result = User.create(user.getLoginId(), user.getEmail(), user.getBirthday().toString(), user.getGender());
+    assertThat(result).isNotNull();
+    assertThat(user).isNotNull();
+    assertThat(result.getId()).isEqualTo(user.getId());
+    assertThat(result.getLoginId()).isEqualTo(user.getLoginId());
+    assertThat(result.getEmail()).isEqualTo(user.getEmail());
+    assertThat(result.getGender()).isEqualTo(user.getGender());
+  }
+}
diff --git a/apps/commerce-api/src/test/java/com/loopers/interfaces/api/OrderV1ApiE2ETest.java b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/OrderV1ApiE2ETest.java
new file mode 100644
index 000000000..94426ffed
--- /dev/null
+++ b/apps/commerce-api/src/test/java/com/loopers/interfaces/api/OrderV1ApiE2ETest.java
@@ -0,0 +1,185 @@
+package com.loopers.interfaces.api;
+
+import com.loopers.application.order.OrderFacade;
+import com.loopers.domain.brand.Brand;
+import com.loopers.domain.brand.BrandFixture;
+import com.loopers.domain.brand.BrandService;
+import com.loopers.domain.order.Money;
+import com.loopers.domain.order.OrderService;
+import com.loopers.domain.point.PointService;
+import com.loopers.domain.product.Product;
+import com.loopers.domain.product.ProductFixture;
+import com.loopers.domain.product.ProductService;
+import com.loopers.domain.stock.StockFixture;
+import com.loopers.domain.stock.StockService;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+import com.loopers.domain.user.UserRepository;
+import com.loopers.domain.user.UserService;
+import com.loopers.interfaces.api.order.OrderCreateV1Dto;
+import com.loopers.interfaces.api.user.UserCreateV1Dto;
+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.web.client.TestRestTemplate;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
+
+import java.util.List;
+import java.util.function.Function;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class OrderV1ApiE2ETest {
+
+  private static final String ENDPOINT = "/api/v1/orders";
+  private static final Function<String, String> ENDPOINT_GET = id -> "/api/v1/orders/" + id;
+
+  private final TestRestTemplate testRestTemplate;
+  private final UserService userService;
+  private final DatabaseCleanUp databaseCleanUp;
+
+    @Autowired
+    private OrderFacade sut;
+    @MockitoSpyBean
+    private UserRepository userRepository;
+    @MockitoSpyBean
+    private PointService pointService;
+    @MockitoSpyBean
+    private BrandService brandService;
+    @MockitoSpyBean
+    private ProductService productService;
+    @MockitoSpyBean
+    private StockService stockService;
+
+    @MockitoSpyBean
+    private OrderService orderService;
+    List<User> savedUsers;
+    List<Brand> savedBrands;
+    List<Product> savedProducts;
+
+    @Autowired
+  public OrderV1ApiE2ETest(
+      TestRestTemplate testRestTemplate,
+      UserService userService,
+      DatabaseCleanUp databaseCleanUp
+  ) {
+    this.testRestTemplate = testRestTemplate;
+    this.userService = userService;
+    this.databaseCleanUp = databaseCleanUp;
+  }
+    @BeforeEach
+    void setup() {
+        // 사용자 생성
+        savedUsers = List.of(
+                userService.join(UserFixture.createUserWithLoginId("user1")),
+                userService.join(UserFixture.createUserWithLoginId("user2"))
+        );
+
+        // 브랜드 생성
+        savedBrands = brandService.saveAll(List.of(
+                BrandFixture.createBrand(),
+                BrandFixture.createBrand()
+        ));
+
+        // 상품 생성
+        savedProducts = productService.saveAll(List.of(
+                ProductFixture.createProductWith("product1", Money.wons(1)),
+                ProductFixture.createProductWith("product2", Money.wons(4)),
+                ProductFixture.createProduct(savedBrands.get(1))
+        ));
+
+        // 재고 생성
+        stockService.save(StockFixture.createStockWith(savedProducts.get(0).getId(), 10));
+        stockService.save(StockFixture.createStockWith(savedProducts.get(1).getId(), 10));
+    }
+  @AfterEach
+  void tearDown() {
+    databaseCleanUp.truncateAllTables();
+  }
+
+  @DisplayName("주문 생성")
+  @Nested
+  class Post {
+    @DisplayName("주문 생성-E2E테스트1")
+    @Test
+    void 성공_주문생성() {
+      //given
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("X-USER-ID", savedUsers.get(0).getId().toString());
+        List<OrderCreateV1Dto.OrderItemRequest> items = List.of(
+                new OrderCreateV1Dto.OrderItemRequest(savedProducts.get(0).getId(), 1L)
+        );
+        OrderCreateV1Dto.OrderRequest req = new OrderCreateV1Dto.OrderRequest(items);
+      //when
+      ParameterizedTypeReference<ApiResponse<OrderCreateV1Dto.OrderResponse>> resType = new ParameterizedTypeReference<>() {
+      };
+      ResponseEntity<ApiResponse<OrderCreateV1Dto.OrderResponse>> res = testRestTemplate.exchange(ENDPOINT, HttpMethod.POST, new HttpEntity<>(req,headers), resType);
+
+      //then
+      assertThat(res.getStatusCode()).isEqualTo(HttpStatus.CREATED);
+      assertThat(res.getBody().data()).isNotNull();
+      assertThat(res.getBody().data().totalPrice()).isEqualByComparingTo(savedProducts.get(0).getPrice().getAmount());
+    }
+  }
+
+  @DisplayName("주문 정보 조회")
+  @Nested
+  class Get {
+    @DisplayName("E2E테스트1")
+    @Test
+    void 성공_주문정보조회() {
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("X-USER-ID", savedUsers.get(0).getId().toString());
+        List<OrderCreateV1Dto.OrderItemRequest> orderitems = List.of(
+                new OrderCreateV1Dto.OrderItemRequest(savedProducts.get(0).getId(), 1L)
+        );
+        OrderCreateV1Dto.OrderRequest orderRequest = new OrderCreateV1Dto.OrderRequest(orderitems);
+        //when
+        ParameterizedTypeReference<ApiResponse<OrderCreateV1Dto.OrderResponse>> orderResType = new ParameterizedTypeReference<>() {
+        };
+        ResponseEntity<ApiResponse<OrderCreateV1Dto.OrderResponse>> orderRes = testRestTemplate.exchange(ENDPOINT, HttpMethod.POST, new HttpEntity<>(orderRequest,headers), orderResType);
+
+
+        //given
+        List<OrderCreateV1Dto.OrderItemRequest> items = List.of(
+                new OrderCreateV1Dto.OrderItemRequest(savedProducts.get(0).getId(), 1L)
+        );
+        OrderCreateV1Dto.OrderRequest req = new OrderCreateV1Dto.OrderRequest(items);
+
+        //when
+      String url = ENDPOINT_GET.apply(savedUsers.get(0).getId().toString());
+      ParameterizedTypeReference<ApiResponse<OrderCreateV1Dto.OrderResponse>> resType = new ParameterizedTypeReference<>() {
+      };
+      ResponseEntity<ApiResponse<OrderCreateV1Dto.OrderResponse>> res = testRestTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(null,headers), resType);
+
+      //then
+      assertThat(res.getStatusCode()).isEqualTo(HttpStatus.OK);
+        assertThat(res.getBody().data()).isNotNull();
+        assertThat(res.getBody().data().totalPrice()).isEqualByComparingTo(savedProducts.get(0).getPrice().getAmount());
+    }
+
+    @DisplayName("E2E테스트2")
+    @Test
+    void 실패_존재하지_않는_주문ID() {
+      //given
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("X-USER-ID", savedUsers.get(0).getId().toString());
+        String orderId = "-1";
+
+      //when
+      String url = ENDPOINT_GET.apply(orderId);
+      ParameterizedTypeReference<ApiResponse<OrderCreateV1Dto.OrderResponse>> resType = new ParameterizedTypeReference<>() {
+      };
+      ResponseEntity<ApiResponse<OrderCreateV1Dto.OrderResponse>> res = testRestTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(null,headers), resType);
+
+      //then
+      assertThat(res.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
+    }
+
+  }
+}
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..ba58bf894 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,7 +1,8 @@
 package com.loopers.interfaces.api;
 
-import com.loopers.domain.user.UserModel;
-import com.loopers.infrastructure.user.UserJpaRepository;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
+import com.loopers.domain.user.UserService;
 import com.loopers.utils.DatabaseCleanUp;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.DisplayName;
@@ -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,14 +51,13 @@ class Get {
       //given
       BigDecimal JOIN_POINT = BigDecimal.TEN;
 
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userJpaRepository.save(userModel);
+      User savedUser = userService.join(UserFixture.createUser());
 
       //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";
+      String url = "/api/v1/users/point";
       ParameterizedTypeReference<ApiResponse<BigDecimal>> resType = new ParameterizedTypeReference<>() {
       };
       ResponseEntity<ApiResponse<BigDecimal>> res = testRestTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), resType);
@@ -74,7 +74,7 @@ class Get {
       //given
 
       //when
-      String url = "/api/v1/user/point";
+      String url = "/api/v1/users/point";
       ParameterizedTypeReference<ApiResponse<BigDecimal>> resType = new ParameterizedTypeReference<>() {
       };
       ResponseEntity<ApiResponse<BigDecimal>> res = testRestTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(null), resType);
@@ -91,24 +91,22 @@ class Charge {
     @Test
     void 성공_포인트충전() {
       //given
-      BigDecimal CHARGE_POINT = BigDecimal.TEN;
-
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userJpaRepository.save(userModel);
+      BigDecimal chargeAmt = new BigDecimal(1_000);
+      User savedUser = userService.join(UserFixture.createUser());
 
       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";
+      String url = "/api/v1/users/point/charge";
       ParameterizedTypeReference<ApiResponse<BigDecimal>> resType = new ParameterizedTypeReference<>() {
       };
-      ResponseEntity<ApiResponse<BigDecimal>> res = testRestTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(new BigDecimal(1_000), headers), resType);
+      ResponseEntity<ApiResponse<BigDecimal>> res = testRestTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(chargeAmt, headers), resType);
 
       //then
       assertThat(res.getStatusCode()).isEqualTo(HttpStatus.OK);
       assertThat(res.getBody().data()).isNotNull();
-      assertEquals(0, res.getBody().data().compareTo(new BigDecimal(1_010)));
+      assertEquals(0, res.getBody().data().compareTo(savedUser.getPoint().getAmount().add(chargeAmt)));
     }
 
     @DisplayName("E2E테스트2-존재하지 않는 유저로 요청할 경우, 404 Not Found 응답을 반환")
@@ -116,10 +114,10 @@ class Charge {
     void 실패_ID없음_400() {
       //given
       HttpHeaders headers = new HttpHeaders();
-      headers.set("X-USER-ID", "user1");
+      headers.set("X-USER-ID", "999999");
 
       //when
-      String url = "/api/v1/user/point/charge";
+      String url = "/api/v1/users/point/charge";
       ParameterizedTypeReference<ApiResponse<BigDecimal>> resType = new ParameterizedTypeReference<>() {
       };
       ResponseEntity<ApiResponse<BigDecimal>> res = testRestTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(BigDecimal.TEN, headers), resType);
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..c9860724f 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,9 @@
 package com.loopers.interfaces.api;
 
-import com.loopers.domain.user.UserModel;
+import com.loopers.domain.user.User;
+import com.loopers.domain.user.UserFixture;
 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;
@@ -26,8 +26,8 @@
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
 public class UserV1ApiE2ETest {
 
-  private static final String ENDPOINT = "/api/v1/user";
-  private static final Function<String, String> ENDPOINT_GET = id -> "/api/v1/user/" + id;
+  private static final String ENDPOINT = "/api/v1/users";
+  private static final Function<String, String> ENDPOINT_GET = id -> "/api/v1/users/" + id;
 
   private final TestRestTemplate testRestTemplate;
   private final UserService userService;
@@ -93,11 +93,11 @@ class Get {
     @Test
     void 성공_정보조회() {
       //given
-      UserModel userModel = UserModel.create("user1", "user1@test.XXX", "1999-01-01", "F");
-      userService.join(userModel);
+      User user = UserFixture.createUser();
+      userService.join(user);
 
       //when
-      String url = ENDPOINT_GET.apply(userModel.getUserId());
+      String url = ENDPOINT_GET.apply(user.getLoginId());
       ParameterizedTypeReference<ApiResponse<UserCreateV1Dto.UserResponse>> resType = new ParameterizedTypeReference<>() {
       };
       ResponseEntity<ApiResponse<UserCreateV1Dto.UserResponse>> res = testRestTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(null), resType);
@@ -105,7 +105,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.getLoginId());
     }
 
     @DisplayName("E2E테스트2")
diff --git a/build.gradle.kts b/build.gradle.kts
index 9c8490b8a..bf8898620 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -63,6 +63,7 @@ subprojects {
         testImplementation("com.ninja-squad:springmockk:${project.properties["springMockkVersion"]}")
         testImplementation("org.mockito:mockito-core:${project.properties["mockitoVersion"]}")
         testImplementation("org.instancio:instancio-junit:${project.properties["instancioJUnitVersion"]}")
+        testImplementation("org.instancio:instancio-core:${project.properties["instancioVersion"]}")
         // Testcontainers
         testImplementation("org.springframework.boot:spring-boot-testcontainers")
         testImplementation("org.testcontainers:testcontainers")
@@ -95,11 +96,11 @@ subprojects {
         }
         afterEvaluate {
             classDirectories.setFrom(
-                files(
-                    classDirectories.files.map {
-                        fileTree(it)
-                    },
-                ),
+                    files(
+                            classDirectories.files.map {
+                                fileTree(it)
+                            },
+                    ),
             )
         }
     }
diff --git a/docs/week2/01-requirements.md b/docs/week2/01-requirements.md
index 118853dbc..bef4af13f 100644
--- a/docs/week2/01-requirements.md
+++ b/docs/week2/01-requirements.md
@@ -53,10 +53,10 @@
 4. 없으면 저장, 있으면 삭제
 5. 좋아요 수 반영
 
-### 유저 스토리5 - 주문 생성 및 결재
+### 유저 스토리5 - 주문 생성 및 결제
 
 - 사용자는 여러상품을 선택해 상품을 주문할수 있다.
-- 결재는 포인트로 가능하다.
+- 결제는 포인트로 가능하다.
 - 주문 생성 후 주문 상세 내역을 확인할수 있다.
 
 #### 기능 흐름
@@ -69,8 +69,8 @@
    4-3. 재고가 있을 경우, 해당 수량 HOLD 및 포인트 확인
 5. 5-1. 포인트가 부족할 경우, "포인트가 부족합니다."
    5-2. 포인트 사용이 가능할 경우, 포인트 차감.
-6. 6-1. 결재중 오류 발생시, "결재중 오류가 발생했습니다."
-   6-2. 결재 성공시, 재고 차감 및 주문 정보 저장
+6. 6-1. 결제중 오류 발생시, "결제중 오류가 발생했습니다."
+   6-2. 결제 성공시, 재고 차감 및 주문 정보 저장
 7. 외부 시스템으로 주문 정보 전송
 8. 주문 상세 정보 조회 및 "주문 완료되었습니다."
 
@@ -129,7 +129,7 @@
 1. 로그인 사용자만 가능
 2. 비로그인일 경우, "로그인이 필요합니다."
 3. 주문 목록에서 주문 상세를 볼수 있다.
-4. 구매자 정보/결재정보/배송지정보를 확인할수 있다.
+4. 구매자 정보/결제정보/배송지정보를 확인할수 있다.
 
 ---
 
diff --git a/docs/week2/02-sequence-diagrams.md b/docs/week2/02-sequence-diagrams.md
index 7ff2daa8b..f1d66331f 100644
--- a/docs/week2/02-sequence-diagrams.md
+++ b/docs/week2/02-sequence-diagrams.md
@@ -108,7 +108,7 @@ S-->>C: 성공
 C-->>U: 응답 200
 ```
 
-### 5. 주문 생성 및 결재
+### 5. 주문 생성 및 결제
 
 ```mermaid
 sequenceDiagram  
@@ -143,7 +143,7 @@ S--x C: 400 BadRequestException
 C-->>U: "포인트가 부족합니다."
 end  
 S->>R : payPoint(user)
-R-->>S: 포인트 결재 성공  
+R-->>S: 포인트 결제 성공  
 S->>R : commitProducts(products)
 R-->>S: 재고차감 완료  
 S->>R : saveOrder(order)
diff --git a/gradle.properties b/gradle.properties
index 142d7120f..b8a8de7aa 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -14,5 +14,6 @@ springDocOpenApiVersion=2.7.0
 springMockkVersion=4.0.2
 mockitoVersion=5.14.0
 instancioJUnitVersion=5.0.2
+instancioVersion=5.0.2
 slackAppenderVersion=1.6.1
 kotlin.daemon.jvmargs=-Xmx1g -XX:MaxMetaspaceSize=512m
