From 6973c9998d4468f66c7ec57daf12598d0d5ad670 Mon Sep 17 00:00:00 2001 From: binarywoo27 Date: Fri, 12 Jan 2024 21:16:17 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feature:=20=EA=B2=B0=EC=A0=9C=20=EC=B7=A8?= =?UTF-8?q?=EC=86=8C(=EB=B0=B0=EC=86=A1=EC=A3=BC=EB=AC=B8)=20API=20?= =?UTF-8?q?=EB=B0=8F=20Test=20Code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OrderClientController.java | 7 ++ .../dto/request/KakaopayCancelRequestDto.java | 15 +++ .../dto/response/ApprovedCancelAmount.java | 17 ++++ .../dto/response/CancelAvailableAmount.java | 14 +++ .../payment/dto/response/CanceledAmount.java | 14 +++ .../response/KakaopayCancelResponseDto.java | 25 +++++ .../bb/payment/service/KakaopayService.java | 20 ++++ .../kr/bb/payment/service/PaymentService.java | 5 + .../payment/service/KakaopayCancelTest.java | 94 +++++++++++++++++++ .../bb/payment/service/KakaopayReadyTest.java | 51 +++++++++- 10 files changed, 257 insertions(+), 5 deletions(-) create mode 100644 src/main/java/kr/bb/payment/dto/request/KakaopayCancelRequestDto.java create mode 100644 src/main/java/kr/bb/payment/dto/response/ApprovedCancelAmount.java create mode 100644 src/main/java/kr/bb/payment/dto/response/CancelAvailableAmount.java create mode 100644 src/main/java/kr/bb/payment/dto/response/CanceledAmount.java create mode 100644 src/main/java/kr/bb/payment/dto/response/KakaopayCancelResponseDto.java create mode 100644 src/test/java/kr/bb/payment/service/KakaopayCancelTest.java diff --git a/src/main/java/kr/bb/payment/controller/clientcontroller/OrderClientController.java b/src/main/java/kr/bb/payment/controller/clientcontroller/OrderClientController.java index 9406b38..447ae7c 100644 --- a/src/main/java/kr/bb/payment/controller/clientcontroller/OrderClientController.java +++ b/src/main/java/kr/bb/payment/controller/clientcontroller/OrderClientController.java @@ -7,6 +7,7 @@ import bloomingblooms.response.CommonResponse; import java.time.LocalDateTime; import java.util.List; +import kr.bb.payment.dto.request.KakaopayCancelRequestDto; import kr.bb.payment.service.KakaopayService; import kr.bb.payment.service.PaymentService; import lombok.RequiredArgsConstructor; @@ -47,4 +48,10 @@ CommonResponse> getPaymentInfo(@RequestBody List or CommonResponse getPaymentDate(@RequestParam String orderGroupId){ return CommonResponse.success(paymentService.getPaymentDate(orderGroupId)); } + + @PostMapping(value = "/cancel") + CommonResponse cancel(@RequestBody KakaopayCancelRequestDto cancelRequestDto){ + kakaopayService.cancelPayment(cancelRequestDto); + return CommonResponse.success(null); + } } diff --git a/src/main/java/kr/bb/payment/dto/request/KakaopayCancelRequestDto.java b/src/main/java/kr/bb/payment/dto/request/KakaopayCancelRequestDto.java new file mode 100644 index 0000000..63418eb --- /dev/null +++ b/src/main/java/kr/bb/payment/dto/request/KakaopayCancelRequestDto.java @@ -0,0 +1,15 @@ +package kr.bb.payment.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class KakaopayCancelRequestDto { + private String orderId; + private Long cancelAmount; +} diff --git a/src/main/java/kr/bb/payment/dto/response/ApprovedCancelAmount.java b/src/main/java/kr/bb/payment/dto/response/ApprovedCancelAmount.java new file mode 100644 index 0000000..87528cd --- /dev/null +++ b/src/main/java/kr/bb/payment/dto/response/ApprovedCancelAmount.java @@ -0,0 +1,17 @@ +package kr.bb.payment.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ApprovedCancelAmount { // 이번 요청으로 취소된 금액 + private Integer total; + private Integer tax_free; + private Integer vat; + private Integer point; +} diff --git a/src/main/java/kr/bb/payment/dto/response/CancelAvailableAmount.java b/src/main/java/kr/bb/payment/dto/response/CancelAvailableAmount.java new file mode 100644 index 0000000..fce208e --- /dev/null +++ b/src/main/java/kr/bb/payment/dto/response/CancelAvailableAmount.java @@ -0,0 +1,14 @@ +package kr.bb.payment.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CancelAvailableAmount { // 남은 취소 가능 금액 + private Integer total; +} diff --git a/src/main/java/kr/bb/payment/dto/response/CanceledAmount.java b/src/main/java/kr/bb/payment/dto/response/CanceledAmount.java new file mode 100644 index 0000000..eb443cc --- /dev/null +++ b/src/main/java/kr/bb/payment/dto/response/CanceledAmount.java @@ -0,0 +1,14 @@ +package kr.bb.payment.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CanceledAmount { // 누계 취소된 금액 + private Integer total; +} diff --git a/src/main/java/kr/bb/payment/dto/response/KakaopayCancelResponseDto.java b/src/main/java/kr/bb/payment/dto/response/KakaopayCancelResponseDto.java new file mode 100644 index 0000000..d4fb8a8 --- /dev/null +++ b/src/main/java/kr/bb/payment/dto/response/KakaopayCancelResponseDto.java @@ -0,0 +1,25 @@ +package kr.bb.payment.dto.response; + +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class KakaopayCancelResponseDto { + private String cid; + private String status; + private String partner_order_id; + private String partner_user_id; + private ApprovedCancelAmount approved_cancel_amount; // 금번 취소 금액 + private CanceledAmount canceled_amount; // 누적 취소 금액 + private CancelAvailableAmount cancel_available_amount; + private LocalDateTime created_at; + private LocalDateTime canceled_at; +} diff --git a/src/main/java/kr/bb/payment/service/KakaopayService.java b/src/main/java/kr/bb/payment/service/KakaopayService.java index c83a8a1..e243fdf 100644 --- a/src/main/java/kr/bb/payment/service/KakaopayService.java +++ b/src/main/java/kr/bb/payment/service/KakaopayService.java @@ -11,7 +11,10 @@ import java.util.List; import java.util.Map; import javax.validation.constraints.NotNull; +import kr.bb.payment.dto.request.KakaopayCancelRequestDto; import kr.bb.payment.dto.response.KakaopayApproveResponseDto; +import kr.bb.payment.dto.response.KakaopayCancelResponseDto; +import kr.bb.payment.entity.Payment; import kr.bb.payment.feign.DeliveryServiceClient; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; @@ -119,6 +122,23 @@ public void renewSubscription(SubscriptionBatchDtoList subscriptionBatchDtoList) } + public void cancelPayment(KakaopayCancelRequestDto cancelRequestDto){ + Payment paymentEntity = paymentService.getPaymentEntity(cancelRequestDto.getOrderId()); + + MultiValueMap parameters = new LinkedMultiValueMap<>(); + + parameters.add("cid", paymentEntity.getPaymentCid()); + parameters.add("tid", paymentEntity.getPaymentTid()); + parameters.add("cancel_amount", String.valueOf(cancelRequestDto.getCancelAmount())); + parameters.add("cancel_tax_free_amount", String.valueOf(0L)); + + HttpEntity> requestEntity = new HttpEntity<>(parameters, this.getHeaders()); + + String url = "https://kapi.kakao.com/v1/payment/cancel"; + + restTemplate.postForObject(url, requestEntity, KakaopayCancelResponseDto.class); + } + @NotNull private HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); diff --git a/src/main/java/kr/bb/payment/service/PaymentService.java b/src/main/java/kr/bb/payment/service/PaymentService.java index 4a4bf6c..9f248e0 100644 --- a/src/main/java/kr/bb/payment/service/PaymentService.java +++ b/src/main/java/kr/bb/payment/service/PaymentService.java @@ -104,4 +104,9 @@ public String getPaymentDate(String orderGroupId){ } return ""; } + + @Transactional(readOnly = true) + public Payment getPaymentEntity(String orderGroupId){ + return paymentRepository.findByOrderId(orderGroupId); + } } diff --git a/src/test/java/kr/bb/payment/service/KakaopayCancelTest.java b/src/test/java/kr/bb/payment/service/KakaopayCancelTest.java new file mode 100644 index 0000000..92a8357 --- /dev/null +++ b/src/test/java/kr/bb/payment/service/KakaopayCancelTest.java @@ -0,0 +1,94 @@ +package kr.bb.payment.service; + +import bloomingblooms.domain.notification.order.OrderType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import java.time.LocalDateTime; +import kr.bb.payment.dto.request.KakaopayCancelRequestDto; +import kr.bb.payment.dto.response.ApprovedCancelAmount; +import kr.bb.payment.dto.response.CancelAvailableAmount; +import kr.bb.payment.dto.response.CanceledAmount; +import kr.bb.payment.dto.response.KakaopayCancelResponseDto; +import kr.bb.payment.entity.Payment; +import kr.bb.payment.entity.PaymentStatus; +import kr.bb.payment.repository.PaymentRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.test.web.client.match.MockRestRequestMatchers; +import org.springframework.test.web.client.response.MockRestResponseCreators; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.client.RestTemplate; + +@SpringBootTest +@Transactional +public class KakaopayCancelTest { + @Autowired private RestTemplate restTemplate; + @Autowired private KakaopayService kakaopayService; + @Autowired private PaymentRepository paymentRepository; + private MockRestServiceServer mockServer; + + @BeforeEach + void setUp() throws Exception { + mockServer = MockRestServiceServer.createServer(restTemplate); + + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + String responseJson = objectMapper.writeValueAsString(kakaopayCancelResponseDto()); + + mockServer + .expect(MockRestRequestMatchers.requestTo("https://kapi.kakao.com/v1/payment/cancel")) + .andExpect(MockRestRequestMatchers.method(HttpMethod.POST)) + .andRespond(MockRestResponseCreators.withSuccess(responseJson, MediaType.APPLICATION_JSON)); + } + + @Test + @DisplayName("카카오 결제 취소 테스트") + void cancelPay() { + // given + KakaopayCancelRequestDto cancelRequestDto = + KakaopayCancelRequestDto.builder().cancelAmount(2000L).orderId("orderGroupId").build(); + + Payment payment = Payment.builder() + .orderId("orderGroupId") + .orderType(OrderType.DELIVERY) + .paymentActualAmount(10000L) + .paymentCid("TC0ONETIME") + .paymentStatus(PaymentStatus.PENDING) + .paymentTid("T59eb9072dff7a6a6515") + .paymentType("MONEY") + .userId(1L) + .build(); + paymentRepository.save(payment); + + // when + kakaopayService.cancelPayment(cancelRequestDto); + + mockServer.verify(); + } + + private KakaopayCancelResponseDto kakaopayCancelResponseDto() { + ApprovedCancelAmount approvedCancelAmount = + ApprovedCancelAmount.builder().total(10000).tax_free(0).vat(0).point(0).build(); + CanceledAmount canceledAmount = CanceledAmount.builder().total(10000).build(); + CancelAvailableAmount cancelAvailableAmount = + CancelAvailableAmount.builder().total(40000).build(); + + return KakaopayCancelResponseDto.builder() + .cid("cid 번호") + .status("주문취소") + .partner_order_id("orderGroupId") + .partner_user_id("userId") + .approved_cancel_amount(approvedCancelAmount) + .canceled_amount(canceledAmount) + .cancel_available_amount(cancelAvailableAmount) + .created_at(LocalDateTime.now().minusDays(10)) + .canceled_at(LocalDateTime.now()) + .build(); + } +} diff --git a/src/test/java/kr/bb/payment/service/KakaopayReadyTest.java b/src/test/java/kr/bb/payment/service/KakaopayReadyTest.java index 1f319d5..ed96155 100644 --- a/src/test/java/kr/bb/payment/service/KakaopayReadyTest.java +++ b/src/test/java/kr/bb/payment/service/KakaopayReadyTest.java @@ -2,19 +2,45 @@ import bloomingblooms.domain.payment.KakaopayReadyRequestDto; import bloomingblooms.domain.payment.KakaopayReadyResponseDto; -import org.junit.jupiter.api.Assertions; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import java.time.LocalDateTime; +import kr.bb.payment.dto.response.Amount; +import kr.bb.payment.dto.response.KakaopayApproveResponseDto; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.test.web.client.match.MockRestRequestMatchers; +import org.springframework.test.web.client.response.MockRestResponseCreators; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.client.RestTemplate; @SpringBootTest @Transactional public class KakaopayReadyTest { + @Autowired private RestTemplate restTemplate; @Autowired private KakaopayService kakaopayService; + private MockRestServiceServer mockServer; + @BeforeEach + void setUp() throws Exception { + mockServer = MockRestServiceServer.createServer(restTemplate); + + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + String responseJson = objectMapper.writeValueAsString(kakaopayReadyResponseDto()); + + mockServer + .expect(MockRestRequestMatchers.requestTo("https://kapi.kakao.com/v1/payment/ready")) + .andExpect(MockRestRequestMatchers.method(HttpMethod.POST)) + .andRespond(MockRestResponseCreators.withSuccess(responseJson, MediaType.APPLICATION_JSON)); + } @DisplayName("단건결제 준비 - 픽업") @DirtiesContext @Test @@ -34,8 +60,7 @@ void kakaopayReadyForDeliveryAndPickupTest() { // then KakaopayReadyResponseDto responseDto = kakaopayService.kakaoPayReady(DTO_1); - Assertions.assertEquals(20, responseDto.getTid().length()); - Assertions.assertTrue(responseDto.getNextRedirectPcUrl().startsWith("https://")); + mockServer.verify(); } @DisplayName("단건결제 준비 - 배송&구독") @@ -57,7 +82,23 @@ void kakaopayReadyForSubscriptionTest() { // then KakaopayReadyResponseDto responseDto2 = kakaopayService.kakaoPayReady(DTO_2); - Assertions.assertEquals(20, responseDto2.getTid().length()); - Assertions.assertTrue(responseDto2.getNextRedirectPcUrl().startsWith("https://")); + mockServer.verify(); + } + + KakaopayApproveResponseDto kakaopayReadyResponseDto() { + return KakaopayApproveResponseDto.builder() + .aid("고유번호") + .tid("tid고유번호") + .cid("cid번호") + .sid("sid") + .partnerOrderId("1") + .partnerUserId("1") + .paymentMethodType("MONEY") + .itemName("상품명") + .quantity(1) + .createdAt(LocalDateTime.now()) + .approvedAt(LocalDateTime.now()) + .amount(new Amount(1000, 0, 0, 0, 0)) + .build(); } } From e51afd60a41d997c5a7820f409b1ae185430e440 Mon Sep 17 00:00:00 2001 From: binarywoo27 Date: Mon, 15 Jan 2024 00:55:19 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=EB=B0=B0=EC=B9=98=20=EC=A0=95?= =?UTF-8?q?=EA=B8=B0=EA=B2=B0=EC=A0=9C=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EC=A0=95=EA=B8=B0=EA=B2=B0=EC=A0=9C=20?= =?UTF-8?q?=EC=B7=A8=EC=86=8C=20API=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 +-- .../OrderClientController.java | 13 +++++++ ...KakaopayCancelSubscriptionResponseDto.java | 20 +++++++++++ .../repository/SubscriptionRepository.java | 2 ++ .../bb/payment/service/KakaopayService.java | 36 +++++++++++++++---- .../kr/bb/payment/service/PaymentService.java | 5 +++ .../service/KakaopaySubscriptionTest.java | 11 ++---- 7 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 src/main/java/kr/bb/payment/dto/response/KakaopayCancelSubscriptionResponseDto.java diff --git a/build.gradle b/build.gradle index da4c127..f004856 100644 --- a/build.gradle +++ b/build.gradle @@ -38,13 +38,14 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation 'org.springframework.kafka:spring-kafka' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'io.github.lotteon-maven:blooming-blooms-utils:202401091420' + implementation 'io.github.lotteon-maven:blooming-blooms-utils:202401140749' runtimeOnly 'com.h2database:h2' implementation 'mysql:mysql-connector-java:8.0.33' testImplementation 'org.mock-server:mockserver-netty:5.11.2' // 사용 중인 MockServer 버전 implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.1' implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'io.micrometer:micrometer-registry-prometheus:1.12.2' } dependencyManagement { @@ -112,4 +113,4 @@ jacocoTestReport { ) } finalizedBy 'jacocoTestCoverageVerification' -} \ No newline at end of file +} diff --git a/src/main/java/kr/bb/payment/controller/clientcontroller/OrderClientController.java b/src/main/java/kr/bb/payment/controller/clientcontroller/OrderClientController.java index 447ae7c..f3fd563 100644 --- a/src/main/java/kr/bb/payment/controller/clientcontroller/OrderClientController.java +++ b/src/main/java/kr/bb/payment/controller/clientcontroller/OrderClientController.java @@ -1,5 +1,6 @@ package kr.bb.payment.controller.clientcontroller; +import bloomingblooms.domain.batch.SubscriptionBatchDtoList; import bloomingblooms.domain.payment.KakaopayApproveRequestDto; import bloomingblooms.domain.payment.KakaopayReadyRequestDto; import bloomingblooms.domain.payment.KakaopayReadyResponseDto; @@ -54,4 +55,16 @@ CommonResponse cancel(@RequestBody KakaopayCancelRequestDto cancelRequestD kakaopayService.cancelPayment(cancelRequestDto); return CommonResponse.success(null); } + + @PostMapping(value = "/subscription") + CommonResponse subscription(@RequestBody SubscriptionBatchDtoList subscriptionBatchDtolist){ + kakaopayService.renewSubscription(subscriptionBatchDtolist); + return CommonResponse.success(null); + } + + @PostMapping(value = "/subscription/cancel") + CommonResponse cancelSubscription(@RequestBody KakaopayCancelRequestDto cancelRequestDto){ + kakaopayService.cancelSubscription(cancelRequestDto); + return CommonResponse.success(null); + } } diff --git a/src/main/java/kr/bb/payment/dto/response/KakaopayCancelSubscriptionResponseDto.java b/src/main/java/kr/bb/payment/dto/response/KakaopayCancelSubscriptionResponseDto.java new file mode 100644 index 0000000..a072bc2 --- /dev/null +++ b/src/main/java/kr/bb/payment/dto/response/KakaopayCancelSubscriptionResponseDto.java @@ -0,0 +1,20 @@ +package kr.bb.payment.dto.response; + +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class KakaopayCancelSubscriptionResponseDto { + private String status; + private LocalDateTime created_at; + private LocalDateTime inactivated_at; + private LocalDateTime last_approved_at; +} diff --git a/src/main/java/kr/bb/payment/repository/SubscriptionRepository.java b/src/main/java/kr/bb/payment/repository/SubscriptionRepository.java index e95d6a7..c3c68b6 100644 --- a/src/main/java/kr/bb/payment/repository/SubscriptionRepository.java +++ b/src/main/java/kr/bb/payment/repository/SubscriptionRepository.java @@ -1,8 +1,10 @@ package kr.bb.payment.repository; +import java.util.Optional; import kr.bb.payment.entity.Subscription; import org.springframework.data.jpa.repository.JpaRepository; public interface SubscriptionRepository extends JpaRepository { Subscription findBySubscriptionSid(String subscriptionSid); + Optional findByOrderSubscriptionId(String orderSubscriptionId); } diff --git a/src/main/java/kr/bb/payment/service/KakaopayService.java b/src/main/java/kr/bb/payment/service/KakaopayService.java index e243fdf..477f4f4 100644 --- a/src/main/java/kr/bb/payment/service/KakaopayService.java +++ b/src/main/java/kr/bb/payment/service/KakaopayService.java @@ -14,7 +14,9 @@ import kr.bb.payment.dto.request.KakaopayCancelRequestDto; import kr.bb.payment.dto.response.KakaopayApproveResponseDto; import kr.bb.payment.dto.response.KakaopayCancelResponseDto; +import kr.bb.payment.dto.response.KakaopayCancelSubscriptionResponseDto; import kr.bb.payment.entity.Payment; +import kr.bb.payment.entity.Subscription; import kr.bb.payment.feign.DeliveryServiceClient; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; @@ -94,17 +96,22 @@ public void renewSubscription(SubscriptionBatchDtoList subscriptionBatchDtoList) Map oldDeliveryIdsMap = new HashMap<>(); // <결제기록id, old 배송id> for(SubscriptionBatchDto subscriptionBatchDto : subscriptionBatchDtoList.getSubscriptionBatchDtoList()){ + Long userId = subscriptionBatchDto.getUserId(); + String orderSubscriptionId = subscriptionBatchDto.getOrderSubscriptionId(); + + Subscription subscription = paymentService.getSubscriptionEntity( + subscriptionBatchDto.getOrderSubscriptionId()); + MultiValueMap parameters = new LinkedMultiValueMap<>(); - parameters.add("cid", subscriptionBatchDto.getCid()); - parameters.add("sid", subscriptionBatchDto.getSid()); - parameters.add("partner_order_id", String.valueOf(subscriptionBatchDto.getPartnerOrderId())); - parameters.add("partner_user_id", String.valueOf(subscriptionBatchDto.getPartnerUserId())); - parameters.add("quantity", String.valueOf(subscriptionBatchDto.getQuantity())); - parameters.add("total_amount", String.valueOf(subscriptionBatchDto.getTotalAmount())); + parameters.add("cid", subscription.getSubscriptionCid()); + parameters.add("sid", subscription.getSubscriptionSid()); + parameters.add("partner_order_id", String.valueOf(orderSubscriptionId)); + parameters.add("partner_user_id", String.valueOf(userId)); + parameters.add("quantity", String.valueOf(subscription.getSubscriptionQuantity())); + parameters.add("total_amount", String.valueOf(subscription.getSubscriptionTotalAmount())); parameters.add("tax_free_amount", String.valueOf(0)); - HttpEntity> requestEntity = new HttpEntity<>(parameters, this.getHeaders()); @@ -139,6 +146,21 @@ public void cancelPayment(KakaopayCancelRequestDto cancelRequestDto){ restTemplate.postForObject(url, requestEntity, KakaopayCancelResponseDto.class); } + public void cancelSubscription(KakaopayCancelRequestDto cancelRequestDto ){ + Subscription subscription = paymentService.getSubscriptionEntity(cancelRequestDto.getOrderId()); + + MultiValueMap parameters = new LinkedMultiValueMap<>(); + + parameters.add("cid", subscription.getSubscriptionCid()); + parameters.add("sid", subscription.getSubscriptionSid()); + + HttpEntity> requestEntity = new HttpEntity<>(parameters, this.getHeaders()); + + String url = "https://kapi.kakao.com/v1/payment/manage/subscription/inactive"; + + restTemplate.postForObject(url, requestEntity, KakaopayCancelSubscriptionResponseDto.class); + } + @NotNull private HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); diff --git a/src/main/java/kr/bb/payment/service/PaymentService.java b/src/main/java/kr/bb/payment/service/PaymentService.java index 9f248e0..6d55748 100644 --- a/src/main/java/kr/bb/payment/service/PaymentService.java +++ b/src/main/java/kr/bb/payment/service/PaymentService.java @@ -109,4 +109,9 @@ public String getPaymentDate(String orderGroupId){ public Payment getPaymentEntity(String orderGroupId){ return paymentRepository.findByOrderId(orderGroupId); } + + @Transactional + public Subscription getSubscriptionEntity(String orderSubscriptionId) { + return subscriptionRepository.findByOrderSubscriptionId(orderSubscriptionId).orElseThrow(EntityNotFoundException::new); + } } diff --git a/src/test/java/kr/bb/payment/service/KakaopaySubscriptionTest.java b/src/test/java/kr/bb/payment/service/KakaopaySubscriptionTest.java index eb1651b..9193a1e 100644 --- a/src/test/java/kr/bb/payment/service/KakaopaySubscriptionTest.java +++ b/src/test/java/kr/bb/payment/service/KakaopaySubscriptionTest.java @@ -89,14 +89,7 @@ public void batchSubscription() { } private SubscriptionBatchDto createSubscriptionBatchDto() { - return SubscriptionBatchDto.builder() - .cid("TCSUBSCRIP") - .sid("sid 고유번호") - .partnerOrderId("partner_order_id_1") - .partnerUserId("1") - .quantity(1L) - .totalAmount(44500L) - .build(); + return SubscriptionBatchDto.builder().userId(1L).orderSubscriptionId("구독 주문 id").build(); } private SubscriptionRecords createSubscriptionRecords() { @@ -105,7 +98,7 @@ private SubscriptionRecords createSubscriptionRecords() { private Subscription createSubscription() { return Subscription.builder() - .orderSubscriptionId("주문 id") + .orderSubscriptionId("구독 주문 id") .subscriptionCid("TCSUBSCRIP") .subscriptionTid("tid 고유번호") .subscriptionSid("sid 고유번호")