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

Merged
pricelees merged 45 commits from refactor/#56 into main 2025-10-09 09:33:29 +00:00
2 changed files with 405 additions and 378 deletions
Showing only changes of commit c4cd168175 - Show all commits

View File

@ -0,0 +1,26 @@
package com.sangdol.roomescape.order.infrastructure.persistence
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
interface PaymentAttemptRepository: JpaRepository<PaymentAttemptEntity, Long> {
fun countByReservationId(reservationId: Long): Long
@Query(
"""
SELECT
CASE
WHEN COUNT(pa) > 0
THEN TRUE
ELSE FALSE
END
FROM
PaymentAttemptEntity pa
WHERE
pa.reservationId = :reservationId
AND pa.result = com.sangdol.roomescape.order.infrastructure.persistence.AttemptResult.SUCCESS
"""
)
fun isSuccessAttemptExists(reservationId: Long): Boolean
}

View File

@ -1,378 +1,379 @@
//package com.sangdol.roomescape.payment
//
//import com.ninjasquad.springmockk.MockkBean
//import com.sangdol.common.types.web.HttpStatus
//import com.sangdol.roomescape.auth.exception.AuthErrorCode
//import com.sangdol.roomescape.payment.business.PaymentService
//import com.sangdol.roomescape.payment.exception.PaymentErrorCode
//import com.sangdol.roomescape.payment.infrastructure.client.CardDetail
//import com.sangdol.roomescape.payment.infrastructure.client.EasyPayDetail
//import com.sangdol.roomescape.payment.infrastructure.client.TosspayClient
//import com.sangdol.roomescape.payment.infrastructure.client.TransferDetail
//import com.sangdol.roomescape.payment.infrastructure.common.*
//import com.sangdol.roomescape.payment.infrastructure.persistence.*
//import com.sangdol.roomescape.payment.dto.PaymentConfirmRequest
//import com.sangdol.roomescape.payment.web.PaymentCreateResponse
//import com.sangdol.roomescape.supports.*
//import io.kotest.matchers.shouldBe
//import io.mockk.every
//import org.springframework.data.repository.findByIdOrNull
//import org.springframework.http.HttpMethod
//
//class PaymentAPITest(
// @MockkBean
// private val tosspayClient: TosspayClient,
// private val paymentService: PaymentService,
// private val paymentRepository: PaymentRepository,
// private val paymentDetailRepository: PaymentDetailRepository,
// private val canceledPaymentRepository: CanceledPaymentRepository
//) : FunSpecSpringbootTest() {
// init {
// context("결제를 승인한다.") {
// context("권한이 없으면 접근할 수 없다.") {
// val endpoint = "/payments?reservationId=$INVALID_PK"
//
// test("비회원") {
// runExceptionTest(
// method = HttpMethod.POST,
// endpoint = endpoint,
// expectedErrorCode = AuthErrorCode.TOKEN_NOT_FOUND
// )
// }
//
// test("관리자") {
// runExceptionTest(
// token = testAuthUtil.defaultHqAdminLogin().second,
// method = HttpMethod.POST,
// endpoint = endpoint,
// expectedErrorCode = AuthErrorCode.ACCESS_DENIED
// )
// }
// }
//
// val amount = 100_000
// context("간편결제 + 카드로 ${amount}원을 결제한다.") {
// context("일시불") {
// test("토스페이 + 토스뱅크카드(신용)") {
// runConfirmTest(
// amount = amount,
// cardDetail = PaymentFixture.cardDetail(
// amount = amount,
// issuerCode = CardIssuerCode.TOSS_BANK,
// cardType = CardType.CREDIT,
// ),
// easyPayDetail = PaymentFixture.easypayDetail(
// amount = 0,
// provider = EasyPayCompanyCode.TOSSPAY
// )
// )
// }
//
// test("삼성페이 + 삼성카드(법인)") {
// runConfirmTest(
// amount = amount,
// cardDetail = PaymentFixture.cardDetail(
// amount = amount,
// issuerCode = CardIssuerCode.SAMSUNG,
// cardType = CardType.CREDIT,
// ownerType = CardOwnerType.CORPORATE
// ),
// easyPayDetail = PaymentFixture.easypayDetail(
// amount = 0,
// provider = EasyPayCompanyCode.SAMSUNGPAY
// )
// )
// }
// }
//
// context("할부") {
// val installmentPlanMonths = 12
// test("네이버페이 + 신한카드 / 12개월") {
// runConfirmTest(
// amount = amount,
// cardDetail = PaymentFixture.cardDetail(
// amount = amount,
// issuerCode = CardIssuerCode.SHINHAN,
// installmentPlanMonths = installmentPlanMonths
// ),
// easyPayDetail = PaymentFixture.easypayDetail(
// amount = 0,
// provider = EasyPayCompanyCode.NAVERPAY
// )
// )
// }
// }
//
// context("간편결제사 포인트 일부 사용") {
// val point = (amount * 0.1).toInt()
// test("토스페이 + 국민카드(체크) / 일시불 / $point 포인트 사용") {
// runConfirmTest(
// amount = amount,
// cardDetail = PaymentFixture.cardDetail(
// amount = (amount - point),
// issuerCode = CardIssuerCode.KOOKMIN,
// cardType = CardType.CHECK
// ),
// easyPayDetail = PaymentFixture.easypayDetail(
// amount = 0,
// provider = EasyPayCompanyCode.TOSSPAY,
// discountAmount = point
// )
// )
// }
// }
// }
//
// context("간편결제사의 선불 충전금액으로 ${amount}원을 결제한다.") {
// test("토스페이 + 토스페이머니 / 전액") {
// runConfirmTest(
// easyPayDetail = PaymentFixture.easypayDetail(
// amount = amount,
// provider = EasyPayCompanyCode.TOSSPAY
// )
// )
// }
//
// val point = (amount * 0.05).toInt()
//
// test("카카오페이 + 카카오페이머니 / $point 사용") {
// runConfirmTest(
// easyPayDetail = PaymentFixture.easypayDetail(
// amount = (amount - point),
// provider = EasyPayCompanyCode.KAKAOPAY,
// discountAmount = point
// )
// )
// }
// }
//
// context("계좌이체로 결제한다.") {
// test("토스뱅크") {
// runConfirmTest(
// transferDetail = PaymentFixture.transferDetail(bankCode = BankCode.TOSS_BANK)
// )
// }
// }
//
// context("지원하지 않는 결제수단으로 요청시 실패한다.") {
// val supportedMethod = listOf(
// PaymentMethod.CARD,
// PaymentMethod.EASY_PAY,
// PaymentMethod.TRANSFER,
// )
//
// PaymentMethod.entries.filter { it !in supportedMethod }.forEach {
// test("결제 수단: ${it.koreanName}") {
// val (user, token) = testAuthUtil.defaultUserLogin()
// val reservation = dummyInitializer.createConfirmReservation(user = user)
//
// val request = PaymentFixture.confirmRequest
//
// every {
// tosspayClient.confirm(request.paymentKey, request.orderId, request.amount)
// } returns PaymentFixture.confirmResponse(
// paymentKey = request.paymentKey,
// amount = request.amount,
// method = it,
// cardDetail = null,
// easyPayDetail = null,
// transferDetail = null,
// )
//
// runExceptionTest(
// token = token,
// method = HttpMethod.POST,
// endpoint = "/payments?reservationId=${reservation.id}",
// requestBody = PaymentFixture.confirmRequest,
// expectedErrorCode = PaymentErrorCode.NOT_SUPPORTED_PAYMENT_TYPE
// )
// }
// }
// }
// }
//
// context("결제를 취소한다.") {
// context("권한이 없으면 접근할 수 없다.") {
// val endpoint = "/payments/cancel"
//
// test("비회원") {
// runExceptionTest(
// method = HttpMethod.POST,
// endpoint = endpoint,
// requestBody = PaymentFixture.cancelRequest,
// expectedErrorCode = AuthErrorCode.MEMBER_NOT_FOUND
// )
// }
//
// test("관리자") {
// runExceptionTest(
// token = testAuthUtil.defaultHqAdminLogin().second,
// method = HttpMethod.POST,
// endpoint = endpoint,
// requestBody = PaymentFixture.cancelRequest,
// expectedErrorCode = AuthErrorCode.MEMBER_NOT_FOUND
// )
// }
// }
//
// test("정상 취소") {
// val (user, token) = testAuthUtil.defaultUserLogin()
// val reservation = dummyInitializer.createConfirmReservation(user = user)
// val confirmRequest = PaymentFixture.confirmRequest
//
// val paymentCreateResponse = createPayment(
// request = confirmRequest,
// reservationId = reservation.id
// )
//
// every {
// tosspayClient.cancel(
// confirmRequest.paymentKey,
// confirmRequest.amount,
// cancelReason = "cancelReason"
// )
// } returns PaymentFixture.cancelResponse(confirmRequest.amount)
//
// val requestBody = PaymentFixture.cancelRequest.copy(reservationId = reservation.id)
//
// runTest(
// token = token,
// using = {
// body(requestBody)
// },
// on = {
// post("/payments/cancel")
// },
// expect = {
// statusCode(HttpStatus.OK.value())
// }
// ).also {
// val payment = paymentRepository.findByIdOrNull(paymentCreateResponse.paymentId)
// ?: throw AssertionError("Unexpected Exception Occurred.")
// val canceledPayment =
// canceledPaymentRepository.findByPaymentId(paymentCreateResponse.paymentId)
// ?: throw AssertionError("Unexpected Exception Occurred.")
//
// payment.status shouldBe PaymentStatus.CANCELED
// canceledPayment.paymentId shouldBe payment.id
// canceledPayment.cancelAmount shouldBe payment.totalAmount
// }
// }
//
// test("예약에 대한 결제 정보가 없으면 실패한다.") {
// val (user, token) = testAuthUtil.defaultUserLogin()
// val reservation = dummyInitializer.createConfirmReservation(user = user)
//
// runExceptionTest(
// token = token,
// method = HttpMethod.POST,
// endpoint = "/payments/cancel",
// requestBody = PaymentFixture.cancelRequest.copy(reservationId = reservation.id),
// expectedErrorCode = PaymentErrorCode.PAYMENT_NOT_FOUND
// )
// }
// }
// }
//
// private fun createPayment(
// request: PaymentConfirmRequest,
// reservationId: Long,
// ): PaymentCreateResponse {
// every {
// tosspayClient.confirm(request.paymentKey, request.orderId, request.amount)
// } returns PaymentFixture.confirmResponse(
// request.paymentKey,
// request.amount,
// method = PaymentMethod.CARD,
// cardDetail = PaymentFixture.cardDetail(request.amount),
// easyPayDetail = null,
// transferDetail = null,
// )
//
// return paymentService.confirm(reservationId, request)
// }
//
// fun runConfirmTest(
// cardDetail: CardDetail? = null,
// easyPayDetail: EasyPayDetail? = null,
// transferDetail: TransferDetail? = null,
// paymentKey: String = "paymentKey",
// amount: Int = 10000,
// ) {
// val (user, token) = testAuthUtil.defaultUserLogin()
// val reservation = dummyInitializer.createConfirmReservation(user = user)
// val request = PaymentFixture.confirmRequest.copy(paymentKey = paymentKey, amount = amount)
//
// val method = if (easyPayDetail != null) {
// PaymentMethod.EASY_PAY
// } else if (cardDetail != null) {
// PaymentMethod.CARD
// } else if (transferDetail != null) {
// PaymentMethod.TRANSFER
// } else {
// throw AssertionError("결제타입 확인 필요.")
// }
//
// val clientResponse = PaymentFixture.confirmResponse(
// paymentKey, amount, method, cardDetail, easyPayDetail, transferDetail
// )
//
// every {
// tosspayClient.confirm(request.paymentKey, request.orderId, request.amount)
// } returns clientResponse
//
// runTest(
// token = token,
// using = {
// body(request)
// },
// on = {
// post("/payments?reservationId=${reservation.id}")
// },
// expect = {
// statusCode(HttpStatus.OK.value())
// }
// ).also {
// val createdPayment = paymentRepository.findByIdOrNull(it.extract().path("data.paymentId"))
// ?: throw AssertionError("Unexpected Exception Occurred.")
// val createdPaymentDetail =
// paymentDetailRepository.findByIdOrNull(it.extract().path("data.detailId"))
// ?: throw AssertionError("Unexpected Exception Occurred.")
//
// createdPayment.status shouldBe clientResponse.status
// createdPayment.method shouldBe clientResponse.method
// createdPayment.reservationId shouldBe reservation.id
//
// when (createdPaymentDetail) {
// is PaymentCardDetailEntity -> {
// createdPaymentDetail.issuerCode shouldBe clientResponse.card!!.issuerCode
// createdPaymentDetail.cardType shouldBe clientResponse.card.cardType
// createdPaymentDetail.cardNumber shouldBe clientResponse.card.number
// createdPaymentDetail.suppliedAmount shouldBe clientResponse.suppliedAmount
// createdPaymentDetail.vat shouldBe clientResponse.vat
// createdPaymentDetail.amount shouldBe (clientResponse.totalAmount - (clientResponse.easyPay?.discountAmount
// ?: 0))
// clientResponse.easyPay?.let { easypay ->
// createdPaymentDetail.easypayProviderCode shouldBe easypay.provider
// createdPaymentDetail.easypayDiscountAmount shouldBe easypay.discountAmount
// }
// }
//
// is PaymentBankTransferDetailEntity -> {
// createdPaymentDetail.suppliedAmount shouldBe clientResponse.suppliedAmount
// createdPaymentDetail.vat shouldBe clientResponse.vat
// createdPaymentDetail.bankCode shouldBe clientResponse.transfer!!.bankCode
// createdPaymentDetail.settlementStatus shouldBe clientResponse.transfer.settlementStatus
// }
//
// is PaymentEasypayPrepaidDetailEntity -> {
// createdPaymentDetail.suppliedAmount shouldBe clientResponse.suppliedAmount
// createdPaymentDetail.vat shouldBe clientResponse.vat
// createdPaymentDetail.easypayProviderCode shouldBe clientResponse.easyPay!!.provider
// createdPaymentDetail.amount shouldBe clientResponse.easyPay.amount
// createdPaymentDetail.discountAmount shouldBe clientResponse.easyPay.discountAmount
// }
// }
// }
// }
//}
package com.sangdol.roomescape.payment
import com.ninjasquad.springmockk.MockkBean
import com.sangdol.common.types.web.HttpStatus
import com.sangdol.roomescape.auth.exception.AuthErrorCode
import com.sangdol.roomescape.payment.business.PaymentService
import com.sangdol.roomescape.payment.business.domain.*
import com.sangdol.roomescape.payment.dto.*
import com.sangdol.roomescape.payment.exception.ExternalPaymentException
import com.sangdol.roomescape.payment.exception.PaymentErrorCode
import com.sangdol.roomescape.payment.infrastructure.client.TosspayClient
import com.sangdol.roomescape.payment.infrastructure.persistence.CanceledPaymentRepository
import com.sangdol.roomescape.payment.infrastructure.persistence.PaymentRepository
import com.sangdol.roomescape.supports.FunSpecSpringbootTest
import com.sangdol.roomescape.supports.PaymentFixture
import com.sangdol.roomescape.supports.runExceptionTest
import com.sangdol.roomescape.supports.runTest
import io.kotest.matchers.shouldBe
import io.mockk.clearMocks
import io.mockk.every
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.equalTo
import org.springframework.data.repository.findByIdOrNull
import org.springframework.http.HttpMethod
class PaymentAPITest(
@MockkBean
private val tosspayClient: TosspayClient,
private val paymentService: PaymentService,
private val paymentRepository: PaymentRepository,
private val canceledPaymentRepository: CanceledPaymentRepository
) : FunSpecSpringbootTest() {
init {
context("결제를 승인한다.") {
context("권한이 없으면 접근할 수 없다.") {
val endpoint = "/payments/confirm"
test("비회원") {
runExceptionTest(
method = HttpMethod.POST,
endpoint = endpoint,
expectedErrorCode = AuthErrorCode.TOKEN_NOT_FOUND
)
}
test("관리자") {
runExceptionTest(
token = testAuthUtil.defaultHqAdminLogin().second,
method = HttpMethod.POST,
endpoint = endpoint,
expectedErrorCode = AuthErrorCode.ACCESS_DENIED
)
}
}
val amount = 100_000
context("간편결제 + 카드로 ${amount}원을 결제한다.") {
context("일시불") {
test("토스페이 + 토스뱅크카드(신용)") {
runConfirmTest(
amount = amount,
cardDetail = PaymentFixture.cardDetail(
amount = amount,
issuerCode = CardIssuerCode.TOSS_BANK,
cardType = CardType.CREDIT,
),
easyPayDetail = PaymentFixture.easypayDetail(
amount = 0,
provider = EasyPayCompanyCode.TOSSPAY
)
)
}
test("삼성페이 + 삼성카드(법인)") {
runConfirmTest(
amount = amount,
cardDetail = PaymentFixture.cardDetail(
amount = amount,
issuerCode = CardIssuerCode.SAMSUNG,
cardType = CardType.CREDIT,
ownerType = CardOwnerType.CORPORATE
),
easyPayDetail = PaymentFixture.easypayDetail(
amount = 0,
provider = EasyPayCompanyCode.SAMSUNGPAY
)
)
}
}
context("할부") {
val installmentPlanMonths = 12
test("네이버페이 + 신한카드 / 12개월") {
runConfirmTest(
amount = amount,
cardDetail = PaymentFixture.cardDetail(
amount = amount,
issuerCode = CardIssuerCode.SHINHAN,
installmentPlanMonths = installmentPlanMonths
),
easyPayDetail = PaymentFixture.easypayDetail(
amount = 0,
provider = EasyPayCompanyCode.NAVERPAY
)
)
}
}
context("간편결제사 포인트 일부 사용") {
val point = (amount * 0.1).toInt()
test("토스페이 + 국민카드(체크) / 일시불 / $point 포인트 사용") {
runConfirmTest(
amount = amount,
cardDetail = PaymentFixture.cardDetail(
amount = (amount - point),
issuerCode = CardIssuerCode.KOOKMIN,
cardType = CardType.CHECK
),
easyPayDetail = PaymentFixture.easypayDetail(
amount = 0,
provider = EasyPayCompanyCode.TOSSPAY,
discountAmount = point
)
)
}
}
}
context("간편결제사의 선불 충전금액으로 ${amount}원을 결제한다.") {
test("토스페이 + 토스페이머니 / 전액") {
runConfirmTest(
easyPayDetail = PaymentFixture.easypayDetail(
amount = amount,
provider = EasyPayCompanyCode.TOSSPAY
)
)
}
val point = (amount * 0.05).toInt()
test("카카오페이 + 카카오페이머니 / $point 사용") {
runConfirmTest(
easyPayDetail = PaymentFixture.easypayDetail(
amount = (amount - point),
provider = EasyPayCompanyCode.KAKAOPAY,
discountAmount = point
)
)
}
}
context("계좌이체로 결제한다.") {
test("토스뱅크") {
runConfirmTest(
transferDetail = PaymentFixture.transferDetail(bankCode = BankCode.TOSS_BANK)
)
}
}
context("결제 처리중 오류가 발생한다.") {
lateinit var token: String
val commonRequest = PaymentFixture.confirmRequest
beforeTest {
token = testAuthUtil.defaultUserLogin().second
}
afterTest {
clearMocks(tosspayClient)
}
test("예외 코드가 UserFacingPaymentErrorCode에 있으면 결제 실패 메시지를 같이 담는다.") {
val statusCode = HttpStatus.BAD_REQUEST.value()
val message = "거래금액 한도를 초과했습니다."
every {
tosspayClient.confirm(commonRequest.paymentKey, commonRequest.orderId, commonRequest.amount)
} throws ExternalPaymentException(
httpStatusCode = statusCode,
errorCode = UserFacingPaymentErrorCode.EXCEED_MAX_AMOUNT.name,
message = message
)
runTest(
token = token,
using = {
body(commonRequest)
},
on = {
post("/payments/confirm")
},
expect = {
statusCode(statusCode)
body("code", equalTo(PaymentErrorCode.PAYMENT_CLIENT_ERROR.errorCode))
body("message", containsString(message))
}
)
}
context("예외 코드가 UserFacingPaymentErrorCode에 없으면 Client의 상태 코드에 따라 다르게 처리한다.") {
mapOf(
HttpStatus.BAD_REQUEST.value() to PaymentErrorCode.PAYMENT_CLIENT_ERROR,
HttpStatus.INTERNAL_SERVER_ERROR.value() to PaymentErrorCode.PAYMENT_PROVIDER_ERROR
).forEach { (statusCode, expectedErrorCode) ->
test("statusCode=${statusCode}") {
val message = "잘못된 시크릿키 연동 정보 입니다."
every {
tosspayClient.confirm(commonRequest.paymentKey, commonRequest.orderId, commonRequest.amount)
} throws ExternalPaymentException(
httpStatusCode = statusCode,
errorCode = "INVALID_API_KEY",
message = message
)
runTest(
token = token,
using = {
body(commonRequest)
},
on = {
post("/payments/confirm")
},
expect = {
statusCode(statusCode)
body("code", equalTo(expectedErrorCode.errorCode))
body("message", equalTo(expectedErrorCode.message))
}
)
}
}
}
}
}
context("결제를 취소한다.") {
context("권한이 없으면 접근할 수 없다.") {
val endpoint = "/payments/cancel"
test("비회원") {
runExceptionTest(
method = HttpMethod.POST,
endpoint = endpoint,
requestBody = PaymentFixture.cancelRequest,
expectedErrorCode = AuthErrorCode.MEMBER_NOT_FOUND
)
}
test("관리자") {
runExceptionTest(
token = testAuthUtil.defaultHqAdminLogin().second,
method = HttpMethod.POST,
endpoint = endpoint,
requestBody = PaymentFixture.cancelRequest,
expectedErrorCode = AuthErrorCode.MEMBER_NOT_FOUND
)
}
}
test("정상 취소") {
val (user, token) = testAuthUtil.defaultUserLogin()
val reservation = dummyInitializer.createConfirmReservation(user = user)
val confirmRequest = PaymentFixture.confirmRequest
val paymentCreateResponse = createPayment(
request = confirmRequest,
reservationId = reservation.id
)
every {
tosspayClient.cancel(
confirmRequest.paymentKey,
confirmRequest.amount,
cancelReason = "cancelReason"
)
} returns PaymentFixture.cancelResponse(confirmRequest.amount)
val requestBody = PaymentFixture.cancelRequest.copy(reservationId = reservation.id)
runTest(
token = token,
using = {
body(requestBody)
},
on = {
post("/payments/cancel")
},
expect = {
statusCode(HttpStatus.OK.value())
}
).also {
val payment = paymentRepository.findByIdOrNull(paymentCreateResponse.paymentId)
?: throw AssertionError("Unexpected Exception Occurred.")
val canceledPayment =
canceledPaymentRepository.findByPaymentId(paymentCreateResponse.paymentId)
?: throw AssertionError("Unexpected Exception Occurred.")
payment.status shouldBe PaymentStatus.CANCELED
canceledPayment.paymentId shouldBe payment.id
canceledPayment.cancelAmount shouldBe payment.totalAmount
}
}
test("예약에 대한 결제 정보가 없으면 실패한다.") {
val (user, token) = testAuthUtil.defaultUserLogin()
val reservation = dummyInitializer.createConfirmReservation(user = user)
runExceptionTest(
token = token,
method = HttpMethod.POST,
endpoint = "/payments/cancel",
requestBody = PaymentFixture.cancelRequest.copy(reservationId = reservation.id),
expectedErrorCode = PaymentErrorCode.PAYMENT_NOT_FOUND
)
}
}
}
private fun createPayment(
request: PaymentConfirmRequest,
reservationId: Long,
): PaymentCreateResponse {
every {
tosspayClient.confirm(request.paymentKey, request.orderId, request.amount)
} returns PaymentFixture.confirmResponse(
request.paymentKey,
request.amount,
method = PaymentMethod.CARD,
cardDetail = PaymentFixture.cardDetail(request.amount),
easyPayDetail = null,
transferDetail = null,
)
val paymentResponse = paymentService.requestConfirm(request)
return paymentService.savePayment(reservationId, paymentResponse)
}
fun runConfirmTest(
cardDetail: CardDetailResponse? = null,
easyPayDetail: EasyPayDetailResponse? = null,
transferDetail: TransferDetailResponse? = null,
paymentKey: String = "paymentKey",
amount: Int = 10000,
) {
val token = testAuthUtil.defaultUserLogin().second
val request = PaymentFixture.confirmRequest.copy(paymentKey = paymentKey, amount = amount)
val method = if (easyPayDetail != null) {
PaymentMethod.EASY_PAY
} else if (cardDetail != null) {
PaymentMethod.CARD
} else if (transferDetail != null) {
PaymentMethod.TRANSFER
} else {
throw AssertionError("결제타입 확인 필요.")
}
val clientResponse = PaymentFixture.confirmResponse(
paymentKey, amount, method, cardDetail, easyPayDetail, transferDetail
)
every {
tosspayClient.confirm(request.paymentKey, request.orderId, request.amount)
} returns clientResponse
runTest(
token = token,
using = {
body(request)
},
on = {
post("/payments/confirm")
},
expect = {
statusCode(HttpStatus.OK.value())
}
)
}
}