From 280cf917fbb3fe464727b72667c84df9e4af9311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EA=B4=80=EA=B7=9C?= Date: Wed, 2 Jul 2025 21:05:47 +0900 Subject: [PATCH 1/9] =?UTF-8?q?fix:=20=EC=97=90=EB=9F=AC=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/in/koreatech/payment/service/TossService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/in/koreatech/payment/service/TossService.java b/src/main/java/in/koreatech/payment/service/TossService.java index 5ff4790..d3bc4ec 100644 --- a/src/main/java/in/koreatech/payment/service/TossService.java +++ b/src/main/java/in/koreatech/payment/service/TossService.java @@ -113,7 +113,7 @@ public String createTemporaryTakeoutPayment(String accessToken, TemporaryTakeout if (!request.totalMenuPrice().equals(totalProductPrice) || !request.totalAmount().equals(finalAmount) ) { - throw OrderPriceMismatchException.withDetail("totalProductPrice : " + totalProductPrice + "totalAmount : " + totalProductPrice + "finalAmount : " + finalAmount); + throw OrderPriceMismatchException.withDetail("totalProductPrice : " + totalProductPrice + "finalAmount : " + finalAmount); } String orderId = orderIdGenerator.generateOrderId(); From 89201d9a2e2f259c9a764f7202d0c0a8ca837a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EA=B4=80=EA=B7=9C?= Date: Wed, 2 Jul 2025 21:43:57 +0900 Subject: [PATCH 2/9] =?UTF-8?q?fix:=20=EA=B2=B0=EC=A0=9C=20=EC=8A=B9?= =?UTF-8?q?=EC=9D=B8=20API=20=EC=9D=91=EB=8B=B5=EA=B0=92=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/PaymentConfirmResponse.java | 124 +++++++++++++++++- 1 file changed, 118 insertions(+), 6 deletions(-) diff --git a/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java b/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java index 2fdb76a..2092cb9 100644 --- a/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java +++ b/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java @@ -1,14 +1,25 @@ package in.koreatech.payment.dto.response; import static com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonNaming; +import in.koreatech.koin.domain.order.cart.model.Cart; +import in.koreatech.koin.domain.order.cart.model.CartMenuItem; +import in.koreatech.koin.domain.order.cart.model.CartMenuItemOption; +import in.koreatech.koin.domain.order.model.Order; +import in.koreatech.koin.domain.order.model.OrderDelivery; +import in.koreatech.koin.domain.order.model.OrderTakeout; import in.koreatech.koin.domain.order.model.Payment; +import in.koreatech.koin.domain.order.shop.model.entity.shop.OrderableShop; +import in.koreatech.koin.domain.shop.model.shop.Shop; import io.swagger.v3.oas.annotations.media.Schema; @JsonNaming(value = SnakeCaseStrategy.class) @@ -16,9 +27,30 @@ public record PaymentConfirmResponse( @Schema(description = "결제 고유 id", example = "1", requiredMode = REQUIRED) Integer id, + @Schema(description = "배달 주소", example = "충청남도 천안시 동남구 병천면 충절로 1600 은솔관 422호", requiredMode = NOT_REQUIRED) + String deliveryAddress, + + @Schema(description = "가게 주소", example = "충청남도 천안시 동남구 병천면 충절로 1600 은솔관 422호", requiredMode = NOT_REQUIRED) + String shopAddress, + + @Schema(description = "사장님에게", example = "리뷰 이벤트 감사합니다.", requiredMode = REQUIRED) + String toOwner, + + @Schema(description = "라이더에게", example = "문 앞에 놔주세요.", requiredMode = NOT_REQUIRED) + String toRider, + @Schema(description = "결제 금액", example = "1000", requiredMode = REQUIRED) Integer amount, + @Schema(description = "상점 이름", example = "굿모닝 살로만 치킨", requiredMode = REQUIRED) + String shopName, + + @Schema(description = "주문 메뉴 목록", requiredMode = REQUIRED) + List items, + + @Schema(description = "주문 방법", example = "DELIVERY", requiredMode = REQUIRED) + String orderType, + @Schema(description = "결제 요청 일시", example = "2025.06.21 21:00", requiredMode = REQUIRED) @JsonFormat(pattern = "yyyy.MM.dd HH:mm") LocalDateTime requestedAt, @@ -30,13 +62,93 @@ public record PaymentConfirmResponse( @Schema(description = "결제 수단", example = "카드", requiredMode = REQUIRED) String paymentMethod ) { - public static PaymentConfirmResponse from(Payment payment) { + + @JsonNaming(value = SnakeCaseStrategy.class) + public record InnerCartItemResponse ( + @Schema(description = "메뉴 이름", example = "허니콤보", requiredMode = REQUIRED) + String name, + + @Schema(description = "수량", example = "1", requiredMode = REQUIRED) + Integer quantity, + + @Schema(description = "선택한 옵션 목록", requiredMode = NOT_REQUIRED) + List options + ) { + public static InnerCartItemResponse from(CartMenuItem cartMenuItem) { + List optionResponses = cartMenuItem.getCartMenuItemOptions().stream() + .map(InnerMenuOptionResponse::from) + .collect(Collectors.toList()); + + return new InnerCartItemResponse( + cartMenuItem.getOrderableShopMenu().getName(), + cartMenuItem.getQuantity(), + optionResponses + ); + } + } + + @JsonNaming(value = SnakeCaseStrategy.class) + public record InnerMenuOptionResponse ( + @Schema(description = "옵션 그룹 이름", example = "소스 추가", requiredMode = NOT_REQUIRED) + String optionGroupName, + @Schema(description = "옵션 이름", example = "레드디핑 소스", requiredMode = REQUIRED) + String optionName + ) { + public static InnerMenuOptionResponse from(CartMenuItemOption cartMenuItemOption) { + String groupName = cartMenuItemOption.getOrderableShopMenuOption() + .getOptionGroup() + .getName(); + + return new InnerMenuOptionResponse( + groupName, + cartMenuItemOption.getOptionName() + ); + } + } + + public static PaymentConfirmResponse takeOut(Payment payment, Order order, Cart cart) { + OrderableShop orderableShop = order.getOrderableShop(); + Shop shop = orderableShop.getShop(); + OrderTakeout orderTakeout = order.getOrderTakeout(); + + return new PaymentConfirmResponse( + payment.getId(), + null, + shop.getAddress(), + orderTakeout.getToOwner(), + null, + payment.getAmount(), + shop.getName(), + cart.getCartMenuItems().stream() + .map(InnerCartItemResponse::from) + .toList(), + order.getOrderType().name(), + payment.getRequestedAt(), + payment.getApprovedAt(), + payment.getPaymentMethod().getDisplayName() + ); + } + + public static PaymentConfirmResponse delivery(Payment payment, Order order, Cart cart) { + OrderableShop orderableShop = order.getOrderableShop(); + Shop shop = orderableShop.getShop(); + OrderDelivery orderDelivery = order.getOrderDelivery(); + return new PaymentConfirmResponse( - payment.getId(), - payment.getAmount(), - payment.getRequestedAt(), - payment.getApprovedAt(), - payment.getPaymentMethod().getDisplayName() + payment.getId(), + orderDelivery.getAddress(), + shop.getAddress(), + orderDelivery.getToOwner(), + orderDelivery.getToRider(), + payment.getAmount(), + shop.getName(), + cart.getCartMenuItems().stream() + .map(InnerCartItemResponse::from) + .toList(), + order.getOrderType().name(), + payment.getRequestedAt(), + payment.getApprovedAt(), + payment.getPaymentMethod().getDisplayName() ); } } From e568a0ea91543c7e8d99bae5560b3c29499a4a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EA=B4=80=EA=B7=9C?= Date: Wed, 2 Jul 2025 21:57:25 +0900 Subject: [PATCH 3/9] =?UTF-8?q?fix:=20=EA=B2=B0=EC=A0=9C=20=EC=8A=B9?= =?UTF-8?q?=EC=9D=B8=20API=20=EC=9D=91=EB=8B=B5=EA=B0=92=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/PaymentConfirmResponse.java | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java b/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java index 2092cb9..24b84de 100644 --- a/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java +++ b/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java @@ -6,20 +6,18 @@ import java.time.LocalDateTime; import java.util.List; -import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonNaming; -import in.koreatech.koin.domain.order.cart.model.Cart; -import in.koreatech.koin.domain.order.cart.model.CartMenuItem; -import in.koreatech.koin.domain.order.cart.model.CartMenuItemOption; import in.koreatech.koin.domain.order.model.Order; import in.koreatech.koin.domain.order.model.OrderDelivery; import in.koreatech.koin.domain.order.model.OrderTakeout; import in.koreatech.koin.domain.order.model.Payment; import in.koreatech.koin.domain.order.shop.model.entity.shop.OrderableShop; import in.koreatech.koin.domain.shop.model.shop.Shop; +import in.koreatech.payment.model.domain.TemporaryMenuItems; +import in.koreatech.payment.model.domain.TemporaryMenuOption; import io.swagger.v3.oas.annotations.media.Schema; @JsonNaming(value = SnakeCaseStrategy.class) @@ -64,7 +62,7 @@ public record PaymentConfirmResponse( ) { @JsonNaming(value = SnakeCaseStrategy.class) - public record InnerCartItemResponse ( + public record InnerCartItemResponse( @Schema(description = "메뉴 이름", example = "허니콤보", requiredMode = REQUIRED) String name, @@ -74,39 +72,36 @@ public record InnerCartItemResponse ( @Schema(description = "선택한 옵션 목록", requiredMode = NOT_REQUIRED) List options ) { - public static InnerCartItemResponse from(CartMenuItem cartMenuItem) { - List optionResponses = cartMenuItem.getCartMenuItemOptions().stream() + public static InnerCartItemResponse from(TemporaryMenuItems temporaryMenuItems) { + List optionResponses = temporaryMenuItems.options().stream() .map(InnerMenuOptionResponse::from) - .collect(Collectors.toList()); + .toList(); return new InnerCartItemResponse( - cartMenuItem.getOrderableShopMenu().getName(), - cartMenuItem.getQuantity(), + temporaryMenuItems.name(), + temporaryMenuItems.quantity(), optionResponses ); } } @JsonNaming(value = SnakeCaseStrategy.class) - public record InnerMenuOptionResponse ( + public record InnerMenuOptionResponse( @Schema(description = "옵션 그룹 이름", example = "소스 추가", requiredMode = NOT_REQUIRED) String optionGroupName, @Schema(description = "옵션 이름", example = "레드디핑 소스", requiredMode = REQUIRED) String optionName ) { - public static InnerMenuOptionResponse from(CartMenuItemOption cartMenuItemOption) { - String groupName = cartMenuItemOption.getOrderableShopMenuOption() - .getOptionGroup() - .getName(); - + public static InnerMenuOptionResponse from(TemporaryMenuOption temporaryMenuOption) { return new InnerMenuOptionResponse( - groupName, - cartMenuItemOption.getOptionName() + temporaryMenuOption.optionGroupName(), + temporaryMenuOption.optionName() ); } } - public static PaymentConfirmResponse takeOut(Payment payment, Order order, Cart cart) { + public static PaymentConfirmResponse takeOut(Payment payment, Order order, + List temporaryMenuItems) { OrderableShop orderableShop = order.getOrderableShop(); Shop shop = orderableShop.getShop(); OrderTakeout orderTakeout = order.getOrderTakeout(); @@ -119,7 +114,7 @@ public static PaymentConfirmResponse takeOut(Payment payment, Order order, Cart null, payment.getAmount(), shop.getName(), - cart.getCartMenuItems().stream() + temporaryMenuItems.stream() .map(InnerCartItemResponse::from) .toList(), order.getOrderType().name(), @@ -129,7 +124,8 @@ public static PaymentConfirmResponse takeOut(Payment payment, Order order, Cart ); } - public static PaymentConfirmResponse delivery(Payment payment, Order order, Cart cart) { + public static PaymentConfirmResponse delivery(Payment payment, Order order, + List temporaryMenuItems) { OrderableShop orderableShop = order.getOrderableShop(); Shop shop = orderableShop.getShop(); OrderDelivery orderDelivery = order.getOrderDelivery(); @@ -142,7 +138,7 @@ public static PaymentConfirmResponse delivery(Payment payment, Order order, Cart orderDelivery.getToRider(), payment.getAmount(), shop.getName(), - cart.getCartMenuItems().stream() + temporaryMenuItems.stream() .map(InnerCartItemResponse::from) .toList(), order.getOrderType().name(), From b288eb8372e4cd6b670ac1d6a0141b78584715c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EA=B4=80=EA=B7=9C?= Date: Wed, 2 Jul 2025 21:59:10 +0900 Subject: [PATCH 4/9] =?UTF-8?q?fix:=20=EA=B2=B0=EC=A0=9C=20=EC=8A=B9?= =?UTF-8?q?=EC=9D=B8=20API=20=EC=9D=91=EB=8B=B5=EA=B0=92=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/PaymentConfirmResponse.java | 52 ++++++++----------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java b/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java index 24b84de..f76acee 100644 --- a/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java +++ b/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java @@ -1,6 +1,8 @@ package in.koreatech.payment.dto.response; import static com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import static in.koreatech.koin.domain.order.model.OrderType.DELIVERY; +import static in.koreatech.koin.domain.order.model.OrderType.TAKE_OUT; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; @@ -100,42 +102,34 @@ public static InnerMenuOptionResponse from(TemporaryMenuOption temporaryMenuOpti } } - public static PaymentConfirmResponse takeOut(Payment payment, Order order, - List temporaryMenuItems) { + public static PaymentConfirmResponse of( + Payment payment, + Order order, + List temporaryMenuItems + ) { OrderableShop orderableShop = order.getOrderableShop(); Shop shop = orderableShop.getShop(); - OrderTakeout orderTakeout = order.getOrderTakeout(); - return new PaymentConfirmResponse( - payment.getId(), - null, - shop.getAddress(), - orderTakeout.getToOwner(), - null, - payment.getAmount(), - shop.getName(), - temporaryMenuItems.stream() - .map(InnerCartItemResponse::from) - .toList(), - order.getOrderType().name(), - payment.getRequestedAt(), - payment.getApprovedAt(), - payment.getPaymentMethod().getDisplayName() - ); - } - - public static PaymentConfirmResponse delivery(Payment payment, Order order, - List temporaryMenuItems) { - OrderableShop orderableShop = order.getOrderableShop(); - Shop shop = orderableShop.getShop(); - OrderDelivery orderDelivery = order.getOrderDelivery(); + String deliveryAddress = null; + String toOwner = null; + String toRider = null; + + if (order.getOrderType() == DELIVERY) { + OrderDelivery delivery = order.getOrderDelivery(); + deliveryAddress = delivery.getAddress(); + toOwner = delivery.getToOwner(); + toRider = delivery.getToRider(); + } else if (order.getOrderType() == TAKE_OUT) { + OrderTakeout takeout = order.getOrderTakeout(); + toOwner = takeout.getToOwner(); + } return new PaymentConfirmResponse( payment.getId(), - orderDelivery.getAddress(), + deliveryAddress, shop.getAddress(), - orderDelivery.getToOwner(), - orderDelivery.getToRider(), + toOwner, + toRider, payment.getAmount(), shop.getName(), temporaryMenuItems.stream() From f1b42d5b24b623f1b670a2809bdcf2538454f8ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EA=B4=80=EA=B7=9C?= Date: Wed, 2 Jul 2025 22:02:48 +0900 Subject: [PATCH 5/9] =?UTF-8?q?fix:=20=EA=B2=B0=EC=A0=9C=20=EC=8A=B9?= =?UTF-8?q?=EC=9D=B8=20=EC=9D=91=EB=8B=B5=EA=B0=92=20=EB=B0=98=ED=99=98=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/client/TossPaymentClient.java | 6 +++--- ...onse.java => TossPaymentConfirmResponse.java} | 2 +- .../payment/controller/PaymentsController.java | 3 +-- .../payment/service/PaymentService.java | 4 ++-- .../koreatech/payment/service/TossService.java | 16 +++++++++------- 5 files changed, 16 insertions(+), 15 deletions(-) rename src/main/java/in/koreatech/payment/client/dto/response/{PaymentConfirmResponse.java => TossPaymentConfirmResponse.java} (96%) diff --git a/src/main/java/in/koreatech/payment/client/TossPaymentClient.java b/src/main/java/in/koreatech/payment/client/TossPaymentClient.java index 97afdb5..17268f3 100644 --- a/src/main/java/in/koreatech/payment/client/TossPaymentClient.java +++ b/src/main/java/in/koreatech/payment/client/TossPaymentClient.java @@ -17,7 +17,7 @@ import in.koreatech.payment.client.dto.request.PaymentCancelRequest; import in.koreatech.payment.client.dto.request.PaymentConfirmRequest; import in.koreatech.payment.client.dto.response.PaymentCancelResponse; -import in.koreatech.payment.client.dto.response.PaymentConfirmResponse; +import in.koreatech.payment.client.dto.response.TossPaymentConfirmResponse; import in.koreatech.payment.client.exception.TossPaymentErrorCode; import in.koreatech.payment.client.exception.TossPaymentErrorResponse; import in.koreatech.payment.client.exception.TossPaymentException; @@ -47,7 +47,7 @@ public TossPaymentClient( .build(); } - public PaymentConfirmResponse requestConfirm(String paymentKey, String orderId, Integer amount) { + public TossPaymentConfirmResponse requestConfirm(String paymentKey, String orderId, Integer amount) { PaymentConfirmRequest request = new PaymentConfirmRequest(paymentKey, orderId, amount); try { @@ -55,7 +55,7 @@ public PaymentConfirmResponse requestConfirm(String paymentKey, String orderId, .uri("/confirm") .bodyValue(request) .retrieve() - .bodyToMono(PaymentConfirmResponse.class) + .bodyToMono(TossPaymentConfirmResponse.class) .block(); } catch (WebClientResponseException e) { diff --git a/src/main/java/in/koreatech/payment/client/dto/response/PaymentConfirmResponse.java b/src/main/java/in/koreatech/payment/client/dto/response/TossPaymentConfirmResponse.java similarity index 96% rename from src/main/java/in/koreatech/payment/client/dto/response/PaymentConfirmResponse.java rename to src/main/java/in/koreatech/payment/client/dto/response/TossPaymentConfirmResponse.java index 2034452..cbcab26 100644 --- a/src/main/java/in/koreatech/payment/client/dto/response/PaymentConfirmResponse.java +++ b/src/main/java/in/koreatech/payment/client/dto/response/TossPaymentConfirmResponse.java @@ -8,7 +8,7 @@ import in.koreatech.koin.domain.order.model.PaymentMethod; import in.koreatech.koin.domain.order.model.PaymentStatus; -public record PaymentConfirmResponse( +public record TossPaymentConfirmResponse( String paymentKey, Integer totalAmount, String status, diff --git a/src/main/java/in/koreatech/payment/controller/PaymentsController.java b/src/main/java/in/koreatech/payment/controller/PaymentsController.java index b06e0ca..e39fbb2 100644 --- a/src/main/java/in/koreatech/payment/controller/PaymentsController.java +++ b/src/main/java/in/koreatech/payment/controller/PaymentsController.java @@ -55,9 +55,8 @@ public ResponseEntity confirmPayment( @RequestBody @Valid final PaymentConfirmRequest request, @AccessToken final String accessToken ) { - Payment payment = paymentService.confirmPayment(accessToken, request.paymentKey(), request.orderId(), + PaymentConfirmResponse response = paymentService.confirmPayment(accessToken, request.paymentKey(), request.orderId(), request.amount()); - PaymentConfirmResponse response = PaymentConfirmResponse.from(payment); return ResponseEntity.ok(response); } diff --git a/src/main/java/in/koreatech/payment/service/PaymentService.java b/src/main/java/in/koreatech/payment/service/PaymentService.java index e175716..7ab482e 100644 --- a/src/main/java/in/koreatech/payment/service/PaymentService.java +++ b/src/main/java/in/koreatech/payment/service/PaymentService.java @@ -2,14 +2,14 @@ import java.util.List; -import in.koreatech.koin.domain.order.model.Payment; import in.koreatech.koin.domain.order.model.PaymentCancel; import in.koreatech.payment.dto.request.TemporaryDeliveryPaymentSaveRequest; import in.koreatech.payment.dto.request.TemporaryTakeoutPaymentSaveRequest; +import in.koreatech.payment.dto.response.PaymentConfirmResponse; public interface PaymentService { String createTemporaryDeliveryPayment(String accessToken, TemporaryDeliveryPaymentSaveRequest request); String createTemporaryTakeoutPayment(String accessToken, TemporaryTakeoutPaymentSaveRequest request); - Payment confirmPayment(String accessToken, String paymentKey, String orderId, Integer amount); + PaymentConfirmResponse confirmPayment(String accessToken, String paymentKey, String orderId, Integer amount); List cancelPayment(String accessToken, String paymentKey, String cancelReason); } diff --git a/src/main/java/in/koreatech/payment/service/TossService.java b/src/main/java/in/koreatech/payment/service/TossService.java index d3bc4ec..8b75f2e 100644 --- a/src/main/java/in/koreatech/payment/service/TossService.java +++ b/src/main/java/in/koreatech/payment/service/TossService.java @@ -23,10 +23,11 @@ import in.koreatech.koin.domain.user.repository.UserRepository; import in.koreatech.payment.client.TossPaymentClient; import in.koreatech.payment.client.dto.response.PaymentCancelResponse; -import in.koreatech.payment.client.dto.response.PaymentConfirmResponse; +import in.koreatech.payment.client.dto.response.TossPaymentConfirmResponse; import in.koreatech.payment.common.auth.JwtTokenResolver; import in.koreatech.payment.dto.request.TemporaryDeliveryPaymentSaveRequest; import in.koreatech.payment.dto.request.TemporaryTakeoutPaymentSaveRequest; +import in.koreatech.payment.dto.response.PaymentConfirmResponse; import in.koreatech.payment.exception.OrderPriceMismatchException; import in.koreatech.payment.exception.PaymentAlreadyCanceledException; import in.koreatech.payment.exception.PaymentCancelException; @@ -134,16 +135,16 @@ public String createTemporaryTakeoutPayment(String accessToken, TemporaryTakeout } @Transactional(transactionManager = "koinTransactionManager") - public Payment confirmPayment(String accessToken, String paymentKey, String orderId, Integer amount) { + public PaymentConfirmResponse confirmPayment(String accessToken, String paymentKey, String orderId, Integer amount) { Integer userId = jwtTokenResolver.getUserId(accessToken); User user = userRepository.getById(userId); TemporaryPayment temporaryPayment = temporaryPaymentRedisRepository.getById(orderId); temporaryPayment.validateMatches(orderId, user.getId(), amount); - PaymentConfirmResponse response = tossPaymentClient.requestConfirm(paymentKey, orderId, amount); - PaymentStatus paymentStatus = PaymentStatus.valueOf(response.status()); + TossPaymentConfirmResponse tossPaymentResponse = tossPaymentClient.requestConfirm(paymentKey, orderId, amount); + PaymentStatus paymentStatus = PaymentStatus.valueOf(tossPaymentResponse.status()); if (!paymentStatus.isDone()) { - throw PaymentConfirmException.withDetail("paymentStatus : " + response.status()); + throw PaymentConfirmException.withDetail("paymentStatus : " + tossPaymentResponse.status()); } OrderableShop orderableShop = orderableShopRepository.getById(temporaryPayment.getOrderableShopId()); @@ -155,11 +156,12 @@ public Payment confirmPayment(String accessToken, String paymentKey, String orde .toList(); orderMenuRepository.saveAll(orderMenus); - Payment payment = response.toEntity(order); + Payment payment = tossPaymentResponse.toEntity(order); paymentRepository.save(payment); + PaymentConfirmResponse response = PaymentConfirmResponse.of(payment, order, temporaryPayment.getTemporaryMenuItems()); temporaryPaymentRedisRepository.deleteById(orderId); cartRepository.deleteByUserId(user.getId()); - return payment; + return response; } @Transactional From eabbb7739919cc427f5ac0f8036ade8829075acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EA=B4=80=EA=B7=9C?= Date: Wed, 2 Jul 2025 22:04:14 +0900 Subject: [PATCH 6/9] =?UTF-8?q?fix:=20=EC=9D=91=EB=8B=B5=EA=B0=92=20?= =?UTF-8?q?=EB=B3=80=EC=88=98=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../koreatech/payment/dto/response/PaymentConfirmResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java b/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java index f76acee..ead6d8d 100644 --- a/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java +++ b/src/main/java/in/koreatech/payment/dto/response/PaymentConfirmResponse.java @@ -46,7 +46,7 @@ public record PaymentConfirmResponse( String shopName, @Schema(description = "주문 메뉴 목록", requiredMode = REQUIRED) - List items, + List menus, @Schema(description = "주문 방법", example = "DELIVERY", requiredMode = REQUIRED) String orderType, From 1d199774a35cb4a13b21b9066b1f16faa6e7eb02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EA=B4=80=EA=B7=9C?= Date: Wed, 2 Jul 2025 22:04:28 +0900 Subject: [PATCH 7/9] =?UTF-8?q?feat:=20=EC=9D=91=EB=8B=B5=20dto=20final=20?= =?UTF-8?q?=EC=84=A0=EC=96=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/in/koreatech/payment/service/TossService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/in/koreatech/payment/service/TossService.java b/src/main/java/in/koreatech/payment/service/TossService.java index 8b75f2e..173d9c4 100644 --- a/src/main/java/in/koreatech/payment/service/TossService.java +++ b/src/main/java/in/koreatech/payment/service/TossService.java @@ -158,7 +158,7 @@ public PaymentConfirmResponse confirmPayment(String accessToken, String paymentK Payment payment = tossPaymentResponse.toEntity(order); paymentRepository.save(payment); - PaymentConfirmResponse response = PaymentConfirmResponse.of(payment, order, temporaryPayment.getTemporaryMenuItems()); + final PaymentConfirmResponse response = PaymentConfirmResponse.of(payment, order, temporaryPayment.getTemporaryMenuItems()); temporaryPaymentRedisRepository.deleteById(orderId); cartRepository.deleteByUserId(user.getId()); return response; From 445c3a36b747262b9a6b993ee958c42fed792dfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EA=B4=80=EA=B7=9C?= Date: Wed, 2 Jul 2025 22:12:42 +0900 Subject: [PATCH 8/9] =?UTF-8?q?docs:=20=EA=B2=B0=EC=A0=9C=20=EC=8A=B9?= =?UTF-8?q?=EC=9D=B8=20API=20=EC=9D=91=EB=8B=B5=EA=B0=92=20=EC=8A=A4?= =?UTF-8?q?=EC=9B=A8=EA=B1=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/controller/PaymentsApi.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/main/java/in/koreatech/payment/controller/PaymentsApi.java b/src/main/java/in/koreatech/payment/controller/PaymentsApi.java index e1fdbd3..6b0cf7e 100644 --- a/src/main/java/in/koreatech/payment/controller/PaymentsApi.java +++ b/src/main/java/in/koreatech/payment/controller/PaymentsApi.java @@ -16,6 +16,10 @@ import in.koreatech.payment.dto.response.TemporaryPaymentResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +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 jakarta.validation.Valid; @@ -70,6 +74,66 @@ ResponseEntity createTemporaryTakeoutPayment( @AccessToken final String accessToken ); + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "결제 승인 성공", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "배달", value = """ + { + "id": 1, + "delivery_address": "충청남도 천안시 동남구 병천면 충절로 1600 은솔관 422호", + "shop_address": "충청남도 천안시 동남구 병천면 충절로 1600 은솔관 422호", + "to_owner": "리뷰 이벤트 감사합니다.", + "to_rider": "문 앞에 놔주세요.", + "amount": 1000, + "shop_name": "굿모닝 살로만 치킨", + "menus": [ + { + "name": "허니콤보", + "quantity": 1, + "options": [ + { + "option_group_name": "소스 추가", + "option_name": "레드디핑 소스" + } + ] + } + ], + "order_type": "DELIVERY", + "requested_at": "2025-07-02T13:07:07.359Z", + "approved_at": "2025-07-02T13:07:07.360Z", + "payment_method": "카드" + } + """), + @ExampleObject(name = "포장", value = """ + { + "id": 1, + "delivery_address": "null", + "shop_address": "충청남도 천안시 동남구 병천면 충절로 1600 은솔관 422호", + "to_owner": "리뷰 이벤트 감사합니다.", + "to_rider": "null", + "amount": 1000, + "shop_name": "굿모닝 살로만 치킨", + "menus": [ + { + "name": "허니콤보", + "quantity": 1, + "options": [ + { + "option_group_name": "소스 추가", + "option_name": "레드디핑 소스" + } + ] + } + ], + "order_type": "TAKE_OUT", + "requested_at": "2025-07-02T13:07:07.359Z", + "approved_at": "2025-07-02T13:07:07.360Z", + "payment_method": "카드" + } + """) + }) + )} + ) @Operation( summary = "결제 승인을 한다.", description = """ From 9b3c9e2cef49bb1dfb41cf1d8a740b4f682506fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EA=B4=80=EA=B7=9C?= Date: Wed, 2 Jul 2025 22:14:12 +0900 Subject: [PATCH 9/9] =?UTF-8?q?docs:=20=EA=B2=B0=EC=A0=9C=20=EC=8A=B9?= =?UTF-8?q?=EC=9D=B8=20API=20=EC=9D=91=EB=8B=B5=EA=B0=92=20=EC=8A=A4?= =?UTF-8?q?=EC=9B=A8=EA=B1=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/in/koreatech/payment/controller/PaymentsApi.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/in/koreatech/payment/controller/PaymentsApi.java b/src/main/java/in/koreatech/payment/controller/PaymentsApi.java index 6b0cf7e..af6516f 100644 --- a/src/main/java/in/koreatech/payment/controller/PaymentsApi.java +++ b/src/main/java/in/koreatech/payment/controller/PaymentsApi.java @@ -107,10 +107,10 @@ ResponseEntity createTemporaryTakeoutPayment( @ExampleObject(name = "포장", value = """ { "id": 1, - "delivery_address": "null", + "delivery_address": null, "shop_address": "충청남도 천안시 동남구 병천면 충절로 1600 은솔관 422호", "to_owner": "리뷰 이벤트 감사합니다.", - "to_rider": "null", + "to_rider": null, "amount": 1000, "shop_name": "굿모닝 살로만 치킨", "menus": [