generated from pricelees/issue-pr-template
refactor: payment 전용 API 구성을 위한 PaymentService 개선
This commit is contained in:
parent
d62bd444f1
commit
7f4af4770d
@ -1,99 +1,112 @@
|
||||
package roomescape.payment.business
|
||||
|
||||
import io.github.oshai.kotlinlogging.KLogger
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import roomescape.payment.implement.PaymentFinder
|
||||
import roomescape.payment.implement.PaymentWriter
|
||||
import roomescape.payment.infrastructure.client.PaymentApproveResponse
|
||||
import roomescape.common.util.TransactionExecutionUtil
|
||||
import roomescape.payment.exception.PaymentErrorCode
|
||||
import roomescape.payment.exception.PaymentException
|
||||
import roomescape.payment.infrastructure.client.PaymentClientCancelResponse
|
||||
import roomescape.payment.infrastructure.client.PaymentClientConfirmResponse
|
||||
import roomescape.payment.infrastructure.client.TosspaymentClient
|
||||
import roomescape.payment.infrastructure.persistence.CanceledPaymentEntity
|
||||
import roomescape.payment.infrastructure.persistence.CanceledPaymentRepository
|
||||
import roomescape.payment.infrastructure.persistence.PaymentDetailEntity
|
||||
import roomescape.payment.infrastructure.persistence.PaymentDetailRepository
|
||||
import roomescape.payment.infrastructure.persistence.PaymentEntity
|
||||
import roomescape.payment.infrastructure.persistence.PaymentRepository
|
||||
import roomescape.payment.web.PaymentCancelRequest
|
||||
import roomescape.payment.web.PaymentCancelResponse
|
||||
import roomescape.payment.web.PaymentConfirmRequest
|
||||
import roomescape.payment.web.PaymentCreateResponse
|
||||
import roomescape.payment.web.toCreateResponse
|
||||
import roomescape.reservation.infrastructure.persistence.ReservationEntity
|
||||
import java.time.OffsetDateTime
|
||||
import roomescape.payment.web.PaymentRetrieveResponse
|
||||
import roomescape.payment.web.toCancelDetailResponse
|
||||
import roomescape.payment.web.toPaymentDetailResponse
|
||||
import roomescape.payment.web.toRetrieveResponse
|
||||
|
||||
private val log = KotlinLogging.logger {}
|
||||
private val log: KLogger = KotlinLogging.logger {}
|
||||
|
||||
@Service
|
||||
class PaymentService(
|
||||
private val paymentFinder: PaymentFinder,
|
||||
private val paymentWriter: PaymentWriter
|
||||
private val paymentClient: TosspaymentClient,
|
||||
private val paymentRepository: PaymentRepository,
|
||||
private val paymentDetailRepository: PaymentDetailRepository,
|
||||
private val canceledPaymentRepository: CanceledPaymentRepository,
|
||||
private val paymentWriter: PaymentWriter,
|
||||
private val transactionExecutionUtil: TransactionExecutionUtil,
|
||||
) {
|
||||
@Transactional(readOnly = true)
|
||||
fun existsByReservationId(reservationId: Long): Boolean {
|
||||
log.debug { "[PaymentService.existsByReservationId] 시작: reservationId=$reservationId" }
|
||||
|
||||
return paymentFinder.existsPaymentByReservationId(reservationId)
|
||||
.also { log.info { "[PaymentService.existsByReservationId] 완료: reservationId=$reservationId, isPaid=$it" } }
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun createPayment(
|
||||
approvedPaymentInfo: PaymentApproveResponse,
|
||||
reservation: ReservationEntity,
|
||||
): PaymentCreateResponse {
|
||||
log.debug { "[PaymentService.createPayment] 시작: paymentKey=${approvedPaymentInfo.paymentKey}, reservationId=${reservation.id}" }
|
||||
|
||||
val created: PaymentEntity = paymentWriter.create(
|
||||
paymentKey = approvedPaymentInfo.paymentKey,
|
||||
orderId = approvedPaymentInfo.orderId,
|
||||
totalAmount = approvedPaymentInfo.totalAmount,
|
||||
approvedAt = approvedPaymentInfo.approvedAt,
|
||||
reservation = reservation
|
||||
fun confirm(reservationId: Long, request: PaymentConfirmRequest): PaymentCreateResponse {
|
||||
val clientConfirmResponse: PaymentClientConfirmResponse = paymentClient.confirm(
|
||||
paymentKey = request.paymentKey,
|
||||
orderId = request.orderId,
|
||||
amount = request.amount,
|
||||
)
|
||||
|
||||
return created.toCreateResponse()
|
||||
.also { log.info { "[PaymentService.createPayment] 완료: paymentKey=${it.paymentKey}, reservationId=${reservation.id}, paymentId=${it.id}" } }
|
||||
}
|
||||
return transactionExecutionUtil.withNewTransaction(isReadOnly = false) {
|
||||
val payment: PaymentEntity = paymentWriter.createPayment(
|
||||
reservationId = reservationId,
|
||||
orderId = request.orderId,
|
||||
paymentType = request.paymentType,
|
||||
paymentClientConfirmResponse = clientConfirmResponse
|
||||
)
|
||||
val detail: PaymentDetailEntity = paymentWriter.createDetail(clientConfirmResponse, payment.id)
|
||||
|
||||
@Transactional
|
||||
fun createCanceledPayment(
|
||||
canceledPaymentInfo: PaymentCancelResponse,
|
||||
approvedAt: OffsetDateTime,
|
||||
paymentKey: String,
|
||||
): CanceledPaymentEntity {
|
||||
log.debug { "[PaymentService.createCanceledPayment] 시작: paymentKey=$paymentKey" }
|
||||
|
||||
val created: CanceledPaymentEntity = paymentWriter.createCanceled(
|
||||
cancelReason = canceledPaymentInfo.cancelReason,
|
||||
cancelAmount = canceledPaymentInfo.cancelAmount,
|
||||
canceledAt = canceledPaymentInfo.canceledAt,
|
||||
approvedAt = approvedAt,
|
||||
paymentKey = paymentKey
|
||||
)
|
||||
|
||||
return created.also {
|
||||
log.info { "[PaymentService.createCanceledPayment] 완료: paymentKey=${paymentKey}, canceledPaymentId=${it.id}" }
|
||||
PaymentCreateResponse(paymentId = payment.id, detailId = detail.id)
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun createCanceledPayment(reservationId: Long): PaymentCancelRequest {
|
||||
log.debug { "[PaymentService.createCanceledPayment] 시작: reservationId=$reservationId" }
|
||||
fun cancel(memberId: Long, request: PaymentCancelRequest) {
|
||||
val payment: PaymentEntity = findByReservationIdOrThrow(request.reservationId)
|
||||
|
||||
val payment: PaymentEntity = paymentFinder.findByReservationId(reservationId)
|
||||
val canceled: CanceledPaymentEntity = paymentWriter.createCanceled(
|
||||
payment = payment,
|
||||
cancelReason = "예약 취소",
|
||||
canceledAt = OffsetDateTime.now(),
|
||||
val clientCancelResponse: PaymentClientCancelResponse = paymentClient.cancel(
|
||||
paymentKey = payment.paymentKey,
|
||||
amount = payment.totalAmount,
|
||||
cancelReason = request.cancelReason
|
||||
)
|
||||
|
||||
return PaymentCancelRequest(canceled.paymentKey, canceled.cancelAmount, canceled.cancelReason)
|
||||
.also { log.info { "[PaymentService.createCanceledPayment] 완료: reservationId=$reservationId, paymentKey=${it.paymentKey}" } }
|
||||
transactionExecutionUtil.withNewTransaction(isReadOnly = false) {
|
||||
paymentWriter.cancel(
|
||||
memberId = memberId,
|
||||
payment = payment,
|
||||
requestedAt = request.requestedAt,
|
||||
cancelResponse = clientCancelResponse
|
||||
)
|
||||
}.also {
|
||||
log.info { "[PaymentService.cancel] 결제 취소 완료: paymentId=${payment.id}" }
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun updateCanceledTime(
|
||||
paymentKey: String,
|
||||
canceledAt: OffsetDateTime,
|
||||
) {
|
||||
log.debug { "[PaymentService.updateCanceledTime] 시작: paymentKey=$paymentKey, canceledAt=$canceledAt" }
|
||||
@Transactional(readOnly = true)
|
||||
fun findDetailByReservationId(reservationId: Long): PaymentRetrieveResponse {
|
||||
val payment: PaymentEntity = findByReservationIdOrThrow(reservationId)
|
||||
val paymentDetail: PaymentDetailEntity = findDetailByPaymentIdOrThrow(payment.id)
|
||||
val cancelDetail: CanceledPaymentEntity? = canceledPaymentRepository.findByPaymentId(payment.id)
|
||||
|
||||
paymentFinder.findCanceledByKey(paymentKey).apply { this.canceledAt = canceledAt }
|
||||
return payment.toRetrieveResponse(
|
||||
detail = paymentDetail.toPaymentDetailResponse(),
|
||||
cancel = cancelDetail?.toCancelDetailResponse()
|
||||
)
|
||||
}
|
||||
|
||||
log.info { "[PaymentService.updateCanceledTime] 완료: paymentKey=$paymentKey, canceledAt=$canceledAt" }
|
||||
private fun findByReservationIdOrThrow(reservationId: Long): PaymentEntity {
|
||||
log.info { "[PaymentService.findByReservationIdOrThrow] 결제 정보 조회 시작: reservationId=: $reservationId" }
|
||||
|
||||
return paymentRepository.findByReservationId(reservationId)
|
||||
?.also { log.info { "[PaymentService.findByReservationIdOrThrow] 결제 정보 조회 완료: reservationId=$reservationId, paymentId=${it.id}" } }
|
||||
?: run {
|
||||
log.warn { "[PaymentService.findByReservationIdOrThrow] 결제 정보 조회 실패: reservationId=$reservationId" }
|
||||
throw PaymentException(PaymentErrorCode.PAYMENT_NOT_FOUND)
|
||||
}
|
||||
}
|
||||
|
||||
private fun findDetailByPaymentIdOrThrow(paymentId: Long): PaymentDetailEntity {
|
||||
log.info { "[PaymentService.findDetailByPaymentIdOrThrow] 결제 상세 정보 조회 시작: paymentId=$paymentId" }
|
||||
|
||||
return paymentDetailRepository.findByPaymentId(paymentId)
|
||||
?.also { log.info { "[PaymentService.findDetailByPaymentIdOrThrow] 결제 상세 정보 조회 완료: paymentId=$paymentId, detailId=${it.id}}" } }
|
||||
?: run {
|
||||
log.warn { "[PaymentService.findDetailByPaymentIdOrThrow] 결제 상세 정보 조회 실패: paymentId=$paymentId" }
|
||||
throw PaymentException(PaymentErrorCode.PAYMENT_DETAIL_NOT_FOUND)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user