refactor: 기존의 외부 API 호출 + 결제 정보 저장 통합 로직을 각각 분리

This commit is contained in:
이상진 2025-10-07 16:31:40 +09:00
parent dd406505ec
commit ef64a740c2
3 changed files with 36 additions and 24 deletions

View File

@ -1,6 +1,8 @@
package com.sangdol.roomescape.payment.business
import com.sangdol.common.persistence.TransactionExecutionUtil
import com.sangdol.roomescape.payment.business.domain.PaymentClientError
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
@ -24,25 +26,37 @@ class PaymentService(
private val paymentWriter: PaymentWriter,
private val transactionExecutionUtil: TransactionExecutionUtil,
) {
fun confirm(reservationId: Long, request: PaymentConfirmRequest): PaymentCreateResponse {
val clientConfirmResponse: PaymentClientConfirmResponse = paymentClient.confirm(
paymentKey = request.paymentKey,
orderId = request.orderId,
amount = request.amount,
)
fun requestConfirm(request: PaymentConfirmRequest): PaymentClientConfirmResponse {
try {
return paymentClient.confirm(request.paymentKey, request.orderId, request.amount)
} catch (e: ExternalPaymentException) {
val errorCode = if (e.httpStatusCode in 400..<500) {
PaymentErrorCode.PAYMENT_CLIENT_ERROR
} else {
PaymentErrorCode.PAYMENT_PROVIDER_ERROR
}
return transactionExecutionUtil.withNewTransaction(isReadOnly = false) {
val message = if (PaymentClientError.contains(e.errorCode)) {
"${errorCode.message}(${e.message})"
} else {
errorCode.message
}
throw PaymentException(errorCode, message)
}
}
fun savePayment(
reservationId: Long,
paymentConfirmResponse: PaymentClientConfirmResponse
): PaymentCreateResponse {
val payment: PaymentEntity = paymentWriter.createPayment(
reservationId = reservationId,
paymentClientConfirmResponse = clientConfirmResponse
paymentClientConfirmResponse = paymentConfirmResponse
)
val detail: PaymentDetailEntity = paymentWriter.createDetail(clientConfirmResponse, payment.id)
val detail: PaymentDetailEntity = paymentWriter.createDetail(paymentConfirmResponse, payment.id)
PaymentCreateResponse(paymentId = payment.id, detailId = detail.id)
} ?: run {
log.warn { "[confirm] 결제 확정 중 예상치 못한 null 반환" }
throw PaymentException(PaymentErrorCode.PAYMENT_UNEXPECTED_ERROR)
}
return PaymentCreateResponse(paymentId = payment.id, detailId = detail.id)
}
fun cancel(userId: Long, request: PaymentCancelRequest) {

View File

@ -4,16 +4,15 @@ import com.sangdol.common.types.web.CommonApiResponse
import com.sangdol.roomescape.auth.web.support.User
import com.sangdol.roomescape.auth.web.support.UserOnly
import com.sangdol.roomescape.common.types.CurrentUserContext
import com.sangdol.roomescape.payment.infrastructure.client.PaymentClientConfirmResponse
import com.sangdol.roomescape.payment.web.PaymentCancelRequest
import com.sangdol.roomescape.payment.web.PaymentConfirmRequest
import com.sangdol.roomescape.payment.web.PaymentCreateResponse
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.responses.ApiResponses
import jakarta.validation.Valid
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestParam
interface PaymentAPI {
@ -21,9 +20,8 @@ interface PaymentAPI {
@Operation(summary = "결제 승인")
@ApiResponses(ApiResponse(responseCode = "200", useReturnTypeSchema = true))
fun confirmPayment(
@RequestParam(required = true) reservationId: Long,
@Valid @RequestBody request: PaymentConfirmRequest
): ResponseEntity<CommonApiResponse<PaymentCreateResponse>>
): ResponseEntity<CommonApiResponse<PaymentClientConfirmResponse>>
@Operation(summary = "결제 취소")
@ApiResponses(ApiResponse(responseCode = "200", useReturnTypeSchema = true))

View File

@ -5,6 +5,7 @@ import com.sangdol.roomescape.auth.web.support.User
import com.sangdol.roomescape.common.types.CurrentUserContext
import com.sangdol.roomescape.payment.business.PaymentService
import com.sangdol.roomescape.payment.docs.PaymentAPI
import com.sangdol.roomescape.payment.infrastructure.client.PaymentClientConfirmResponse
import jakarta.validation.Valid
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@ -15,12 +16,11 @@ class PaymentController(
private val paymentService: PaymentService
) : PaymentAPI {
@PostMapping
@PostMapping("/confirm")
override fun confirmPayment(
@RequestParam(required = true) reservationId: Long,
@Valid @RequestBody request: PaymentConfirmRequest
): ResponseEntity<CommonApiResponse<PaymentCreateResponse>> {
val response = paymentService.confirm(reservationId, request)
): ResponseEntity<CommonApiResponse<PaymentClientConfirmResponse>> {
val response = paymentService.requestConfirm(request)
return ResponseEntity.ok(CommonApiResponse(response))
}