generated from pricelees/issue-pr-template
[#66] 결제 & 예약 확정 로직 수정 #67
@ -0,0 +1,48 @@
|
|||||||
|
package com.sangdol.roomescape.payment.business.event
|
||||||
|
|
||||||
|
import com.sangdol.common.persistence.IDGenerator
|
||||||
|
import com.sangdol.roomescape.payment.infrastructure.persistence.PaymentDetailEntity
|
||||||
|
import com.sangdol.roomescape.payment.infrastructure.persistence.PaymentDetailRepository
|
||||||
|
import com.sangdol.roomescape.payment.infrastructure.persistence.PaymentEntity
|
||||||
|
import com.sangdol.roomescape.payment.infrastructure.persistence.PaymentRepository
|
||||||
|
import com.sangdol.roomescape.payment.mapper.toDetailEntity
|
||||||
|
import com.sangdol.roomescape.payment.mapper.toEntity
|
||||||
|
import io.github.oshai.kotlinlogging.KLogger
|
||||||
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import org.springframework.context.event.EventListener
|
||||||
|
import org.springframework.scheduling.annotation.Async
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import org.springframework.transaction.annotation.Transactional
|
||||||
|
|
||||||
|
private val log: KLogger = KotlinLogging.logger {}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class PaymentEventListener(
|
||||||
|
private val idGenerator: IDGenerator,
|
||||||
|
private val paymentRepository: PaymentRepository,
|
||||||
|
private val paymentDetailRepository: PaymentDetailRepository
|
||||||
|
) {
|
||||||
|
|
||||||
|
@Async
|
||||||
|
@EventListener
|
||||||
|
@Transactional
|
||||||
|
fun handlePaymentEvent(event: PaymentEvent) {
|
||||||
|
val reservationId = event.reservationId
|
||||||
|
|
||||||
|
log.info { "[handlePaymentEvent] 결제 정보 저장 이벤트 수신: reservationId=${reservationId}, paymentKey=${event.paymentKey}" }
|
||||||
|
|
||||||
|
val paymentId = idGenerator.create()
|
||||||
|
val paymentEntity: PaymentEntity = event.toEntity(paymentId)
|
||||||
|
paymentRepository.save(paymentEntity).also {
|
||||||
|
log.info { "[handlePaymentEvent] 결제 정보 저장 완료: paymentId=${paymentId}" }
|
||||||
|
}
|
||||||
|
|
||||||
|
val paymentDetailId = idGenerator.create()
|
||||||
|
val paymentDetailEntity: PaymentDetailEntity = event.toDetailEntity(id = paymentDetailId, paymentId = paymentId)
|
||||||
|
paymentDetailRepository.save(paymentDetailEntity).also {
|
||||||
|
log.info { "[handlePaymentEvent] 결제 상세 저장 완료: paymentDetailId=${paymentDetailId}" }
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info { "[handlePaymentEvent] 결제 정보 저장 이벤트 처리 완료" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
package com.sangdol.roomescape.payment.business.event
|
||||||
|
|
||||||
|
import com.sangdol.roomescape.payment.business.domain.PaymentMethod
|
||||||
|
import com.sangdol.roomescape.payment.infrastructure.persistence.PaymentCardDetailEntity
|
||||||
|
import com.sangdol.roomescape.payment.infrastructure.persistence.PaymentDetailRepository
|
||||||
|
import com.sangdol.roomescape.payment.infrastructure.persistence.PaymentRepository
|
||||||
|
import com.sangdol.roomescape.payment.mapper.toEvent
|
||||||
|
import com.sangdol.roomescape.supports.FunSpecSpringbootTest
|
||||||
|
import com.sangdol.roomescape.supports.PaymentFixture
|
||||||
|
import com.sangdol.roomescape.supports.initialize
|
||||||
|
import io.kotest.assertions.assertSoftly
|
||||||
|
import io.kotest.matchers.nulls.shouldNotBeNull
|
||||||
|
import io.kotest.matchers.shouldBe
|
||||||
|
|
||||||
|
class PaymentEventListenerTest(
|
||||||
|
private val paymentEventListener: PaymentEventListener,
|
||||||
|
private val paymentRepository: PaymentRepository,
|
||||||
|
private val paymentDetailRepository: PaymentDetailRepository,
|
||||||
|
) : FunSpecSpringbootTest() {
|
||||||
|
|
||||||
|
init {
|
||||||
|
test("결제 완료 이벤트를 처리한다.") {
|
||||||
|
val reservationId = initialize("FK 제약조건 해소를 위한 예약 생성") {
|
||||||
|
val user = testAuthUtil.defaultUser()
|
||||||
|
dummyInitializer.createPendingReservation(user)
|
||||||
|
}.id
|
||||||
|
|
||||||
|
val paymentExternalAPIResponse = PaymentFixture.confirmResponse(
|
||||||
|
paymentKey = "paymentKey",
|
||||||
|
amount = 100_000,
|
||||||
|
method = PaymentMethod.CARD
|
||||||
|
)
|
||||||
|
|
||||||
|
paymentEventListener.handlePaymentEvent(paymentExternalAPIResponse.toEvent(reservationId)).also {
|
||||||
|
Thread.sleep(100)
|
||||||
|
}
|
||||||
|
|
||||||
|
val payment = paymentRepository.findByReservationId(reservationId)
|
||||||
|
assertSoftly(payment!!) {
|
||||||
|
this.paymentKey shouldBe paymentExternalAPIResponse.paymentKey
|
||||||
|
this.totalAmount shouldBe paymentExternalAPIResponse.totalAmount
|
||||||
|
this.method shouldBe paymentExternalAPIResponse.method
|
||||||
|
}
|
||||||
|
|
||||||
|
val paymentDetail = paymentDetailRepository.findByPaymentId(payment.id)
|
||||||
|
assertSoftly(paymentDetail) {
|
||||||
|
this.shouldNotBeNull()
|
||||||
|
this::class shouldBe PaymentCardDetailEntity::class
|
||||||
|
(this as PaymentCardDetailEntity).amount shouldBe paymentExternalAPIResponse.totalAmount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user