캔 결제 메시지 다국어 처리
This commit is contained in:
@@ -27,7 +27,7 @@ class CanController(private val service: CanService) {
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
ApiResponse.ok(service.getCanStatus(member, container))
|
||||
@@ -41,7 +41,7 @@ class CanController(private val service: CanService) {
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
ApiResponse.ok(service.getCanUseStatus(member, pageable, timezone, container))
|
||||
@@ -55,7 +55,7 @@ class CanController(private val service: CanService) {
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
ApiResponse.ok(service.getCanChargeStatus(member, pageable, timezone, container))
|
||||
|
||||
@@ -33,7 +33,7 @@ class ChargeController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
ApiResponse.ok(service.payverseCharge(member, request))
|
||||
@@ -45,7 +45,7 @@ class ChargeController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
val response = service.payverseVerify(memberId = member.id!!, verifyRequest)
|
||||
@@ -83,7 +83,7 @@ class ChargeController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
ApiResponse.ok(service.charge(member, chargeRequest))
|
||||
@@ -95,7 +95,7 @@ class ChargeController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
val response = service.verify(memberId = member.id!!, verifyRequest)
|
||||
@@ -109,7 +109,7 @@ class ChargeController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
val response = service.verifyHecto(memberId = member.id!!, verifyRequest)
|
||||
@@ -123,7 +123,7 @@ class ChargeController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
ApiResponse.ok(service.appleCharge(member, chargeRequest))
|
||||
@@ -135,7 +135,7 @@ class ChargeController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
val response = service.appleVerify(memberId = member.id!!, verifyRequest)
|
||||
@@ -149,7 +149,7 @@ class ChargeController(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
if (request.paymentGateway == PaymentGateway.GOOGLE_IAP) {
|
||||
@@ -174,7 +174,7 @@ class ChargeController(
|
||||
trackingCharge(member, response)
|
||||
ApiResponse.ok(Unit)
|
||||
} else {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ 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.google.GooglePlayService
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.MemberRepository
|
||||
import kr.co.vividnext.sodalive.point.MemberPoint
|
||||
@@ -53,6 +55,8 @@ class ChargeService(
|
||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
||||
|
||||
private val googlePlayService: GooglePlayService,
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext,
|
||||
|
||||
@Value("\${bootpay.application-id}")
|
||||
private val bootpayApplicationId: String,
|
||||
@@ -174,10 +178,10 @@ class ChargeService(
|
||||
@Transactional
|
||||
fun chargeByCoupon(couponNumber: String, member: Member): String {
|
||||
val canCouponNumber = couponNumberRepository.findByCouponNumber(couponNumber = couponNumber)
|
||||
?: throw SodaException("잘못된 쿠폰번호입니다.\n고객센터로 문의해 주시기 바랍니다.")
|
||||
?: throw SodaException(messageKey = "can.coupon.invalid_number_contact")
|
||||
|
||||
if (canCouponNumber.member != null) {
|
||||
throw SodaException("이미 사용한 쿠폰번호 입니다.")
|
||||
throw SodaException(messageKey = "can.coupon.already_used")
|
||||
}
|
||||
canCouponNumber.member = member
|
||||
|
||||
@@ -186,7 +190,7 @@ class ChargeService(
|
||||
when (coupon.couponType) {
|
||||
CouponType.CAN -> {
|
||||
val couponCharge = Charge(0, coupon.can, status = ChargeStatus.COUPON)
|
||||
couponCharge.title = "${coupon.can} 캔"
|
||||
couponCharge.title = formatMessage("can.charge.title", coupon.can)
|
||||
couponCharge.member = member
|
||||
|
||||
val payment = Payment(
|
||||
@@ -198,7 +202,7 @@ class ChargeService(
|
||||
chargeRepository.save(couponCharge)
|
||||
|
||||
member.charge(0, coupon.can, "pg")
|
||||
return "쿠폰 사용이 완료되었습니다.\n${coupon.can}캔이 지급되었습니다."
|
||||
return formatMessage("can.coupon.use_complete", coupon.can)
|
||||
}
|
||||
|
||||
CouponType.POINT -> {
|
||||
@@ -226,7 +230,7 @@ class ChargeService(
|
||||
)
|
||||
)
|
||||
|
||||
return "쿠폰 사용이 완료되었습니다.\n${coupon.can}포인트가 지급되었습니다."
|
||||
return formatMessage("can.coupon.use_complete_point", coupon.can)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,7 +238,7 @@ class ChargeService(
|
||||
@Transactional
|
||||
fun payverseCharge(member: Member, request: PayverseChargeRequest): PayverseChargeResponse {
|
||||
val can = canRepository.findByIdOrNull(request.canId)
|
||||
?: throw SodaException("잘못된 요청입니다\n앱 종료 후 다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "can.charge.invalid_request_restart")
|
||||
|
||||
val requestCurrency = can.currency
|
||||
val isKrw = requestCurrency == "KRW"
|
||||
@@ -304,9 +308,9 @@ class ChargeService(
|
||||
@Transactional
|
||||
fun payverseVerify(memberId: Long, verifyRequest: PayverseVerifyRequest): ChargeCompleteResponse {
|
||||
val charge = chargeRepository.findByIdOrNull(verifyRequest.orderId.toLong())
|
||||
?: throw SodaException("결제정보에 오류가 있습니다.")
|
||||
?: throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
val member = memberRepository.findByIdOrNull(memberId)
|
||||
?: throw SodaException("로그인 정보를 확인해주세요.")
|
||||
?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
val isKrw = charge.can?.currency == "KRW"
|
||||
val mid = if (isKrw) {
|
||||
@@ -322,7 +326,7 @@ class ChargeService(
|
||||
|
||||
// 결제수단 확인
|
||||
if (charge.payment?.paymentGateway != PaymentGateway.PAYVERSE) {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
|
||||
// 결제 상태에 따른 분기 처리
|
||||
@@ -339,10 +343,11 @@ class ChargeService(
|
||||
|
||||
val response = okHttpClient.newCall(request).execute()
|
||||
if (!response.isSuccessful) {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
|
||||
val body = response.body?.string() ?: throw SodaException("결제정보에 오류가 있습니다.")
|
||||
val body = response.body?.string()
|
||||
?: throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
val verifyResponse = objectMapper.readValue(body, PayverseVerifyResponse::class.java)
|
||||
|
||||
val customerId = "${serverEnv}_user_${member.id!!}"
|
||||
@@ -380,10 +385,10 @@ class ChargeService(
|
||||
isFirstCharged = chargeRepository.isFirstCharged(memberId)
|
||||
)
|
||||
} else {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +402,7 @@ class ChargeService(
|
||||
}
|
||||
|
||||
else -> {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -405,7 +410,7 @@ class ChargeService(
|
||||
@Transactional
|
||||
fun charge(member: Member, request: ChargeRequest): ChargeResponse {
|
||||
val can = canRepository.findByIdOrNull(request.canId)
|
||||
?: throw SodaException("잘못된 요청입니다\n앱 종료 후 다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "can.charge.invalid_request_restart")
|
||||
|
||||
val charge = Charge(can.can, can.rewardCan)
|
||||
charge.title = can.title
|
||||
@@ -424,9 +429,9 @@ class ChargeService(
|
||||
@Transactional
|
||||
fun verify(memberId: Long, verifyRequest: VerifyRequest): ChargeCompleteResponse {
|
||||
val charge = chargeRepository.findByIdOrNull(verifyRequest.orderId.toLong())
|
||||
?: throw SodaException("결제정보에 오류가 있습니다.")
|
||||
?: throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
val member = memberRepository.findByIdOrNull(memberId)
|
||||
?: throw SodaException("로그인 정보를 확인해주세요.")
|
||||
?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
if (charge.payment!!.paymentGateway == PaymentGateway.PG) {
|
||||
val bootpay = Bootpay(bootpayApplicationId, bootpayPrivateKey)
|
||||
@@ -457,22 +462,22 @@ class ChargeService(
|
||||
isFirstCharged = chargeRepository.isFirstCharged(memberId)
|
||||
)
|
||||
} else {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
} else {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun verifyHecto(memberId: Long, verifyRequest: VerifyRequest): ChargeCompleteResponse {
|
||||
val charge = chargeRepository.findByIdOrNull(verifyRequest.orderId.toLong())
|
||||
?: throw SodaException("결제정보에 오류가 있습니다.")
|
||||
?: throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
val member = memberRepository.findByIdOrNull(memberId)
|
||||
?: throw SodaException("로그인 정보를 확인해주세요.")
|
||||
?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
if (charge.payment!!.paymentGateway == PaymentGateway.PG) {
|
||||
val bootpay = Bootpay(bootpayHectoApplicationId, bootpayHectoPrivateKey)
|
||||
@@ -507,13 +512,13 @@ class ChargeService(
|
||||
isFirstCharged = chargeRepository.isFirstCharged(memberId)
|
||||
)
|
||||
} else {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
} else {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,15 +547,17 @@ class ChargeService(
|
||||
@Transactional
|
||||
fun appleVerify(memberId: Long, verifyRequest: AppleVerifyRequest): ChargeCompleteResponse {
|
||||
val charge = chargeRepository.findByIdOrNull(verifyRequest.chargeId)
|
||||
?: throw SodaException("결제정보에 오류가 있습니다.")
|
||||
?: throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
val member = memberRepository.findByIdOrNull(memberId)
|
||||
?: throw SodaException("로그인 정보를 확인해주세요.")
|
||||
?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
if (charge.payment!!.paymentGateway == PaymentGateway.APPLE_IAP) {
|
||||
// 검증로직
|
||||
if (requestRealServerVerify(verifyRequest)) {
|
||||
charge.payment?.receiptId = verifyRequest.receiptString
|
||||
charge.payment?.method = "애플(인 앱 결제)"
|
||||
charge.payment?.method = messageSource
|
||||
.getMessage("can.charge.payment_method.apple_iap", langContext.lang)
|
||||
.orEmpty()
|
||||
charge.payment?.status = PaymentStatus.COMPLETE
|
||||
member.charge(charge.chargeCan, charge.rewardCan, "ios")
|
||||
|
||||
@@ -567,10 +574,10 @@ class ChargeService(
|
||||
isFirstCharged = chargeRepository.isFirstCharged(memberId)
|
||||
)
|
||||
} else {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
} else {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,7 +601,9 @@ class ChargeService(
|
||||
payment.locale = currencyCode
|
||||
payment.price = price
|
||||
payment.receiptId = purchaseToken
|
||||
payment.method = "구글(인 앱 결제)"
|
||||
payment.method = messageSource
|
||||
.getMessage("can.charge.payment_method.google_iap", langContext.lang)
|
||||
.orEmpty()
|
||||
|
||||
charge.payment = payment
|
||||
chargeRepository.save(charge)
|
||||
@@ -610,9 +619,9 @@ class ChargeService(
|
||||
purchaseToken: String
|
||||
): ChargeCompleteResponse {
|
||||
val charge = chargeRepository.findByIdOrNull(id = chargeId)
|
||||
?: throw SodaException("결제정보에 오류가 있습니다.")
|
||||
?: throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
val member = memberRepository.findByIdOrNull(id = memberId)
|
||||
?: throw SodaException("로그인 정보를 확인해주세요.")
|
||||
?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
if (charge.payment!!.status == PaymentStatus.REQUEST) {
|
||||
val orderId = verifyPurchase(purchaseToken, productId)
|
||||
@@ -634,10 +643,10 @@ class ChargeService(
|
||||
isFirstCharged = chargeRepository.isFirstCharged(memberId)
|
||||
)
|
||||
} else {
|
||||
throw SodaException("구매를 하지 못했습니다.\n고객센터로 문의해 주세요")
|
||||
throw SodaException(messageKey = "can.charge.purchase_failed_contact")
|
||||
}
|
||||
} else {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -670,14 +679,14 @@ class ChargeService(
|
||||
}
|
||||
|
||||
else -> {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw SodaException("결제를 완료하지 못했습니다.")
|
||||
throw SodaException(messageKey = "can.charge.payment_incomplete")
|
||||
}
|
||||
} else {
|
||||
throw SodaException("결제를 완료하지 못했습니다.")
|
||||
throw SodaException(messageKey = "can.charge.payment_incomplete")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -701,23 +710,31 @@ class ChargeService(
|
||||
}
|
||||
|
||||
else -> {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw SodaException("결제를 완료하지 못했습니다.")
|
||||
throw SodaException(messageKey = "can.charge.payment_incomplete")
|
||||
}
|
||||
} else {
|
||||
throw SodaException("결제를 완료하지 못했습니다.")
|
||||
throw SodaException(messageKey = "can.charge.payment_incomplete")
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatMessage(key: String, vararg args: Any): String {
|
||||
val template = messageSource.getMessage(key, langContext.lang) ?: return ""
|
||||
return String.format(template, *args)
|
||||
}
|
||||
|
||||
// Payverse 결제수단 매핑: 특정 schemeCode는 "카드"로 표기, 아니면 null 반환
|
||||
private fun mapPayverseSchemeToMethodByCode(schemeCode: String?): String? {
|
||||
val cardCodes = setOf(
|
||||
"041", "044", "361", "364", "365", "366", "367", "368", "369", "370", "371", "372", "373", "374", "381",
|
||||
"218", "071", "002", "089", "045", "050", "048", "090", "092"
|
||||
)
|
||||
return if (schemeCode != null && cardCodes.contains(schemeCode)) "카드" else null
|
||||
if (schemeCode == null || !cardCodes.contains(schemeCode)) {
|
||||
return null
|
||||
}
|
||||
return messageSource.getMessage("can.charge.payment_method.card", langContext.lang)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ import kr.co.vividnext.sodalive.can.payment.PaymentStatus
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEvent
|
||||
import kr.co.vividnext.sodalive.fcm.FcmEventType
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.MemberRepository
|
||||
import kr.co.vividnext.sodalive.member.auth.AuthRepository
|
||||
@@ -26,15 +28,17 @@ class ChargeEventService(
|
||||
private val memberRepository: MemberRepository,
|
||||
private val chargeRepository: ChargeRepository,
|
||||
private val chargeEventRepository: ChargeEventRepository,
|
||||
private val applicationEventPublisher: ApplicationEventPublisher
|
||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext
|
||||
) {
|
||||
@Transactional
|
||||
fun applyChargeEvent(chargeId: Long, memberId: Long) {
|
||||
val charge = chargeRepository.findByIdOrNull(chargeId)
|
||||
?: throw SodaException("이벤트가 적용되지 않았습니다.\n고객센터에 문의해 주세요.")
|
||||
?: throw SodaException(messageKey = "can.charge.event.not_applied_contact")
|
||||
|
||||
val member = memberRepository.findByIdOrNull(memberId)
|
||||
?: throw SodaException("이벤트가 적용되지 않았습니다.\n고객센터에 문의해 주세요.")
|
||||
?: throw SodaException(messageKey = "can.charge.event.not_applied_contact")
|
||||
|
||||
if (member.auth != null) {
|
||||
val authDate = authRepository.getOldestCreatedAtByDi(member.auth!!.di)
|
||||
@@ -79,7 +83,10 @@ class ChargeEventService(
|
||||
FcmEvent(
|
||||
type = FcmEventType.INDIVIDUAL,
|
||||
title = chargeEvent.title,
|
||||
message = "$additionalCan 캔이 추가 지급되었습니다.",
|
||||
message = formatMessage(
|
||||
"can.charge.event.additional_can_paid",
|
||||
additionalCan
|
||||
),
|
||||
recipients = listOf(member.id!!),
|
||||
isAuth = null
|
||||
)
|
||||
@@ -94,14 +101,21 @@ class ChargeEventService(
|
||||
additionalCan = additionalCan,
|
||||
member = member,
|
||||
paymentGateway = charge.payment?.paymentGateway!!,
|
||||
method = "첫 충전 이벤트"
|
||||
method = messageSource
|
||||
.getMessage("can.charge.event.first_title", langContext.lang)
|
||||
.orEmpty()
|
||||
)
|
||||
|
||||
applicationEventPublisher.publishEvent(
|
||||
FcmEvent(
|
||||
type = FcmEventType.INDIVIDUAL,
|
||||
title = "첫 충전 이벤트",
|
||||
message = "$additionalCan 캔이 추가 지급되었습니다.",
|
||||
title = messageSource
|
||||
.getMessage("can.charge.event.first_title", langContext.lang)
|
||||
.orEmpty(),
|
||||
message = formatMessage(
|
||||
"can.charge.event.additional_can_paid",
|
||||
additionalCan
|
||||
),
|
||||
recipients = listOf(member.id!!),
|
||||
isAuth = null
|
||||
)
|
||||
@@ -110,7 +124,7 @@ class ChargeEventService(
|
||||
|
||||
private fun applyEvent(additionalCan: Int, member: Member, paymentGateway: PaymentGateway, method: String) {
|
||||
val eventCharge = Charge(0, additionalCan, status = ChargeStatus.EVENT)
|
||||
eventCharge.title = "$additionalCan 캔"
|
||||
eventCharge.title = formatMessage("can.charge.title", additionalCan)
|
||||
eventCharge.member = member
|
||||
|
||||
val payment = Payment(
|
||||
@@ -127,4 +141,9 @@ class ChargeEventService(
|
||||
else -> member.charge(0, additionalCan, "pg")
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatMessage(key: String, vararg args: Any): String {
|
||||
val template = messageSource.getMessage(key, langContext.lang) ?: return ""
|
||||
return String.format(template, *args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class ChargeTempController(private val service: ChargeTempService) {
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) {
|
||||
throw SodaException("로그인 정보를 확인해주세요.")
|
||||
throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
}
|
||||
|
||||
ApiResponse.ok(service.charge(member, request))
|
||||
|
||||
@@ -12,6 +12,8 @@ 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.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.MemberRepository
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
@@ -27,6 +29,8 @@ class ChargeTempService(
|
||||
private val memberRepository: MemberRepository,
|
||||
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext,
|
||||
|
||||
@Value("\${bootpay.hecto-application-id}")
|
||||
private val bootpayApplicationId: String,
|
||||
@@ -37,7 +41,7 @@ class ChargeTempService(
|
||||
@Transactional
|
||||
fun charge(member: Member, request: ChargeTempRequest): ChargeResponse {
|
||||
val charge = Charge(request.can, 0)
|
||||
charge.title = "${request.can.moneyFormat()} 캔"
|
||||
charge.title = formatMessage("can.charge.title", request.can.moneyFormat())
|
||||
charge.member = member
|
||||
|
||||
val payment = Payment(paymentGateway = request.paymentGateway)
|
||||
@@ -52,9 +56,9 @@ class ChargeTempService(
|
||||
@Transactional
|
||||
fun verify(user: User, verifyRequest: VerifyRequest) {
|
||||
val charge = chargeRepository.findByIdOrNull(verifyRequest.orderId.toLong())
|
||||
?: throw SodaException("결제정보에 오류가 있습니다.")
|
||||
?: throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
val member = memberRepository.findByEmail(user.username)
|
||||
?: throw SodaException("로그인 정보를 확인해주세요.")
|
||||
?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
if (charge.payment!!.paymentGateway == PaymentGateway.PG) {
|
||||
val bootpay = Bootpay(bootpayApplicationId, bootpayPrivateKey)
|
||||
@@ -72,13 +76,18 @@ class ChargeTempService(
|
||||
charge.payment?.status = PaymentStatus.COMPLETE
|
||||
member.charge(charge.chargeCan, charge.rewardCan, "pg")
|
||||
} else {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
} else {
|
||||
throw SodaException("결제정보에 오류가 있습니다.")
|
||||
throw SodaException(messageKey = "can.charge.invalid_payment_info")
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatMessage(key: String, vararg args: Any): String {
|
||||
val template = messageSource.getMessage(key, langContext.lang) ?: return ""
|
||||
return String.format(template, *args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package kr.co.vividnext.sodalive.can.coupon
|
||||
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import org.springframework.core.io.InputStreamResource
|
||||
import org.springframework.data.domain.Pageable
|
||||
@@ -22,14 +24,18 @@ import java.nio.charset.StandardCharsets
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/can/coupon")
|
||||
class CanCouponController(private val service: CanCouponService) {
|
||||
class CanCouponController(
|
||||
private val service: CanCouponService,
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext
|
||||
) {
|
||||
@PostMapping
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
fun generateCoupon(
|
||||
@RequestBody request: GenerateCanCouponRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.generateCoupon(request))
|
||||
}
|
||||
@@ -40,7 +46,7 @@ class CanCouponController(private val service: CanCouponService) {
|
||||
@RequestBody request: ModifyCanCouponRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.modifyCoupon(request))
|
||||
}
|
||||
@@ -51,7 +57,7 @@ class CanCouponController(private val service: CanCouponService) {
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(service.getCouponList(offset = pageable.offset, limit = pageable.pageSize.toLong()))
|
||||
}
|
||||
@@ -63,7 +69,7 @@ class CanCouponController(private val service: CanCouponService) {
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
ApiResponse.ok(
|
||||
service.getCouponNumberList(
|
||||
@@ -80,9 +86,11 @@ class CanCouponController(private val service: CanCouponService) {
|
||||
@RequestParam couponId: Long,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
val fileName = "쿠폰번호리스트.xlsx"
|
||||
val fileName = messageSource
|
||||
.getMessage("can.coupon.download_filename", langContext.lang)
|
||||
.orEmpty()
|
||||
val encodedFileName = URLEncoder.encode(
|
||||
fileName,
|
||||
StandardCharsets.UTF_8.toString()
|
||||
@@ -107,7 +115,7 @@ class CanCouponController(private val service: CanCouponService) {
|
||||
@RequestBody request: UseCanCouponRequest,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
|
||||
) = run {
|
||||
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
val completeMessage = service.useCanCoupon(
|
||||
couponNumber = request.couponNumber,
|
||||
|
||||
@@ -12,7 +12,7 @@ class CanCouponIssueService(private val couponNumberRepository: CanCouponNumberR
|
||||
if (!isMultipleUse(canCouponNumber)) {
|
||||
val canCouponNumberList = couponNumberRepository.findByMemberId(memberId = memberId)
|
||||
if (canCouponNumberList.isNotEmpty()) {
|
||||
throw SodaException("해당 쿠폰은 1회만 충전이 가능합니다.")
|
||||
throw SodaException(messageKey = "can.coupon.single_use_only")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@ class CanCouponIssueService(private val couponNumberRepository: CanCouponNumberR
|
||||
|
||||
private fun checkCanCouponNumber(couponNumber: String): CanCouponNumber {
|
||||
val canCouponNumber = couponNumberRepository.findByCouponNumber(couponNumber = couponNumber)
|
||||
?: throw SodaException("잘못된 쿠폰번호입니다.\n고객센터로 문의해 주시기 바랍니다.")
|
||||
?: throw SodaException(messageKey = "can.coupon.invalid_number_contact")
|
||||
|
||||
if (canCouponNumber.member != null) {
|
||||
throw SodaException("이미 사용한 쿠폰번호 입니다.")
|
||||
throw SodaException(messageKey = "can.coupon.already_used")
|
||||
}
|
||||
|
||||
return canCouponNumber
|
||||
@@ -34,17 +34,17 @@ class CanCouponIssueService(private val couponNumberRepository: CanCouponNumberR
|
||||
|
||||
private fun validateCoupon(canCoupon: CanCoupon) {
|
||||
if (canCoupon.validity < LocalDateTime.now()) {
|
||||
throw SodaException("유효기간이 경과된 쿠폰입니다.")
|
||||
throw SodaException(messageKey = "can.coupon.expired")
|
||||
}
|
||||
|
||||
if (!canCoupon.isActive) {
|
||||
throw SodaException("이용이 불가능한 쿠폰입니다.")
|
||||
throw SodaException(messageKey = "can.coupon.inactive")
|
||||
}
|
||||
}
|
||||
|
||||
fun checkAnyChanges(request: ModifyCanCouponRequest) {
|
||||
if (request.isMultipleUse == null && request.isActive == null && request.validity == null) {
|
||||
throw SodaException("변경사항이 없습니다.")
|
||||
throw SodaException(messageKey = "can.coupon.no_changes")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import kr.co.vividnext.sodalive.aws.sqs.SqsEvent
|
||||
import kr.co.vividnext.sodalive.aws.sqs.SqsEventType
|
||||
import kr.co.vividnext.sodalive.can.charge.ChargeService
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import kr.co.vividnext.sodalive.member.MemberRepository
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||
import org.springframework.context.ApplicationEventPublisher
|
||||
@@ -29,7 +31,9 @@ class CanCouponService(
|
||||
private val memberRepository: MemberRepository,
|
||||
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val applicationEventPublisher: ApplicationEventPublisher
|
||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext
|
||||
) {
|
||||
fun generateCoupon(request: GenerateCanCouponRequest) {
|
||||
val message = objectMapper.writeValueAsString(request)
|
||||
@@ -41,7 +45,7 @@ class CanCouponService(
|
||||
issueService.checkAnyChanges(request)
|
||||
|
||||
val canCoupon = repository.findByIdOrNull(id = request.couponId)
|
||||
?: throw SodaException("잘못된 쿠폰번호입니다.\n고객센터로 문의해 주시기 바랍니다.")
|
||||
?: throw SodaException(messageKey = "can.coupon.invalid_number_contact")
|
||||
|
||||
if (request.validity != null) {
|
||||
val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
|
||||
@@ -51,7 +55,7 @@ class CanCouponService(
|
||||
.toLocalDateTime()
|
||||
|
||||
if (validity <= canCoupon.validity) {
|
||||
throw SodaException("유효기간은 기존 유효기간 이후 날짜로 설정하실 수 있습니다.")
|
||||
throw SodaException(messageKey = "can.coupon.validity_after_current")
|
||||
}
|
||||
|
||||
canCoupon.validity = validity
|
||||
@@ -85,7 +89,11 @@ class CanCouponService(
|
||||
}
|
||||
|
||||
fun downloadCouponNumberList(couponId: Long): ByteArrayInputStream {
|
||||
val header = listOf("순번", "쿠폰번호", "사용여부")
|
||||
val header = listOf(
|
||||
messageSource.getMessage("can.coupon.download_header.index", langContext.lang).orEmpty(),
|
||||
messageSource.getMessage("can.coupon.download_header.number", langContext.lang).orEmpty(),
|
||||
messageSource.getMessage("can.coupon.download_header.used", langContext.lang).orEmpty()
|
||||
)
|
||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||
val couponNumberList = couponNumberRepository.getAllCouponNumberList(couponId)
|
||||
|
||||
@@ -104,9 +112,9 @@ class CanCouponService(
|
||||
couponNumberRow.createCell(1).setCellValue(insertHyphens(item.couponNumber))
|
||||
couponNumberRow.createCell(2).setCellValue(
|
||||
if (item.isUsed) {
|
||||
"O"
|
||||
messageSource.getMessage("can.coupon.download_used_mark", langContext.lang).orEmpty()
|
||||
} else {
|
||||
"X"
|
||||
messageSource.getMessage("can.coupon.download_unused_mark", langContext.lang).orEmpty()
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -114,7 +122,7 @@ class CanCouponService(
|
||||
workbook.write(byteArrayOutputStream)
|
||||
return ByteArrayInputStream(byteArrayOutputStream.toByteArray())
|
||||
} catch (e: IOException) {
|
||||
throw SodaException("다운로드를 하지 못했습니다.\n다시 시도해 주세요.")
|
||||
throw SodaException(messageKey = "can.coupon.download_failed_retry")
|
||||
} finally {
|
||||
workbook.close()
|
||||
byteArrayOutputStream.close()
|
||||
@@ -123,9 +131,9 @@ class CanCouponService(
|
||||
|
||||
fun useCanCoupon(couponNumber: String, memberId: Long): String {
|
||||
val member = memberRepository.findByIdOrNull(id = memberId)
|
||||
?: throw SodaException("로그인 정보를 확인해주세요.")
|
||||
?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
|
||||
if (member.auth == null) throw SodaException("쿠폰은 본인인증을 하셔야 사용이 가능합니다.")
|
||||
if (member.auth == null) throw SodaException(messageKey = "can.coupon.auth_required")
|
||||
|
||||
issueService.validateAvailableUseCoupon(couponNumber, memberId)
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.content.AudioContent
|
||||
import kr.co.vividnext.sodalive.content.order.Order
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.CreatorCommunity
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import kr.co.vividnext.sodalive.live.room.LiveRoom
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.MemberRepository
|
||||
@@ -31,7 +33,9 @@ class CanPaymentService(
|
||||
private val memberRepository: MemberRepository,
|
||||
private val chargeRepository: ChargeRepository,
|
||||
private val useCanRepository: UseCanRepository,
|
||||
private val useCanCalculateRepository: UseCanCalculateRepository
|
||||
private val useCanCalculateRepository: UseCanCalculateRepository,
|
||||
private val messageSource: SodaMessageSource,
|
||||
private val langContext: LangContext
|
||||
) {
|
||||
@Transactional
|
||||
fun spendCan(
|
||||
@@ -49,7 +53,7 @@ class CanPaymentService(
|
||||
container: String
|
||||
) {
|
||||
val member = memberRepository.findByIdOrNull(id = memberId)
|
||||
?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "can.payment.invalid_request_retry")
|
||||
val useRewardCan = spendRewardCan(member, needCan, container)
|
||||
val useChargeCan = if (needCan - useRewardCan.total > 0) {
|
||||
spendChargeCan(member, needCan = needCan - useRewardCan.total, container = container)
|
||||
@@ -58,14 +62,14 @@ class CanPaymentService(
|
||||
}
|
||||
|
||||
if (needCan - useRewardCan.total - (useChargeCan?.total ?: 0) > 0) {
|
||||
val shortCan = needCan - useRewardCan.total - (useChargeCan?.total ?: 0)
|
||||
throw SodaException(
|
||||
"${needCan - useRewardCan.total - (useChargeCan?.total ?: 0)} " +
|
||||
"캔이 부족합니다. 충전 후 이용해 주세요."
|
||||
formatMessage("can.payment.insufficient_can", shortCan)
|
||||
)
|
||||
}
|
||||
|
||||
if (!useRewardCan.verify() || useChargeCan?.verify() == false) {
|
||||
throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
|
||||
throw SodaException(messageKey = "can.payment.invalid_request_retry")
|
||||
}
|
||||
|
||||
val useCan = UseCan(
|
||||
@@ -121,7 +125,7 @@ class CanPaymentService(
|
||||
useCan.chatRoomId = chatRoomId
|
||||
useCan.characterId = characterId
|
||||
} else {
|
||||
throw SodaException("잘못된 요청입니다.")
|
||||
throw SodaException(messageKey = "common.error.invalid_request")
|
||||
}
|
||||
|
||||
useCanRepository.save(useCan)
|
||||
@@ -306,20 +310,20 @@ class CanPaymentService(
|
||||
@Transactional
|
||||
fun refund(memberId: Long, roomId: Long) {
|
||||
val member = memberRepository.findByIdOrNull(memberId)
|
||||
?: throw SodaException("잘못된 예약정보 입니다.")
|
||||
?: throw SodaException(messageKey = "can.payment.invalid_reservation")
|
||||
|
||||
val useCan = repository.getCanUsedForLiveRoomNotRefund(
|
||||
memberId = memberId,
|
||||
roomId = roomId,
|
||||
canUsage = CanUsage.LIVE
|
||||
) ?: throw SodaException("잘못된 예약정보 입니다.")
|
||||
) ?: throw SodaException(messageKey = "can.payment.invalid_reservation")
|
||||
useCan.isRefund = true
|
||||
|
||||
val useCanCalculates = useCanCalculateRepository.findByUseCanIdAndStatus(useCan.id!!)
|
||||
useCanCalculates.forEach {
|
||||
it.status = UseCanCalculateStatus.REFUND
|
||||
val charge = Charge(0, it.can, status = ChargeStatus.REFUND_CHARGE)
|
||||
charge.title = "${it.can} 캔"
|
||||
charge.title = formatMessage("can.charge.title", it.can)
|
||||
charge.useCan = useCan
|
||||
|
||||
when (it.paymentGateway) {
|
||||
@@ -333,7 +337,9 @@ class CanPaymentService(
|
||||
status = PaymentStatus.COMPLETE,
|
||||
paymentGateway = it.paymentGateway
|
||||
)
|
||||
payment.method = "환불"
|
||||
payment.method = messageSource
|
||||
.getMessage("can.payment.method.refund", langContext.lang)
|
||||
.orEmpty()
|
||||
charge.payment = payment
|
||||
|
||||
chargeRepository.save(charge)
|
||||
@@ -348,7 +354,7 @@ class CanPaymentService(
|
||||
container: String
|
||||
) {
|
||||
val member = memberRepository.findByIdOrNull(id = memberId)
|
||||
?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "can.payment.invalid_request_retry")
|
||||
|
||||
val useRewardCan = spendRewardCan(member, needCan, container)
|
||||
val useChargeCan = if (needCan - useRewardCan.total > 0) {
|
||||
@@ -358,14 +364,14 @@ class CanPaymentService(
|
||||
}
|
||||
|
||||
if (needCan - useRewardCan.total - (useChargeCan?.total ?: 0) > 0) {
|
||||
val shortCan = needCan - useRewardCan.total - (useChargeCan?.total ?: 0)
|
||||
throw SodaException(
|
||||
"${needCan - useRewardCan.total - (useChargeCan?.total ?: 0)} " +
|
||||
"캔이 부족합니다. 충전 후 이용해 주세요."
|
||||
formatMessage("can.payment.insufficient_can", shortCan)
|
||||
)
|
||||
}
|
||||
|
||||
if (!useRewardCan.verify() || useChargeCan?.verify() == false) {
|
||||
throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
|
||||
throw SodaException(messageKey = "can.payment.invalid_request_retry")
|
||||
}
|
||||
|
||||
val useCan = UseCan(
|
||||
@@ -394,7 +400,7 @@ class CanPaymentService(
|
||||
container: String
|
||||
) {
|
||||
val member = memberRepository.findByIdOrNull(id = memberId)
|
||||
?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
|
||||
?: throw SodaException(messageKey = "can.payment.invalid_request_retry")
|
||||
|
||||
val useRewardCan = spendRewardCan(member, needCan, container)
|
||||
val useChargeCan = if (needCan - useRewardCan.total > 0) {
|
||||
@@ -404,14 +410,14 @@ class CanPaymentService(
|
||||
}
|
||||
|
||||
if (needCan - useRewardCan.total - (useChargeCan?.total ?: 0) > 0) {
|
||||
val shortCan = needCan - useRewardCan.total - (useChargeCan?.total ?: 0)
|
||||
throw SodaException(
|
||||
"${needCan - useRewardCan.total - (useChargeCan?.total ?: 0)} " +
|
||||
"캔이 부족합니다. 충전 후 이용해 주세요."
|
||||
formatMessage("can.payment.insufficient_can", shortCan)
|
||||
)
|
||||
}
|
||||
|
||||
if (!useRewardCan.verify() || useChargeCan?.verify() == false) {
|
||||
throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
|
||||
throw SodaException(messageKey = "can.payment.invalid_request_retry")
|
||||
}
|
||||
|
||||
val useCan = UseCan(
|
||||
@@ -435,4 +441,9 @@ class CanPaymentService(
|
||||
setUseCanCalculate(null, useRewardCan, useChargeCan, useCan, paymentGateway = PaymentGateway.GOOGLE_IAP)
|
||||
setUseCanCalculate(null, useRewardCan, useChargeCan, useCan, paymentGateway = PaymentGateway.APPLE_IAP)
|
||||
}
|
||||
|
||||
private fun formatMessage(key: String, vararg args: Any): String {
|
||||
val template = messageSource.getMessage(key, langContext.lang) ?: return ""
|
||||
return String.format(template, *args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,6 +182,178 @@ class SodaMessageSource {
|
||||
)
|
||||
)
|
||||
|
||||
private val canChargeMessages = mapOf(
|
||||
"can.charge.invalid_payment_info" to mapOf(
|
||||
Lang.KO to "결제정보에 오류가 있습니다.",
|
||||
Lang.EN to "There is an error with the payment information.",
|
||||
Lang.JA to "決済情報に誤りがあります。"
|
||||
),
|
||||
"can.charge.invalid_request_restart" to mapOf(
|
||||
Lang.KO to "잘못된 요청입니다\n앱 종료 후 다시 시도해 주세요.",
|
||||
Lang.EN to "Invalid request.\nPlease restart the app and try again.",
|
||||
Lang.JA to "不正なリクエストです。\nアプリを終了して再度お試しください。"
|
||||
),
|
||||
"can.charge.purchase_failed_contact" to mapOf(
|
||||
Lang.KO to "구매를 하지 못했습니다.\n고객센터로 문의해 주세요",
|
||||
Lang.EN to "Purchase could not be completed.\nPlease contact customer support.",
|
||||
Lang.JA to "購入を完了できませんでした。\nカスタマーサポートへお問い合わせください。"
|
||||
),
|
||||
"can.charge.payment_incomplete" to mapOf(
|
||||
Lang.KO to "결제를 완료하지 못했습니다.",
|
||||
Lang.EN to "Payment could not be completed.",
|
||||
Lang.JA to "決済を完了できませんでした。"
|
||||
),
|
||||
"can.charge.payment_method.apple_iap" to mapOf(
|
||||
Lang.KO to "애플(인 앱 결제)",
|
||||
Lang.EN to "Apple (In-App Purchase)",
|
||||
Lang.JA to "Apple(アプリ内課金)"
|
||||
),
|
||||
"can.charge.payment_method.google_iap" to mapOf(
|
||||
Lang.KO to "구글(인 앱 결제)",
|
||||
Lang.EN to "Google (In-App Purchase)",
|
||||
Lang.JA to "Google(アプリ内課金)"
|
||||
),
|
||||
"can.charge.payment_method.card" to mapOf(
|
||||
Lang.KO to "카드",
|
||||
Lang.EN to "Card",
|
||||
Lang.JA to "カード"
|
||||
),
|
||||
"can.charge.title" to mapOf(
|
||||
Lang.KO to "%s 캔",
|
||||
Lang.EN to "%s cans",
|
||||
Lang.JA to "%s缶"
|
||||
)
|
||||
)
|
||||
|
||||
private val canChargeEventMessages = mapOf(
|
||||
"can.charge.event.not_applied_contact" to mapOf(
|
||||
Lang.KO to "이벤트가 적용되지 않았습니다.\n고객센터에 문의해 주세요.",
|
||||
Lang.EN to "The event was not applied.\nPlease contact customer support.",
|
||||
Lang.JA to "イベントが適用されていません。\nカスタマーサポートへお問い合わせください。"
|
||||
),
|
||||
"can.charge.event.additional_can_paid" to mapOf(
|
||||
Lang.KO to "%s 캔이 추가 지급되었습니다.",
|
||||
Lang.EN to "%s cans have been added.",
|
||||
Lang.JA to "%s缶が追加で支給されました。"
|
||||
),
|
||||
"can.charge.event.first_title" to mapOf(
|
||||
Lang.KO to "첫 충전 이벤트",
|
||||
Lang.EN to "First Recharge Event",
|
||||
Lang.JA to "初回チャージイベント"
|
||||
)
|
||||
)
|
||||
|
||||
private val canCouponMessages = mapOf(
|
||||
"can.coupon.invalid_number_contact" to mapOf(
|
||||
Lang.KO to "잘못된 쿠폰번호입니다.\n고객센터로 문의해 주시기 바랍니다.",
|
||||
Lang.EN to "Invalid coupon number.\nPlease contact customer support.",
|
||||
Lang.JA to "無効なクーポン番号です。\nカスタマーサポートへお問い合わせください。"
|
||||
),
|
||||
"can.coupon.already_used" to mapOf(
|
||||
Lang.KO to "이미 사용한 쿠폰번호 입니다.",
|
||||
Lang.EN to "This coupon number has already been used.",
|
||||
Lang.JA to "すでに使用されたクーポン番号です。"
|
||||
),
|
||||
"can.coupon.use_complete" to mapOf(
|
||||
Lang.KO to "쿠폰 사용이 완료되었습니다.\n%s캔이 지급되었습니다.",
|
||||
Lang.EN to "Coupon redeemed successfully.\n%s cans have been granted.",
|
||||
Lang.JA to "クーポンの使用が完了しました。\n%s缶が支給されました。"
|
||||
),
|
||||
"can.coupon.use_complete_point" to mapOf(
|
||||
Lang.KO to "쿠폰 사용이 완료되었습니다.\n%s포인트가 지급되었습니다.",
|
||||
Lang.EN to "Coupon redeemed successfully.\n%s points have been granted.",
|
||||
Lang.JA to "クーポンの使用が完了しました。\n%sポイントが付与されました。"
|
||||
),
|
||||
"can.coupon.single_use_only" to mapOf(
|
||||
Lang.KO to "해당 쿠폰은 1회만 충전이 가능합니다.",
|
||||
Lang.EN to "This coupon can be used only once for charging.",
|
||||
Lang.JA to "このクーポンは1回のみチャージに使用できます。"
|
||||
),
|
||||
"can.coupon.expired" to mapOf(
|
||||
Lang.KO to "유효기간이 경과된 쿠폰입니다.",
|
||||
Lang.EN to "This coupon has expired.",
|
||||
Lang.JA to "有効期限が切れたクーポンです。"
|
||||
),
|
||||
"can.coupon.inactive" to mapOf(
|
||||
Lang.KO to "이용이 불가능한 쿠폰입니다.",
|
||||
Lang.EN to "This coupon is not available.",
|
||||
Lang.JA to "利用できないクーポンです。"
|
||||
),
|
||||
"can.coupon.no_changes" to mapOf(
|
||||
Lang.KO to "변경사항이 없습니다.",
|
||||
Lang.EN to "No changes found.",
|
||||
Lang.JA to "変更事項がありません。"
|
||||
),
|
||||
"can.coupon.validity_after_current" to mapOf(
|
||||
Lang.KO to "유효기간은 기존 유효기간 이후 날짜로 설정하실 수 있습니다.",
|
||||
Lang.EN to "Validity must be set after the current expiration date.",
|
||||
Lang.JA to "有効期限は現在の有効期限以降に設定できます。"
|
||||
),
|
||||
"can.coupon.auth_required" to mapOf(
|
||||
Lang.KO to "쿠폰은 본인인증을 하셔야 사용이 가능합니다.",
|
||||
Lang.EN to "You must verify your identity to use coupons.",
|
||||
Lang.JA to "クーポンの使用には本人認証が必要です。"
|
||||
),
|
||||
"can.coupon.download_failed_retry" to mapOf(
|
||||
Lang.KO to "다운로드를 하지 못했습니다.\n다시 시도해 주세요.",
|
||||
Lang.EN to "Download failed.\nPlease try again.",
|
||||
Lang.JA to "ダウンロードできませんでした。\nもう一度お試しください。"
|
||||
),
|
||||
"can.coupon.download_filename" to mapOf(
|
||||
Lang.KO to "쿠폰번호리스트.xlsx",
|
||||
Lang.EN to "coupon_number_list.xlsx",
|
||||
Lang.JA to "クーポン番号リスト.xlsx"
|
||||
),
|
||||
"can.coupon.download_header.index" to mapOf(
|
||||
Lang.KO to "순번",
|
||||
Lang.EN to "No.",
|
||||
Lang.JA to "番号"
|
||||
),
|
||||
"can.coupon.download_header.number" to mapOf(
|
||||
Lang.KO to "쿠폰번호",
|
||||
Lang.EN to "Coupon Number",
|
||||
Lang.JA to "クーポン番号"
|
||||
),
|
||||
"can.coupon.download_header.used" to mapOf(
|
||||
Lang.KO to "사용여부",
|
||||
Lang.EN to "Used",
|
||||
Lang.JA to "使用有無"
|
||||
),
|
||||
"can.coupon.download_used_mark" to mapOf(
|
||||
Lang.KO to "O",
|
||||
Lang.EN to "O",
|
||||
Lang.JA to "O"
|
||||
),
|
||||
"can.coupon.download_unused_mark" to mapOf(
|
||||
Lang.KO to "X",
|
||||
Lang.EN to "X",
|
||||
Lang.JA to "X"
|
||||
)
|
||||
)
|
||||
|
||||
private val canPaymentMessages = mapOf(
|
||||
"can.payment.invalid_request_retry" to mapOf(
|
||||
Lang.KO to "잘못된 요청입니다.\n다시 시도해 주세요.",
|
||||
Lang.EN to "Invalid request.\nPlease try again.",
|
||||
Lang.JA to "不正なリクエストです。\nもう一度お試しください。"
|
||||
),
|
||||
"can.payment.invalid_reservation" to mapOf(
|
||||
Lang.KO to "잘못된 예약정보 입니다.",
|
||||
Lang.EN to "Invalid reservation information.",
|
||||
Lang.JA to "無効な予約情報です。"
|
||||
),
|
||||
"can.payment.method.refund" to mapOf(
|
||||
Lang.KO to "환불",
|
||||
Lang.EN to "Refund",
|
||||
Lang.JA to "返金"
|
||||
),
|
||||
"can.payment.insufficient_can" to mapOf(
|
||||
Lang.KO to "%s 캔이 부족합니다. 충전 후 이용해 주세요.",
|
||||
Lang.EN to "You are short of %s cans. Please recharge and try again.",
|
||||
Lang.JA to "%s缶が不足しています。チャージしてからご利用ください。"
|
||||
)
|
||||
)
|
||||
|
||||
private val adminChatBannerMessages = mapOf(
|
||||
"admin.chat.banner.image_save_failed" to mapOf(
|
||||
Lang.KO to "이미지 저장에 실패했습니다.",
|
||||
@@ -1546,6 +1718,10 @@ class SodaMessageSource {
|
||||
auditionVoteMessages,
|
||||
settlementRatioMessages,
|
||||
adminCanMessages,
|
||||
canChargeMessages,
|
||||
canChargeEventMessages,
|
||||
canCouponMessages,
|
||||
canPaymentMessages,
|
||||
adminChatBannerMessages,
|
||||
adminChatCalculateMessages,
|
||||
adminChatCharacterMessages,
|
||||
|
||||
Reference in New Issue
Block a user