From 81e1f7f6b1f6542bdd1105a3aa95d044bb6d7bc7 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 17 May 2024 18:16:27 +0900 Subject: [PATCH 1/2] =?UTF-8?q?PG=20=EC=8B=AC=EC=82=AC=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EC=BA=94=20=EC=B6=A9=EC=A0=84=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../can/charge/temp/ChargeTempController.kt | 34 ++++++++ .../can/charge/temp/ChargeTempRequest.kt | 9 ++ .../can/charge/temp/ChargeTempService.kt | 84 +++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempController.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempRequest.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempService.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempController.kt new file mode 100644 index 0000000..aafbc79 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempController.kt @@ -0,0 +1,34 @@ +package kr.co.vividnext.sodalive.can.charge.temp + +import kr.co.vividnext.sodalive.can.charge.VerifyRequest +import kr.co.vividnext.sodalive.common.ApiResponse +import kr.co.vividnext.sodalive.common.SodaException +import kr.co.vividnext.sodalive.member.Member +import org.springframework.security.core.annotation.AuthenticationPrincipal +import org.springframework.security.core.userdetails.User +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/charge/temp") +class ChargeTempController(private val service: ChargeTempService) { + @PostMapping + fun charge( + @RequestBody request: ChargeTempRequest, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null) { + throw SodaException("로그인 정보를 확인해주세요.") + } + + ApiResponse.ok(service.charge(member, request)) + } + + @PostMapping("/verify") + fun verify( + @RequestBody request: VerifyRequest, + @AuthenticationPrincipal user: User + ) = ApiResponse.ok(service.verify(user, request)) +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempRequest.kt new file mode 100644 index 0000000..d24f907 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempRequest.kt @@ -0,0 +1,9 @@ +package kr.co.vividnext.sodalive.can.charge.temp + +import kr.co.vividnext.sodalive.can.payment.PaymentGateway + +data class ChargeTempRequest( + val can: Int, + val price: Int, + val paymentGateway: PaymentGateway +) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempService.kt new file mode 100644 index 0000000..16545a2 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempService.kt @@ -0,0 +1,84 @@ +package kr.co.vividnext.sodalive.can.charge.temp + +import com.fasterxml.jackson.databind.ObjectMapper +import kr.co.bootpay.Bootpay +import kr.co.vividnext.sodalive.can.charge.Charge +import kr.co.vividnext.sodalive.can.charge.ChargeRepository +import kr.co.vividnext.sodalive.can.charge.ChargeResponse +import kr.co.vividnext.sodalive.can.charge.VerifyRequest +import kr.co.vividnext.sodalive.can.charge.VerifyResult +import kr.co.vividnext.sodalive.can.payment.Payment +import kr.co.vividnext.sodalive.can.payment.PaymentGateway +import kr.co.vividnext.sodalive.can.payment.PaymentStatus +import kr.co.vividnext.sodalive.common.SodaException +import kr.co.vividnext.sodalive.extensions.moneyFormat +import kr.co.vividnext.sodalive.member.Member +import kr.co.vividnext.sodalive.member.MemberRepository +import org.springframework.beans.factory.annotation.Value +import org.springframework.data.repository.findByIdOrNull +import org.springframework.security.core.userdetails.User +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional + +@Service +@Transactional(readOnly = true) +class ChargeTempService( + private val chargeRepository: ChargeRepository, + private val memberRepository: MemberRepository, + + private val objectMapper: ObjectMapper, + + @Value("\${bootpay.application-id}") + private val bootpayApplicationId: String, + @Value("\${bootpay.private-key}") + private val bootpayPrivateKey: String +) { + + @Transactional + fun charge(member: Member, request: ChargeTempRequest): ChargeResponse { + val charge = Charge(request.can, 0) + charge.title = "${request.can.moneyFormat()} 캔" + charge.member = member + + val payment = Payment(paymentGateway = request.paymentGateway) + payment.price = request.price.toDouble() + charge.payment = payment + + chargeRepository.save(charge) + + return ChargeResponse(chargeId = charge.id!!) + } + + @Transactional + fun verify(user: User, verifyRequest: VerifyRequest) { + val charge = chargeRepository.findByIdOrNull(verifyRequest.orderId.toLong()) + ?: throw SodaException("결제정보에 오류가 있습니다.") + val member = memberRepository.findByEmail(user.username) + ?: throw SodaException("로그인 정보를 확인해주세요.") + + if (charge.payment!!.paymentGateway == PaymentGateway.PG) { + val bootpay = Bootpay(bootpayApplicationId, bootpayPrivateKey) + + try { + bootpay.accessToken + val verifyResult = objectMapper.convertValue( + bootpay.getReceipt(verifyRequest.receiptId), + VerifyResult::class.java + ) + + if (verifyResult.status == 1 && verifyResult.price == charge.can?.price) { + charge.payment?.receiptId = verifyResult.receiptId + charge.payment?.method = verifyResult.method + charge.payment?.status = PaymentStatus.COMPLETE + member.charge(charge.chargeCan, charge.rewardCan, "pg") + } else { + throw SodaException("결제정보에 오류가 있습니다.") + } + } catch (e: Exception) { + throw SodaException("결제정보에 오류가 있습니다.") + } + } else { + throw SodaException("결제정보에 오류가 있습니다.") + } + } +} -- 2.40.1 From b0988cca7033530f5dc5df22592a0c230f286ae7 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 17 May 2024 21:14:49 +0900 Subject: [PATCH 2/2] =?UTF-8?q?PG=20=EC=8B=AC=EC=82=AC=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EC=BA=94=20=EC=B6=A9=EC=A0=84=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../co/vividnext/sodalive/can/charge/temp/ChargeTempService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempService.kt index 16545a2..a578dac 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/can/charge/temp/ChargeTempService.kt @@ -66,7 +66,7 @@ class ChargeTempService( VerifyResult::class.java ) - if (verifyResult.status == 1 && verifyResult.price == charge.can?.price) { + if (verifyResult.status == 1 && verifyResult.price == charge.payment!!.price.toInt()) { charge.payment?.receiptId = verifyResult.receiptId charge.payment?.method = verifyResult.method charge.payment?.status = PaymentStatus.COMPLETE -- 2.40.1