diff --git a/src/main/java/site/goldenticket/domain/nego/entity/Nego.java b/src/main/java/site/goldenticket/domain/nego/entity/Nego.java index 0d44ace5..273f6ba1 100644 --- a/src/main/java/site/goldenticket/domain/nego/entity/Nego.java +++ b/src/main/java/site/goldenticket/domain/nego/entity/Nego.java @@ -120,7 +120,7 @@ public Nego(Long id, Integer price, Integer count, Long userId, Long productId, this.updatedAt = updatedAt; } - public void completed() { - status = NegotiationStatus.NEGOTIATION_COMPLETED; + public void transferPending() { + status = NegotiationStatus.TRANSFER_PENDING; } } diff --git a/src/main/java/site/goldenticket/domain/payment/service/PaymentService.java b/src/main/java/site/goldenticket/domain/payment/service/PaymentService.java index 51a0c106..d6f0a347 100644 --- a/src/main/java/site/goldenticket/domain/payment/service/PaymentService.java +++ b/src/main/java/site/goldenticket/domain/payment/service/PaymentService.java @@ -11,6 +11,7 @@ import site.goldenticket.domain.chat.service.ChatService; import site.goldenticket.domain.nego.entity.Nego; import site.goldenticket.domain.nego.repository.NegoRepository; +import site.goldenticket.domain.nego.status.NegotiationStatus; import site.goldenticket.domain.payment.dto.request.PaymentRequest; import site.goldenticket.domain.payment.dto.response.PaymentDetailResponse; import site.goldenticket.domain.payment.dto.response.PaymentReadyResponse; @@ -56,9 +57,18 @@ public PaymentDetailResponse getPaymentDetail(Long productId, PrincipalDetails p throw new CustomException(ErrorCode.PRODUCT_NOT_ON_SALE); } - int price = product.getGoldenPrice(); - + //상품상태 = 예약중, 해당 경우에 본인이 네고를 진행하였고 결제 대기중인지 확인 Optional nego = negoRepository.findFirstByUser_IdAndProduct_IdOrderByCreatedAtDesc(user.getId(), product.getId()); + if (product.getProductStatus() == ProductStatus.RESERVED) { + if (nego.isEmpty()) { + throw new CustomException(ErrorCode.PRODUCT_NOT_ON_SALE); + } + if (nego.get().getStatus() != NegotiationStatus.PAYMENT_PENDING) { + throw new CustomException(ErrorCode.PRODUCT_NOT_ON_SALE); + } + } + + int price = product.getGoldenPrice(); Order order = Order.of(product.getId(), user.getId(), null, price); @@ -91,6 +101,17 @@ public PaymentReadyResponse preparePayment(Long orderId, PrincipalDetails princi throw new CustomException(ErrorCode.PRODUCT_NOT_ON_SALE); } + //상품상태 = 예약중, 해당 경우에 본인이 네고를 진행하였고 결제 대기중인지 확인 + Optional nego = negoRepository.findFirstByUser_IdAndProduct_IdOrderByCreatedAtDesc(user.getId(), product.getId()); + if (product.getProductStatus() == ProductStatus.RESERVED) { + if (nego.isEmpty()) { + throw new CustomException(ErrorCode.PRODUCT_NOT_ON_SALE); + } + if (nego.get().getStatus() != NegotiationStatus.PAYMENT_PENDING) { + throw new CustomException(ErrorCode.PRODUCT_NOT_ON_SALE); + } + } + order.requestPayment(); iamportRepository.prepare(order.getId(), BigDecimal.valueOf(order.getTotalPrice())); @@ -115,20 +136,45 @@ public PaymentResponse savePayment(PaymentRequest request, PrincipalDetails prin throw new CustomException(ErrorCode.INVALID_PAYMENT_AMOUNT_ERROR); } + //결제가 되지 않은 경우 if (savedPayment.isNotPaid()) { order.paymentFailed(); return PaymentResponse.failed(); } - if (order.getNegoStatus() != null) { - Nego nego = negoRepository.findFirstByUser_IdAndProduct_IdOrderByCreatedAtDesc(userId, order.getProductId()).orElseThrow( - () -> new CustomException(ErrorCode.NEGO_NOT_FOUND) - ); - if (nego.getStatus() != order.getNegoStatus()) { + //상품상태 = 상품만료, 솔드아웃 + if (product.isNotOnSale()) { + cancelPayment(request.getImpUid()); + return PaymentResponse.failed(); + } + + Optional nego = negoRepository.findFirstByUser_IdAndProduct_IdOrderByCreatedAtDesc(userId, product.getId()); + + //상품상태 = 예약중 + if (product.getProductStatus() == ProductStatus.RESERVED) { + if (nego.isEmpty()) { + cancelPayment(request.getImpUid()); + return PaymentResponse.failed(); + } + if (nego.get().getStatus() != order.getNegoStatus()) { + cancelPayment(request.getImpUid()); + return PaymentResponse.failed(); + } + if (nego.get().getStatus() != NegotiationStatus.PAYMENT_PENDING) { + cancelPayment(request.getImpUid()); + return PaymentResponse.failed(); + } + } + + //상품상태 = 판매중 + //네고 내역 존재할 때 + if (nego.isPresent()) { + //네고 상태: 결제 대기중 -> 타임아웃 => 결제 결과 타임오버 + if (nego.get().getStatus() != order.getNegoStatus()) { cancelPayment(request.getImpUid()); return PaymentResponse.timeOver(); } - nego.completed(); + nego.get().transferPending(); } order.waitTransfer(); @@ -141,7 +187,7 @@ public PaymentResponse savePayment(PaymentRequest request, PrincipalDetails prin + "까지 양도 신청을 완료해주세요. 양도 미신청 시, 자동 양도 신청됩니다."); //채팅방 생성 + 시작 메세지 생성 - if(!chatService.existsChatRoomByBuyerIdAndProductId(userId, product.getId())) { + if (!chatService.existsChatRoomByBuyerIdAndProductId(userId, product.getId())) { ChatRoomResponse chatRoomResponse = chatService.createChatRoom(userId, product.getId()); chatService.createStartMessageOfNewChatRoom(chatRoomResponse.chatRoomId()); } diff --git a/src/main/java/site/goldenticket/domain/product/model/Product.java b/src/main/java/site/goldenticket/domain/product/model/Product.java index 3da3bfd9..417e54e2 100644 --- a/src/main/java/site/goldenticket/domain/product/model/Product.java +++ b/src/main/java/site/goldenticket/domain/product/model/Product.java @@ -120,14 +120,11 @@ public void setProductStatus(ProductStatus productStatus) { this.productStatus = productStatus; } - public boolean isOnSale() { - return this.productStatus == ProductStatus.SELLING; - } - public boolean isNotOnSale() { - return !isOnSale(); + return this.productStatus == ProductStatus.EXPIRED || this.productStatus == ProductStatus.SOLD_OUT; } + public void setGoldenPrice(int goldenPrice) { this.goldenPrice = goldenPrice; }