package roomescape.payment.business import com.github.f4b6a3.tsid.TsidFactory import io.github.oshai.kotlinlogging.KLogger import io.github.oshai.kotlinlogging.KotlinLogging import org.springframework.stereotype.Component import roomescape.common.config.next import roomescape.payment.exception.PaymentErrorCode import roomescape.payment.exception.PaymentException import roomescape.payment.infrastructure.client.* import roomescape.payment.infrastructure.common.PaymentMethod import roomescape.payment.infrastructure.common.PaymentType 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 java.time.LocalDateTime private val log: KLogger = KotlinLogging.logger {} @Component class PaymentWriter( private val paymentRepository: PaymentRepository, private val paymentDetailRepository: PaymentDetailRepository, private val canceledPaymentRepository: CanceledPaymentRepository, private val tsidFactory: TsidFactory, ) { fun createPayment( reservationId: Long, orderId: String, paymentType: PaymentType, paymentClientConfirmResponse: PaymentClientConfirmResponse ): PaymentEntity { log.info { "[PaymentWriterV2.createPayment] 결제 승인 및 결제 정보 저장 시작: reservationId=${reservationId}, paymentKey=${paymentClientConfirmResponse.paymentKey}" } return paymentClientConfirmResponse.toEntity( id = tsidFactory.next(), reservationId, orderId, paymentType ).also { paymentRepository.save(it) log.info { "[PaymentWriterV2.createPayment] 결제 승인 및 결제 정보 저장 완료: reservationId=${reservationId}, payment.id=${it.id}" } } } fun createDetail( paymentResponse: PaymentClientConfirmResponse, paymentId: Long, ): PaymentDetailEntity { val method: PaymentMethod = paymentResponse.method val id = tsidFactory.next() if (method == PaymentMethod.TRANSFER) { return paymentDetailRepository.save(paymentResponse.toTransferDetailEntity(id, paymentId)) } if (method == PaymentMethod.EASY_PAY && paymentResponse.card == null) { return paymentDetailRepository.save(paymentResponse.toEasypayPrepaidDetailEntity(id, paymentId)) } if (paymentResponse.card != null) { return paymentDetailRepository.save(paymentResponse.toCardDetailEntity(id, paymentId)) } throw PaymentException(PaymentErrorCode.NOT_SUPPORTED_PAYMENT_TYPE) } fun cancel( memberId: Long, payment: PaymentEntity, requestedAt: LocalDateTime, cancelResponse: PaymentClientCancelResponse ) { log.debug { "[PaymentWriterV2.cancelPayment] 결제 취소 정보 저장 시작: payment.id=${payment.id}" } val canceledPayment: CanceledPaymentEntity = cancelResponse.cancels.toEntity( id = tsidFactory.next(), paymentId = payment.id, cancelRequestedAt = requestedAt, canceledBy = memberId ) run { canceledPaymentRepository.save(canceledPayment) paymentRepository.save(payment.apply { this.cancel() }) }.also { log.debug { "[PaymentWriterV2.cancelPayment] 결제 취소 정보 저장 완료: payment.id=${payment.id}" } } } }