diff --git a/service/src/main/kotlin/com/sangdol/roomescape/order/business/OrderPostProcessorService.kt b/service/src/main/kotlin/com/sangdol/roomescape/order/business/OrderPostProcessorService.kt new file mode 100644 index 00000000..ccd7c9b9 --- /dev/null +++ b/service/src/main/kotlin/com/sangdol/roomescape/order/business/OrderPostProcessorService.kt @@ -0,0 +1,60 @@ +package com.sangdol.roomescape.order.business + +import com.sangdol.common.persistence.IDGenerator +import com.sangdol.common.persistence.TransactionExecutionUtil +import com.sangdol.roomescape.order.infrastructure.persistence.PostOrderTaskEntity +import com.sangdol.roomescape.order.infrastructure.persistence.PostOrderTaskRepository +import com.sangdol.roomescape.payment.business.PaymentService +import com.sangdol.roomescape.payment.dto.PaymentGatewayResponse +import com.sangdol.roomescape.reservation.business.ReservationService +import io.github.oshai.kotlinlogging.KLogger +import io.github.oshai.kotlinlogging.KotlinLogging +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Propagation +import org.springframework.transaction.annotation.Transactional +import java.time.Instant + +private val log: KLogger = KotlinLogging.logger {} + +@Service +class OrderPostProcessorService( + private val idGenerator: IDGenerator, + private val reservationService: ReservationService, + private val paymentService: PaymentService, + private val postOrderTaskRepository: PostOrderTaskRepository, + private val transactionExecutionUtil: TransactionExecutionUtil +) { + @Transactional(propagation = Propagation.REQUIRES_NEW) + fun processAfterPaymentConfirmation( + reservationId: Long, + paymentResponse: PaymentGatewayResponse + ) { + val paymentKey = paymentResponse.paymentKey + try { + log.info { "[processAfterPaymentConfirmation] 결제 정보 저장 및 예약 확정 처리 시작: reservationId=${reservationId}, paymentKey=${paymentKey}" } + + val paymentCreateResponse = paymentService.savePayment(reservationId, paymentResponse) + reservationService.confirmReservation(reservationId) + + log.info { + "[processAfterPaymentConfirmation] 결제 정보 저장 및 예약 확정 처리 완료: reservationId=${reservationId}, paymentKey=${paymentKey}, paymentId=${paymentCreateResponse.paymentId}, paymentDetailId=${paymentCreateResponse.detailId}" + } + } catch (_: Exception) { + log.warn { "[processAfterPaymentConfirmation] 결제 정보 저장 및 예약 확정 처리 실패. 작업 저장 시작: reservationId=${reservationId}, paymentKey=$paymentKey}" } + + transactionExecutionUtil.withNewTransaction(isReadOnly = false) { + PostOrderTaskEntity( + id = idGenerator.create(), + reservationId = reservationId, + paymentKey = paymentKey, + trial = 1, + nextRetryAt = Instant.now().plusSeconds(30), + ).also { + postOrderTaskRepository.save(it) + } + } + + log.info { "[processAfterPaymentConfirmation] 작업 저장 완료" } + } + } +}