From d0ef6e7e893ec6d3afb31082ed7125bca6b02fc9 Mon Sep 17 00:00:00 2001 From: dongHyo Date: Sun, 17 Jul 2022 20:52:30 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=ED=94=BC=EB=93=9C=EB=B0=B1=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/global/redis/PaymentCache.java | 5 +- .../movie/service/TicketServiceImpl.java | 20 +---- .../service/interfaces/TicketService.java | 5 +- .../server/movie/setup/MovieSetupService.java | 3 +- .../server/payment/api/MovieClient.java | 5 +- .../payment/api/impl/MovieClientImpl.java | 8 +- .../application/PaymentController.java | 10 ++- .../server/payment/domain/Payment.java | 8 -- .../service/AdminKakaoPayRefundService.java | 40 +++++++++ .../service/MyKakaoPayRefundService.java | 54 ++++++++++++ .../service/PaymentApisServiceImpl.java | 87 +++++-------------- .../interfaces/AbstractKakaoPayRefund.java | 42 +++++++++ .../interfaces/PaymentApisService.java | 4 - .../server/movie/domain/TicketTest.java | 22 ++--- .../service/PaymentServiceImplTest.java | 6 +- .../user/service/UserApisServiceImplTest.java | 6 +- 16 files changed, 204 insertions(+), 121 deletions(-) create mode 100644 server/src/main/java/com/ticketing/server/payment/service/AdminKakaoPayRefundService.java create mode 100644 server/src/main/java/com/ticketing/server/payment/service/MyKakaoPayRefundService.java create mode 100644 server/src/main/java/com/ticketing/server/payment/service/interfaces/AbstractKakaoPayRefund.java diff --git a/server/src/main/java/com/ticketing/server/global/redis/PaymentCache.java b/server/src/main/java/com/ticketing/server/global/redis/PaymentCache.java index d8557dd..4730a8c 100644 --- a/server/src/main/java/com/ticketing/server/global/redis/PaymentCache.java +++ b/server/src/main/java/com/ticketing/server/global/redis/PaymentCache.java @@ -33,12 +33,15 @@ public class PaymentCache { private Long paymentNumber; - public PaymentCache(String email, String movieTitle, String tid, List ticketIds, Long userAlternateId, Long paymentNumber) { + private Integer totalAmount; + + public PaymentCache(String email, String movieTitle, String tid, List ticketIds, Long userAlternateId, Long paymentNumber, Integer totalAmount) { this.email = email; this.movieTitle = movieTitle; this.tid = tid; this.ticketIds = ticketIds; this.userAlternateId = userAlternateId; this.paymentNumber = paymentNumber; + this.totalAmount = totalAmount; } } diff --git a/server/src/main/java/com/ticketing/server/movie/service/TicketServiceImpl.java b/server/src/main/java/com/ticketing/server/movie/service/TicketServiceImpl.java index f24b2d2..4b59574 100644 --- a/server/src/main/java/com/ticketing/server/movie/service/TicketServiceImpl.java +++ b/server/src/main/java/com/ticketing/server/movie/service/TicketServiceImpl.java @@ -20,6 +20,8 @@ import com.ticketing.server.movie.service.interfaces.TicketService; import com.ticketing.server.payment.service.dto.TicketDetailDTO; import java.time.LocalDateTime; import java.util.List; +import java.util.function.Function; +import java.util.function.UnaryOperator; import java.util.stream.Collectors; import javax.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; @@ -109,25 +111,11 @@ public class TicketServiceImpl implements TicketService { @Override @Transactional - public TicketsRefundDTO ticketRefundByDateTime(@NotNull Long paymentId) { - List tickets = ticketRepository.findTicketFetchJoinByPaymentId(paymentId); - LocalDateTime now = LocalDateTime.now(); - - List refundDtoList = tickets.stream() - .map(ticket -> ticket.refund(now)) - .map(TicketRefundDTO::new) - .collect(Collectors.toList()); - - return new TicketsRefundDTO(refundDtoList); - } - - @Override - @Transactional - public TicketsRefundDTO ticketsRefund(@NotNull Long paymentId) { + public TicketsRefundDTO ticketsRefund(@NotNull Long paymentId, UnaryOperator refund) { List tickets = ticketRepository.findTicketFetchJoinByPaymentId(paymentId); List refundDtoList = tickets.stream() - .map(Ticket::refund) + .map(refund) .map(TicketRefundDTO::new) .collect(Collectors.toList()); diff --git a/server/src/main/java/com/ticketing/server/movie/service/interfaces/TicketService.java b/server/src/main/java/com/ticketing/server/movie/service/interfaces/TicketService.java index 1d85521..017369d 100644 --- a/server/src/main/java/com/ticketing/server/movie/service/interfaces/TicketService.java +++ b/server/src/main/java/com/ticketing/server/movie/service/interfaces/TicketService.java @@ -1,6 +1,7 @@ package com.ticketing.server.movie.service.interfaces; import com.ticketing.server.global.validator.constraints.NotEmptyCollection; +import com.ticketing.server.movie.domain.Ticket; import com.ticketing.server.movie.service.dto.TicketDetailsDTO; import com.ticketing.server.movie.service.dto.TicketListDTO; import com.ticketing.server.movie.service.dto.TicketsCancelDTO; @@ -8,6 +9,7 @@ import com.ticketing.server.movie.service.dto.TicketsRefundDTO; import com.ticketing.server.movie.service.dto.TicketsReservationDTO; import com.ticketing.server.movie.service.dto.TicketsSoldDTO; import java.util.List; +import java.util.function.UnaryOperator; import javax.validation.constraints.NotNull; public interface TicketService { @@ -22,7 +24,6 @@ public interface TicketService { TicketsCancelDTO ticketCancel(@NotEmptyCollection List ticketIds); - TicketsRefundDTO ticketRefundByDateTime(@NotNull Long paymentId); + TicketsRefundDTO ticketsRefund(@NotNull Long paymentId, UnaryOperator refund); - TicketsRefundDTO ticketsRefund(@NotNull Long paymentId); } diff --git a/server/src/main/java/com/ticketing/server/movie/setup/MovieSetupService.java b/server/src/main/java/com/ticketing/server/movie/setup/MovieSetupService.java index 5c58970..00a59d7 100644 --- a/server/src/main/java/com/ticketing/server/movie/setup/MovieSetupService.java +++ b/server/src/main/java/com/ticketing/server/movie/setup/MovieSetupService.java @@ -125,7 +125,8 @@ MovieSetupService { "T2d03c9130bf237a9700", List.of(1L, 2L), user.getAlternateId(), - 124124231513245L + 124124231513245L, + 30_000 ); Payment payment = new Payment(paymentCache, PaymentType.KAKAO_PAY, PaymentStatus.SOLD, 30_000); diff --git a/server/src/main/java/com/ticketing/server/payment/api/MovieClient.java b/server/src/main/java/com/ticketing/server/payment/api/MovieClient.java index 4732741..1088e5f 100644 --- a/server/src/main/java/com/ticketing/server/payment/api/MovieClient.java +++ b/server/src/main/java/com/ticketing/server/payment/api/MovieClient.java @@ -2,13 +2,14 @@ package com.ticketing.server.payment.api; import com.ticketing.server.movie.application.request.TicketCancelRequest; import com.ticketing.server.movie.application.request.TicketReservationRequest; +import com.ticketing.server.movie.application.request.TicketSoldRequest; import com.ticketing.server.movie.application.response.TicketCancelResponse; import com.ticketing.server.movie.application.response.TicketDetailsResponse; import com.ticketing.server.movie.application.response.TicketReservationResponse; -import com.ticketing.server.movie.application.request.TicketSoldRequest; import com.ticketing.server.movie.application.response.TicketSoldResponse; import com.ticketing.server.movie.service.dto.TicketsRefundResponse; import com.ticketing.server.payment.api.impl.TicketsRefundRequest; +import java.time.LocalDateTime; import javax.validation.constraints.NotNull; public interface MovieClient { @@ -21,7 +22,7 @@ public interface MovieClient { TicketCancelResponse ticketCancel(@NotNull TicketCancelRequest request); - TicketsRefundResponse ticketRefundByDateTime(TicketsRefundRequest request); + TicketsRefundResponse ticketRefundByDateTime(TicketsRefundRequest request, LocalDateTime dateTime); TicketsRefundResponse ticketRefund(TicketsRefundRequest request); } diff --git a/server/src/main/java/com/ticketing/server/payment/api/impl/MovieClientImpl.java b/server/src/main/java/com/ticketing/server/payment/api/impl/MovieClientImpl.java index bd98d5b..ef93e81 100644 --- a/server/src/main/java/com/ticketing/server/payment/api/impl/MovieClientImpl.java +++ b/server/src/main/java/com/ticketing/server/payment/api/impl/MovieClientImpl.java @@ -7,6 +7,7 @@ import com.ticketing.server.movie.application.response.TicketCancelResponse; import com.ticketing.server.movie.application.response.TicketDetailsResponse; import com.ticketing.server.movie.application.response.TicketReservationResponse; import com.ticketing.server.movie.application.response.TicketSoldResponse; +import com.ticketing.server.movie.domain.Ticket; import com.ticketing.server.movie.service.dto.TicketDetailsDTO; import com.ticketing.server.movie.service.dto.TicketsCancelDTO; import com.ticketing.server.movie.service.dto.TicketsRefundDTO; @@ -15,6 +16,7 @@ import com.ticketing.server.movie.service.dto.TicketsReservationDTO; import com.ticketing.server.movie.service.dto.TicketsSoldDTO; import com.ticketing.server.movie.service.interfaces.TicketService; import com.ticketing.server.payment.api.MovieClient; +import java.time.LocalDateTime; import javax.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -52,14 +54,14 @@ public class MovieClientImpl implements MovieClient { } @Override - public TicketsRefundResponse ticketRefundByDateTime(TicketsRefundRequest request) { - TicketsRefundDTO ticketsRefundDto = ticketService.ticketRefundByDateTime(request.getPaymentId()); + public TicketsRefundResponse ticketRefundByDateTime(TicketsRefundRequest request, LocalDateTime dateTime) { + TicketsRefundDTO ticketsRefundDto = ticketService.ticketsRefund(request.getPaymentId(), ticket -> ticket.refund(dateTime)); return ticketsRefundDto.toResponse(); } @Override public TicketsRefundResponse ticketRefund(TicketsRefundRequest request) { - TicketsRefundDTO ticketsRefundDto = ticketService.ticketRefundByDateTime(request.getPaymentId()); + TicketsRefundDTO ticketsRefundDto = ticketService.ticketsRefund(request.getPaymentId(), Ticket::refund); return ticketsRefundDto.toResponse(); } diff --git a/server/src/main/java/com/ticketing/server/payment/application/PaymentController.java b/server/src/main/java/com/ticketing/server/payment/application/PaymentController.java index f352ee4..4516899 100644 --- a/server/src/main/java/com/ticketing/server/payment/application/PaymentController.java +++ b/server/src/main/java/com/ticketing/server/payment/application/PaymentController.java @@ -10,11 +10,13 @@ import com.ticketing.server.payment.application.response.PaymentCompleteResponse import com.ticketing.server.payment.application.response.PaymentDetailResponse; import com.ticketing.server.payment.application.response.PaymentRefundResponse; import com.ticketing.server.payment.application.response.SimplePaymentsResponse; -import com.ticketing.server.payment.service.dto.PaymentRefundDTO; +import com.ticketing.server.payment.service.AdminKakaoPayRefundService; +import com.ticketing.server.payment.service.MyKakaoPayRefundService; import com.ticketing.server.payment.service.dto.PaymentCancelDTO; import com.ticketing.server.payment.service.dto.PaymentCompleteDTO; import com.ticketing.server.payment.service.dto.PaymentDetailDTO; import com.ticketing.server.payment.service.dto.PaymentReadyDTO; +import com.ticketing.server.payment.service.dto.PaymentRefundDTO; import com.ticketing.server.payment.service.dto.SimplePaymentsDTO; import com.ticketing.server.payment.service.interfaces.PaymentApisService; import com.ticketing.server.payment.service.interfaces.PaymentService; @@ -42,6 +44,8 @@ public class PaymentController { private final PaymentApisService paymentApisService; private final PaymentService paymentService; + private final AdminKakaoPayRefundService adminKakaoPayRefundService; + private final MyKakaoPayRefundService myKakaoPayRefundService; @GetMapping @Secured(USER) @@ -93,7 +97,7 @@ public class PaymentController { @PostMapping("/refund") @Secured(USER) public ResponseEntity refund(@RequestBody @Valid PaymentRefundRequest request) { - PaymentRefundDTO paymentRefundDto = paymentApisService.myPaymentRefund(request.getPaymentId()); + PaymentRefundDTO paymentRefundDto = myKakaoPayRefundService.refund(request.getPaymentId()); return ResponseEntity.status(HttpStatus.OK) .body(paymentRefundDto.toResponse()); @@ -102,7 +106,7 @@ public class PaymentController { @PostMapping("/staff/refund") @Secured(STAFF) public ResponseEntity adminRefund(@RequestBody @Valid PaymentRefundRequest request) { - PaymentRefundDTO paymentRefundDto = paymentApisService.paymentRefund(request.getPaymentId()); + PaymentRefundDTO paymentRefundDto = adminKakaoPayRefundService.refund(request.getPaymentId()); return ResponseEntity.status(HttpStatus.OK) .body(paymentRefundDto.toResponse()); diff --git a/server/src/main/java/com/ticketing/server/payment/domain/Payment.java b/server/src/main/java/com/ticketing/server/payment/domain/Payment.java index fdf7c2e..5089d4a 100644 --- a/server/src/main/java/com/ticketing/server/payment/domain/Payment.java +++ b/server/src/main/java/com/ticketing/server/payment/domain/Payment.java @@ -2,7 +2,6 @@ package com.ticketing.server.payment.domain; import com.ticketing.server.global.dto.repository.AbstractEntity; import com.ticketing.server.global.redis.PaymentCache; -import com.ticketing.server.payment.api.dto.response.UserDetailResponse; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; @@ -83,13 +82,6 @@ public class Payment extends AbstractEntity { this.totalPrice = totalPrice; } - public boolean validUser(UserDetailResponse userDetail) { - if (!userDetail.hasUserAlternateId(this)) { - return false; - } - return true; - } - public void refund() { status = PaymentStatus.REFUNDED; } diff --git a/server/src/main/java/com/ticketing/server/payment/service/AdminKakaoPayRefundService.java b/server/src/main/java/com/ticketing/server/payment/service/AdminKakaoPayRefundService.java new file mode 100644 index 0000000..ae63fb4 --- /dev/null +++ b/server/src/main/java/com/ticketing/server/payment/service/AdminKakaoPayRefundService.java @@ -0,0 +1,40 @@ +package com.ticketing.server.payment.service; + +import com.ticketing.server.global.exception.ErrorCode; +import com.ticketing.server.movie.service.dto.TicketsRefundResponse; +import com.ticketing.server.payment.api.KakaoPayClient; +import com.ticketing.server.payment.api.KakaoPayProperties; +import com.ticketing.server.payment.api.MovieClient; +import com.ticketing.server.payment.api.impl.TicketsRefundRequest; +import com.ticketing.server.payment.domain.Payment; +import com.ticketing.server.payment.domain.repository.PaymentRepository; +import com.ticketing.server.payment.service.interfaces.AbstractKakaoPayRefund; +import org.springframework.stereotype.Service; + +@Service +public class AdminKakaoPayRefundService extends AbstractKakaoPayRefund { + + private final PaymentRepository paymentRepository; + private final MovieClient movieClient; + + public AdminKakaoPayRefundService(KakaoPayClient kakaoPayClient, KakaoPayProperties kakaoPayProperties, PaymentRepository paymentRepository, MovieClient movieClient) { + super(kakaoPayClient, kakaoPayProperties); + this.paymentRepository = paymentRepository; + this.movieClient = movieClient; + } + + @Override + protected Payment getPayment(Long paymentId) { + return paymentRepository.findById(paymentId) + .orElseThrow(ErrorCode::throwPaymentIdNotFound); + } + + @Override + protected TicketsRefundResponse movieAndPaymentRefund(Payment payment) { + TicketsRefundResponse refundResponse = movieClient.ticketRefund(new TicketsRefundRequest(payment.getId())); + payment.refund(); + + return refundResponse; + } + +} diff --git a/server/src/main/java/com/ticketing/server/payment/service/MyKakaoPayRefundService.java b/server/src/main/java/com/ticketing/server/payment/service/MyKakaoPayRefundService.java new file mode 100644 index 0000000..16a902f --- /dev/null +++ b/server/src/main/java/com/ticketing/server/payment/service/MyKakaoPayRefundService.java @@ -0,0 +1,54 @@ +package com.ticketing.server.payment.service; + +import com.ticketing.server.global.exception.ErrorCode; +import com.ticketing.server.movie.service.dto.TicketsRefundResponse; +import com.ticketing.server.payment.api.KakaoPayClient; +import com.ticketing.server.payment.api.KakaoPayProperties; +import com.ticketing.server.payment.api.MovieClient; +import com.ticketing.server.payment.api.UserClient; +import com.ticketing.server.payment.api.dto.response.UserDetailResponse; +import com.ticketing.server.payment.api.impl.TicketsRefundRequest; +import com.ticketing.server.payment.domain.Payment; +import com.ticketing.server.payment.domain.repository.PaymentRepository; +import com.ticketing.server.payment.service.interfaces.AbstractKakaoPayRefund; +import java.time.LocalDateTime; +import org.springframework.stereotype.Service; + +@Service +public class MyKakaoPayRefundService extends AbstractKakaoPayRefund { + + private final PaymentRepository paymentRepository; + private final MovieClient movieClient; + private final UserClient userClient; + + public MyKakaoPayRefundService(KakaoPayClient kakaoPayClient, KakaoPayProperties kakaoPayProperties, PaymentRepository paymentRepository, + MovieClient movieClient, UserClient userClient) { + super(kakaoPayClient, kakaoPayProperties); + this.paymentRepository = paymentRepository; + this.movieClient = movieClient; + this.userClient = userClient; + } + + @Override + protected Payment getPayment(Long paymentId) { + UserDetailResponse userDetail = userClient.detail(); + Payment payment = paymentRepository.findById(paymentId) + .orElseThrow(ErrorCode::throwPaymentIdNotFound); + + if (userDetail.hasUserAlternateId(payment)) { + throw ErrorCode.throwValidUserId(); + } + + return payment; + } + + @Override + protected TicketsRefundResponse movieAndPaymentRefund(Payment payment) { + LocalDateTime now = LocalDateTime.now(); + TicketsRefundResponse refundResponse = movieClient.ticketRefundByDateTime(new TicketsRefundRequest(payment.getId()), now); + payment.refund(); + + return refundResponse; + } + +} diff --git a/server/src/main/java/com/ticketing/server/payment/service/PaymentApisServiceImpl.java b/server/src/main/java/com/ticketing/server/payment/service/PaymentApisServiceImpl.java index d0932a9..4061634 100644 --- a/server/src/main/java/com/ticketing/server/payment/service/PaymentApisServiceImpl.java +++ b/server/src/main/java/com/ticketing/server/payment/service/PaymentApisServiceImpl.java @@ -10,8 +10,6 @@ import com.ticketing.server.movie.application.request.TicketReservationRequest; import com.ticketing.server.movie.application.request.TicketSoldRequest; import com.ticketing.server.movie.application.response.TicketDetailsResponse; import com.ticketing.server.movie.application.response.TicketReservationResponse; -import com.ticketing.server.movie.service.dto.TicketsRefundResponse; -import com.ticketing.server.payment.api.dto.requset.KakaoPayCancelRequest; import com.ticketing.server.payment.api.KakaoPayClient; import com.ticketing.server.payment.api.KakaoPayProperties; import com.ticketing.server.payment.api.MovieClient; @@ -19,10 +17,8 @@ import com.ticketing.server.payment.api.UserClient; import com.ticketing.server.payment.api.dto.requset.KakaoPayApproveRequest; import com.ticketing.server.payment.api.dto.requset.KakaoPayReadyRequest; import com.ticketing.server.payment.api.dto.response.KakaoPayApproveResponse; -import com.ticketing.server.payment.api.dto.response.KakaoPayCancelResponse; import com.ticketing.server.payment.api.dto.response.KakaoPayReadyResponse; import com.ticketing.server.payment.api.dto.response.UserDetailResponse; -import com.ticketing.server.payment.api.impl.TicketsRefundRequest; import com.ticketing.server.payment.domain.Payment; import com.ticketing.server.payment.domain.PaymentStatus; import com.ticketing.server.payment.domain.PaymentType; @@ -31,7 +27,6 @@ import com.ticketing.server.payment.service.dto.PaymentCancelDTO; import com.ticketing.server.payment.service.dto.PaymentCompleteDTO; import com.ticketing.server.payment.service.dto.PaymentDetailDTO; import com.ticketing.server.payment.service.dto.PaymentReadyDTO; -import com.ticketing.server.payment.service.dto.PaymentRefundDTO; import com.ticketing.server.payment.service.interfaces.PaymentApisService; import java.util.List; import javax.validation.constraints.NotEmpty; @@ -81,6 +76,10 @@ public class PaymentApisServiceImpl implements PaymentApisService { UserDetailResponse userResponse = userClient.detail(); Long userAlternateId = userResponse.getUserAlternateId(); + // 다른 결제중인 데이터가 있다면, 예외처리 + paymentCacheRepository.findByEmail(userResponse.getEmail()) + .ifPresent(paymentCache -> ErrorCode.throwBadRequestPaymentReady()); + // Ticket 정보 조회 - 영화제목, 티켓가격이 필요함. TicketReservationResponse ticketResponse = movieClient.ticketReservation(new TicketReservationRequest(ticketIds)); String movieTitle = ticketResponse.getMovieTitle(); @@ -100,21 +99,18 @@ public class PaymentApisServiceImpl implements PaymentApisService { ); KakaoPayReadyResponse response = kakaoPayClient.ready(kakaoPayProperties.getAuthorization(), request); - PaymentCache paymentReady = new PaymentCache( - userResponse.getEmail(), - movieTitle, - response.getTid(), - ticketIds, - userAlternateId, - paymentNumber + paymentCacheRepository.save( + new PaymentCache( + userResponse.getEmail(), + movieTitle, + response.getTid(), + ticketIds, + userAlternateId, + paymentNumber, + request.getTotalAmount() + ) ); - paymentCacheRepository.findByEmail(userResponse.getEmail()) - .ifPresentOrElse( - paymentCache -> ErrorCode.throwBadRequestPaymentReady() - , () -> paymentCacheRepository.save(paymentReady) - ); - return new PaymentReadyDTO(response); } @@ -124,6 +120,13 @@ public class PaymentApisServiceImpl implements PaymentApisService { PaymentCache paymentCache = paymentCacheRepository.findByEmail(email) .orElseThrow(ErrorCode::throwBadRequestPaymentComplete); + Payment payment = new Payment(paymentCache, PaymentType.KAKAO_PAY, PaymentStatus.SOLD, paymentCache.getTotalAmount()); + payment = paymentRepository.save(payment); + + movieClient.ticketSold(new TicketSoldRequest(payment.getId(), paymentCache.getTicketIds())); + paymentCacheRepository.delete(paymentCache); + + // 카카오페이 결제완료 String paymentNumberToString = paymentCache.getPaymentNumber().toString(); String userAlternateIdToString = paymentCache.getUserAlternateId().toString(); KakaoPayApproveRequest kakaoPayApproveRequest = new KakaoPayApproveRequest( @@ -137,12 +140,6 @@ public class PaymentApisServiceImpl implements PaymentApisService { kakaoPayApproveRequest ); - Payment payment = new Payment(paymentCache, PaymentType.KAKAO_PAY, PaymentStatus.SOLD, kakaoPayApproveResponse.getTotalAmount()); - payment = paymentRepository.save(payment); - - movieClient.ticketSold(new TicketSoldRequest(payment.getId(), paymentCache.getTicketIds())); - paymentCacheRepository.delete(paymentCache); - return new PaymentCompleteDTO(email, kakaoPayApproveResponse); } @@ -158,46 +155,4 @@ public class PaymentApisServiceImpl implements PaymentApisService { return new PaymentCancelDTO(paymentCache); } - @Override - @Transactional - public PaymentRefundDTO myPaymentRefund(@NotNull Long paymentId) { - UserDetailResponse userDetail = userClient.detail(); - Payment payment = paymentRepository.findById(paymentId) - .orElseThrow(ErrorCode::throwPaymentIdNotFound); - - if (!payment.validUser(userDetail)) { - throw ErrorCode.throwValidUserId(); - } - - // 카카오페이 환불 - KakaoPayCancelResponse kakaoPayCancelResponse = kakaoPayClient.cancel( - kakaoPayProperties.getAuthorization(), - new KakaoPayCancelRequest(payment.getTid(), payment.getTotalPrice()) - ); - - // 내부 환불진행 - TicketsRefundResponse refundResponse = movieClient.ticketRefundByDateTime(new TicketsRefundRequest(payment.getId())); - payment.refund(); - - return new PaymentRefundDTO(payment, kakaoPayCancelResponse, refundResponse); - } - - @Override - public PaymentRefundDTO paymentRefund(@NotNull Long paymentId) { - Payment payment = paymentRepository.findById(paymentId) - .orElseThrow(ErrorCode::throwPaymentIdNotFound); - - // 카카오페이 환불 - KakaoPayCancelResponse kakaoPayCancelResponse = kakaoPayClient.cancel( - kakaoPayProperties.getAuthorization(), - new KakaoPayCancelRequest(payment.getTid(), payment.getTotalPrice()) - ); - - // 내부 환불진행 - TicketsRefundResponse refundResponse = movieClient.ticketRefund(new TicketsRefundRequest(payment.getId())); - payment.refund(); - - return new PaymentRefundDTO(payment, kakaoPayCancelResponse, refundResponse); - } - } diff --git a/server/src/main/java/com/ticketing/server/payment/service/interfaces/AbstractKakaoPayRefund.java b/server/src/main/java/com/ticketing/server/payment/service/interfaces/AbstractKakaoPayRefund.java new file mode 100644 index 0000000..0f9b165 --- /dev/null +++ b/server/src/main/java/com/ticketing/server/payment/service/interfaces/AbstractKakaoPayRefund.java @@ -0,0 +1,42 @@ +package com.ticketing.server.payment.service.interfaces; + +import com.ticketing.server.movie.service.dto.TicketsRefundResponse; +import com.ticketing.server.payment.api.KakaoPayClient; +import com.ticketing.server.payment.api.KakaoPayProperties; +import com.ticketing.server.payment.api.dto.requset.KakaoPayCancelRequest; +import com.ticketing.server.payment.api.dto.response.KakaoPayCancelResponse; +import com.ticketing.server.payment.domain.Payment; +import com.ticketing.server.payment.service.dto.PaymentRefundDTO; +import javax.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +@RequiredArgsConstructor +@Validated +public abstract class AbstractKakaoPayRefund { + + private final KakaoPayClient kakaoPayClient; + private final KakaoPayProperties kakaoPayProperties; + + @Transactional + public PaymentRefundDTO refund(@NotNull Long paymentId) { + Payment payment = getPayment(paymentId); + + // 내부 환불 + TicketsRefundResponse refundResponse = movieAndPaymentRefund(payment); + + // 카카오페이 환불 + KakaoPayCancelResponse kakaoPayCancelResponse = kakaoPayClient.cancel( + kakaoPayProperties.getAuthorization(), + new KakaoPayCancelRequest(payment.getTid(), payment.getTotalPrice()) + ); + + return new PaymentRefundDTO(payment, kakaoPayCancelResponse, refundResponse); + } + + protected abstract Payment getPayment(Long paymentId); + + protected abstract TicketsRefundResponse movieAndPaymentRefund(Payment payment); + +} diff --git a/server/src/main/java/com/ticketing/server/payment/service/interfaces/PaymentApisService.java b/server/src/main/java/com/ticketing/server/payment/service/interfaces/PaymentApisService.java index 78b1cae..50afb7a 100644 --- a/server/src/main/java/com/ticketing/server/payment/service/interfaces/PaymentApisService.java +++ b/server/src/main/java/com/ticketing/server/payment/service/interfaces/PaymentApisService.java @@ -1,7 +1,6 @@ package com.ticketing.server.payment.service.interfaces; import com.ticketing.server.global.validator.constraints.NotEmptyCollection; -import com.ticketing.server.payment.service.dto.PaymentRefundDTO; import com.ticketing.server.payment.service.dto.PaymentCancelDTO; import com.ticketing.server.payment.service.dto.PaymentCompleteDTO; import com.ticketing.server.payment.service.dto.PaymentDetailDTO; @@ -20,7 +19,4 @@ public interface PaymentApisService { PaymentCancelDTO cancel(@NotEmpty String email); - PaymentRefundDTO myPaymentRefund(@NotNull Long paymentId); - - PaymentRefundDTO paymentRefund(@NotNull Long paymentId); } diff --git a/server/src/test/java/com/ticketing/server/movie/domain/TicketTest.java b/server/src/test/java/com/ticketing/server/movie/domain/TicketTest.java index 6c44f8d..c1ee3c4 100644 --- a/server/src/test/java/com/ticketing/server/movie/domain/TicketTest.java +++ b/server/src/test/java/com/ticketing/server/movie/domain/TicketTest.java @@ -175,7 +175,7 @@ public class TicketTest { @Test @DisplayName("시간 비교 환불 성공") void refundByDateTimeSuccess() { - // given + // given LocalDateTime now = LocalDateTime.now(); LocalDateTime dateTime = LocalDateTime.of(now.getYear(), now.getMonthValue(), now.getDayOfMonth(), 7, 50); Ticket ticket = tickets.get(0); @@ -184,7 +184,7 @@ public class TicketTest { ticket.makeSold(123L); ticket.refund(dateTime); - // then + // then assertAll( () -> assertThat(ticket.getStatus()).isEqualTo(TicketStatus.SALE), () -> assertThat(ticket.getPaymentId()).isNull() @@ -212,14 +212,14 @@ public class TicketTest { @Test @DisplayName("관리자 환불 성공") void refundSuccess() { - // given + // given Ticket ticket = tickets.get(0); - // when + // when ticket.makeSold(123L); ticket.refund(); - // then + // then assertAll( () -> assertThat(ticket.getStatus()).isEqualTo(TicketStatus.SALE), () -> assertThat(ticket.getPaymentId()).isNull() @@ -229,11 +229,11 @@ public class TicketTest { @Test @DisplayName("관리자 환불 실패 - 상태 SALE") void refundFail_SALE() { - // given + // given Ticket ticket = tickets.get(0); - // when - // then + // when + // then assertThatThrownBy(ticket::refund) .isInstanceOf(TicketingException.class) .extracting("errorCode") @@ -243,13 +243,13 @@ public class TicketTest { @Test @DisplayName("관리자 환불 실패 - 상태 RESERVATION") void refundFail_RESERVATION() { - // given + // given Ticket ticket = tickets.get(0); - // when + // when ticket.makeReservation(); - // then + // then assertThatThrownBy(ticket::refund) .isInstanceOf(TicketingException.class) .extracting("errorCode") diff --git a/server/src/test/java/com/ticketing/server/payment/service/PaymentServiceImplTest.java b/server/src/test/java/com/ticketing/server/payment/service/PaymentServiceImplTest.java index 8a124a0..9270157 100644 --- a/server/src/test/java/com/ticketing/server/payment/service/PaymentServiceImplTest.java +++ b/server/src/test/java/com/ticketing/server/payment/service/PaymentServiceImplTest.java @@ -57,7 +57,8 @@ class PaymentServiceImplTest { "T2d03c9130bf237a97001", List.of(3L), userAlternateId, - 1241242343245L + 1241242343245L, + 15_000 ), KAKAO_PAY, SOLD, @@ -70,7 +71,8 @@ class PaymentServiceImplTest { "T2d03c9130bf237a97002", List.of(3L), userAlternateId, - 12412343212445L + 12412343212445L, + 30_000 ), KAKAO_PAY, SOLD, diff --git a/server/src/test/java/com/ticketing/server/user/service/UserApisServiceImplTest.java b/server/src/test/java/com/ticketing/server/user/service/UserApisServiceImplTest.java index 4749b70..8402962 100644 --- a/server/src/test/java/com/ticketing/server/user/service/UserApisServiceImplTest.java +++ b/server/src/test/java/com/ticketing/server/user/service/UserApisServiceImplTest.java @@ -76,7 +76,8 @@ class UserApisServiceImplTest { "T2d03c9130bf237a9700", List.of(1L, 2L), user.getAlternateId(), - 124124231513245L + 124124231513245L, + 15_000 ), KAKAO_PAY, SOLD, @@ -91,7 +92,8 @@ class UserApisServiceImplTest { "T2d03c9130bf237a97001", List.of(3L), user.getAlternateId(), - 1241242343245L + 1241242343245L, + 15_000 ), KAKAO_PAY, SOLD,