package roomescape.payment.business 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.payment.infrastructure.persistence.CanceledPaymentEntity import roomescape.payment.infrastructure.persistence.PaymentEntity import roomescape.payment.web.PaymentCancelRequest import roomescape.payment.web.PaymentCancelResponse import roomescape.payment.web.PaymentCreateResponse import roomescape.payment.web.toCreateResponse import roomescape.reservation.infrastructure.persistence.ReservationEntity import java.time.OffsetDateTime private val log = KotlinLogging.logger {} @Service class PaymentService( private val paymentFinder: PaymentFinder, private val paymentWriter: PaymentWriter ) { @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 ) return created.toCreateResponse() .also { log.info { "[PaymentService.createPayment] 완료: paymentKey=${it.paymentKey}, reservationId=${reservation.id}, paymentId=${it.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}" } } } @Transactional fun createCanceledPayment(reservationId: Long): PaymentCancelRequest { log.debug { "[PaymentService.createCanceledPayment] 시작: reservationId=$reservationId" } val payment: PaymentEntity = paymentFinder.findByReservationId(reservationId) val canceled: CanceledPaymentEntity = paymentWriter.createCanceled( payment = payment, cancelReason = "예약 취소", canceledAt = OffsetDateTime.now(), ) return PaymentCancelRequest(canceled.paymentKey, canceled.cancelAmount, canceled.cancelReason) .also { log.info { "[PaymentService.createCanceledPayment] 완료: reservationId=$reservationId, paymentKey=${it.paymentKey}" } } } @Transactional fun updateCanceledTime( paymentKey: String, canceledAt: OffsetDateTime, ) { log.debug { "[PaymentService.updateCanceledTime] 시작: paymentKey=$paymentKey, canceledAt=$canceledAt" } paymentFinder.findCanceledByKey(paymentKey).apply { this.canceledAt = canceledAt } log.info { "[PaymentService.updateCanceledTime] 완료: paymentKey=$paymentKey, canceledAt=$canceledAt" } } }