Skip to content

Commit

Permalink
Api-v1.0.5
Browse files Browse the repository at this point in the history
Api-v1.0.5
  • Loading branch information
ImNM committed Jul 9, 2023
2 parents 0b4ed84 + 5478555 commit 49cd3d4
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@


import band.gosrock.common.validator.PhoneValidator;
import java.lang.annotation.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;

@Target({ElementType.FIELD})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

@FeignClient(
name = "PaymentsCancelClient",
url = "https://api.tosspayments.com",
url = "${feign.toss.url}",
configuration = {PaymentsCancelConfig.class})
public interface PaymentsCancelClient {
@PostMapping("/v1/payments/{paymentKey}/cancel")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,47 @@
import band.gosrock.infrastructure.outer.api.tossPayments.exception.PaymentsCancelErrorCode;
import band.gosrock.infrastructure.outer.api.tossPayments.exception.PaymentsUnHandleException;
import band.gosrock.infrastructure.outer.api.tossPayments.exception.TossPaymentsErrorDto;
import feign.FeignException;
import feign.Response;
import feign.RetryableException;
import feign.Retryer;
import feign.codec.ErrorDecoder;
import java.util.concurrent.TimeUnit;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;

public class PaymentCancelErrorDecoder implements ErrorDecoder {
private static final long PERIOD = 500L;
private static final long MAX_PERIOD = TimeUnit.SECONDS.toMillis(3L);
private static final int MAX_ATTEMPTS = 3;

@Bean
Retryer.Default retryer() {
return new Retryer.Default(PERIOD, MAX_PERIOD, MAX_ATTEMPTS);
}

@Override
public Exception decode(String methodKey, Response response) {
TossPaymentsErrorDto body = TossPaymentsErrorDto.from(response);
try {
PaymentsCancelErrorCode paymentsCancelErrorCode =
FeignException exception = feign.FeignException.errorStatus(methodKey, response);
int status = response.status();
// 500번대는 기본적으로 리트라이
if (HttpStatus.valueOf(status).is5xxServerError()) {
throw new RetryableException(
status,
exception.getMessage(),
response.request().httpMethod(),
exception,
null,
response.request());
}
// payments 에러 코드 Decode
TossPaymentsErrorDto body = TossPaymentsErrorDto.from(response);

final PaymentsCancelErrorCode paymentsCancelErrorCode =
PaymentsCancelErrorCode.valueOf(body.getCode());
ErrorReason errorReason = paymentsCancelErrorCode.getErrorReason();
final ErrorReason errorReason = paymentsCancelErrorCode.getErrorReason();

throw new DuDoongDynamicException(
errorReason.getStatus(), errorReason.getCode(), errorReason.getReason());
} catch (IllegalArgumentException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
</div>
<br/>
<div>
<b>입금과 세금 계산서 발행</b>을 위해
<b>입금</b>을 위해
</div>
<div>
입금받으실 분의 주민등록번호와 성함을 평문으로,
입금받으실 분의 성함을 평문으로,
</div>
<div>
통장사본은 첨부하셔서 <b>support@dudoong.com</b> 으로 이메일을 보내주시면 감사하겠습니다.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@
<div>
두둥의 매출인 수수료에 대해서는 매출 발생이 확정된 공연 종료일을 기준으로 매출이 발생한 것으로 봅니다.
</div>
<div>
이에 대한 증빙으로 두둥에서 호스트 앞으로 수수료에 대한 전자세금계산서를 발행해 드릴때
공연의 종료일을 기준으로 발급해드립니다.
</div>
<!-- <div>-->
<!-- 이에 대한 증빙으로 두둥에서 호스트 앞으로 수수료에 대한 전자세금계산서를 발행해 드릴때-->
<!-- 공연의 종료일을 기준으로 발급해드립니다.-->
<!-- </div>-->
<div>
정산드린 금액에 대해선 입금 받는 호스트 분께서 성실하게 세금에대해 신고할 의무가 있습니다.
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package band.gosrock.infrastructure.outer.api.tossPayments.client;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.catchThrowable;

import band.gosrock.infrastructure.InfraIntegrateProfileResolver;
import band.gosrock.infrastructure.InfraIntegrateTestConfig;
import band.gosrock.infrastructure.outer.api.tossPayments.dto.request.CancelPaymentsRequest;
import feign.RetryableException;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.contract.spec.internal.HttpStatus;
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;

@ContextConfiguration
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = InfraIntegrateTestConfig.class)
@AutoConfigureWireMock(port = 0)
@ActiveProfiles(resolver = InfraIntegrateProfileResolver.class)
@TestPropertySource(properties = {"feign.toss.url=http://localhost:${wiremock.server.port}"})
class PaymentsCancelClientTest {
private static final String IDEMPOTENCY_KEY = "idempotency-key";
private static final String PAYMENT_KEY = "1234";
private static final CancelPaymentsRequest REQUEST =
CancelPaymentsRequest.builder().cancelReason("test").build();
@Autowired private PaymentsCancelClient paymentsCancelClient;

@Test
public void 주문취소_실패시_멱등성_테스트() {
final String URL = "/v1/payments/" + PAYMENT_KEY + "/cancel";
// given
stubFor(
post(urlEqualTo(URL))
.willReturn(aResponse().withStatus(HttpStatus.SERVICE_UNAVAILABLE)));

// when
Throwable exception =
catchThrowable(
() -> paymentsCancelClient.execute(IDEMPOTENCY_KEY, PAYMENT_KEY, REQUEST));

// then
assertThat(exception).isInstanceOf(RetryableException.class);
verify(3, postRequestedFor(urlEqualTo(URL)));
}
}

0 comments on commit 49cd3d4

Please sign in to comment.