generated from pricelees/issue-pr-template
refactor: PaymentConfig의 빈 타입을 RestClient -> RestClient.Builder으로 롤백 및 테스트 전용 property 추가
This commit is contained in:
parent
635f015b3c
commit
51b0877508
@ -15,21 +15,19 @@ import java.util.*
|
|||||||
class PaymentConfig {
|
class PaymentConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
fun paymentClient(
|
fun tossPaymentClientBuilder(
|
||||||
paymentProperties: PaymentProperties,
|
paymentProperties: PaymentProperties,
|
||||||
restClientBuilder: RestClient.Builder
|
): RestClient.Builder {
|
||||||
): RestClient {
|
|
||||||
val settings: ClientHttpRequestFactorySettings = ClientHttpRequestFactorySettings.defaults().also {
|
val settings: ClientHttpRequestFactorySettings = ClientHttpRequestFactorySettings.defaults().also {
|
||||||
it.withReadTimeout(Duration.ofSeconds(paymentProperties.readTimeout.toLong()))
|
it.withReadTimeout(Duration.ofSeconds(paymentProperties.readTimeout.toLong()))
|
||||||
it.withConnectTimeout(Duration.ofSeconds(paymentProperties.connectTimeout.toLong()))
|
it.withConnectTimeout(Duration.ofSeconds(paymentProperties.connectTimeout.toLong()))
|
||||||
}
|
}
|
||||||
val requestFactory = ClientHttpRequestFactoryBuilder.jdk().build(settings)
|
val requestFactory = ClientHttpRequestFactoryBuilder.jdk().build(settings)
|
||||||
|
|
||||||
return restClientBuilder
|
return RestClient.builder()
|
||||||
.baseUrl(paymentProperties.apiBaseUrl)
|
.baseUrl(paymentProperties.apiBaseUrl)
|
||||||
.defaultHeader("Authorization", getAuthorizations(paymentProperties.confirmSecretKey))
|
.defaultHeader("Authorization", getAuthorizations(paymentProperties.confirmSecretKey))
|
||||||
.requestFactory(requestFactory)
|
.requestFactory(requestFactory)
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAuthorizations(secretKey: String): String {
|
private fun getAuthorizations(secretKey: String): String {
|
||||||
|
|||||||
@ -16,58 +16,55 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
|
|
||||||
import roomescape.common.exception.ErrorType;
|
import roomescape.common.exception.ErrorType;
|
||||||
import roomescape.common.exception.RoomescapeException;
|
import roomescape.common.exception.RoomescapeException;
|
||||||
import roomescape.payment.web.dto.request.PaymentCancelRequest;
|
import roomescape.payment.web.PaymentApprove;
|
||||||
import roomescape.payment.web.dto.request.PaymentRequest;
|
import roomescape.payment.web.PaymentCancel;
|
||||||
import roomescape.payment.web.dto.response.PaymentCancelResponse;
|
|
||||||
import roomescape.payment.web.dto.response.PaymentResponse;
|
|
||||||
import roomescape.payment.web.dto.response.TossPaymentErrorResponse;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class TossPaymentClient {
|
public class TossPaymentClient {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(TossPaymentClient.class);
|
private static final Logger log = LoggerFactory.getLogger(TossPaymentClient.class);
|
||||||
|
|
||||||
private final RestClient paymentClient;
|
private final RestClient tossPaymentClient;
|
||||||
|
|
||||||
public TossPaymentClient(RestClient paymentClient) {
|
public TossPaymentClient(RestClient.Builder tossPaymentClientBuilder) {
|
||||||
this.paymentClient = paymentClient;
|
this.tossPaymentClient = tossPaymentClientBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PaymentResponse confirmPayment(PaymentRequest paymentRequest) {
|
public PaymentApprove.Response confirmPayment(PaymentApprove.Request paymentRequest) {
|
||||||
logPaymentInfo(paymentRequest);
|
logPaymentInfo(paymentRequest);
|
||||||
return paymentClient.post()
|
return tossPaymentClient.post()
|
||||||
.uri("/v1/payments/confirm")
|
.uri("/v1/payments/confirm")
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.body(paymentRequest)
|
.body(paymentRequest)
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.onStatus(status -> status.is4xxClientError() || status.is5xxServerError(),
|
.onStatus(status -> status.is4xxClientError() || status.is5xxServerError(),
|
||||||
(req, res) -> handlePaymentError(res))
|
(req, res) -> handlePaymentError(res))
|
||||||
.body(PaymentResponse.class);
|
.body(PaymentApprove.Response.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PaymentCancelResponse cancelPayment(PaymentCancelRequest cancelRequest) {
|
public PaymentCancel.Response cancelPayment(PaymentCancel.Request cancelRequest) {
|
||||||
logPaymentCancelInfo(cancelRequest);
|
logPaymentCancelInfo(cancelRequest);
|
||||||
Map<String, String> param = Map.of("cancelReason", cancelRequest.cancelReason());
|
Map<String, String> param = Map.of("cancelReason", cancelRequest.cancelReason);
|
||||||
|
|
||||||
return paymentClient.post()
|
return tossPaymentClient.post()
|
||||||
.uri("/v1/payments/{paymentKey}/cancel", cancelRequest.paymentKey())
|
.uri("/v1/payments/{paymentKey}/cancel", cancelRequest.paymentKey)
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.body(param)
|
.body(param)
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.onStatus(status -> status.is4xxClientError() || status.is5xxServerError(),
|
.onStatus(status -> status.is4xxClientError() || status.is5xxServerError(),
|
||||||
(req, res) -> handlePaymentError(res))
|
(req, res) -> handlePaymentError(res))
|
||||||
.body(PaymentCancelResponse.class);
|
.body(PaymentCancel.Response.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logPaymentInfo(PaymentRequest paymentRequest) {
|
private void logPaymentInfo(PaymentApprove.Request paymentRequest) {
|
||||||
log.info("결제 승인 요청: paymentKey={}, orderId={}, amount={}, paymentType={}",
|
log.info("결제 승인 요청: paymentKey={}, orderId={}, amount={}, paymentType={}",
|
||||||
paymentRequest.paymentKey(), paymentRequest.orderId(), paymentRequest.amount(),
|
paymentRequest.paymentKey, paymentRequest.orderId, paymentRequest.amount,
|
||||||
paymentRequest.paymentType());
|
paymentRequest.paymentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logPaymentCancelInfo(PaymentCancelRequest cancelRequest) {
|
private void logPaymentCancelInfo(PaymentCancel.Request cancelRequest) {
|
||||||
log.info("결제 취소 요청: paymentKey={}, amount={}, cancelReason={}",
|
log.info("결제 취소 요청: paymentKey={}, amount={}, cancelReason={}",
|
||||||
cancelRequest.paymentKey(), cancelRequest.amount(), cancelRequest.cancelReason());
|
cancelRequest.paymentKey, cancelRequest.amount, cancelRequest.cancelReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePaymentError(ClientHttpResponse res)
|
private void handlePaymentError(ClientHttpResponse res)
|
||||||
@ -77,7 +74,7 @@ public class TossPaymentClient {
|
|||||||
TossPaymentErrorResponse errorResponse = getErrorResponse(res);
|
TossPaymentErrorResponse errorResponse = getErrorResponse(res);
|
||||||
|
|
||||||
throw new RoomescapeException(errorType,
|
throw new RoomescapeException(errorType,
|
||||||
String.format("[ErrorCode = %s, ErrorMessage = %s]", errorResponse.code(), errorResponse.message()),
|
String.format("[ErrorCode = %s, ErrorMessage = %s]", errorResponse.code, errorResponse.message),
|
||||||
statusCode);
|
statusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,10 +19,8 @@ import org.springframework.test.web.client.MockRestServiceServer;
|
|||||||
import roomescape.common.exception.ErrorType;
|
import roomescape.common.exception.ErrorType;
|
||||||
import roomescape.common.exception.RoomescapeException;
|
import roomescape.common.exception.RoomescapeException;
|
||||||
import roomescape.payment.SampleTossPaymentConst;
|
import roomescape.payment.SampleTossPaymentConst;
|
||||||
import roomescape.payment.web.dto.request.PaymentCancelRequest;
|
import roomescape.payment.web.PaymentApprove;
|
||||||
import roomescape.payment.web.dto.request.PaymentRequest;
|
import roomescape.payment.web.PaymentCancel;
|
||||||
import roomescape.payment.web.dto.response.PaymentCancelResponse;
|
|
||||||
import roomescape.payment.web.dto.response.PaymentResponse;
|
|
||||||
|
|
||||||
@RestClientTest(TossPaymentClient.class)
|
@RestClientTest(TossPaymentClient.class)
|
||||||
class TossPaymentClientTest {
|
class TossPaymentClientTest {
|
||||||
@ -46,12 +44,12 @@ class TossPaymentClientTest {
|
|||||||
.body(SampleTossPaymentConst.confirmJson));
|
.body(SampleTossPaymentConst.confirmJson));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
PaymentRequest paymentRequest = SampleTossPaymentConst.paymentRequest;
|
PaymentApprove.Request paymentRequest = SampleTossPaymentConst.paymentRequest;
|
||||||
PaymentResponse paymentResponse = tossPaymentClient.confirmPayment(paymentRequest);
|
PaymentApprove.Response paymentResponse = tossPaymentClient.confirmPayment(paymentRequest);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(paymentResponse.paymentKey()).isEqualTo(paymentRequest.paymentKey());
|
assertThat(paymentResponse.paymentKey).isEqualTo(paymentRequest.paymentKey);
|
||||||
assertThat(paymentResponse.orderId()).isEqualTo(paymentRequest.orderId());
|
assertThat(paymentResponse.orderId).isEqualTo(paymentRequest.orderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -67,12 +65,12 @@ class TossPaymentClientTest {
|
|||||||
.body(SampleTossPaymentConst.cancelJson));
|
.body(SampleTossPaymentConst.cancelJson));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
PaymentCancelRequest cancelRequest = SampleTossPaymentConst.cancelRequest;
|
PaymentCancel.Request cancelRequest = SampleTossPaymentConst.cancelRequest;
|
||||||
PaymentCancelResponse paymentCancelResponse = tossPaymentClient.cancelPayment(cancelRequest);
|
PaymentCancel.Response paymentCancelResponse = tossPaymentClient.cancelPayment(cancelRequest);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(paymentCancelResponse.cancelStatus()).isEqualTo("DONE");
|
assertThat(paymentCancelResponse.cancelStatus).isEqualTo("DONE");
|
||||||
assertThat(paymentCancelResponse.cancelReason()).isEqualTo(cancelRequest.cancelReason());
|
assertThat(paymentCancelResponse.cancelReason).isEqualTo(cancelRequest.cancelReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@ -25,3 +25,9 @@ security:
|
|||||||
secret-key: daijawligagaf@LIJ$@U)9nagnalkkgalijaddljfi
|
secret-key: daijawligagaf@LIJ$@U)9nagnalkkgalijaddljfi
|
||||||
access:
|
access:
|
||||||
expire-length: 1800000 # 30 분
|
expire-length: 1800000 # 30 분
|
||||||
|
|
||||||
|
payment:
|
||||||
|
api-base-url: https://api.tosspayments.com
|
||||||
|
confirm-secret-key: test_gsk_docs_OaPz8L5KdmQXkzRz3y47BMw6
|
||||||
|
read-timeout: 3
|
||||||
|
connect-timeout: 30
|
||||||
Loading…
x
Reference in New Issue
Block a user