From 6eb74c4bc88b7c74bc3207f22055b54c3a40a390 Mon Sep 17 00:00:00 2001 From: persi Date: Thu, 26 Jun 2025 17:54:18 +0900 Subject: [PATCH 01/10] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/service/PaymentService.java | 85 ++++++++++--------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java index d551b99..01c6868 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java @@ -8,6 +8,12 @@ import com.example.silverbridgeX_user.payment.repository.PaymentRepository; import com.example.silverbridgeX_user.user.domain.User; import com.example.silverbridgeX_user.user.repository.UserRepository; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; @@ -17,13 +23,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.client.RestTemplate; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - @Service @RequiredArgsConstructor @Transactional @@ -60,10 +59,12 @@ public PaymentDto.KakaoReadyResponse kakaoPayReady() { parameters.put("total_amount", "9900"); parameters.put("vat_amount", "200"); parameters.put("tax_free_amount", "0"); - parameters.put("approval_url", "http://15.165.17.95/user/payment/success"); // http://15.165.17.95/user/payment/success http://localhost:8080/payment/success - parameters.put("fail_url", "http://15.165.17.95/user/payment/fail"); // http://15.165.17.95/user/payment/fail http://localhost:8080/payment/fail - parameters.put("cancel_url", "http://15.165.17.95/user/payment/cancel"); // http://15.165.17.95/user/payment/cancel http://localhost:8080/payment/cancel - + parameters.put("approval_url", + "http://15.165.17.95/user/payment/success"); // http://15.165.17.95/user/payment/success http://localhost:8080/payment/success + parameters.put("fail_url", + "http://15.165.17.95/user/payment/fail"); // http://15.165.17.95/user/payment/fail http://localhost:8080/payment/fail + parameters.put("cancel_url", + "http://15.165.17.95/user/payment/cancel"); // http://15.165.17.95/user/payment/cancel http://localhost:8080/payment/cancel HttpEntity> requestEntity = new HttpEntity<>(parameters, this.getHeaders()); @@ -113,7 +114,8 @@ public PaymentDto.KakaoCancelResponse cancelResponse(String tid) { } public Payment getKakaoPayInfo(Long userId) { - Payment kakaoPay = paymentRepository.findByUser_Id(userId).orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); + Payment kakaoPay = paymentRepository.findByUser_Id(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); return kakaoPay; } @@ -126,10 +128,11 @@ public boolean getPremiumState(Long userId) { boolean isPremium = false; if (paymentRepository.existsByUser_Id(userId)) { - Payment kakaoPay = paymentRepository.findByUser_Id(userId).orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); + Payment kakaoPay = paymentRepository.findByUser_Id(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); - if (kakaoPay.getSid() == null || kakaoPay.getSid().isEmpty()) {} - else { + if (kakaoPay.getSid() == null || kakaoPay.getSid().isEmpty()) { + } else { Map parameters = new HashMap<>(); parameters.put("cid", cid); parameters.put("sid", kakaoPay.getSid()); @@ -143,13 +146,14 @@ public boolean getPremiumState(Long userId) { if (kakaoSubscribeStatusResponse.getStatus().equals("ACTIVE")) { isPremium = true; - } - else { + } else { String last_approved_at; - if(kakaoSubscribeStatusResponse.getLast_approved_at() == null || kakaoSubscribeStatusResponse.getLast_approved_at().isEmpty()) { + if (kakaoSubscribeStatusResponse.getLast_approved_at() == null + || kakaoSubscribeStatusResponse.getLast_approved_at().isEmpty()) { last_approved_at = kakaoSubscribeStatusResponse.getCreated_at(); + } else { + last_approved_at = kakaoSubscribeStatusResponse.getLast_approved_at(); } - else last_approved_at = kakaoSubscribeStatusResponse.getLast_approved_at(); DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; LocalDateTime lastApprovedAt = LocalDateTime.parse(last_approved_at, formatter); @@ -233,11 +237,12 @@ public PaymentDto.KakaoSubscribeStatusResponse subscribeStatusResponse(String si public void saveTid(Long userId, String tid) { Payment kakaoPay; if (paymentRepository.existsByUser_Id(userId)) { - kakaoPay = paymentRepository.findByUser_Id(userId).orElseThrow(() -> new GeneralException(ErrorCode.TID_SID_UNSUPPORTED)); + kakaoPay = paymentRepository.findByUser_Id(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.TID_SID_UNSUPPORTED)); kakaoPay.updateTid(tid); - } - else { - User user = userRepository.findById(userId).orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); + } else { + User user = userRepository.findById(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); kakaoPay = PaymentConverter.toKakaoPayTid(tid, user); } paymentRepository.save(kakaoPay); @@ -245,7 +250,8 @@ public void saveTid(Long userId, String tid) { public void saveSid(PaymentDto.KakaoApproveResponse kakaoApproveResponse) { - Payment kakaoPay = paymentRepository.findByTid(kakaoApproveResponse.getTid()).orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); + Payment kakaoPay = paymentRepository.findByTid(kakaoApproveResponse.getTid()) + .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); kakaoPay.updateSid(kakaoApproveResponse.getSid()); @@ -255,18 +261,21 @@ public void saveSid(PaymentDto.KakaoApproveResponse kakaoApproveResponse) { public void savePayInfo(Long userId, PaymentDto.KakaoApproveResponse kakaoApproveResponse) { Payment kakaoPay; if (paymentRepository.existsByUser_Id(userId)) { - kakaoPay = paymentRepository.findByUser_Id(userId).orElseThrow(() -> new GeneralException(ErrorCode.TID_SID_UNSUPPORTED)); + kakaoPay = paymentRepository.findByUser_Id(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.TID_SID_UNSUPPORTED)); kakaoPay.updatePayInfo(kakaoApproveResponse.getTid(), kakaoApproveResponse.getSid()); - } - else { - User member = userRepository.findById(userId).orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); - kakaoPay = PaymentConverter.toKakaoPay(kakaoApproveResponse.getTid(), kakaoApproveResponse.getSid(), member); + } else { + User member = userRepository.findById(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); + kakaoPay = PaymentConverter.toKakaoPay(kakaoApproveResponse.getTid(), kakaoApproveResponse.getSid(), + member); } paymentRepository.save(kakaoPay); } public void cancelPay(Long userId) { - Payment kakaoPay = paymentRepository.findByUser_Id(userId).orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); + Payment kakaoPay = paymentRepository.findByUser_Id(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); paymentRepository.delete(kakaoPay); } @@ -277,7 +286,8 @@ public void regularPayment() { kakaoPayList.stream() .forEach(kakaoPay -> { if (kakaoPay.getSid() != null && !kakaoPay.getSid().isEmpty()) { - PaymentDto.KakaoSubscribeStatusResponse kakaoSubscribeStatusResponse = subscribeStatusResponse(kakaoPay.getSid()); + PaymentDto.KakaoSubscribeStatusResponse kakaoSubscribeStatusResponse = subscribeStatusResponse( + kakaoPay.getSid()); // "ACTIVE" 상태인지 확인 if (kakaoSubscribeStatusResponse.getStatus().equals("ACTIVE")) { @@ -294,21 +304,16 @@ public void regularPayment() { // 결제일과 오늘의 일(day)이 같고, 마지막 결제일이 이번 달이 아닌 경우에만 결제 수행 if (today.getDayOfMonth() == lastApprovedAt.getDayOfMonth() && - (today.getYear() != lastApprovedAt.getYear() || today.getMonthValue() != lastApprovedAt.getMonthValue())) { + (today.getYear() != lastApprovedAt.getYear() + || today.getMonthValue() != lastApprovedAt.getMonthValue())) { - PaymentDto.KakaoApproveResponse approveResponse = approveSubscribeResponse(kakaoPay.getSid()); + PaymentDto.KakaoApproveResponse approveResponse = approveSubscribeResponse( + kakaoPay.getSid()); savePayInfo(kakaoPay.getUser().getId(), approveResponse); } -// if (today.getDayOfMonth() == lastApprovedAt.getDayOfMonth()) { -// KakaoPayDTO.KakaoApproveResponse approveResponse = approveSubscribeResponse(kakaoPay.getSid()); -// -// savePayInfo(kakaoPay.getMember().getId(), approveResponse); -// } } } }); - -// System.out.println("정기 결제 작업 완료"); } } From 63327baef29752dbd58eb44ed935234d56b7855c Mon Sep 17 00:00:00 2001 From: persi Date: Thu, 26 Jun 2025 18:27:07 +0900 Subject: [PATCH 02/10] =?UTF-8?q?refactor:=20Controller=EC=9D=98=20?= =?UTF-8?q?=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20Ser?= =?UTF-8?q?vice=EB=A1=9C=20=EC=9C=84=EC=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/controller/PaymentController.java | 126 +++++++++--------- .../payment/service/PaymentService.java | 19 ++- 2 files changed, 78 insertions(+), 67 deletions(-) diff --git a/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java b/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java index f6ae878..1998fdd 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java @@ -2,17 +2,19 @@ import com.example.silverbridgeX_user.global.api_payload.ApiResponse; import com.example.silverbridgeX_user.global.api_payload.SuccessCode; -import com.example.silverbridgeX_user.payment.converter.PaymentConverter; import com.example.silverbridgeX_user.payment.domain.Payment; import com.example.silverbridgeX_user.payment.dto.PaymentDto; import com.example.silverbridgeX_user.payment.service.PaymentService; -import com.example.silverbridgeX_user.user.domain.User; import com.example.silverbridgeX_user.user.jwt.CustomUserDetails; import com.example.silverbridgeX_user.user.service.UserService; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; @RestController @@ -25,11 +27,12 @@ public class PaymentController { @PostMapping("/ready") @Operation(summary = "카카오페이 URL 생성 API", description = "카카오페이 URL을 생성하는 API 입니다.") - public ApiResponse readyToKakaoPay(@AuthenticationPrincipal CustomUserDetails customUserDetails) { + public ApiResponse readyToKakaoPay( + @AuthenticationPrincipal CustomUserDetails customUserDetails + ) { PaymentDto.KakaoReadyResponse kakaoReadyResponse = paymentService.kakaoPayReady(); - User user = userService.findByUserName(customUserDetails.getUsername()); - Long userId = user.getId(); + Long userId = userService.findByUserName(customUserDetails.getUsername()).getId(); paymentService.saveTid(userId, kakaoReadyResponse.getTid()); @@ -38,11 +41,12 @@ public ApiResponse readyToKakaoPay(@Authenticatio @PostMapping("/ready/key") @Operation(summary = "카카오페이 URL 생성 API", description = "key를 이용하여 카카오페이 URL을 생성하는 API 입니다.") - public ApiResponse readyToKakaoPay(@RequestParam("id") String key) { + public ApiResponse readyToKakaoPay( + @RequestParam("id") String key + ) { PaymentDto.KakaoReadyResponse kakaoReadyResponse = paymentService.kakaoPayReady(); - User user = userService.findByUserName(key); - Long userId = user.getId(); + Long userId = userService.findByUserName(key).getId(); paymentService.saveTid(userId, kakaoReadyResponse.getTid()); @@ -50,7 +54,9 @@ public ApiResponse readyToKakaoPay(@RequestParam( } @GetMapping("/success") - public ModelAndView afterPayRequest(@RequestParam("pg_token") String pgToken) { + public ModelAndView afterPayRequest( + @RequestParam("pg_token") String pgToken + ) { PaymentDto.KakaoApproveResponse kakaoApproveResponse = paymentService.approveResponse(pgToken); ModelAndView modelAndView = new ModelAndView("success"); // "success"는 템플릿 파일 이름 @@ -67,10 +73,11 @@ public String fail() { } @GetMapping("/cancel") - public ApiResponse refund(@AuthenticationPrincipal CustomUserDetails customUserDetails) { + public ApiResponse refund( + @AuthenticationPrincipal CustomUserDetails customUserDetails + ) { - User user = userService.findByUserName(customUserDetails.getUsername()); - Long userId = user.getId(); + Long userId = userService.findByUserName(customUserDetails.getUsername()).getId(); Payment kakaoPay = paymentService.getKakaoPayInfo(userId); @@ -82,10 +89,11 @@ public ApiResponse refund(@AuthenticationPrincip } @GetMapping("/cancel/key") - public ApiResponse refund(@RequestParam("id") String key) { + public ApiResponse refund( + @RequestParam("id") String key + ) { - User user = userService.findByUserName(key); - Long userId = user.getId(); + Long userId = userService.findByUserName(key).getId(); Payment kakaoPay = paymentService.getKakaoPayInfo(userId); @@ -97,13 +105,15 @@ public ApiResponse refund(@RequestParam("id") St } @PostMapping("/subscribe") - public ApiResponse subscribePayRequest(@AuthenticationPrincipal CustomUserDetails customUserDetails) { - User user = userService.findByUserName(customUserDetails.getUsername()); - Long userId = user.getId(); + public ApiResponse subscribePayRequest( + @AuthenticationPrincipal CustomUserDetails customUserDetails + ) { + Long userId = userService.findByUserName(customUserDetails.getUsername()).getId(); Payment kakaoPay = paymentService.getKakaoPayInfo(userId); - PaymentDto.KakaoApproveResponse kakaoApproveResponse = paymentService.approveSubscribeResponse(kakaoPay.getSid()); + PaymentDto.KakaoApproveResponse kakaoApproveResponse = paymentService.approveSubscribeResponse( + kakaoPay.getSid()); paymentService.savePayInfo(userId, kakaoApproveResponse); @@ -111,13 +121,15 @@ public ApiResponse subscribePayRequest(@Authent } @PostMapping("/subscribe/key") - public ApiResponse subscribePayRequest(@RequestParam("id") String key) { - User user = userService.findByUserName(key); - Long userId = user.getId(); + public ApiResponse subscribePayRequest( + @RequestParam("id") String key + ) { + Long userId = userService.findByUserName(key).getId(); Payment kakaoPay = paymentService.getKakaoPayInfo(userId); - PaymentDto.KakaoApproveResponse kakaoApproveResponse = paymentService.approveSubscribeResponse(kakaoPay.getSid()); + PaymentDto.KakaoApproveResponse kakaoApproveResponse = paymentService.approveSubscribeResponse( + kakaoPay.getSid()); paymentService.savePayInfo(userId, kakaoApproveResponse); @@ -126,73 +138,55 @@ public ApiResponse subscribePayRequest(@Request @PostMapping("/subscribe/cancel") @Operation(summary = "카카오페이 구독 취소 API", description = "카카오페이 구독을 취소하는 API 입니다.") - public ApiResponse subscribeCancelRequest(@AuthenticationPrincipal CustomUserDetails customUserDetails) { - User user = userService.findByUserName(customUserDetails.getUsername()); - Long userId = user.getId(); + public ApiResponse subscribeCancelRequest( + @AuthenticationPrincipal CustomUserDetails customUserDetails + ) { + Long userId = userService.findByUserName(customUserDetails.getUsername()).getId(); Payment kakaoPay = paymentService.getKakaoPayInfo(userId); - PaymentDto.KakaoSubscribeCancelResponse kakaoSubscribeCancelResponse = paymentService.subscribeCancelResponse(kakaoPay.getSid()); + PaymentDto.KakaoSubscribeCancelResponse kakaoSubscribeCancelResponse = paymentService.subscribeCancelResponse( + kakaoPay.getSid()); return ApiResponse.onSuccess(SuccessCode.PAYMENT_URL_CREATE_SUCCESS, kakaoSubscribeCancelResponse); } @PostMapping("/subscribe/cancel/key") @Operation(summary = "카카오페이 구독 취소 API", description = "key를 이용하여 카카오페이 구독을 취소하는 API 입니다.") - public ApiResponse subscribeCancelRequest(@RequestParam("id") String key) { - User user = userService.findByUserName(key); - Long userId = user.getId(); + public ApiResponse subscribeCancelRequest( + @RequestParam("id") String key + ) { + Long userId = userService.findByUserName(key).getId(); Payment kakaoPay = paymentService.getKakaoPayInfo(userId); - PaymentDto.KakaoSubscribeCancelResponse kakaoSubscribeCancelResponse = paymentService.subscribeCancelResponse(kakaoPay.getSid()); + PaymentDto.KakaoSubscribeCancelResponse kakaoSubscribeCancelResponse = paymentService.subscribeCancelResponse( + kakaoPay.getSid()); return ApiResponse.onSuccess(SuccessCode.PAYMENT_URL_CREATE_SUCCESS, kakaoSubscribeCancelResponse); } @GetMapping("/subscribe/status") @Operation(summary = "카카오페이 구독 상태 확인 API", description = "카카오페이 구독 상태를 확인하는 API 입니다.") - public ApiResponse subscribeStatusRequest(@AuthenticationPrincipal CustomUserDetails customUserDetails) { - User user = userService.findByUserName(customUserDetails.getUsername()); - Long userId = user.getId(); + public ApiResponse subscribeStatusRequest( + @AuthenticationPrincipal CustomUserDetails customUserDetails + ) { + Long userId = userService.findByUserName(customUserDetails.getUsername()).getId(); - PaymentDto.KakaoSubscribeStatusResponse kakaoSubscribeStatusResponse = new PaymentDto.KakaoSubscribeStatusResponse(); + PaymentDto.KakaoPayStatus kakaoPayStatus = paymentService.getSubscribeStatus(userId); - boolean isLogExist = false; - if (paymentService.getKakaoPayLog(userId)) { - Payment kakaoPay = paymentService.getKakaoPayInfo(userId); - - if (kakaoPay.getSid() == null || kakaoPay.getSid().isEmpty()) {} - else { - isLogExist = true; - - kakaoSubscribeStatusResponse = paymentService.subscribeStatusResponse(kakaoPay.getSid()); - } - } - - return ApiResponse.onSuccess(SuccessCode.PAYMENT_VIEW_SUBSCRIBE_STATUS_SUCCESS, PaymentConverter.toKakaoPayStatus(isLogExist, kakaoSubscribeStatusResponse)); + return ApiResponse.onSuccess(SuccessCode.PAYMENT_VIEW_SUBSCRIBE_STATUS_SUCCESS, kakaoPayStatus); } @GetMapping("/subscribe/status/key") @Operation(summary = "카카오페이 구독 상태 확인 API", description = "key를 이용하여 카카오페이 구독 상태를 확인하는 API 입니다.") - public ApiResponse subscribeStatusRequest(@RequestParam("id") String key) { - User user = userService.findByUserName(key); - Long userId = user.getId(); - - PaymentDto.KakaoSubscribeStatusResponse kakaoSubscribeStatusResponse = new PaymentDto.KakaoSubscribeStatusResponse(); - - boolean isLogExist = false; - if (paymentService.getKakaoPayLog(userId)) { - Payment kakaoPay = paymentService.getKakaoPayInfo(userId); - - if (kakaoPay.getSid() == null || kakaoPay.getSid().isEmpty()) {} - else { - isLogExist = true; + public ApiResponse subscribeStatusRequest( + @RequestParam("id") String key + ) { + Long userId = userService.findByUserName(key).getId(); - kakaoSubscribeStatusResponse = paymentService.subscribeStatusResponse(kakaoPay.getSid()); - } - } + PaymentDto.KakaoPayStatus kakaoPayStatus = paymentService.getSubscribeStatus(userId); - return ApiResponse.onSuccess(SuccessCode.PAYMENT_VIEW_SUBSCRIBE_STATUS_SUCCESS, PaymentConverter.toKakaoPayStatus(isLogExist, kakaoSubscribeStatusResponse)); + return ApiResponse.onSuccess(SuccessCode.PAYMENT_VIEW_SUBSCRIBE_STATUS_SUCCESS, kakaoPayStatus); } } diff --git a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java index 01c6868..bddfd5a 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java @@ -120,7 +120,7 @@ public Payment getKakaoPayInfo(Long userId) { return kakaoPay; } - public boolean getKakaoPayLog(Long userId) { + public boolean existKakaoPayLog(Long userId) { return paymentRepository.existsByUser_Id(userId); } @@ -316,4 +316,21 @@ public void regularPayment() { } }); } + + public PaymentDto.KakaoPayStatus getSubscribeStatus(Long userId) { + boolean isLogExist = false; + PaymentDto.KakaoSubscribeStatusResponse kakaoSubscribeStatusResponse = new PaymentDto.KakaoSubscribeStatusResponse(); + + if (existKakaoPayLog(userId)) { + Payment kakaoPay = getKakaoPayInfo(userId); + + if (kakaoPay.getSid() != null && !kakaoPay.getSid().isEmpty()) { + isLogExist = true; + kakaoSubscribeStatusResponse = subscribeStatusResponse(kakaoPay.getSid()); + } + } + + return PaymentConverter.toKakaoPayStatus(isLogExist, kakaoSubscribeStatusResponse); + } + } From 238ca1510f0d405faac454b41484e90f6762fcb9 Mon Sep 17 00:00:00 2001 From: persi Date: Thu, 26 Jun 2025 19:24:53 +0900 Subject: [PATCH 03/10] =?UTF-8?q?refactor:=20=EC=99=B8=EB=B6=80=20API=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=20=EB=A1=9C=EC=A7=81=EC=9D=84=20=ED=85=9C?= =?UTF-8?q?=ED=94=8C=EB=A6=BF=ED=99=94=ED=95=98=EC=97=AC=20=EC=9E=AC?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EC=84=B1=EA=B3=BC=20=EA=B0=80=EB=8F=85?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/util/RestTemplateUtil.java | 22 +++ .../payment/service/PaymentService.java | 153 ++++-------------- 2 files changed, 57 insertions(+), 118 deletions(-) create mode 100644 src/main/java/com/example/silverbridgeX_user/global/util/RestTemplateUtil.java diff --git a/src/main/java/com/example/silverbridgeX_user/global/util/RestTemplateUtil.java b/src/main/java/com/example/silverbridgeX_user/global/util/RestTemplateUtil.java new file mode 100644 index 0000000..f733051 --- /dev/null +++ b/src/main/java/com/example/silverbridgeX_user/global/util/RestTemplateUtil.java @@ -0,0 +1,22 @@ +package com.example.silverbridgeX_user.global.util; + +import java.util.Map; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +@Component +@RequiredArgsConstructor +public class RestTemplateUtil { + + private final RestTemplate restTemplate; + + public T post(String url, Map parameters, HttpHeaders headers, Class responseType) { + HttpEntity> requestEntity = new HttpEntity<>(parameters, headers); + ResponseEntity response = restTemplate.postForEntity(url, requestEntity, responseType); + return response.getBody(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java index bddfd5a..cd48896 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java @@ -2,6 +2,7 @@ import com.example.silverbridgeX_user.global.api_payload.ErrorCode; import com.example.silverbridgeX_user.global.exception.GeneralException; +import com.example.silverbridgeX_user.global.util.RestTemplateUtil; import com.example.silverbridgeX_user.payment.converter.PaymentConverter; import com.example.silverbridgeX_user.payment.domain.Payment; import com.example.silverbridgeX_user.payment.dto.PaymentDto; @@ -9,30 +10,25 @@ import com.example.silverbridgeX_user.user.domain.User; import com.example.silverbridgeX_user.user.repository.UserRepository; import java.time.LocalDate; -import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; -import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.client.RestTemplate; @Service @RequiredArgsConstructor @Transactional -@EnableScheduling public class PaymentService { - private RestTemplate restTemplate = new RestTemplate(); - private PaymentDto.KakaoReadyResponse kakaoReadyResponse; private final PaymentRepository paymentRepository; private final UserRepository userRepository; + private final RestTemplateUtil restTemplateUtil; + private PaymentDto.KakaoReadyResponse kakaoReadyResponse; @Value("${kakaopay.secret_key}") private String secretKey; @@ -40,6 +36,14 @@ public class PaymentService { @Value("${kakaopay.cid}") private String cid; + public static final String BASE_URL = "https://open-api.kakaopay.com/online/v1/payment"; + public static final String READY_URL = BASE_URL + "/ready"; + public static final String APPROVE_URL = BASE_URL + "/approve"; + public static final String CANCEL_URL = BASE_URL + "/cancel"; + public static final String SUBSCRIBE_URL = BASE_URL + "/subscription"; + public static final String SUBSCRIBE_STATUS_URL = BASE_URL + "/manage/subscription/status"; + public static final String SUBSCRIBE_CANCEL_URL = BASE_URL + "/manage/subscription/inactive"; + private HttpHeaders getHeaders() { HttpHeaders httpHeaders = new HttpHeaders(); String auth = "SECRET_KEY " + secretKey; @@ -50,7 +54,6 @@ private HttpHeaders getHeaders() { public PaymentDto.KakaoReadyResponse kakaoPayReady() { Map parameters = new HashMap<>(); - parameters.put("cid", cid); parameters.put("partner_order_id", "ORDER_ID"); parameters.put("partner_user_id", "USER_ID"); @@ -59,20 +62,11 @@ public PaymentDto.KakaoReadyResponse kakaoPayReady() { parameters.put("total_amount", "9900"); parameters.put("vat_amount", "200"); parameters.put("tax_free_amount", "0"); - parameters.put("approval_url", - "http://15.165.17.95/user/payment/success"); // http://15.165.17.95/user/payment/success http://localhost:8080/payment/success - parameters.put("fail_url", - "http://15.165.17.95/user/payment/fail"); // http://15.165.17.95/user/payment/fail http://localhost:8080/payment/fail - parameters.put("cancel_url", - "http://15.165.17.95/user/payment/cancel"); // http://15.165.17.95/user/payment/cancel http://localhost:8080/payment/cancel - - HttpEntity> requestEntity = new HttpEntity<>(parameters, this.getHeaders()); - - kakaoReadyResponse = restTemplate.postForObject( - "https://open-api.kakaopay.com/online/v1/payment/ready", - requestEntity, - PaymentDto.KakaoReadyResponse.class); - return kakaoReadyResponse; + parameters.put("approval_url", "http://15.165.17.95/user/payment/success"); + parameters.put("fail_url", "http://15.165.17.95/user/payment/fail"); + parameters.put("cancel_url", "http://15.165.17.95/user/payment/cancel"); + + return restTemplateUtil.post(READY_URL, parameters, getHeaders(), PaymentDto.KakaoReadyResponse.class); } public PaymentDto.KakaoApproveResponse approveResponse(String pgToken) { @@ -83,13 +77,7 @@ public PaymentDto.KakaoApproveResponse approveResponse(String pgToken) { parameters.put("partner_user_id", "USER_ID"); parameters.put("pg_token", pgToken); - HttpEntity> requestEntity = new HttpEntity<>(parameters, this.getHeaders()); - - PaymentDto.KakaoApproveResponse kakaoApproveResponse = restTemplate.postForObject( - "https://open-api.kakaopay.com/online/v1/payment/approve", - requestEntity, - PaymentDto.KakaoApproveResponse.class); - return kakaoApproveResponse; + return restTemplateUtil.post(APPROVE_URL, parameters, getHeaders(), PaymentDto.KakaoApproveResponse.class); } public PaymentDto.KakaoCancelResponse cancelResponse(String tid) { @@ -104,73 +92,7 @@ public PaymentDto.KakaoCancelResponse cancelResponse(String tid) { parameters.put("cancel_tax_free_amount", "0"); parameters.put("cancel_vat_amount", "0"); - HttpEntity> requestEntity = new HttpEntity<>(parameters, this.getHeaders()); - - PaymentDto.KakaoCancelResponse kakaoCancelResponse = restTemplate.postForObject( - "https://open-api.kakaopay.com/online/v1/payment/cancel", - requestEntity, - PaymentDto.KakaoCancelResponse.class); - return kakaoCancelResponse; - } - - public Payment getKakaoPayInfo(Long userId) { - Payment kakaoPay = paymentRepository.findByUser_Id(userId) - .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); - - return kakaoPay; - } - - public boolean existKakaoPayLog(Long userId) { - return paymentRepository.existsByUser_Id(userId); - } - - public boolean getPremiumState(Long userId) { - boolean isPremium = false; - - if (paymentRepository.existsByUser_Id(userId)) { - Payment kakaoPay = paymentRepository.findByUser_Id(userId) - .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); - - if (kakaoPay.getSid() == null || kakaoPay.getSid().isEmpty()) { - } else { - Map parameters = new HashMap<>(); - parameters.put("cid", cid); - parameters.put("sid", kakaoPay.getSid()); - - HttpEntity> requestEntity = new HttpEntity<>(parameters, this.getHeaders()); - - PaymentDto.KakaoSubscribeStatusResponse kakaoSubscribeStatusResponse = restTemplate.postForObject( - "https://open-api.kakaopay.com/online/v1/payment/manage/subscription/status", - requestEntity, - PaymentDto.KakaoSubscribeStatusResponse.class); - - if (kakaoSubscribeStatusResponse.getStatus().equals("ACTIVE")) { - isPremium = true; - } else { - String last_approved_at; - if (kakaoSubscribeStatusResponse.getLast_approved_at() == null - || kakaoSubscribeStatusResponse.getLast_approved_at().isEmpty()) { - last_approved_at = kakaoSubscribeStatusResponse.getCreated_at(); - } else { - last_approved_at = kakaoSubscribeStatusResponse.getLast_approved_at(); - } - - DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; - LocalDateTime lastApprovedAt = LocalDateTime.parse(last_approved_at, formatter); - - LocalDateTime oneMonthLater = lastApprovedAt.plusMonths(1).withHour(14).withMinute(0).withSecond(0); - - LocalDateTime now = LocalDateTime.now(); - - if (now.isBefore(oneMonthLater)) { - isPremium = true; - } - } - } - - } - - return isPremium; + return restTemplateUtil.post(CANCEL_URL, parameters, getHeaders(), PaymentDto.KakaoCancelResponse.class); } public PaymentDto.KakaoApproveResponse approveSubscribeResponse(String sid) { @@ -189,16 +111,10 @@ public PaymentDto.KakaoApproveResponse approveSubscribeResponse(String sid) { parameters.put("vat_amount", "200"); parameters.put("tax_free_amount", "0"); - HttpEntity> requestEntity = new HttpEntity<>(parameters, this.getHeaders()); - - PaymentDto.KakaoApproveResponse kakaoApproveResponse = restTemplate.postForObject( - "https://open-api.kakaopay.com/online/v1/payment/subscription", - requestEntity, - PaymentDto.KakaoApproveResponse.class); - return kakaoApproveResponse; + return restTemplateUtil.post(SUBSCRIBE_URL, parameters, getHeaders(), PaymentDto.KakaoApproveResponse.class); } - public PaymentDto.KakaoSubscribeCancelResponse subscribeCancelResponse(String sid) { + public PaymentDto.KakaoSubscribeStatusResponse subscribeStatusResponse(String sid) { if (sid == null || sid.isEmpty()) { throw new GeneralException(ErrorCode.SID_NOT_EXIST); } @@ -207,16 +123,11 @@ public PaymentDto.KakaoSubscribeCancelResponse subscribeCancelResponse(String si parameters.put("cid", cid); parameters.put("sid", sid); - HttpEntity> requestEntity = new HttpEntity<>(parameters, this.getHeaders()); - - PaymentDto.KakaoSubscribeCancelResponse kakaoSubscribeCancelResponse = restTemplate.postForObject( - "https://open-api.kakaopay.com/online/v1/payment/manage/subscription/inactive", - requestEntity, - PaymentDto.KakaoSubscribeCancelResponse.class); - return kakaoSubscribeCancelResponse; + return restTemplateUtil.post(SUBSCRIBE_STATUS_URL, parameters, getHeaders(), + PaymentDto.KakaoSubscribeStatusResponse.class); } - public PaymentDto.KakaoSubscribeStatusResponse subscribeStatusResponse(String sid) { + public PaymentDto.KakaoSubscribeCancelResponse subscribeCancelResponse(String sid) { if (sid == null || sid.isEmpty()) { throw new GeneralException(ErrorCode.SID_NOT_EXIST); } @@ -225,13 +136,19 @@ public PaymentDto.KakaoSubscribeStatusResponse subscribeStatusResponse(String si parameters.put("cid", cid); parameters.put("sid", sid); - HttpEntity> requestEntity = new HttpEntity<>(parameters, this.getHeaders()); + return restTemplateUtil.post(SUBSCRIBE_CANCEL_URL, parameters, getHeaders(), + PaymentDto.KakaoSubscribeCancelResponse.class); + } - PaymentDto.KakaoSubscribeStatusResponse kakaoSubscribeStatusResponse = restTemplate.postForObject( - "https://open-api.kakaopay.com/online/v1/payment/manage/subscription/status", - requestEntity, - PaymentDto.KakaoSubscribeStatusResponse.class); - return kakaoSubscribeStatusResponse; + public Payment getKakaoPayInfo(Long userId) { + Payment kakaoPay = paymentRepository.findByUser_Id(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); + + return kakaoPay; + } + + public boolean existKakaoPayLog(Long userId) { + return paymentRepository.existsByUser_Id(userId); } public void saveTid(Long userId, String tid) { From 005ee7f4f53844e8635a4a9ab90685c90df79a69 Mon Sep 17 00:00:00 2001 From: persi Date: Thu, 26 Jun 2025 19:57:48 +0900 Subject: [PATCH 04/10] =?UTF-8?q?fix:=20=EA=B2=B0=EC=A0=9C=20=EC=8A=B9?= =?UTF-8?q?=EC=9D=B8=20=EC=8B=9C=20=EC=82=AC=EC=9A=A9=EC=9E=90=EB=B3=84=20?= =?UTF-8?q?tid=20DB=20=EC=A1=B0=ED=9A=8C=EB=A1=9C=20=EC=B6=A9=EB=8F=8C=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/controller/PaymentController.java | 12 ++++----- .../payment/repository/PaymentRepository.java | 14 ++++++---- .../payment/service/PaymentService.java | 27 ++++++++++--------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java b/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java index 1998fdd..7ee0f07 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java @@ -30,10 +30,10 @@ public class PaymentController { public ApiResponse readyToKakaoPay( @AuthenticationPrincipal CustomUserDetails customUserDetails ) { - PaymentDto.KakaoReadyResponse kakaoReadyResponse = paymentService.kakaoPayReady(); - Long userId = userService.findByUserName(customUserDetails.getUsername()).getId(); + PaymentDto.KakaoReadyResponse kakaoReadyResponse = paymentService.kakaoPayReady(userId); + paymentService.saveTid(userId, kakaoReadyResponse.getTid()); return ApiResponse.onSuccess(SuccessCode.PAYMENT_URL_CREATE_SUCCESS, kakaoReadyResponse); @@ -44,10 +44,10 @@ public ApiResponse readyToKakaoPay( public ApiResponse readyToKakaoPay( @RequestParam("id") String key ) { - PaymentDto.KakaoReadyResponse kakaoReadyResponse = paymentService.kakaoPayReady(); - Long userId = userService.findByUserName(key).getId(); + PaymentDto.KakaoReadyResponse kakaoReadyResponse = paymentService.kakaoPayReady(userId); + paymentService.saveTid(userId, kakaoReadyResponse.getTid()); return ApiResponse.onSuccess(SuccessCode.PAYMENT_URL_CREATE_SUCCESS, kakaoReadyResponse); @@ -55,9 +55,9 @@ public ApiResponse readyToKakaoPay( @GetMapping("/success") public ModelAndView afterPayRequest( - @RequestParam("pg_token") String pgToken + @RequestParam("pg_token") String pgToken, @RequestParam("userId") Long userId ) { - PaymentDto.KakaoApproveResponse kakaoApproveResponse = paymentService.approveResponse(pgToken); + PaymentDto.KakaoApproveResponse kakaoApproveResponse = paymentService.approveResponse(pgToken, userId); ModelAndView modelAndView = new ModelAndView("success"); // "success"는 템플릿 파일 이름 modelAndView.addObject("paymentInfo", kakaoApproveResponse); diff --git a/src/main/java/com/example/silverbridgeX_user/payment/repository/PaymentRepository.java b/src/main/java/com/example/silverbridgeX_user/payment/repository/PaymentRepository.java index 5c131c3..e12001d 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/repository/PaymentRepository.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/repository/PaymentRepository.java @@ -1,17 +1,21 @@ package com.example.silverbridgeX_user.payment.repository; import com.example.silverbridgeX_user.payment.domain.Payment; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - import java.util.List; import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface PaymentRepository extends JpaRepository { - boolean existsByUser_Id(Long userId); - Optional findByUser_Id(Long userId); + boolean existsByUserId(Long userId); + Optional findByTid(String tid); + @Query("SELECT k FROM Payment k JOIN FETCH k.user WHERE k.sid IS NOT NULL") List findAllWithMemberAndSidNotNull(); + + @Query("SELECT p FROM Payment p WHERE p.user.id = :userId ORDER BY p.createdAt DESC") + Optional getLatestKakaoPayInfo(@Param("userId") Long userId); } diff --git a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java index cd48896..1a7dda1 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java @@ -28,7 +28,6 @@ public class PaymentService { private final PaymentRepository paymentRepository; private final UserRepository userRepository; private final RestTemplateUtil restTemplateUtil; - private PaymentDto.KakaoReadyResponse kakaoReadyResponse; @Value("${kakaopay.secret_key}") private String secretKey; @@ -52,7 +51,7 @@ private HttpHeaders getHeaders() { return httpHeaders; } - public PaymentDto.KakaoReadyResponse kakaoPayReady() { + public PaymentDto.KakaoReadyResponse kakaoPayReady(Long userId) { Map parameters = new HashMap<>(); parameters.put("cid", cid); parameters.put("partner_order_id", "ORDER_ID"); @@ -62,17 +61,21 @@ public PaymentDto.KakaoReadyResponse kakaoPayReady() { parameters.put("total_amount", "9900"); parameters.put("vat_amount", "200"); parameters.put("tax_free_amount", "0"); - parameters.put("approval_url", "http://15.165.17.95/user/payment/success"); + parameters.put("approval_url", "http://15.165.17.95/user/payment/success?userId=" + userId); parameters.put("fail_url", "http://15.165.17.95/user/payment/fail"); parameters.put("cancel_url", "http://15.165.17.95/user/payment/cancel"); return restTemplateUtil.post(READY_URL, parameters, getHeaders(), PaymentDto.KakaoReadyResponse.class); } - public PaymentDto.KakaoApproveResponse approveResponse(String pgToken) { + public PaymentDto.KakaoApproveResponse approveResponse(String pgToken, Long userId) { + Payment payment = paymentRepository.getLatestKakaoPayInfo(userId) + .orElseThrow(() -> GeneralException.of(ErrorCode.TID_NOT_EXIST)); + String tid = payment.getTid(); + Map parameters = new HashMap<>(); parameters.put("cid", cid); - parameters.put("tid", kakaoReadyResponse.getTid()); + parameters.put("tid", tid); parameters.put("partner_order_id", "ORDER_ID"); parameters.put("partner_user_id", "USER_ID"); parameters.put("pg_token", pgToken); @@ -141,20 +144,20 @@ public PaymentDto.KakaoSubscribeCancelResponse subscribeCancelResponse(String si } public Payment getKakaoPayInfo(Long userId) { - Payment kakaoPay = paymentRepository.findByUser_Id(userId) + Payment kakaoPay = paymentRepository.getLatestKakaoPayInfo(userId) .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); return kakaoPay; } public boolean existKakaoPayLog(Long userId) { - return paymentRepository.existsByUser_Id(userId); + return paymentRepository.existsByUserId(userId); } public void saveTid(Long userId, String tid) { Payment kakaoPay; - if (paymentRepository.existsByUser_Id(userId)) { - kakaoPay = paymentRepository.findByUser_Id(userId) + if (paymentRepository.existsByUserId(userId)) { + kakaoPay = paymentRepository.getLatestKakaoPayInfo(userId) .orElseThrow(() -> new GeneralException(ErrorCode.TID_SID_UNSUPPORTED)); kakaoPay.updateTid(tid); } else { @@ -177,8 +180,8 @@ public void saveSid(PaymentDto.KakaoApproveResponse kakaoApproveResponse) { public void savePayInfo(Long userId, PaymentDto.KakaoApproveResponse kakaoApproveResponse) { Payment kakaoPay; - if (paymentRepository.existsByUser_Id(userId)) { - kakaoPay = paymentRepository.findByUser_Id(userId) + if (paymentRepository.existsByUserId(userId)) { + kakaoPay = paymentRepository.getLatestKakaoPayInfo(userId) .orElseThrow(() -> new GeneralException(ErrorCode.TID_SID_UNSUPPORTED)); kakaoPay.updatePayInfo(kakaoApproveResponse.getTid(), kakaoApproveResponse.getSid()); } else { @@ -191,7 +194,7 @@ public void savePayInfo(Long userId, PaymentDto.KakaoApproveResponse kakaoApprov } public void cancelPay(Long userId) { - Payment kakaoPay = paymentRepository.findByUser_Id(userId) + Payment kakaoPay = paymentRepository.getLatestKakaoPayInfo(userId) .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); paymentRepository.delete(kakaoPay); From b443bcf21df237cd8c2f48a8952b0a4629db9b9b Mon Sep 17 00:00:00 2001 From: persi Date: Thu, 26 Jun 2025 22:09:59 +0900 Subject: [PATCH 05/10] =?UTF-8?q?refactor:=20=EA=B2=B0=EC=A0=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=A0=A5=20=EA=B4=80=EB=A6=AC=20=EC=9C=84=ED=95=B4=20?= =?UTF-8?q?=EA=B1=B4=EB=8B=B9=20=EA=B2=B0=EC=A0=9C=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=EC=8B=9C=EB=A7=88=EB=8B=A4=20=EC=83=88=EB=A1=9C=EC=9A=B4=20?= =?UTF-8?q?=ED=8A=9C=ED=94=8C=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/controller/PaymentController.java | 4 +- .../payment/domain/Payment.java | 21 ++++++---- .../payment/service/PaymentService.java | 39 +++++++------------ 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java b/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java index 7ee0f07..86397fc 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java @@ -113,7 +113,7 @@ public ApiResponse subscribePayRequest( Payment kakaoPay = paymentService.getKakaoPayInfo(userId); PaymentDto.KakaoApproveResponse kakaoApproveResponse = paymentService.approveSubscribeResponse( - kakaoPay.getSid()); + kakaoPay.getSid(), userId); paymentService.savePayInfo(userId, kakaoApproveResponse); @@ -129,7 +129,7 @@ public ApiResponse subscribePayRequest( Payment kakaoPay = paymentService.getKakaoPayInfo(userId); PaymentDto.KakaoApproveResponse kakaoApproveResponse = paymentService.approveSubscribeResponse( - kakaoPay.getSid()); + kakaoPay.getSid(), userId); paymentService.savePayInfo(userId, kakaoApproveResponse); diff --git a/src/main/java/com/example/silverbridgeX_user/payment/domain/Payment.java b/src/main/java/com/example/silverbridgeX_user/payment/domain/Payment.java index d5c231d..1ee58e1 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/domain/Payment.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/domain/Payment.java @@ -2,8 +2,18 @@ import com.example.silverbridgeX_user.global.entity.BaseEntity; import com.example.silverbridgeX_user.user.domain.User; -import jakarta.persistence.*; -import lombok.*; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Entity @Getter @@ -23,12 +33,7 @@ public class Payment extends BaseEntity { @JoinColumn(name = "user_id") private User user; - public void updateTid(String tid) { this.tid = tid; } - - public void updateSid(String sid) { this.sid = sid; } - - public void updatePayInfo(String tid, String sid) { - this.tid = tid; + public void updateSid(String sid) { this.sid = sid; } } diff --git a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java index 1a7dda1..e8e4ef8 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java @@ -55,7 +55,7 @@ public PaymentDto.KakaoReadyResponse kakaoPayReady(Long userId) { Map parameters = new HashMap<>(); parameters.put("cid", cid); parameters.put("partner_order_id", "ORDER_ID"); - parameters.put("partner_user_id", "USER_ID"); + parameters.put("partner_user_id", String.valueOf(userId)); parameters.put("item_name", "은빛동행 구독"); parameters.put("quantity", "1"); parameters.put("total_amount", "9900"); @@ -98,7 +98,7 @@ public PaymentDto.KakaoCancelResponse cancelResponse(String tid) { return restTemplateUtil.post(CANCEL_URL, parameters, getHeaders(), PaymentDto.KakaoCancelResponse.class); } - public PaymentDto.KakaoApproveResponse approveSubscribeResponse(String sid) { + public PaymentDto.KakaoApproveResponse approveSubscribeResponse(String sid, Long userId) { if (sid == null || sid.isEmpty()) { throw new GeneralException(ErrorCode.SID_NOT_EXIST); } @@ -107,7 +107,7 @@ public PaymentDto.KakaoApproveResponse approveSubscribeResponse(String sid) { parameters.put("cid", cid); parameters.put("sid", sid); parameters.put("partner_order_id", "ORDER_ID"); - parameters.put("partner_user_id", "USER_ID"); + parameters.put("partner_user_id", String.valueOf(userId)); parameters.put("item_name", "BodyCheck 구독"); parameters.put("quantity", "1"); parameters.put("total_amount", "4900"); @@ -155,16 +155,11 @@ public boolean existKakaoPayLog(Long userId) { } public void saveTid(Long userId, String tid) { - Payment kakaoPay; - if (paymentRepository.existsByUserId(userId)) { - kakaoPay = paymentRepository.getLatestKakaoPayInfo(userId) - .orElseThrow(() -> new GeneralException(ErrorCode.TID_SID_UNSUPPORTED)); - kakaoPay.updateTid(tid); - } else { - User user = userRepository.findById(userId) - .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); - kakaoPay = PaymentConverter.toKakaoPayTid(tid, user); - } + User user = userRepository.findById(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); + + Payment kakaoPay = PaymentConverter.toKakaoPayTid(tid, user); + paymentRepository.save(kakaoPay); } @@ -179,17 +174,11 @@ public void saveSid(PaymentDto.KakaoApproveResponse kakaoApproveResponse) { } public void savePayInfo(Long userId, PaymentDto.KakaoApproveResponse kakaoApproveResponse) { - Payment kakaoPay; - if (paymentRepository.existsByUserId(userId)) { - kakaoPay = paymentRepository.getLatestKakaoPayInfo(userId) - .orElseThrow(() -> new GeneralException(ErrorCode.TID_SID_UNSUPPORTED)); - kakaoPay.updatePayInfo(kakaoApproveResponse.getTid(), kakaoApproveResponse.getSid()); - } else { - User member = userRepository.findById(userId) - .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); - kakaoPay = PaymentConverter.toKakaoPay(kakaoApproveResponse.getTid(), kakaoApproveResponse.getSid(), - member); - } + User member = userRepository.findById(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); + Payment kakaoPay = PaymentConverter.toKakaoPay(kakaoApproveResponse.getTid(), kakaoApproveResponse.getSid(), + member); + paymentRepository.save(kakaoPay); } @@ -228,7 +217,7 @@ public void regularPayment() { || today.getMonthValue() != lastApprovedAt.getMonthValue())) { PaymentDto.KakaoApproveResponse approveResponse = approveSubscribeResponse( - kakaoPay.getSid()); + kakaoPay.getSid(), kakaoPay.getUser().getId()); savePayInfo(kakaoPay.getUser().getId(), approveResponse); } From 5a4de22846c7bbcadbd019a5161dba17090adceb Mon Sep 17 00:00:00 2001 From: persi Date: Thu, 26 Jun 2025 23:03:02 +0900 Subject: [PATCH 06/10] =?UTF-8?q?refactor:=20=EC=A0=95=EA=B8=B0=20?= =?UTF-8?q?=EA=B2=B0=EC=A0=9C=20=EC=83=81=ED=83=9C=EB=A5=BC=20=EC=B9=B4?= =?UTF-8?q?=EC=B9=B4=EC=98=A4=20=EC=84=9C=EB=B2=84=20=EB=8C=80=EC=8B=A0=20?= =?UTF-8?q?DB=EC=97=90=EC=84=9C=20=EC=A7=81=EC=A0=91=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/controller/PaymentController.java | 8 +- .../payment/service/PaymentService.java | 84 +++++++++++++------ .../user/converter/UserConverter.java | 1 + .../silverbridgeX_user/user/domain/User.java | 14 ++++ 4 files changed, 76 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java b/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java index 86397fc..2e121ad 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/controller/PaymentController.java @@ -143,10 +143,8 @@ public ApiResponse subscribeCancelReque ) { Long userId = userService.findByUserName(customUserDetails.getUsername()).getId(); - Payment kakaoPay = paymentService.getKakaoPayInfo(userId); - PaymentDto.KakaoSubscribeCancelResponse kakaoSubscribeCancelResponse = paymentService.subscribeCancelResponse( - kakaoPay.getSid()); + userId); return ApiResponse.onSuccess(SuccessCode.PAYMENT_URL_CREATE_SUCCESS, kakaoSubscribeCancelResponse); } @@ -158,10 +156,8 @@ public ApiResponse subscribeCancelReque ) { Long userId = userService.findByUserName(key).getId(); - Payment kakaoPay = paymentService.getKakaoPayInfo(userId); - PaymentDto.KakaoSubscribeCancelResponse kakaoSubscribeCancelResponse = paymentService.subscribeCancelResponse( - kakaoPay.getSid()); + userId); return ApiResponse.onSuccess(SuccessCode.PAYMENT_URL_CREATE_SUCCESS, kakaoSubscribeCancelResponse); } diff --git a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java index e8e4ef8..0f5cc8a 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java @@ -114,10 +114,22 @@ public PaymentDto.KakaoApproveResponse approveSubscribeResponse(String sid, Long parameters.put("vat_amount", "200"); parameters.put("tax_free_amount", "0"); - return restTemplateUtil.post(SUBSCRIBE_URL, parameters, getHeaders(), PaymentDto.KakaoApproveResponse.class); + PaymentDto.KakaoApproveResponse response = restTemplateUtil.post(SUBSCRIBE_URL, parameters, getHeaders(), + PaymentDto.KakaoApproveResponse.class); + + User user = userRepository.findById(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); + user.enableSubscription(); + + return response; } - public PaymentDto.KakaoSubscribeStatusResponse subscribeStatusResponse(String sid) { + @Transactional + public PaymentDto.KakaoSubscribeCancelResponse subscribeCancelResponse(Long userId) { + Payment kakaoPay = paymentRepository.getLatestKakaoPayInfo(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); + + String sid = kakaoPay.getSid(); if (sid == null || sid.isEmpty()) { throw new GeneralException(ErrorCode.SID_NOT_EXIST); } @@ -126,11 +138,18 @@ public PaymentDto.KakaoSubscribeStatusResponse subscribeStatusResponse(String si parameters.put("cid", cid); parameters.put("sid", sid); - return restTemplateUtil.post(SUBSCRIBE_STATUS_URL, parameters, getHeaders(), - PaymentDto.KakaoSubscribeStatusResponse.class); + PaymentDto.KakaoSubscribeCancelResponse response = restTemplateUtil.post(SUBSCRIBE_CANCEL_URL, parameters, + getHeaders(), + PaymentDto.KakaoSubscribeCancelResponse.class); + + User user = userRepository.findById(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); + user.disableSubscription(); + + return response; } - public PaymentDto.KakaoSubscribeCancelResponse subscribeCancelResponse(String sid) { + public PaymentDto.KakaoSubscribeStatusResponse subscribeStatusResponse(String sid) { if (sid == null || sid.isEmpty()) { throw new GeneralException(ErrorCode.SID_NOT_EXIST); } @@ -139,10 +158,11 @@ public PaymentDto.KakaoSubscribeCancelResponse subscribeCancelResponse(String si parameters.put("cid", cid); parameters.put("sid", sid); - return restTemplateUtil.post(SUBSCRIBE_CANCEL_URL, parameters, getHeaders(), - PaymentDto.KakaoSubscribeCancelResponse.class); + return restTemplateUtil.post(SUBSCRIBE_STATUS_URL, parameters, getHeaders(), + PaymentDto.KakaoSubscribeStatusResponse.class); } + public Payment getKakaoPayInfo(Long userId) { Payment kakaoPay = paymentRepository.getLatestKakaoPayInfo(userId) .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); @@ -154,6 +174,7 @@ public boolean existKakaoPayLog(Long userId) { return paymentRepository.existsByUserId(userId); } + @Transactional public void saveTid(Long userId, String tid) { User user = userRepository.findById(userId) .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); @@ -163,6 +184,7 @@ public void saveTid(Long userId, String tid) { paymentRepository.save(kakaoPay); } + @Transactional public void saveSid(PaymentDto.KakaoApproveResponse kakaoApproveResponse) { Payment kakaoPay = paymentRepository.findByTid(kakaoApproveResponse.getTid()) @@ -173,6 +195,7 @@ public void saveSid(PaymentDto.KakaoApproveResponse kakaoApproveResponse) { paymentRepository.save(kakaoPay); } + @Transactional public void savePayInfo(Long userId, PaymentDto.KakaoApproveResponse kakaoApproveResponse) { User member = userRepository.findById(userId) .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); @@ -182,6 +205,7 @@ public void savePayInfo(Long userId, PaymentDto.KakaoApproveResponse kakaoApprov paymentRepository.save(kakaoPay); } + @Transactional public void cancelPay(Long userId) { Payment kakaoPay = paymentRepository.getLatestKakaoPayInfo(userId) .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); @@ -189,6 +213,26 @@ public void cancelPay(Long userId) { paymentRepository.delete(kakaoPay); } + public PaymentDto.KakaoPayStatus getSubscribeStatus(Long userId) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); + + if (!user.isSubscribeActive()) { + return PaymentConverter.toKakaoPayStatus(false, new PaymentDto.KakaoSubscribeStatusResponse()); + } + + Payment kakaoPay = getKakaoPayInfo(userId); + + if (kakaoPay.getSid() != null && !kakaoPay.getSid().isEmpty()) { + PaymentDto.KakaoSubscribeStatusResponse kakaoSubscribeStatusResponse = subscribeStatusResponse( + kakaoPay.getSid()); + return PaymentConverter.toKakaoPayStatus(true, kakaoSubscribeStatusResponse); + } + + return PaymentConverter.toKakaoPayStatus(false, new PaymentDto.KakaoSubscribeStatusResponse()); + } + + @Transactional public void regularPayment() { List kakaoPayList = paymentRepository.findAllWithMemberAndSidNotNull(); @@ -198,20 +242,25 @@ public void regularPayment() { PaymentDto.KakaoSubscribeStatusResponse kakaoSubscribeStatusResponse = subscribeStatusResponse( kakaoPay.getSid()); - // "ACTIVE" 상태인지 확인 + // 사용자가 카카오 결제 내역 화면에서 직접 해지 요청을 한 경우, db에 대항 상황이 반영x + // -> 결제 상태를 우리 DB에도 반영 + if (kakaoSubscribeStatusResponse.getStatus().equals("INACTIVE")) { + kakaoPay.getUser().disableSubscription(); + return; // 결제 해지된 유저는 패스 + } + if (kakaoSubscribeStatusResponse.getStatus().equals("ACTIVE")) { String lastApprovedAtStr = kakaoSubscribeStatusResponse.getLast_approved_at(); if (lastApprovedAtStr == null || lastApprovedAtStr.isEmpty()) { lastApprovedAtStr = kakaoSubscribeStatusResponse.getCreated_at(); } - // last_approved_at을 LocalDate로 변환 DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME; LocalDate lastApprovedAt = LocalDate.parse(lastApprovedAtStr, formatter); LocalDate today = LocalDate.now(); - // 결제일과 오늘의 일(day)이 같고, 마지막 결제일이 이번 달이 아닌 경우에만 결제 수행 + // 결제일 + 새로운 달이 되었을 때 결제 요청 if (today.getDayOfMonth() == lastApprovedAt.getDayOfMonth() && (today.getYear() != lastApprovedAt.getYear() || today.getMonthValue() != lastApprovedAt.getMonthValue())) { @@ -226,20 +275,5 @@ public void regularPayment() { }); } - public PaymentDto.KakaoPayStatus getSubscribeStatus(Long userId) { - boolean isLogExist = false; - PaymentDto.KakaoSubscribeStatusResponse kakaoSubscribeStatusResponse = new PaymentDto.KakaoSubscribeStatusResponse(); - - if (existKakaoPayLog(userId)) { - Payment kakaoPay = getKakaoPayInfo(userId); - - if (kakaoPay.getSid() != null && !kakaoPay.getSid().isEmpty()) { - isLogExist = true; - kakaoSubscribeStatusResponse = subscribeStatusResponse(kakaoPay.getSid()); - } - } - - return PaymentConverter.toKakaoPayStatus(isLogExist, kakaoSubscribeStatusResponse); - } } diff --git a/src/main/java/com/example/silverbridgeX_user/user/converter/UserConverter.java b/src/main/java/com/example/silverbridgeX_user/user/converter/UserConverter.java index cd1aab4..defc0da 100644 --- a/src/main/java/com/example/silverbridgeX_user/user/converter/UserConverter.java +++ b/src/main/java/com/example/silverbridgeX_user/user/converter/UserConverter.java @@ -18,6 +18,7 @@ public static User saveUser(UserRequestDto.UserSigInReqDto userReqDto, String ke .username(key) .nickname(userReqDto.getNickname()) .streetAddress(userReqDto.getStreetAddress()) + .isSubscribed(false) .build(); } diff --git a/src/main/java/com/example/silverbridgeX_user/user/domain/User.java b/src/main/java/com/example/silverbridgeX_user/user/domain/User.java index 37c5aac..b210b55 100644 --- a/src/main/java/com/example/silverbridgeX_user/user/domain/User.java +++ b/src/main/java/com/example/silverbridgeX_user/user/domain/User.java @@ -58,6 +58,8 @@ public class User extends BaseEntity { @OneToMany(mappedBy = "guardian", cascade = CascadeType.ALL) private List olders = new ArrayList<>(); + private Boolean isSubscribed; + private String sex; private LocalDate birth; @@ -117,6 +119,18 @@ public void updateCoordinate(String longitude, String latitude) { public void updateGuardian(User guardian) { this.guardian = guardian; // null 가능 } + + public Boolean isSubscribeActive() { + return isSubscribed; + } + + public void enableSubscription() { + this.isSubscribed = true; + } + + public void disableSubscription() { + this.isSubscribed = false; + } } From 1d91f4a122988cf2b88a8c2d94a3e2afaf33ebc1 Mon Sep 17 00:00:00 2001 From: persi Date: Thu, 26 Jun 2025 23:16:45 +0900 Subject: [PATCH 07/10] =?UTF-8?q?refactor:=20=EC=83=81=ED=99=A9=EC=97=90?= =?UTF-8?q?=20=EB=A7=9E=EB=8A=94=20@Transactional=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../silverbridgeX_user/payment/service/PaymentService.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java index 0f5cc8a..53e6cc6 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java @@ -22,7 +22,6 @@ @Service @RequiredArgsConstructor -@Transactional public class PaymentService { private final PaymentRepository paymentRepository; @@ -68,6 +67,7 @@ public PaymentDto.KakaoReadyResponse kakaoPayReady(Long userId) { return restTemplateUtil.post(READY_URL, parameters, getHeaders(), PaymentDto.KakaoReadyResponse.class); } + @Transactional(readOnly = true) public PaymentDto.KakaoApproveResponse approveResponse(String pgToken, Long userId) { Payment payment = paymentRepository.getLatestKakaoPayInfo(userId) .orElseThrow(() -> GeneralException.of(ErrorCode.TID_NOT_EXIST)); @@ -98,6 +98,7 @@ public PaymentDto.KakaoCancelResponse cancelResponse(String tid) { return restTemplateUtil.post(CANCEL_URL, parameters, getHeaders(), PaymentDto.KakaoCancelResponse.class); } + @Transactional public PaymentDto.KakaoApproveResponse approveSubscribeResponse(String sid, Long userId) { if (sid == null || sid.isEmpty()) { throw new GeneralException(ErrorCode.SID_NOT_EXIST); @@ -162,7 +163,7 @@ public PaymentDto.KakaoSubscribeStatusResponse subscribeStatusResponse(String si PaymentDto.KakaoSubscribeStatusResponse.class); } - + @Transactional(readOnly = true) public Payment getKakaoPayInfo(Long userId) { Payment kakaoPay = paymentRepository.getLatestKakaoPayInfo(userId) .orElseThrow(() -> new GeneralException(ErrorCode.TID_NOT_EXIST)); @@ -213,6 +214,7 @@ public void cancelPay(Long userId) { paymentRepository.delete(kakaoPay); } + @Transactional(readOnly = true) public PaymentDto.KakaoPayStatus getSubscribeStatus(Long userId) { User user = userRepository.findById(userId) .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); From f010d703872bccd7e5b16333f8feabd1d520ec00 Mon Sep 17 00:00:00 2001 From: persi Date: Thu, 26 Jun 2025 23:21:03 +0900 Subject: [PATCH 08/10] =?UTF-8?q?feature:=20=EA=B2=B0=EC=A0=9C=20TID=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EC=A0=80=EC=9E=A5=20=EB=B0=A9=EC=A7=80=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../silverbridgeX_user/global/api_payload/ErrorCode.java | 1 + .../payment/repository/PaymentRepository.java | 2 ++ .../silverbridgeX_user/payment/service/PaymentService.java | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/src/main/java/com/example/silverbridgeX_user/global/api_payload/ErrorCode.java b/src/main/java/com/example/silverbridgeX_user/global/api_payload/ErrorCode.java index 70f7b7a..defa5df 100644 --- a/src/main/java/com/example/silverbridgeX_user/global/api_payload/ErrorCode.java +++ b/src/main/java/com/example/silverbridgeX_user/global/api_payload/ErrorCode.java @@ -37,6 +37,7 @@ public enum ErrorCode implements BaseCode { TID_NOT_EXIST(HttpStatus.BAD_REQUEST, "PAYMENT_4001", "tid가 존재하지 않습니다."), TID_SID_UNSUPPORTED(HttpStatus.BAD_REQUEST, "PAYMENT_4002", "지원되지 않는 tid, sid 입니다."), SID_NOT_EXIST(HttpStatus.BAD_REQUEST, "PAYMENT_4003", "sid가 존재하지 않습니다."), + TID_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "PAYMENT_4004", "tid가 이미 존재합니다."), // Match MATCH_NOT_EXIST(HttpStatus.BAD_REQUEST, "MATCH_4001", "매치 신청 정보가 존재하지 않습니다."), diff --git a/src/main/java/com/example/silverbridgeX_user/payment/repository/PaymentRepository.java b/src/main/java/com/example/silverbridgeX_user/payment/repository/PaymentRepository.java index e12001d..623f422 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/repository/PaymentRepository.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/repository/PaymentRepository.java @@ -13,6 +13,8 @@ public interface PaymentRepository extends JpaRepository { Optional findByTid(String tid); + boolean existsByTid(String tid); + @Query("SELECT k FROM Payment k JOIN FETCH k.user WHERE k.sid IS NOT NULL") List findAllWithMemberAndSidNotNull(); diff --git a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java index 53e6cc6..891c904 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java @@ -177,6 +177,10 @@ public boolean existKakaoPayLog(Long userId) { @Transactional public void saveTid(Long userId, String tid) { + if (paymentRepository.existsByTid(tid)) { + throw new GeneralException(ErrorCode.TID_ALREADY_EXIST); + } + User user = userRepository.findById(userId) .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); From a3368acb46f4b10eed01a7b644fc35caaa7e4fd2 Mon Sep 17 00:00:00 2001 From: persi Date: Thu, 26 Jun 2025 23:21:39 +0900 Subject: [PATCH 09/10] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../silverbridgeX_user/payment/service/PaymentService.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java index 891c904..e034960 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java @@ -171,10 +171,6 @@ public Payment getKakaoPayInfo(Long userId) { return kakaoPay; } - public boolean existKakaoPayLog(Long userId) { - return paymentRepository.existsByUserId(userId); - } - @Transactional public void saveTid(Long userId, String tid) { if (paymentRepository.existsByTid(tid)) { From a3d4b22d53e6713a0e79e0568a5a6fca9533336c Mon Sep 17 00:00:00 2001 From: persi Date: Thu, 26 Jun 2025 23:41:53 +0900 Subject: [PATCH 10/10] =?UTF-8?q?feature:=20=EC=99=B8=EB=B6=80=20API=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/api_payload/ErrorCode.java | 3 ++ .../payment/service/PaymentService.java | 46 +++++++++++++++---- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/example/silverbridgeX_user/global/api_payload/ErrorCode.java b/src/main/java/com/example/silverbridgeX_user/global/api_payload/ErrorCode.java index defa5df..625660e 100644 --- a/src/main/java/com/example/silverbridgeX_user/global/api_payload/ErrorCode.java +++ b/src/main/java/com/example/silverbridgeX_user/global/api_payload/ErrorCode.java @@ -11,6 +11,8 @@ public enum ErrorCode implements BaseCode { // Common BAD_REQUEST(HttpStatus.BAD_REQUEST, "COMMON_400", "잘못된 요청입니다."), INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "COMMON_500", "서버 에러, 서버 개발자에게 문의하세요."), + EXTERNAL_API_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "PAYMENT_5001", "외부 API 호출 중 오류가 발생했습니다."), + // User USER_NOT_FOUND(HttpStatus.NOT_FOUND, "USER_4041", "존재하지 않는 회원입니다."), @@ -38,6 +40,7 @@ public enum ErrorCode implements BaseCode { TID_SID_UNSUPPORTED(HttpStatus.BAD_REQUEST, "PAYMENT_4002", "지원되지 않는 tid, sid 입니다."), SID_NOT_EXIST(HttpStatus.BAD_REQUEST, "PAYMENT_4003", "sid가 존재하지 않습니다."), TID_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "PAYMENT_4004", "tid가 이미 존재합니다."), + PAYMENT_FAILED(HttpStatus.BAD_REQUEST, "PAYMENT_4005", "결제에 실패하였습니다."), // Match MATCH_NOT_EXIST(HttpStatus.BAD_REQUEST, "MATCH_4001", "매치 신청 정보가 존재하지 않습니다."), diff --git a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java index e034960..2eefb86 100644 --- a/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java +++ b/src/main/java/com/example/silverbridgeX_user/payment/service/PaymentService.java @@ -64,7 +64,11 @@ public PaymentDto.KakaoReadyResponse kakaoPayReady(Long userId) { parameters.put("fail_url", "http://15.165.17.95/user/payment/fail"); parameters.put("cancel_url", "http://15.165.17.95/user/payment/cancel"); - return restTemplateUtil.post(READY_URL, parameters, getHeaders(), PaymentDto.KakaoReadyResponse.class); + try { + return restTemplateUtil.post(READY_URL, parameters, getHeaders(), PaymentDto.KakaoReadyResponse.class); + } catch (Exception e) { + throw new GeneralException(ErrorCode.EXTERNAL_API_ERROR); + } } @Transactional(readOnly = true) @@ -80,7 +84,11 @@ public PaymentDto.KakaoApproveResponse approveResponse(String pgToken, Long user parameters.put("partner_user_id", "USER_ID"); parameters.put("pg_token", pgToken); - return restTemplateUtil.post(APPROVE_URL, parameters, getHeaders(), PaymentDto.KakaoApproveResponse.class); + try { + return restTemplateUtil.post(APPROVE_URL, parameters, getHeaders(), PaymentDto.KakaoApproveResponse.class); + } catch (Exception e) { + throw new GeneralException(ErrorCode.PAYMENT_FAILED); + } } public PaymentDto.KakaoCancelResponse cancelResponse(String tid) { @@ -95,7 +103,11 @@ public PaymentDto.KakaoCancelResponse cancelResponse(String tid) { parameters.put("cancel_tax_free_amount", "0"); parameters.put("cancel_vat_amount", "0"); - return restTemplateUtil.post(CANCEL_URL, parameters, getHeaders(), PaymentDto.KakaoCancelResponse.class); + try { + return restTemplateUtil.post(CANCEL_URL, parameters, getHeaders(), PaymentDto.KakaoCancelResponse.class); + } catch (Exception e) { + throw new GeneralException(ErrorCode.PAYMENT_FAILED); + } } @Transactional @@ -115,8 +127,13 @@ public PaymentDto.KakaoApproveResponse approveSubscribeResponse(String sid, Long parameters.put("vat_amount", "200"); parameters.put("tax_free_amount", "0"); - PaymentDto.KakaoApproveResponse response = restTemplateUtil.post(SUBSCRIBE_URL, parameters, getHeaders(), - PaymentDto.KakaoApproveResponse.class); + PaymentDto.KakaoApproveResponse response; + try { + response = restTemplateUtil.post(SUBSCRIBE_URL, parameters, getHeaders(), + PaymentDto.KakaoApproveResponse.class); + } catch (Exception e) { + throw new GeneralException(ErrorCode.PAYMENT_FAILED); + } User user = userRepository.findById(userId) .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); @@ -139,9 +156,14 @@ public PaymentDto.KakaoSubscribeCancelResponse subscribeCancelResponse(Long user parameters.put("cid", cid); parameters.put("sid", sid); - PaymentDto.KakaoSubscribeCancelResponse response = restTemplateUtil.post(SUBSCRIBE_CANCEL_URL, parameters, - getHeaders(), - PaymentDto.KakaoSubscribeCancelResponse.class); + PaymentDto.KakaoSubscribeCancelResponse response; + try { + response = restTemplateUtil.post(SUBSCRIBE_CANCEL_URL, parameters, + getHeaders(), + PaymentDto.KakaoSubscribeCancelResponse.class); + } catch (Exception e) { + throw new GeneralException(ErrorCode.EXTERNAL_API_ERROR); + } User user = userRepository.findById(userId) .orElseThrow(() -> new GeneralException(ErrorCode.USER_NOT_FOUND)); @@ -159,8 +181,12 @@ public PaymentDto.KakaoSubscribeStatusResponse subscribeStatusResponse(String si parameters.put("cid", cid); parameters.put("sid", sid); - return restTemplateUtil.post(SUBSCRIBE_STATUS_URL, parameters, getHeaders(), - PaymentDto.KakaoSubscribeStatusResponse.class); + try { + return restTemplateUtil.post(SUBSCRIBE_STATUS_URL, parameters, getHeaders(), + PaymentDto.KakaoSubscribeStatusResponse.class); + } catch (Exception e) { + throw new GeneralException(ErrorCode.EXTERNAL_API_ERROR); + } } @Transactional(readOnly = true)