[#56] 예약 & 결제 프로세스 및 패키지 구조 재정의 #57

Merged
pricelees merged 45 commits from refactor/#56 into main 2025-10-09 09:33:29 +00:00
3 changed files with 25 additions and 12 deletions
Showing only changes of commit 1652398fcc - Show all commits

View File

@ -6,3 +6,9 @@ class PaymentException(
override val errorCode: PaymentErrorCode,
override val message: String = errorCode.message
) : RoomescapeException(errorCode, message)
class ExternalPaymentException(
val httpStatusCode: Int,
val errorCode: String,
override val message: String
) : RuntimeException(message)

View File

@ -1,6 +1,7 @@
package com.sangdol.roomescape.payment.infrastructure.client
import com.fasterxml.jackson.databind.ObjectMapper
import com.sangdol.roomescape.payment.exception.ExternalPaymentException
import com.sangdol.roomescape.payment.exception.PaymentErrorCode
import com.sangdol.roomescape.payment.exception.PaymentException
import io.github.oshai.kotlinlogging.KLogger
@ -138,9 +139,14 @@ private class TosspayErrorHandler(
response: ClientHttpResponse
): Nothing {
val requestType: String = paymentRequestType(url)
log.warn { "[TosspayClient] $requestType 요청 실패: response: ${parseResponse(response)}" }
val errorResponse: TosspayErrorResponse = parseResponse(response)
log.warn { "[TosspayClient] $requestType 요청 실패: response: $errorResponse" }
throw PaymentException(paymentErrorCode(response.statusCode))
throw ExternalPaymentException(
httpStatusCode = response.statusCode.value(),
errorCode = errorResponse.code,
message = errorResponse.message
)
}
private fun paymentRequestType(url: URI): String {

View File

@ -1,6 +1,7 @@
package com.sangdol.roomescape.payment
import com.ninjasquad.springmockk.MockkBean
import com.sangdol.roomescape.payment.exception.ExternalPaymentException
import com.sangdol.roomescape.payment.exception.PaymentErrorCode
import com.sangdol.roomescape.payment.exception.PaymentException
import com.sangdol.roomescape.payment.infrastructure.client.PaymentClientCancelResponse
@ -67,7 +68,7 @@ class TosspayClientTest(
}
context("실패 응답") {
fun runTest(httpStatus: HttpStatus, expectedError: PaymentErrorCode) {
fun runTest(httpStatus: HttpStatus) {
commonAction().andRespond {
withStatus(httpStatus)
.contentType(MediaType.APPLICATION_JSON)
@ -75,7 +76,7 @@ class TosspayClientTest(
.createResponse(it)
}
val exception = shouldThrow<PaymentException> {
val exception = shouldThrow<ExternalPaymentException> {
client.confirm(
SampleTosspayConstant.PAYMENT_KEY,
SampleTosspayConstant.ORDER_ID,
@ -83,15 +84,15 @@ class TosspayClientTest(
)
}
exception.errorCode shouldBe expectedError
exception.errorCode shouldBe "ERROR_CODE"
}
test("결제 서버에서 4XX 응답 시") {
runTest(HttpStatus.BAD_REQUEST, PaymentErrorCode.PAYMENT_CLIENT_ERROR)
runTest(HttpStatus.BAD_REQUEST)
}
test("결제 서버에서 5XX 응답 시") {
runTest(HttpStatus.INTERNAL_SERVER_ERROR, PaymentErrorCode.PAYMENT_PROVIDER_ERROR)
runTest(HttpStatus.INTERNAL_SERVER_ERROR)
}
}
}
@ -131,7 +132,7 @@ class TosspayClientTest(
}
context("실패 응답") {
fun runTest(httpStatus: HttpStatus, expectedError: PaymentErrorCode) {
fun runTest(httpStatus: HttpStatus) {
commonAction().andRespond {
withStatus(httpStatus)
.contentType(MediaType.APPLICATION_JSON)
@ -139,22 +140,22 @@ class TosspayClientTest(
.createResponse(it)
}
val exception = shouldThrow<PaymentException> {
val exception = shouldThrow<ExternalPaymentException> {
client.cancel(
SampleTosspayConstant.PAYMENT_KEY,
SampleTosspayConstant.AMOUNT,
SampleTosspayConstant.CANCEL_REASON
)
}
exception.errorCode shouldBe expectedError
exception.errorCode shouldBe "ERROR_CODE"
}
test("결제 서버에서 4XX 응답 시") {
runTest(HttpStatus.BAD_REQUEST, PaymentErrorCode.PAYMENT_CLIENT_ERROR)
runTest(HttpStatus.BAD_REQUEST)
}
test("결제 서버에서 5XX 응답 시") {
runTest(HttpStatus.INTERNAL_SERVER_ERROR, PaymentErrorCode.PAYMENT_PROVIDER_ERROR)
runTest(HttpStatus.INTERNAL_SERVER_ERROR)
}
}
}