diff --git a/src/main/java/gift/client/KakaoApiClient.java b/src/main/java/gift/client/KakaoApiClient.java
index 06d088b8d..c2cdf78bb 100644
--- a/src/main/java/gift/client/KakaoApiClient.java
+++ b/src/main/java/gift/client/KakaoApiClient.java
@@ -11,7 +11,7 @@
 import gift.dto.kakao.template.KakaoTemplateContent;
 import gift.dto.kakao.template.KakaoTemplateLink;
 import gift.exception.BadRequestException;
-import gift.exception.InvalidKakaoTokenException;
+import gift.exception.UnauthorizedAccessException;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Component;
@@ -63,10 +63,7 @@ public KakaoTokenResponse getRefreshedTokenResponse(String refreshToken) {
                 .body(body)
                 .retrieve()
                 .onStatus(statusCode -> statusCode.equals(HttpStatus.UNAUTHORIZED), (req, res) -> {
-                    throw new InvalidKakaoTokenException(INVALID_TOKEN_MESSAGE);
-                })
-                .onStatus(statusCode -> statusCode.equals(HttpStatus.BAD_REQUEST), (req, res) -> {
-                    throw new InvalidKakaoTokenException(INVALID_TOKEN_MESSAGE);
+                    throw new UnauthorizedAccessException("유효하지 않은 카카오 리프레시 토큰입니다.");
                 })
                 .body(String.class);
 
@@ -102,7 +99,7 @@ public void sendSelfMessageOrder(String accessToken, GiftOrderResponse giftOrder
                     .body(body)
                     .retrieve()
                     .onStatus(statusCode -> statusCode.equals(HttpStatus.UNAUTHORIZED), (req, res) -> {
-                        throw new InvalidKakaoTokenException(INVALID_TOKEN_MESSAGE);
+                        throw new UnauthorizedAccessException(INVALID_TOKEN_MESSAGE);
                     })
                     .body(String.class);
         } catch (JsonProcessingException exception) {
@@ -122,7 +119,7 @@ private KakaoTemplate getCommerceTemplate(GiftOrderResponse giftOrderResponse) {
         var objectType = "commerce";
         var link = new KakaoTemplateLink("https://gift.kakao.com/product/2370524");
         var content = new KakaoTemplateContent(giftOrderResponse.message(), "https://img1.kakaocdn.net/thumb/C320x320@2x.fwebp.q82/?fname=https%3A%2F%2Fst.kakaocdn.net%2Fproduct%2Fgift%2Fproduct%2F20240417111629_616eccb9d4cd464fa06d3430947dce15.jpg", giftOrderResponse.message(), link);
-        var commerce = new KakaoTemplateCommerce(giftOrderResponse.optionInformation().productName() + "[" + giftOrderResponse.optionInformation().name() + "]", giftOrderResponse.optionInformation().price() * giftOrderResponse.quantity());
+        var commerce = new KakaoTemplateCommerce(giftOrderResponse.productBasicInformation().name() + "[" + giftOrderResponse.optionResponse().name() + "]", giftOrderResponse.productBasicInformation().price() * giftOrderResponse.quantity());
         return new KakaoTemplate(objectType, content, commerce);
     }
 }
diff --git a/src/main/java/gift/controller/CategoryController.java b/src/main/java/gift/controller/CategoryController.java
index 31108fcab..0b8eafedb 100644
--- a/src/main/java/gift/controller/CategoryController.java
+++ b/src/main/java/gift/controller/CategoryController.java
@@ -5,9 +5,6 @@
 import gift.dto.category.CategoryResponse;
 import gift.service.CategoryService;
 import jakarta.validation.Valid;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.web.PageableDefault;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -50,9 +47,8 @@ public ResponseEntity<CategoryResponse> getCategory(@PathVariable Long id) {
     }
 
     @GetMapping
-    public ResponseEntity<List<CategoryResponse>> getCategories(
-            @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
-        var categories = categoryService.getCategories(pageable);
+    public ResponseEntity<List<CategoryResponse>> getCategories() {
+        var categories = categoryService.getCategories();
         return ResponseEntity.ok(categories);
     }
 
diff --git a/src/main/java/gift/controller/OptionController.java b/src/main/java/gift/controller/OptionController.java
index 39229bba7..968707c70 100644
--- a/src/main/java/gift/controller/OptionController.java
+++ b/src/main/java/gift/controller/OptionController.java
@@ -1,14 +1,10 @@
 package gift.controller;
 
 import gift.controller.api.OptionApi;
-import gift.dto.option.OptionAddRequest;
+import gift.dto.option.OptionRequest;
 import gift.dto.option.OptionResponse;
-import gift.dto.option.OptionUpdateRequest;
 import gift.service.OptionService;
 import jakarta.validation.Valid;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.web.PageableDefault;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -17,14 +13,13 @@
 import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.net.URI;
 import java.util.List;
 
 @RestController
-@RequestMapping("/api/options")
+@RequestMapping("/api/products/{productId}/options")
 public class OptionController implements OptionApi {
 
     private final OptionService optionService;
@@ -34,26 +29,32 @@ public OptionController(OptionService optionService) {
     }
 
     @PostMapping
-    public ResponseEntity<Void> addOption(@Valid @RequestBody OptionAddRequest optionAddRequest) {
-        var option = optionService.addOption(optionAddRequest);
-        return ResponseEntity.created(URI.create("/api/options/" + option.id())).build();
+    public ResponseEntity<Void> addOption(@PathVariable Long productId, @Valid @RequestBody OptionRequest optionRequest) {
+        var option = optionService.addOption(productId, optionRequest);
+        return ResponseEntity.created(URI.create("/api/products/" + productId + "/options/" + option.id())).build();
     }
 
     @PutMapping("/{id}")
-    public ResponseEntity<Void> updateOption(@PathVariable Long id, @Valid @RequestBody OptionUpdateRequest optionUpdateRequest) {
-        optionService.updateOption(id, optionUpdateRequest);
+    public ResponseEntity<Void> updateOption(@PathVariable Long productId, @PathVariable Long id, @Valid @RequestBody OptionRequest optionUpdateRequest) {
+        optionService.updateOption(productId, id, optionUpdateRequest);
         return ResponseEntity.noContent().build();
     }
 
+    @GetMapping("/{id}")
+    public ResponseEntity<OptionResponse> getOption(@PathVariable Long productId, @PathVariable Long id) {
+        var option = optionService.getOption(productId, id);
+        return ResponseEntity.ok(option);
+    }
+
     @GetMapping
-    public ResponseEntity<List<OptionResponse>> getOptions(@RequestParam Long productId, @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
-        var options = optionService.getOptions(productId, pageable);
+    public ResponseEntity<List<OptionResponse>> getOptions(@PathVariable Long productId) {
+        var options = optionService.getOptions(productId);
         return ResponseEntity.ok(options);
     }
 
     @DeleteMapping("/{id}")
-    public ResponseEntity<Void> deleteOption(@PathVariable Long id) {
-        optionService.deleteOption(id);
+    public ResponseEntity<Void> deleteOption(@PathVariable Long productId, @PathVariable Long id) {
+        optionService.deleteOption(productId, id);
         return ResponseEntity.noContent().build();
     }
 }
diff --git a/src/main/java/gift/controller/ProductController.java b/src/main/java/gift/controller/ProductController.java
index f04534fad..0f5965211 100644
--- a/src/main/java/gift/controller/ProductController.java
+++ b/src/main/java/gift/controller/ProductController.java
@@ -1,8 +1,9 @@
 package gift.controller;
 
 import gift.controller.api.ProductApi;
-import gift.dto.product.ProductRequest;
+import gift.dto.product.ProductAddRequest;
 import gift.dto.product.ProductResponse;
+import gift.dto.product.ProductUpdateRequest;
 import gift.service.ProductService;
 import jakarta.validation.Valid;
 import org.springframework.data.domain.Pageable;
@@ -16,6 +17,7 @@
 import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.net.URI;
@@ -32,14 +34,14 @@ public ProductController(ProductService productService) {
     }
 
     @PostMapping
-    public ResponseEntity<Void> addProduct(@Valid @RequestBody ProductRequest productRequest) {
-        var product = productService.addProduct(productRequest);
+    public ResponseEntity<Void> addProduct(@Valid @RequestBody ProductAddRequest productAddRequest) {
+        var product = productService.addProduct(productAddRequest);
         return ResponseEntity.created(URI.create("/api/products/" + product.id())).build();
     }
 
     @PutMapping("/{id}")
-    public ResponseEntity<Void> updateProduct(@PathVariable Long id, @Valid @RequestBody ProductRequest productRequest) {
-        productService.updateProduct(id, productRequest);
+    public ResponseEntity<Void> updateProduct(@PathVariable Long id, @Valid @RequestBody ProductUpdateRequest productUpdateRequest) {
+        productService.updateProduct(id, productUpdateRequest);
         return ResponseEntity.noContent().build();
     }
 
@@ -50,8 +52,12 @@ public ResponseEntity<ProductResponse> getProduct(@PathVariable Long id) {
     }
 
     @GetMapping
-    public ResponseEntity<List<ProductResponse>> getProducts(@PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
-        var products = productService.getProducts(pageable);
+    public ResponseEntity<List<ProductResponse>> getProducts(@RequestParam(required = false) Long categoryId, @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
+        if (categoryId == null) {
+            var products = productService.getProducts(pageable);
+            return ResponseEntity.ok(products);
+        }
+        var products = productService.getProducts(categoryId, pageable);
         return ResponseEntity.ok(products);
     }
 
diff --git a/src/main/java/gift/controller/WishProductController.java b/src/main/java/gift/controller/WishProductController.java
index 65b3919b4..a6e2dadd4 100644
--- a/src/main/java/gift/controller/WishProductController.java
+++ b/src/main/java/gift/controller/WishProductController.java
@@ -45,6 +45,12 @@ public ResponseEntity<Void> updateWishProduct(@PathVariable Long id, @Valid @Req
         return ResponseEntity.noContent().build();
     }
 
+    @GetMapping("/{id}")
+    public ResponseEntity<WishProductResponse> getWishProduct(@RequestAttribute("memberId") Long memberId, @PathVariable Long id) {
+        var wishProduct = wishProductService.getWishProduct(memberId, id);
+        return ResponseEntity.ok(wishProduct);
+    }
+
     @GetMapping
     public ResponseEntity<List<WishProductResponse>> getWishProducts(@RequestAttribute("memberId") Long memberId, @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable) {
         var wishProducts = wishProductService.getWishProducts(memberId, pageable);
diff --git a/src/main/java/gift/controller/api/CategoryApi.java b/src/main/java/gift/controller/api/CategoryApi.java
index a27f4a433..e25a88e39 100644
--- a/src/main/java/gift/controller/api/CategoryApi.java
+++ b/src/main/java/gift/controller/api/CategoryApi.java
@@ -9,7 +9,6 @@
 import io.swagger.v3.oas.annotations.responses.ApiResponse;
 import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.data.domain.Pageable;
 import org.springframework.http.ResponseEntity;
 
 import java.util.List;
@@ -20,6 +19,7 @@ public interface CategoryApi {
     @ApiResponses(value = {
             @ApiResponse(responseCode = "201", description = "카테고리 생성 성공"),
             @ApiResponse(responseCode = "401", description = "허용되지 않는 요청"),
+            @ApiResponse(responseCode = "409", description = "카테고리 생성 실패(사유 : 이미 존재하는 이름입니다. )"),
             @ApiResponse(responseCode = "500", description = "내부 서버의 오류")
     })
     ResponseEntity<Void> addCategory(CategoryRequest categoryRequest);
@@ -28,6 +28,7 @@ public interface CategoryApi {
     @ApiResponses(value = {
             @ApiResponse(responseCode = "204", description = "카테고리 수정 성공"),
             @ApiResponse(responseCode = "401", description = "허용되지 않는 요청"),
+            @ApiResponse(responseCode = "409", description = "카테고리 수정 실패(사유 : 이미 존재하는 이름입니다. )"),
             @ApiResponse(responseCode = "500", description = "내부 서버의 오류")
     })
     ResponseEntity<Void> updateCategory(Long id, CategoryRequest categoryRequest);
@@ -46,7 +47,7 @@ public interface CategoryApi {
             @ApiResponse(responseCode = "401", description = "허용되지 않는 요청", content = @Content(schema = @Schema(hidden = true))),
             @ApiResponse(responseCode = "500", description = "내부 서버의 오류", content = @Content(schema = @Schema(hidden = true)))
     })
-    ResponseEntity<List<CategoryResponse>> getCategories(Pageable pageable);
+    ResponseEntity<List<CategoryResponse>> getCategories();
 
     @Operation(summary = "특정 카테고리를 삭제한다.")
     @ApiResponses(value = {
diff --git a/src/main/java/gift/controller/api/GiftOrderApi.java b/src/main/java/gift/controller/api/GiftOrderApi.java
index b70f01768..aeb20697c 100644
--- a/src/main/java/gift/controller/api/GiftOrderApi.java
+++ b/src/main/java/gift/controller/api/GiftOrderApi.java
@@ -20,7 +20,7 @@ public interface GiftOrderApi {
     @Operation(summary = "회원의 새 주문을 생성한다.")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "201", description = "주문 생성 성공"),
-            @ApiResponse(responseCode = "401", description = "허용되지 않는 요청"),
+            @ApiResponse(responseCode = "401", description = "주문 생성 실패(사유 : 카카오 토큰이 만료되었거나, 허용되지 않은 요청입니다.)"),
             @ApiResponse(responseCode = "500", description = "내부 서버의 오류")
     })
     ResponseEntity<Void> orderOption(Long memberId, GiftOrderRequest giftOrderRequest);
diff --git a/src/main/java/gift/controller/api/OptionApi.java b/src/main/java/gift/controller/api/OptionApi.java
index 03a84b511..395c034b8 100644
--- a/src/main/java/gift/controller/api/OptionApi.java
+++ b/src/main/java/gift/controller/api/OptionApi.java
@@ -1,8 +1,7 @@
 package gift.controller.api;
 
-import gift.dto.option.OptionAddRequest;
+import gift.dto.option.OptionRequest;
 import gift.dto.option.OptionResponse;
-import gift.dto.option.OptionUpdateRequest;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.ArraySchema;
 import io.swagger.v3.oas.annotations.media.Content;
@@ -10,7 +9,6 @@
 import io.swagger.v3.oas.annotations.responses.ApiResponse;
 import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.data.domain.Pageable;
 import org.springframework.http.ResponseEntity;
 
 import java.util.List;
@@ -22,17 +20,29 @@ public interface OptionApi {
     @ApiResponses(value = {
             @ApiResponse(responseCode = "201", description = "옵션 추가 성공"),
             @ApiResponse(responseCode = "401", description = "허용되지 않는 요청"),
+            @ApiResponse(responseCode = "409", description = "옵션 추가 실패(사유 : 이미 존재하는 이름입니다. )"),
             @ApiResponse(responseCode = "500", description = "내부 서버의 오류")
     })
-    ResponseEntity<Void> addOption(OptionAddRequest optionAddRequest);
+    ResponseEntity<Void> addOption(Long productId, OptionRequest optionRequest);
 
     @Operation(summary = "기존 옵션을 수정한다.")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "204", description = "옵션 수정 성공"),
+            @ApiResponse(responseCode = "400", description = "옵션 수정 실패(사유 : 옵션과 연결된 상품 ID 가 아닙니다.)"),
             @ApiResponse(responseCode = "401", description = "허용되지 않는 요청"),
+            @ApiResponse(responseCode = "409", description = "옵션 수정 실패(사유 : 이미 존재하는 이름입니다. )"),
             @ApiResponse(responseCode = "500", description = "내부 서버의 오류")
     })
-    ResponseEntity<Void> updateOption(Long id, OptionUpdateRequest optionUpdateRequest);
+    ResponseEntity<Void> updateOption(Long productId, Long id, OptionRequest optionRequest);
+
+    @Operation(summary = "특정 옵션을 조회한다.")
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "특정 옵션 조회 성공", content = @Content(schema = @Schema(implementation = OptionResponse.class))),
+            @ApiResponse(responseCode = "400", description = "특정 옵션 조회 실패(사유 : 옵션과 연결된 상품 ID 가 아닙니다.)"),
+            @ApiResponse(responseCode = "401", description = "허용되지 않는 요청", content = @Content(schema = @Schema(hidden = true))),
+            @ApiResponse(responseCode = "500", description = "내부 서버의 오류", content = @Content(schema = @Schema(hidden = true)))
+    })
+    ResponseEntity<OptionResponse> getOption(Long productId, Long id);
 
     @Operation(summary = "모든 옵션을 페이지 단위로 조회한다.")
     @ApiResponses(value = {
@@ -40,14 +50,15 @@ public interface OptionApi {
             @ApiResponse(responseCode = "401", description = "허용되지 않는 요청", content = @Content(schema = @Schema(hidden = true))),
             @ApiResponse(responseCode = "500", description = "내부 서버의 오류", content = @Content(schema = @Schema(hidden = true)))
     })
-    ResponseEntity<List<OptionResponse>> getOptions(Long productId, Pageable pageable);
+    ResponseEntity<List<OptionResponse>> getOptions(Long productId);
 
     @Operation(summary = "특정 옵션을 삭제한다.")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "204", description = "옵션 삭제 성공"),
+            @ApiResponse(responseCode = "400", description = "옵션 삭제 실패(사유 : 옵션과 연결된 상품 ID 가 아닙니다.)"),
             @ApiResponse(responseCode = "401", description = "허용되지 않는 요청"),
             @ApiResponse(responseCode = "404", description = "옵션 삭제 실패(사유 : 존재하지 않는 ID 입니다.)"),
             @ApiResponse(responseCode = "500", description = "내부 서버의 오류")
     })
-    ResponseEntity<Void> deleteOption(Long id);
+    ResponseEntity<Void> deleteOption(Long productId, Long id);
 }
diff --git a/src/main/java/gift/controller/api/ProductApi.java b/src/main/java/gift/controller/api/ProductApi.java
index 1ff91a45c..1fd85f538 100644
--- a/src/main/java/gift/controller/api/ProductApi.java
+++ b/src/main/java/gift/controller/api/ProductApi.java
@@ -1,7 +1,8 @@
 package gift.controller.api;
 
-import gift.dto.product.ProductRequest;
+import gift.dto.product.ProductAddRequest;
 import gift.dto.product.ProductResponse;
+import gift.dto.product.ProductUpdateRequest;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.ArraySchema;
 import io.swagger.v3.oas.annotations.media.Content;
@@ -20,18 +21,20 @@ public interface ProductApi {
     @Operation(summary = "새 상품을 등록한다.")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "201", description = "상품 등록 성공"),
+            @ApiResponse(responseCode = "400", description = "상품 등록 실패(사유 : 카카오가 포함된 이름입니다.)"),
             @ApiResponse(responseCode = "401", description = "허용되지 않는 요청"),
             @ApiResponse(responseCode = "500", description = "내부 서버의 오류")
     })
-    ResponseEntity<Void> addProduct(ProductRequest productRequest);
+    ResponseEntity<Void> addProduct(ProductAddRequest productAddRequest);
 
     @Operation(summary = "기존 상품을 수정한다.")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "204", description = "상품 수정 성공"),
+            @ApiResponse(responseCode = "400", description = "상품 수정 실패(사유 : 카카오가 포함된 이름입니다.)"),
             @ApiResponse(responseCode = "401", description = "허용되지 않는 요청"),
             @ApiResponse(responseCode = "500", description = "내부 서버의 오류")
     })
-    ResponseEntity<Void> updateProduct(Long id, ProductRequest productRequest);
+    ResponseEntity<Void> updateProduct(Long id, ProductUpdateRequest productUpdateRequest);
 
     @Operation(summary = "특정 상품을 조회한다.")
     @ApiResponses(value = {
@@ -47,7 +50,7 @@ public interface ProductApi {
             @ApiResponse(responseCode = "401", description = "허용되지 않는 요청", content = @Content(schema = @Schema(hidden = true))),
             @ApiResponse(responseCode = "500", description = "내부 서버의 오류", content = @Content(schema = @Schema(hidden = true)))
     })
-    ResponseEntity<List<ProductResponse>> getProducts(Pageable pageable);
+    ResponseEntity<List<ProductResponse>> getProducts(Long categoryId, Pageable pageable);
 
     @Operation(summary = "특정 상품을 삭제한다.")
     @ApiResponses(value = {
diff --git a/src/main/java/gift/controller/api/WishProductApi.java b/src/main/java/gift/controller/api/WishProductApi.java
index 1cebb2dce..ae83c3165 100644
--- a/src/main/java/gift/controller/api/WishProductApi.java
+++ b/src/main/java/gift/controller/api/WishProductApi.java
@@ -1,5 +1,6 @@
 package gift.controller.api;
 
+import gift.dto.option.OptionResponse;
 import gift.dto.wishproduct.WishProductAddRequest;
 import gift.dto.wishproduct.WishProductResponse;
 import gift.dto.wishproduct.WishProductUpdateRequest;
@@ -34,6 +35,15 @@ public interface WishProductApi {
     })
     ResponseEntity<Void> updateWishProduct(Long id, WishProductUpdateRequest wishProductUpdateRequest);
 
+    @Operation(summary = "회원의 특정 위시 리스트를 조회한다.")
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "특정 위시 리스트 조회 성공", content = @Content(schema = @Schema(implementation = OptionResponse.class))),
+            @ApiResponse(responseCode = "400", description = "특정 위시 리스트 조회 실패(사유 : 다른 사람의 위시 리스트는 접근할 수 없습니다.)", content = @Content(schema = @Schema(hidden = true))),
+            @ApiResponse(responseCode = "401", description = "허용되지 않는 요청", content = @Content(schema = @Schema(hidden = true))),
+            @ApiResponse(responseCode = "500", description = "내부 서버의 오류", content = @Content(schema = @Schema(hidden = true)))
+    })
+    ResponseEntity<WishProductResponse> getWishProduct(Long memberId, Long id);
+
     @Operation(summary = "회원의 위시 리스트에 있는 상품을 페이지 단위로 조회한다.")
     @ApiResponses(value = {
             @ApiResponse(responseCode = "200", description = "모든 위시 리스트 조회 성공", content = @Content(array = @ArraySchema(schema = @Schema(implementation = WishProductResponse.class)))),
diff --git a/src/main/java/gift/dto/auth/AuthResponse.java b/src/main/java/gift/dto/auth/AuthResponse.java
index 10dac2a0e..d06dfbaa7 100644
--- a/src/main/java/gift/dto/auth/AuthResponse.java
+++ b/src/main/java/gift/dto/auth/AuthResponse.java
@@ -1,6 +1,8 @@
 package gift.dto.auth;
 
-public record AuthResponse(String token) {
+public record AuthResponse(
+        String token
+) {
     public static AuthResponse of(String token) {
         return new AuthResponse(token);
     }
diff --git a/src/main/java/gift/dto/category/CategoryInformation.java b/src/main/java/gift/dto/category/CategoryInformation.java
index 11c6e1c74..1eff662b6 100644
--- a/src/main/java/gift/dto/category/CategoryInformation.java
+++ b/src/main/java/gift/dto/category/CategoryInformation.java
@@ -1,6 +1,9 @@
 package gift.dto.category;
 
-public record CategoryInformation(Long id, String name) {
+public record CategoryInformation(
+        Long id,
+        String name
+) {
     public static CategoryInformation of(Long id, String name) {
         return new CategoryInformation(id, name);
     }
diff --git a/src/main/java/gift/dto/category/CategoryResponse.java b/src/main/java/gift/dto/category/CategoryResponse.java
index 370a9a4ae..2ab654bf9 100644
--- a/src/main/java/gift/dto/category/CategoryResponse.java
+++ b/src/main/java/gift/dto/category/CategoryResponse.java
@@ -1,6 +1,12 @@
 package gift.dto.category;
 
-public record CategoryResponse(Long id, String name, String description, String color, String imageUrl) {
+public record CategoryResponse(
+        Long id,
+        String name,
+        String description,
+        String color,
+        String imageUrl
+) {
     public static CategoryResponse of(Long id, String name, String description, String color, String imageUrl) {
         return new CategoryResponse(id, name, description, color, imageUrl);
     }
diff --git a/src/main/java/gift/dto/giftorder/GiftOrderResponse.java b/src/main/java/gift/dto/giftorder/GiftOrderResponse.java
index 5bda70e3c..7e21cc0cf 100644
--- a/src/main/java/gift/dto/giftorder/GiftOrderResponse.java
+++ b/src/main/java/gift/dto/giftorder/GiftOrderResponse.java
@@ -1,11 +1,22 @@
 package gift.dto.giftorder;
 
-import gift.dto.option.OptionInformation;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import gift.dto.option.OptionResponse;
+import gift.dto.product.ProductBasicInformation;
 
 import java.time.LocalDateTime;
 
-public record GiftOrderResponse(Long id, OptionInformation optionInformation, Integer quantity, LocalDateTime orderDateTime, String message) {
-    public static GiftOrderResponse of(Long id, OptionInformation optionInformation, Integer quantity, LocalDateTime orderDateTime, String message) {
-        return new GiftOrderResponse(id, optionInformation, quantity, orderDateTime, message);
+public record GiftOrderResponse(
+        Long id,
+        @JsonProperty("product")
+        ProductBasicInformation productBasicInformation,
+        @JsonProperty("option")
+        OptionResponse optionResponse,
+        Integer quantity,
+        LocalDateTime orderDateTime,
+        String message
+) {
+    public static GiftOrderResponse of(Long id, ProductBasicInformation productBasicInformation, OptionResponse optionResponse, Integer quantity, LocalDateTime orderDateTime, String message) {
+        return new GiftOrderResponse(id, productBasicInformation, optionResponse, quantity, orderDateTime, message);
     }
 }
diff --git a/src/main/java/gift/dto/kakao/KakaoAuthInformation.java b/src/main/java/gift/dto/kakao/KakaoAuthInformation.java
index 4c408e5e7..5bde93a88 100644
--- a/src/main/java/gift/dto/kakao/KakaoAuthInformation.java
+++ b/src/main/java/gift/dto/kakao/KakaoAuthInformation.java
@@ -1,6 +1,9 @@
 package gift.dto.kakao;
 
-public record KakaoAuthInformation(String name, String email) {
+public record KakaoAuthInformation(
+        String name,
+        String email
+) {
     public static KakaoAuthInformation of(String name, String email) {
         return new KakaoAuthInformation(name, email);
     }
diff --git a/src/main/java/gift/dto/option/OptionAddRequest.java b/src/main/java/gift/dto/option/OptionAddRequest.java
deleted file mode 100644
index bb0e3ea62..000000000
--- a/src/main/java/gift/dto/option/OptionAddRequest.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package gift.dto.option;
-
-import jakarta.validation.constraints.Max;
-import jakarta.validation.constraints.Min;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Pattern;
-import org.hibernate.validator.constraints.Length;
-
-public record OptionAddRequest(
-        @Pattern(regexp = "^[\s\\-\\&\\(\\)\\[\\]\\+\\/\\_a-zA-z0-9ㄱ-ㅎ가-힣]*$", message = "허용되지 않은 형식의 이름입니다.")
-        @Length(max = 50, message = "이름의 길이는 50자를 초과할 수 없습니다.")
-        @NotBlank(message = "이름의 길이는 최소 1자 이상이어야 합니다.")
-        String name,
-        @Min(value = 1, message = "수량은 최소 1개 이상, 1억개 미만입니다.")
-        @Max(value = 100_000_000, message = "수량은 최소 1개 이상, 1억개 미만입니다.")
-        Integer quantity,
-        @NotNull(message = "상품은 반드시 선택되어야 합니다.")
-        Long productId
-) {
-}
diff --git a/src/main/java/gift/dto/option/OptionInformation.java b/src/main/java/gift/dto/option/OptionInformation.java
deleted file mode 100644
index 6d039dfcb..000000000
--- a/src/main/java/gift/dto/option/OptionInformation.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package gift.dto.option;
-
-public record OptionInformation(Long id, String productName, Integer price, String name) {
-    public static OptionInformation of(Long id, String productName, Integer price, String name) {
-        return new OptionInformation(id, productName, price, name);
-    }
-}
diff --git a/src/main/java/gift/dto/option/OptionUpdateRequest.java b/src/main/java/gift/dto/option/OptionRequest.java
similarity index 95%
rename from src/main/java/gift/dto/option/OptionUpdateRequest.java
rename to src/main/java/gift/dto/option/OptionRequest.java
index d309e1130..9c7f0f982 100644
--- a/src/main/java/gift/dto/option/OptionUpdateRequest.java
+++ b/src/main/java/gift/dto/option/OptionRequest.java
@@ -6,7 +6,7 @@
 import jakarta.validation.constraints.Pattern;
 import org.hibernate.validator.constraints.Length;
 
-public record OptionUpdateRequest(
+public record OptionRequest(
         @Pattern(regexp = "^[\s\\-\\&\\(\\)\\[\\]\\+\\/\\_a-zA-z0-9ㄱ-ㅎ가-힣]*$", message = "허용되지 않은 형식의 이름입니다.")
         @Length(max = 50, message = "이름의 길이는 50자를 초과할 수 없습니다.")
         @NotBlank(message = "이름의 길이는 최소 1자 이상이어야 합니다.")
diff --git a/src/main/java/gift/dto/option/OptionResponse.java b/src/main/java/gift/dto/option/OptionResponse.java
index 91b41ced6..6d76c4fbb 100644
--- a/src/main/java/gift/dto/option/OptionResponse.java
+++ b/src/main/java/gift/dto/option/OptionResponse.java
@@ -1,6 +1,10 @@
 package gift.dto.option;
 
-public record OptionResponse(Long id, String name, Integer quantity) {
+public record OptionResponse(
+        Long id,
+        String name,
+        Integer quantity
+) {
     public static OptionResponse of(Long id, String name, Integer quantity) {
         return new OptionResponse(id, name, quantity);
     }
diff --git a/src/main/java/gift/dto/product/ProductAddRequest.java b/src/main/java/gift/dto/product/ProductAddRequest.java
new file mode 100644
index 000000000..317eab665
--- /dev/null
+++ b/src/main/java/gift/dto/product/ProductAddRequest.java
@@ -0,0 +1,27 @@
+package gift.dto.product;
+
+import gift.dto.option.OptionRequest;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Pattern;
+import jakarta.validation.constraints.PositiveOrZero;
+import org.hibernate.validator.constraints.Length;
+
+import java.util.List;
+
+public record ProductAddRequest(
+        @Pattern(regexp = "^[\s\\-\\&\\(\\)\\[\\]\\+\\/\\_a-zA-z0-9ㄱ-ㅎ가-힣]*$", message = "허용되지 않은 형식의 이름입니다.")
+        @Length(max = 15, message = "이름의 길이는 15자를 초과할 수 없습니다.")
+        @NotBlank(message = "이름의 길이는 최소 1자 이상이어야 합니다.")
+        String name,
+        @PositiveOrZero(message = "금액은 0보다 크거나 같아야 합니다.")
+        Integer price,
+        @NotBlank(message = "상품 이미지는 필수로 입력해야 합니다.")
+        String imageUrl,
+        @NotNull(message = "상품 카테고리는 반드시 선택되어야 합니다.")
+        Long categoryId,
+        @NotEmpty(message = "상품의 옵션은 반드시 1개 이상 존재해야 합니다.")
+        List<OptionRequest> options
+) {
+}
diff --git a/src/main/java/gift/dto/product/ProductBasicInformation.java b/src/main/java/gift/dto/product/ProductBasicInformation.java
index 3d8a0ae57..71990461b 100644
--- a/src/main/java/gift/dto/product/ProductBasicInformation.java
+++ b/src/main/java/gift/dto/product/ProductBasicInformation.java
@@ -1,6 +1,10 @@
 package gift.dto.product;
 
-public record ProductBasicInformation(Long id, String name, Integer price) {
+public record ProductBasicInformation(
+        Long id,
+        String name,
+        Integer price
+) {
     public static ProductBasicInformation of(Long id, String name, Integer price) {
         return new ProductBasicInformation(id, name, price);
     }
diff --git a/src/main/java/gift/dto/product/ProductResponse.java b/src/main/java/gift/dto/product/ProductResponse.java
index 806988f31..4c53a6cb6 100644
--- a/src/main/java/gift/dto/product/ProductResponse.java
+++ b/src/main/java/gift/dto/product/ProductResponse.java
@@ -1,9 +1,21 @@
 package gift.dto.product;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
 import gift.dto.category.CategoryInformation;
+import gift.dto.option.OptionResponse;
 
-public record ProductResponse(Long id, String name, Integer price, String imageUrl, CategoryInformation categoryInformation) {
-    public static ProductResponse of(Long id, String name, Integer price, String imageUrl, CategoryInformation categoryInformation) {
-        return new ProductResponse(id, name, price, imageUrl, categoryInformation);
+import java.util.List;
+
+public record ProductResponse(
+        Long id,
+        String name,
+        Integer price,
+        String imageUrl,
+        @JsonProperty("category")
+        CategoryInformation categoryInformation,
+        List<OptionResponse> options
+) {
+    public static ProductResponse of(Long id, String name, Integer price, String imageUrl, CategoryInformation categoryInformation, List<OptionResponse> options) {
+        return new ProductResponse(id, name, price, imageUrl, categoryInformation, options);
     }
 }
diff --git a/src/main/java/gift/dto/product/ProductRequest.java b/src/main/java/gift/dto/product/ProductUpdateRequest.java
similarity index 96%
rename from src/main/java/gift/dto/product/ProductRequest.java
rename to src/main/java/gift/dto/product/ProductUpdateRequest.java
index 70182125c..19bafe1a5 100644
--- a/src/main/java/gift/dto/product/ProductRequest.java
+++ b/src/main/java/gift/dto/product/ProductUpdateRequest.java
@@ -6,7 +6,7 @@
 import jakarta.validation.constraints.PositiveOrZero;
 import org.hibernate.validator.constraints.Length;
 
-public record ProductRequest(
+public record ProductUpdateRequest(
         @Pattern(regexp = "^[\s\\-\\&\\(\\)\\[\\]\\+\\/\\_a-zA-z0-9ㄱ-ㅎ가-힣]*$", message = "허용되지 않은 형식의 이름입니다.")
         @Length(max = 15, message = "이름의 길이는 15자를 초과할 수 없습니다.")
         @NotBlank(message = "이름의 길이는 최소 1자 이상이어야 합니다.")
diff --git a/src/main/java/gift/dto/wishproduct/WishProductResponse.java b/src/main/java/gift/dto/wishproduct/WishProductResponse.java
index 2eb609312..b2e5d3353 100644
--- a/src/main/java/gift/dto/wishproduct/WishProductResponse.java
+++ b/src/main/java/gift/dto/wishproduct/WishProductResponse.java
@@ -1,8 +1,14 @@
 package gift.dto.wishproduct;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
 import gift.dto.product.ProductBasicInformation;
 
-public record WishProductResponse(Long id, ProductBasicInformation productBasicInformation, Integer quantity) {
+public record WishProductResponse(
+        Long id,
+        @JsonProperty("product")
+        ProductBasicInformation productBasicInformation,
+        Integer quantity
+) {
     public static WishProductResponse of(Long id, ProductBasicInformation productBasicInformation, Integer quantity) {
         return new WishProductResponse(id, productBasicInformation, quantity);
     }
diff --git a/src/main/java/gift/repository/OptionRepository.java b/src/main/java/gift/repository/OptionRepository.java
index aa8ee4394..089597def 100644
--- a/src/main/java/gift/repository/OptionRepository.java
+++ b/src/main/java/gift/repository/OptionRepository.java
@@ -2,7 +2,6 @@
 
 import gift.model.Option;
 import jakarta.persistence.LockModeType;
-import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Lock;
 import org.springframework.data.jpa.repository.Query;
@@ -13,7 +12,7 @@
 
 @Repository
 public interface OptionRepository extends JpaRepository<Option, Long> {
-    List<Option> findAllByProductId(Long productId, Pageable pageable);
+    List<Option> findAllByProductId(Long productId);
 
     boolean existsOptionByProductIdAndName(Long productId, String name);
 
diff --git a/src/main/java/gift/repository/ProductRepository.java b/src/main/java/gift/repository/ProductRepository.java
index 51ec2a939..2ba6cd06c 100644
--- a/src/main/java/gift/repository/ProductRepository.java
+++ b/src/main/java/gift/repository/ProductRepository.java
@@ -1,6 +1,7 @@
 package gift.repository;
 
 import gift.model.Product;
+import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 
@@ -9,4 +10,6 @@
 @Repository
 public interface ProductRepository extends JpaRepository<Product, Long> {
     List<Product> findAllByCategoryId(Long categoryId);
+
+    List<Product> findAllByCategoryId(Long categoryId, Pageable pageable);
 }
diff --git a/src/main/java/gift/service/CategoryService.java b/src/main/java/gift/service/CategoryService.java
index ab080a051..d147130fc 100644
--- a/src/main/java/gift/service/CategoryService.java
+++ b/src/main/java/gift/service/CategoryService.java
@@ -6,7 +6,6 @@
 import gift.exception.NotFoundElementException;
 import gift.model.Category;
 import gift.repository.CategoryRepository;
-import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -44,8 +43,8 @@ public CategoryResponse getCategory(Long id) {
     }
 
     @Transactional(readOnly = true)
-    public List<CategoryResponse> getCategories(Pageable pageable) {
-        return categoryRepository.findAll(pageable)
+    public List<CategoryResponse> getCategories() {
+        return categoryRepository.findAll()
                 .stream()
                 .map(this::getCategoryResponseFromCategory)
                 .toList();
diff --git a/src/main/java/gift/service/GiftOrderService.java b/src/main/java/gift/service/GiftOrderService.java
index a4eb4f558..09ca4d96a 100644
--- a/src/main/java/gift/service/GiftOrderService.java
+++ b/src/main/java/gift/service/GiftOrderService.java
@@ -2,7 +2,8 @@
 
 import gift.dto.giftorder.GiftOrderRequest;
 import gift.dto.giftorder.GiftOrderResponse;
-import gift.dto.option.OptionInformation;
+import gift.dto.option.OptionResponse;
+import gift.dto.product.ProductBasicInformation;
 import gift.exception.NotFoundElementException;
 import gift.model.GiftOrder;
 import gift.model.Option;
@@ -69,7 +70,9 @@ private GiftOrder saveGiftOrderWithGiftOrderRequest(Long memberId, Option option
     }
 
     private GiftOrderResponse getGiftOrderResponseFromGiftOrder(GiftOrder giftOrder) {
-        var optionInformation = OptionInformation.of(giftOrder.getId(), giftOrder.getOption().getProduct().getName(), giftOrder.getOption().getProduct().getPrice(), giftOrder.getOption().getName());
-        return GiftOrderResponse.of(giftOrder.getId(), optionInformation, giftOrder.getQuantity(), giftOrder.getCreatedDate(), giftOrder.getMessage());
+        var product = giftOrder.getOption().getProduct();
+        var productBasicInformation = ProductBasicInformation.of(product.getId(), product.getName(), product.getPrice());
+        var optionResponse = OptionResponse.of(giftOrder.getId(), giftOrder.getOption().getProduct().getName(), giftOrder.getQuantity());
+        return GiftOrderResponse.of(giftOrder.getId(), productBasicInformation, optionResponse, giftOrder.getQuantity(), giftOrder.getCreatedDate(), giftOrder.getMessage());
     }
 }
diff --git a/src/main/java/gift/service/KakaoService.java b/src/main/java/gift/service/KakaoService.java
index 30292d38f..db3e1d7da 100644
--- a/src/main/java/gift/service/KakaoService.java
+++ b/src/main/java/gift/service/KakaoService.java
@@ -7,6 +7,7 @@
 import gift.dto.kakao.KakaoTokenResponse;
 import gift.exception.InvalidKakaoTokenException;
 import gift.exception.NotFoundElementException;
+import gift.exception.UnauthorizedAccessException;
 import gift.model.Member;
 import gift.model.OauthToken;
 import gift.model.OauthType;
@@ -59,7 +60,7 @@ public KakaoAuthInformation getKakaoAuthInformation(KakaoTokenResponse kakaoToke
 
     public void sendOrderResponseWithKakaoMessage(Long memberId, GiftOrderResponse giftOrderResponse) {
         var kakaoToken = oauthTokenRepository.findByMemberIdAndOauthType(memberId, OauthType.KAKAO)
-                .orElseThrow(() -> new InvalidKakaoTokenException(memberId + "를 가진 이용자의 카카오 토큰 정보가 존재하지 않습니다."));
+                .orElseThrow(() -> new NotFoundElementException(memberId + "를 가진 이용자의 카카오 토큰 정보가 존재하지 않습니다."));
         var validatedKakaoToken = tokenValidation(kakaoToken);
         kakaoApiClient.sendSelfMessageOrder(validatedKakaoToken.getAccessToken(), giftOrderResponse);
     }
@@ -71,7 +72,7 @@ public void deleteByMemberId(Long memberId) {
 
     private OauthToken tokenValidation(OauthToken oauthToken) {
         if (!oauthToken.canUseRefreshToken()) {
-            throw new InvalidKakaoTokenException("유효하지 않은 토큰입니다. 갱신이 필요합니다.");
+            throw new UnauthorizedAccessException("유효하지 않은 카카오 토큰입니다. 갱신이 필요합니다.");
         }
         if (!oauthToken.canUseAccessToken()) {
             var kakaoTokenResponse = kakaoApiClient.getRefreshedTokenResponse(oauthToken.getRefreshToken());
diff --git a/src/main/java/gift/service/OptionService.java b/src/main/java/gift/service/OptionService.java
index 61d755579..68d5bf8e8 100644
--- a/src/main/java/gift/service/OptionService.java
+++ b/src/main/java/gift/service/OptionService.java
@@ -2,16 +2,15 @@
 
 import gift.dto.giftorder.GiftOrderRequest;
 import gift.dto.giftorder.GiftOrderResponse;
-import gift.dto.option.OptionAddRequest;
+import gift.dto.option.OptionRequest;
 import gift.dto.option.OptionResponse;
-import gift.dto.option.OptionUpdateRequest;
+import gift.exception.BadRequestException;
 import gift.exception.DuplicatedNameException;
 import gift.exception.NotFoundElementException;
 import gift.model.Option;
 import gift.model.Product;
 import gift.repository.OptionRepository;
 import gift.repository.ProductRepository;
-import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -31,27 +30,37 @@ public OptionService(OptionRepository optionRepository, ProductRepository produc
         this.giftOrderService = giftOrderService;
     }
 
-    public OptionResponse addOption(OptionAddRequest optionAddRequest) {
-        optionNameValidation(optionAddRequest.productId(), optionAddRequest.name());
-        var option = saveOptionWithOptionRequest(optionAddRequest);
+    public OptionResponse addOption(Long productId, OptionRequest optionRequest) {
+        optionNameValidation(productId, optionRequest.name());
+        var option = saveOptionWithOptionRequest(productId, optionRequest);
         return getOptionResponseFromOption(option);
     }
 
-    public void updateOption(Long id, OptionUpdateRequest optionUpdateRequest) {
+    public void updateOption(Long productId, Long id, OptionRequest optionRequest) {
         var option = findOptionById(id);
-        option.updateOptionInfo(optionUpdateRequest.name(), optionUpdateRequest.quantity());
+        optionProductValidation(productId, option);
+        option.updateOptionInfo(optionRequest.name(), optionRequest.quantity());
         optionRepository.save(option);
     }
 
     @Transactional(readOnly = true)
-    public List<OptionResponse> getOptions(Long productId, Pageable pageable) {
-        return optionRepository.findAllByProductId(productId, pageable)
+    public OptionResponse getOption(Long productId, Long id) {
+        var option = findOptionById(id);
+        optionProductValidation(productId, option);
+        return getOptionResponseFromOption(option);
+    }
+
+    @Transactional(readOnly = true)
+    public List<OptionResponse> getOptions(Long productId) {
+        return optionRepository.findAllByProductId(productId)
                 .stream()
                 .map(this::getOptionResponseFromOption)
                 .toList();
     }
 
-    public void deleteOption(Long optionId) {
+    public void deleteOption(Long productId, Long optionId) {
+        var option = findOptionById(optionId);
+        optionProductValidation(productId, option);
         if (!optionRepository.existsById(optionId)) {
             throw new NotFoundElementException("존재하지 않는 상품 옵션의 ID 입니다.");
         }
@@ -63,11 +72,6 @@ public void deleteAllByProductId(Long productId) {
         optionRepository.deleteAllByProductId(productId);
     }
 
-    public void makeDefaultOption(Product product) {
-        var option = new Option(product, "기본", 1000);
-        optionRepository.save(option);
-    }
-
     public GiftOrderResponse orderOption(Long memberId, GiftOrderRequest giftOrderRequest) {
         var option = subtractOptionQuantity(giftOrderRequest.optionId(), giftOrderRequest.quantity());
         return giftOrderService.addGiftOrder(memberId, option, giftOrderRequest);
@@ -80,9 +84,9 @@ private Option subtractOptionQuantity(Long id, Integer quantity) {
         return optionRepository.save(option);
     }
 
-    private Option saveOptionWithOptionRequest(OptionAddRequest optionAddRequest) {
-        var product = findProductById(optionAddRequest.productId());
-        var option = new Option(product, optionAddRequest.name(), optionAddRequest.quantity());
+    private Option saveOptionWithOptionRequest(Long productId, OptionRequest optionRequest) {
+        var product = findProductById(productId);
+        var option = new Option(product, optionRequest.name(), optionRequest.quantity());
         return optionRepository.save(option);
     }
 
@@ -105,4 +109,10 @@ private void optionNameValidation(Long productId, String name) {
             throw new DuplicatedNameException("이미 존재하는 상품의 상품 옵션입니다.");
         }
     }
+
+    private void optionProductValidation(Long productId, Option option) {
+        if (!option.getProduct().getId().equals(productId)) {
+            throw new BadRequestException("잘못된 접근입니다.");
+        }
+    }
 }
diff --git a/src/main/java/gift/service/ProductService.java b/src/main/java/gift/service/ProductService.java
index 8a54344be..e8c66f5cf 100644
--- a/src/main/java/gift/service/ProductService.java
+++ b/src/main/java/gift/service/ProductService.java
@@ -1,14 +1,15 @@
 package gift.service;
 
 import gift.dto.category.CategoryInformation;
-import gift.dto.product.ProductRequest;
+import gift.dto.option.OptionRequest;
+import gift.dto.product.ProductAddRequest;
 import gift.dto.product.ProductResponse;
+import gift.dto.product.ProductUpdateRequest;
 import gift.exception.InvalidProductNameWithKAKAOException;
 import gift.exception.NotFoundElementException;
 import gift.model.Category;
 import gift.model.Product;
 import gift.repository.CategoryRepository;
-import gift.repository.OptionRepository;
 import gift.repository.ProductRepository;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
@@ -25,23 +26,24 @@ public class ProductService {
     private final WishProductService wishProductService;
     private final OptionService optionService;
 
-    public ProductService(ProductRepository productRepository, CategoryRepository categoryRepository, WishProductService wishProductService, OptionRepository optionRepository, OptionService optionService) {
+    public ProductService(ProductRepository productRepository, CategoryRepository categoryRepository, WishProductService wishProductService, OptionService optionService) {
         this.productRepository = productRepository;
         this.categoryRepository = categoryRepository;
         this.wishProductService = wishProductService;
         this.optionService = optionService;
     }
 
-    public ProductResponse addProduct(ProductRequest productRequest) {
-        productNameValidation(productRequest);
-        var product = saveProductWithProductRequest(productRequest);
-        optionService.makeDefaultOption(product);
+    public ProductResponse addProduct(ProductAddRequest productAddRequest) {
+        productNameValidation(productAddRequest.name());
+        var product = saveProductWithProductRequest(productAddRequest);
+        makeOptionsWithProductRequest(product, productAddRequest.options());
         return getProductResponseFromProduct(product);
     }
 
-    public void updateProduct(Long id, ProductRequest productRequest) {
+    public void updateProduct(Long id, ProductUpdateRequest productUpdateRequest) {
+        productNameValidation(productUpdateRequest.name());
         var product = findProductById(id);
-        updateProductWithProductRequest(product, productRequest);
+        updateProductWithProductRequest(product, productUpdateRequest);
     }
 
     @Transactional(readOnly = true)
@@ -58,6 +60,14 @@ public List<ProductResponse> getProducts(Pageable pageable) {
                 .toList();
     }
 
+    @Transactional(readOnly = true)
+    public List<ProductResponse> getProducts(Long categoryId, Pageable pageable) {
+        return productRepository.findAllByCategoryId(categoryId, pageable)
+                .stream()
+                .map(this::getProductResponseFromProduct)
+                .toList();
+    }
+
     public void deleteProduct(Long productId) {
         if (!productRepository.existsById(productId)) {
             throw new NotFoundElementException("존재하지 않는 상품의 ID 입니다.");
@@ -74,26 +84,33 @@ public void deleteAllProductWithCategoryId(Long categoryId) {
         }
     }
 
-    private Product saveProductWithProductRequest(ProductRequest productRequest) {
-        var category = categoryRepository.findById(productRequest.categoryId())
-                .orElseThrow(() -> new NotFoundElementException(productRequest.categoryId() + "를 가진 상품 카테고리가 존재하지 않습니다."));
-        var product = new Product(productRequest.name(), productRequest.price(), productRequest.imageUrl(), category);
+    private Product saveProductWithProductRequest(ProductAddRequest productAddRequest) {
+        var category = categoryRepository.findById(productAddRequest.categoryId())
+                .orElseThrow(() -> new NotFoundElementException(productAddRequest.categoryId() + "를 가진 상품 카테고리가 존재하지 않습니다."));
+        var product = new Product(productAddRequest.name(), productAddRequest.price(), productAddRequest.imageUrl(), category);
         return productRepository.save(product);
     }
 
-    private void updateProductWithProductRequest(Product product, ProductRequest productRequest) {
-        product.updateProductInfo(productRequest.name(), productRequest.price(), productRequest.imageUrl());
+    private void makeOptionsWithProductRequest(Product product, List<OptionRequest> options) {
+        for (var option : options) {
+            optionService.addOption(product.getId(), option);
+        }
+    }
+
+    private void updateProductWithProductRequest(Product product, ProductUpdateRequest productUpdateRequest) {
+        product.updateProductInfo(productUpdateRequest.name(), productUpdateRequest.price(), productUpdateRequest.imageUrl());
         productRepository.save(product);
     }
 
-    private void productNameValidation(ProductRequest productRequest) {
-        if (!productRequest.name().contains("카카오")) return;
+    private void productNameValidation(String name) {
+        if (!name.contains("카카오")) return;
         throw new InvalidProductNameWithKAKAOException("카카오가 포함된 문구는 담당 MD와 협의한 경우에만 사용할 수 있습니다.");
     }
 
     private ProductResponse getProductResponseFromProduct(Product product) {
         var categoryInformation = getCategoryInformationFromCategory(product.getCategory());
-        return ProductResponse.of(product.getId(), product.getName(), product.getPrice(), product.getImageUrl(), categoryInformation);
+        var options = optionService.getOptions(product.getId());
+        return ProductResponse.of(product.getId(), product.getName(), product.getPrice(), product.getImageUrl(), categoryInformation, options);
     }
 
     private Product findProductById(Long id) {
diff --git a/src/main/java/gift/service/WishProductService.java b/src/main/java/gift/service/WishProductService.java
index 7b0503592..41254faa4 100644
--- a/src/main/java/gift/service/WishProductService.java
+++ b/src/main/java/gift/service/WishProductService.java
@@ -4,6 +4,7 @@
 import gift.dto.wishproduct.WishProductAddRequest;
 import gift.dto.wishproduct.WishProductResponse;
 import gift.dto.wishproduct.WishProductUpdateRequest;
+import gift.exception.BadRequestException;
 import gift.exception.NotFoundElementException;
 import gift.model.Member;
 import gift.model.Product;
@@ -52,6 +53,15 @@ public void updateWishProduct(Long id, WishProductUpdateRequest wishProductUpdat
         updateWishProductWithQuantity(wishProduct, wishProductUpdateRequest.quantity());
     }
 
+    @Transactional(readOnly = true)
+    public WishProductResponse getWishProduct(Long memberId, Long id) {
+        var wishProduct = findWishProductById(id);
+        if (!wishProduct.getMember().getId().equals(memberId)) {
+            throw new BadRequestException("다른 사람의 위시 리스트는 접근할 수 없습니다.");
+        }
+        return getWishProductResponseFromWishProduct(wishProduct);
+    }
+
     @Transactional(readOnly = true)
     public List<WishProductResponse> getWishProducts(Long memberId, Pageable pageable) {
         return wishProductRepository.findAllByMemberId(memberId, pageable)
diff --git a/src/test/java/gift/controller/OptionControllerTest.java b/src/test/java/gift/controller/OptionControllerTest.java
index 0595d3782..97464c132 100644
--- a/src/test/java/gift/controller/OptionControllerTest.java
+++ b/src/test/java/gift/controller/OptionControllerTest.java
@@ -2,7 +2,7 @@
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import gift.dto.auth.LoginRequest;
-import gift.dto.option.OptionAddRequest;
+import gift.dto.option.OptionRequest;
 import gift.exception.ExceptionResponse;
 import gift.service.OptionService;
 import gift.service.auth.AuthService;
@@ -48,10 +48,10 @@ void setBaseData() {
     @DisplayName("잘못된 수량으로 된 오류 상품 옵션 생성하기")
     void failAddOptionWithWrongQuantity() throws Exception {
         //given
-        var postRequest = post("/api/options")
+        var postRequest = post("/api/products/1/options")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new OptionAddRequest("기본", 0, 1L)));
+                .content(objectMapper.writeValueAsString(new OptionRequest("기본", 0)));
         //when
         var result = mockMvc.perform(postRequest).andReturn();
         //then
@@ -64,10 +64,10 @@ void failAddOptionWithWrongQuantity() throws Exception {
     @DisplayName("빈 이름을 가진 오류 상품 옵션 생성하기")
     void failAddOptionWithEmptyName() throws Exception {
         //given
-        var postRequest = post("/api/options")
+        var postRequest = post("/api/products/1/options")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new OptionAddRequest("", 1000, 1L)));
+                .content(objectMapper.writeValueAsString(new OptionRequest("", 1000)));
         //when
         var result = mockMvc.perform(postRequest).andReturn();
         //then
@@ -80,10 +80,10 @@ void failAddOptionWithEmptyName() throws Exception {
     @DisplayName("이름의 길이가 50초과인 오류 상품 생성하기")
     void failAddOptionWithNameOverLength() throws Exception {
         //given
-        var postRequest = post("/api/options")
+        var postRequest = post("/api/products/1/options")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new OptionAddRequest("aaaaaaaaaaaaaaaaaabbbbbbbbbbbbcccccccccccccccddddddddddddddddddddwwwwwwwwwwqqqqqqqqqqqqqqq", 1000, 1L)));
+                .content(objectMapper.writeValueAsString(new OptionRequest("aaaaaaaaaaaaaaaaaabbbbbbbbbbbbcccccccccccccccddddddddddddddddddddwwwwwwwwwwqqqqqqqqqqqqqqq", 1000)));
         //when
         var result = mockMvc.perform(postRequest).andReturn();
         //then
@@ -96,10 +96,10 @@ void failAddOptionWithNameOverLength() throws Exception {
     @DisplayName("정상 상품 옵션 생성하기")
     void successAddOption() throws Exception {
         //given
-        var postRequest = post("/api/options")
+        var postRequest = post("/api/products/1/options")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new OptionAddRequest("Large", 1500, 1L)));
+                .content(objectMapper.writeValueAsString(new OptionRequest("Large", 1500)));
         //when
         var result = mockMvc.perform(postRequest);
         //then
@@ -112,10 +112,10 @@ void successAddOption() throws Exception {
     @DisplayName("존재하지 않는 상품에 대한 옵션 생성하기")
     void failAddOptionWithNotExistProductId() throws Exception {
         //given
-        var postRequest = post("/api/options")
+        var postRequest = post("/api/products/1000/options")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new OptionAddRequest("Large", 1500, 1000L)));
+                .content(objectMapper.writeValueAsString(new OptionRequest("Large", 1500)));
         //when
         var result = mockMvc.perform(postRequest).andReturn();
         //then
@@ -127,10 +127,10 @@ void failAddOptionWithNotExistProductId() throws Exception {
     @DisplayName("정상 옵션 생성하기 - 특수문자 포함")
     void successAddOptionWithSpecialChar() throws Exception {
         //given
-        var postRequest = post("/api/options")
+        var postRequest = post("/api/products/1/options")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new OptionAddRequest("햄버거()[]+-&/_", 1000, 1L)));
+                .content(objectMapper.writeValueAsString(new OptionRequest("햄버거()[]+-&/_", 1000)));
         //when
         var result = mockMvc.perform(postRequest);
         //then
@@ -143,10 +143,10 @@ void successAddOptionWithSpecialChar() throws Exception {
     @DisplayName("정상 옵션 생성하기 - 공백 포함")
     void successAddOptionWithEmptySpace() throws Exception {
         //given
-        var postRequest = post("/api/options")
+        var postRequest = post("/api/products/1/options")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new OptionAddRequest("햄버거 햄버거 햄버거", 1000, 1L)));
+                .content(objectMapper.writeValueAsString(new OptionRequest("햄버거 햄버거 햄버거", 1000)));
         //when
         var result = mockMvc.perform(postRequest);
         //then
@@ -159,10 +159,10 @@ void successAddOptionWithEmptySpace() throws Exception {
     @DisplayName("오류 상품 생성하기 - 허용되지 않은 특수문자 포함")
     void failAddOptionWithSpecialChar() throws Exception {
         //given
-        var postRequest = post("/api/options")
+        var postRequest = post("/api/products/1/options")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new OptionAddRequest("햄버거()[]+-&/_**", 1000, 1L)));
+                .content(objectMapper.writeValueAsString(new OptionRequest("햄버거()[]+-&/_**", 1000)));
         //when
         var result = mockMvc.perform(postRequest).andReturn();
         //then
@@ -173,8 +173,10 @@ void failAddOptionWithSpecialChar() throws Exception {
 
     private void deleteOptionWithCreatedHeader(MvcResult mvcResult) {
         var location = mvcResult.getResponse().getHeader("Location");
-        var optionId = location.replaceAll("/api/options/", "");
-        optionService.deleteOption(Long.parseLong(optionId));
+        var splitResult = location.split("/");
+        var productId = Long.parseLong(splitResult[splitResult.length - 3]);
+        var optionId = Long.parseLong(splitResult[splitResult.length - 1]);
+        optionService.deleteOption(productId, optionId);
     }
 
     private ExceptionResponse getResponseMessage(MvcResult result) throws Exception {
diff --git a/src/test/java/gift/controller/ProductControllerTest.java b/src/test/java/gift/controller/ProductControllerTest.java
index 00d42ff86..874784b91 100644
--- a/src/test/java/gift/controller/ProductControllerTest.java
+++ b/src/test/java/gift/controller/ProductControllerTest.java
@@ -3,7 +3,8 @@
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import gift.dto.auth.LoginRequest;
-import gift.dto.product.ProductRequest;
+import gift.dto.option.OptionRequest;
+import gift.dto.product.ProductAddRequest;
 import gift.dto.product.ProductResponse;
 import gift.exception.ExceptionResponse;
 import gift.service.OptionService;
@@ -16,7 +17,6 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.data.domain.Pageable;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.test.web.servlet.MockMvc;
@@ -61,10 +61,14 @@ void setBaseData() {
     @DisplayName("잘못된 가격으로 된 오류 상품 생성하기")
     void failAddProductWithWrongPrice() throws Exception {
         //given
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
+        var productRequest = new ProductAddRequest("상품1", -10000, "이미지 주소", 1L, options);
         var postRequest = post("/api/products")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new ProductRequest("상품1", -1000, "이미지 주소", 1L)));
+                .content(objectMapper.writeValueAsString(productRequest));
         //when
         var result = mockMvc.perform(postRequest).andReturn();
         //then
@@ -77,10 +81,13 @@ void failAddProductWithWrongPrice() throws Exception {
     @DisplayName("이름의 길이가 15초과인 오류 상품 생성하기")
     void failAddProductWithNameOverLength() throws Exception {
         //given
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
         var postRequest = post("/api/products")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new ProductRequest("햄버거햄버거햄버거햄버거햄버거햄", 1000, "이미지 주소", 1L)));
+                .content(objectMapper.writeValueAsString(new ProductAddRequest("햄버거햄버거햄버거햄버거햄버거햄", 1000, "이미지 주소", 1L, options)));
         //when
         var result = mockMvc.perform(postRequest).andReturn();
         //then
@@ -93,10 +100,13 @@ void failAddProductWithNameOverLength() throws Exception {
     @DisplayName("카카오를 포함한 이름을 가진 오류 상품 생성하기")
     void failAddProductWithNameKakao() throws Exception {
         //given
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
         var postRequest = post("/api/products")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new ProductRequest("카카오456", 1000, "이미지 주소", 1L)));
+                .content(objectMapper.writeValueAsString(new ProductAddRequest("카카오456", 1000, "이미지 주소", 1L, options)));
         //when
         var result = mockMvc.perform(postRequest).andReturn();
         //then
@@ -109,10 +119,13 @@ void failAddProductWithNameKakao() throws Exception {
     @DisplayName("빈 이름을 가진 오류 상품 생성하기")
     void failAddProductWithEmptyName() throws Exception {
         //given
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
         var postRequest = post("/api/products")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new ProductRequest("", 1000, "이미지 주소", 1L)));
+                .content(objectMapper.writeValueAsString(new ProductAddRequest("", 1000, "이미지 주소", 1L, options)));
         //when
         var result = mockMvc.perform(postRequest).andReturn();
         //then
@@ -125,10 +138,13 @@ void failAddProductWithEmptyName() throws Exception {
     @DisplayName("정상 상품 생성하기 - 특수문자 포함")
     void successAddProductWithSpecialChar() throws Exception {
         //given
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
         var postRequest = post("/api/products")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new ProductRequest("햄버거()[]+-&/_", 1000, "이미지 주소", 1L)));
+                .content(objectMapper.writeValueAsString(new ProductAddRequest("햄버거()[]+-&/_", 1000, "이미지 주소", 1L, options)));
         //when
         var result = mockMvc.perform(postRequest);
         //then
@@ -141,10 +157,13 @@ void successAddProductWithSpecialChar() throws Exception {
     @DisplayName("정상 상품 생성하기 - 공백 포함")
     void successAddProductWithEmptySpace() throws Exception {
         //given
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
         var postRequest = post("/api/products")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new ProductRequest("햄버거 햄버거 햄버거", 1000, "이미지 주소", 1L)));
+                .content(objectMapper.writeValueAsString(new ProductAddRequest("햄버거 햄버거 햄버거", 1000, "이미지 주소", 1L, options)));
         //when
         var result = mockMvc.perform(postRequest);
         //then
@@ -157,10 +176,13 @@ void successAddProductWithEmptySpace() throws Exception {
     @DisplayName("오류 상품 생성하기 - 허용되지 않은 특수문자 포함")
     void failAddProductWithSpecialChar() throws Exception {
         //given
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
         var postRequest = post("/api/products")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new ProductRequest("햄버거()[]+-&/_**", 1000, "이미지 주소", 1L)));
+                .content(objectMapper.writeValueAsString(new ProductAddRequest("햄버거()[]+-&/_**", 1000, "이미지 주소", 1L, options)));
         //when
         var result = mockMvc.perform(postRequest).andReturn();
         //then
@@ -174,7 +196,10 @@ void failAddProductWithSpecialChar() throws Exception {
     void successGetProductsWithPageable() throws Exception {
         List<ProductResponse> productResponseList = new ArrayList<>();
         //given
-        var productRequest = new ProductRequest("햄버거()[]+-&/_**", 1000, "이미지 주소", 1L);
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
+        var productRequest = new ProductAddRequest("햄버거()[]+-&/_**", 1000, "이미지 주소", 1L, options);
         for (int i = 0; i < 11; i++) {
             var product = productService.addProduct(productRequest);
             productResponseList.add(product);
@@ -212,10 +237,13 @@ void failGetProductsWithInvalidPageSort() throws Exception {
     @DisplayName("상품이 추가되면 옵션이 자동적으로 생성된다.")
     void successAddDefaultOption() throws Exception {
         //given
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
         var postRequest = post("/api/products")
                 .contentType(MediaType.APPLICATION_JSON)
                 .header("Authorization", "Bearer " + memberToken)
-                .content(objectMapper.writeValueAsString(new ProductRequest("햄버거", 1000, "이미지 주소", 1L)));
+                .content(objectMapper.writeValueAsString(new ProductAddRequest("햄버거", 1000, "이미지 주소", 1L, options)));
         //when
         var result = mockMvc.perform(postRequest);
         //then
@@ -224,9 +252,8 @@ void successAddDefaultOption() throws Exception {
         var location = createdResult.getResponse().getHeader("Location");
         var productId = Long.parseLong(location.replaceAll("/api/products/", ""));
 
-        var optionResponses = optionService.getOptions(productId, Pageable.unpaged());
+        var optionResponses = optionService.getOptions(productId);
         Assertions.assertThat(optionResponses.size()).isEqualTo(1);
-        Assertions.assertThat(optionResponses.get(0).name()).isEqualTo("기본");
         productService.deleteProduct(productId);
     }
 
diff --git a/src/test/java/gift/service/CategoryServiceTest.java b/src/test/java/gift/service/CategoryServiceTest.java
index 739e5caf4..024655a10 100644
--- a/src/test/java/gift/service/CategoryServiceTest.java
+++ b/src/test/java/gift/service/CategoryServiceTest.java
@@ -59,7 +59,7 @@ void successGetCategory() {
     @DisplayName("전체 카테고리 조회하기")
     void successGatCategories() {
         //given, when
-        var categories = categoryService.getCategories(pageable);
+        var categories = categoryService.getCategories();
         //then
         Assertions.assertThat(categories.size()).isEqualTo(4);
     }
diff --git a/src/test/java/gift/service/OptionServiceTest.java b/src/test/java/gift/service/OptionServiceTest.java
index 4c576557d..bf28b1860 100644
--- a/src/test/java/gift/service/OptionServiceTest.java
+++ b/src/test/java/gift/service/OptionServiceTest.java
@@ -1,8 +1,7 @@
 package gift.service;
 
 import gift.dto.giftorder.GiftOrderRequest;
-import gift.dto.option.OptionAddRequest;
-import gift.dto.option.OptionUpdateRequest;
+import gift.dto.option.OptionRequest;
 import gift.exception.BadRequestException;
 import gift.exception.DuplicatedNameException;
 import org.assertj.core.api.Assertions;
@@ -10,8 +9,6 @@
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.concurrent.CountDownLatch;
@@ -22,7 +19,6 @@
 @Transactional
 class OptionServiceTest {
 
-    private final Pageable pageable = PageRequest.of(0, 10);
     @Autowired
     private OptionService optionService;
 
@@ -30,75 +26,75 @@ class OptionServiceTest {
     @DisplayName("정상 옵션 추가하기")
     void successAddOption() {
         //given
-        var optionRequest = new OptionAddRequest("옵션1", 1000, 1L);
+        var optionRequest = new OptionRequest("옵션1", 1000);
         //when
-        var savedOption = optionService.addOption(optionRequest);
+        var savedOption = optionService.addOption(1L, optionRequest);
         //then
-        var options = optionService.getOptions(1L, pageable);
+        var options = optionService.getOptions(1L);
         Assertions.assertThat(options.size()).isEqualTo(1);
 
-        optionService.deleteOption(savedOption.id());
+        optionService.deleteOption(1L, savedOption.id());
     }
 
     @Test
     @DisplayName("둘 이상의 옵션 추가하기")
     void successAddOptions() {
         //given
-        var optionRequest1 = new OptionAddRequest("옵션1", 1000, 1L);
-        var optionRequest2 = new OptionAddRequest("옵션2", 1000, 1L);
+        var optionRequest1 = new OptionRequest("옵션1", 1000);
+        var optionRequest2 = new OptionRequest("옵션2", 1000);
         //when
-        var savedOption1 = optionService.addOption(optionRequest1);
-        var savedOption2 = optionService.addOption(optionRequest2);
+        var savedOption1 = optionService.addOption(1L, optionRequest1);
+        var savedOption2 = optionService.addOption(1L, optionRequest2);
         //then
-        var options = optionService.getOptions(1L, pageable);
+        var options = optionService.getOptions(1L);
         Assertions.assertThat(options.size()).isEqualTo(2);
 
-        optionService.deleteOption(savedOption1.id());
-        optionService.deleteOption(savedOption2.id());
+        optionService.deleteOption(1L, savedOption1.id());
+        optionService.deleteOption(1L, savedOption2.id());
     }
 
     @Test
     @DisplayName("중복된 이름으로 된 상품 옵션 추가시 예외가 발생한다.")
     void failAddOptionWithDuplicatedName() {
         //given
-        var optionRequest = new OptionAddRequest("옵션1", 1000, 1L);
-        var savedOption = optionService.addOption(optionRequest);
+        var optionRequest = new OptionRequest("옵션1", 1000);
+        var savedOption = optionService.addOption(1L, optionRequest);
         //when, then
-        Assertions.assertThatThrownBy(() -> optionService.addOption(optionRequest)).isInstanceOf(DuplicatedNameException.class);
+        Assertions.assertThatThrownBy(() -> optionService.addOption(1L, optionRequest)).isInstanceOf(DuplicatedNameException.class);
 
-        optionService.deleteOption(savedOption.id());
+        optionService.deleteOption(1L, savedOption.id());
     }
 
     @Test
     @DisplayName("옵션 수정하기")
     void successUpdateOption() {
         //given
-        var optionRequest = new OptionAddRequest("옵션1", 1000, 1L);
-        var savedOption = optionService.addOption(optionRequest);
-        var optionUpdateDto = new OptionUpdateRequest("수정된 옵션", 12345);
+        var optionRequest = new OptionRequest("옵션1", 1000);
+        var savedOption = optionService.addOption(1L, optionRequest);
+        var optionUpdateDto = new OptionRequest("수정된 옵션", 12345);
         //when
-        optionService.updateOption(savedOption.id(), optionUpdateDto);
+        optionService.updateOption(1L, savedOption.id(), optionUpdateDto);
         //then
-        var options = optionService.getOptions(1L, pageable);
+        var options = optionService.getOptions(1L);
         var filteredOptions = options.stream().filter(productOptionResponse -> productOptionResponse.id().equals(savedOption.id())).toList();
         Assertions.assertThat(filteredOptions.size()).isEqualTo(1);
         Assertions.assertThat(filteredOptions.get(0).name()).isEqualTo("수정된 옵션");
         Assertions.assertThat(filteredOptions.get(0).quantity()).isEqualTo(12345);
 
-        optionService.deleteOption(savedOption.id());
+        optionService.deleteOption(1L, savedOption.id());
     }
 
     @Test
     @DisplayName("옵션의 잔여수량이 0인 경우에 차감요청이 들어오면 예외를 발생시킨다.")
     void failAddOptionWithZeroQuantity() {
         //given
-        var optionRequest = new OptionAddRequest("옵션1", 0, 1L);
-        var savedOption = optionService.addOption(optionRequest);
+        var optionRequest = new OptionRequest("옵션1", 0);
+        var savedOption = optionService.addOption(1L, optionRequest);
         var orderRequest = new GiftOrderRequest(savedOption.id(), 1, "hello");
         //when, then
         Assertions.assertThatThrownBy(() -> optionService.orderOption(savedOption.id(), orderRequest)).isInstanceOf(BadRequestException.class);
 
-        optionService.deleteOption(savedOption.id());
+        optionService.deleteOption(1L, savedOption.id());
     }
 
     @Test
@@ -121,7 +117,7 @@ public void concurrencyTest() throws InterruptedException {
         }
         countDownLatch.await();
         //then
-        var option = optionService.getOptions(3L, Pageable.unpaged()).stream()
+        var option = optionService.getOptions(3L).stream()
                 .filter((op) -> op.id().equals(1L))
                 .findFirst()
                 .get();
diff --git a/src/test/java/gift/service/ProductServiceTest.java b/src/test/java/gift/service/ProductServiceTest.java
index 71c54b7e5..486e85efb 100644
--- a/src/test/java/gift/service/ProductServiceTest.java
+++ b/src/test/java/gift/service/ProductServiceTest.java
@@ -1,6 +1,8 @@
 package gift.service;
 
-import gift.dto.product.ProductRequest;
+import gift.dto.option.OptionRequest;
+import gift.dto.product.ProductAddRequest;
+import gift.dto.product.ProductUpdateRequest;
 import gift.exception.InvalidProductNameWithKAKAOException;
 import org.assertj.core.api.Assertions;
 import org.junit.jupiter.api.DisplayName;
@@ -9,6 +11,8 @@
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
+
 @SpringBootTest
 @Transactional
 class ProductServiceTest {
@@ -20,7 +24,10 @@ class ProductServiceTest {
     @DisplayName("정상 상품 추가하기")
     void successAddProduct() {
         //given
-        var productRequest = new ProductRequest("상품1", 10000, "이미지 주소", 1L);
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
+        var productRequest = new ProductAddRequest("상품1", 10000, "이미지 주소", 1L, options);
         //when
         var savedProduct = productService.addProduct(productRequest);
         //then
@@ -33,7 +40,10 @@ void successAddProduct() {
     @DisplayName("이용자로 카카오가 포함된 상품 추가하기")
     void failAddProductWithNameKakao() {
         //given
-        var productRequest = new ProductRequest("카카오상품", 10000, "이미지 주소", 1L);
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
+        var productRequest = new ProductAddRequest("카카오상품", 10000, "이미지 주소", 1L, options);
         //when, then
         Assertions.assertThatThrownBy(() -> productService.addProduct(productRequest))
                 .isInstanceOf(InvalidProductNameWithKAKAOException.class);
@@ -43,10 +53,13 @@ void failAddProductWithNameKakao() {
     @DisplayName("상품 수정하기")
     void successUpdateProduct() {
         //given
-        var productRequest = new ProductRequest("상품1", 10000, "이미지 주소", 1L);
+        var optionRequest = new OptionRequest("옵션", 1000);
+        var options = new ArrayList<OptionRequest>();
+        options.add(optionRequest);
+        var productRequest = new ProductAddRequest("상품1", 10000, "이미지 주소", 1L, options);
         var savedProduct = productService.addProduct(productRequest);
         var id = savedProduct.id();
-        var updateDto = new ProductRequest("상품1", 7000, "이미지 주소2", 1L);
+        var updateDto = new ProductUpdateRequest("상품1", 7000, "이미지 주소2", 1L);
         //when
         productService.updateProduct(id, updateDto);
         //then