test #196
| @@ -122,12 +122,15 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) { | ||||
|                     order.type, | ||||
|                     order.can, | ||||
|                     order.id.count(), | ||||
|                     order.can.sum() | ||||
|                     order.can.sum(), | ||||
|                     creatorSettlementRatio.contentSettlementRatio | ||||
|                 ) | ||||
|             ) | ||||
|             .from(order) | ||||
|             .innerJoin(order.audioContent, audioContent) | ||||
|             .innerJoin(audioContent.member, member) | ||||
|             .leftJoin(creatorSettlementRatio) | ||||
|             .on(member.id.eq(creatorSettlementRatio.member.id)) | ||||
|             .where(order.isActive.isTrue) | ||||
|             .groupBy(member.id, audioContent.id, order.type, order.can) | ||||
|             .offset(offset) | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| package kr.co.vividnext.sodalive.admin.calculate | ||||
|  | ||||
| import com.querydsl.core.annotations.QueryProjection | ||||
| import kotlin.math.roundToInt | ||||
| import java.math.BigDecimal | ||||
| import java.math.RoundingMode | ||||
|  | ||||
| data class GetCalculateCommunityPostQueryData @QueryProjection constructor( | ||||
|     val nickname: String, | ||||
| @@ -13,15 +14,24 @@ data class GetCalculateCommunityPostQueryData @QueryProjection constructor( | ||||
|     val settlementRatio: Int? | ||||
| ) { | ||||
|     fun toGetCalculateCommunityPostResponse(): GetCalculateCommunityPostResponse { | ||||
|         val totalKrw = totalCan * 100 | ||||
|         val paymentFee = totalKrw * 0.066f | ||||
|         // 원화 = totalCoin * 100 ( 캔 1개 = 100원 ) | ||||
|         val totalKrw = BigDecimal(totalCan).multiply(BigDecimal(100)) | ||||
|  | ||||
|         // 결제수수료 : 6.6% | ||||
|         val paymentFee = totalKrw.multiply(BigDecimal(0.066)) | ||||
|  | ||||
|         // 정산금액 = (원화 - 결제수수료) 의 70% | ||||
|         val settlementAmount = if (settlementRatio != null) { | ||||
|             (totalKrw.toFloat() - paymentFee) * (settlementRatio.toFloat() / 100.0f) | ||||
|             totalKrw.subtract(paymentFee).multiply(BigDecimal(settlementRatio).divide(BigDecimal(100.0))) | ||||
|         } else { | ||||
|             (totalKrw.toFloat() - paymentFee) * 0.7f | ||||
|             totalKrw.subtract(paymentFee).multiply(BigDecimal(0.7)) | ||||
|         } | ||||
|         val tax = settlementAmount * 0.033 | ||||
|         val depositAmount = settlementAmount - tax | ||||
|  | ||||
|         // 원천세 = 정산금액의 3.3% | ||||
|         val tax = settlementAmount.multiply(BigDecimal(0.033)) | ||||
|  | ||||
|         // 입금액 | ||||
|         val depositAmount = settlementAmount.subtract(tax) | ||||
|  | ||||
|         return GetCalculateCommunityPostResponse( | ||||
|             nickname = nickname, | ||||
| @@ -30,11 +40,11 @@ data class GetCalculateCommunityPostQueryData @QueryProjection constructor( | ||||
|             can = can, | ||||
|             numberOfPurchase = numberOfPurchase.toInt(), | ||||
|             totalCan = totalCan, | ||||
|             totalKrw = totalKrw, | ||||
|             paymentFee = paymentFee.roundToInt(), | ||||
|             settlementAmount = settlementAmount.roundToInt(), | ||||
|             tax = tax.roundToInt(), | ||||
|             depositAmount = depositAmount.roundToInt() | ||||
|             totalKrw = totalKrw.toInt(), | ||||
|             paymentFee = paymentFee.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             settlementAmount = settlementAmount.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             tax = tax.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             depositAmount = depositAmount.setScale(0, RoundingMode.HALF_UP).toInt() | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| package kr.co.vividnext.sodalive.admin.calculate | ||||
|  | ||||
| import com.querydsl.core.annotations.QueryProjection | ||||
| import kotlin.math.roundToInt | ||||
| import java.math.BigDecimal | ||||
| import java.math.RoundingMode | ||||
|  | ||||
| data class GetCalculateContentDonationQueryData @QueryProjection constructor( | ||||
|     // 등록 크리에이터 닉네임 | ||||
| @@ -21,25 +22,25 @@ data class GetCalculateContentDonationQueryData @QueryProjection constructor( | ||||
| ) { | ||||
|     fun toGetCalculateContentDonationResponse(): GetCalculateContentDonationResponse { | ||||
|         // 원화 = totalCoin * 100 ( 캔 1개 = 100원 ) | ||||
|         val totalKrw = totalCan * 100 | ||||
|         val totalKrw = BigDecimal(totalCan).multiply(BigDecimal(100)) | ||||
|  | ||||
|         // 결제수수료 : 6.6% | ||||
|         val paymentFee = totalKrw * 0.066f | ||||
|         val paymentFee = totalKrw.multiply(BigDecimal(0.066)) | ||||
|  | ||||
|         // 정산금액 | ||||
|         // 유료콘텐츠 (원화 - 결제수수료) 의 90% | ||||
|         // 무료콘텐츠 (원화 - 결제수수료) 의 70% | ||||
|         val settlementAmount = if (price > 0) { | ||||
|             (totalKrw.toFloat() - paymentFee) * 0.9 | ||||
|             totalKrw.subtract(paymentFee).multiply(BigDecimal(0.9)) | ||||
|         } else { | ||||
|             (totalKrw.toFloat() - paymentFee) * 0.7 | ||||
|             totalKrw.subtract(paymentFee).multiply(BigDecimal(0.7)) | ||||
|         } | ||||
|  | ||||
|         // 원천세 = 정산금액의 3.3% | ||||
|         val tax = settlementAmount * 0.033 | ||||
|         val tax = settlementAmount.multiply(BigDecimal(0.033)) | ||||
|  | ||||
|         // 입금액 | ||||
|         val depositAmount = settlementAmount - tax | ||||
|         val depositAmount = settlementAmount.subtract(tax) | ||||
|  | ||||
|         val paidOrFree = if (price > 0) { | ||||
|             "유료" | ||||
| @@ -55,11 +56,11 @@ data class GetCalculateContentDonationQueryData @QueryProjection constructor( | ||||
|             donationDate = donationDate, | ||||
|             numberOfDonation = numberOfDonation.toInt(), | ||||
|             totalCan = totalCan, | ||||
|             totalKrw = totalKrw, | ||||
|             paymentFee = paymentFee.roundToInt(), | ||||
|             settlementAmount = settlementAmount.roundToInt(), | ||||
|             tax = tax.roundToInt(), | ||||
|             depositAmount = depositAmount.roundToInt() | ||||
|             totalKrw = totalKrw.toInt(), | ||||
|             paymentFee = paymentFee.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             settlementAmount = settlementAmount.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             tax = tax.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             depositAmount = depositAmount.setScale(0, RoundingMode.HALF_UP).toInt() | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,8 @@ package kr.co.vividnext.sodalive.admin.calculate | ||||
|  | ||||
| import com.querydsl.core.annotations.QueryProjection | ||||
| import kr.co.vividnext.sodalive.content.order.OrderType | ||||
| import kotlin.math.roundToInt | ||||
| import java.math.BigDecimal | ||||
| import java.math.RoundingMode | ||||
|  | ||||
| data class GetCalculateContentQueryData @QueryProjection constructor( | ||||
|     // 등록 크리에이터 닉네임 | ||||
| @@ -32,23 +33,22 @@ data class GetCalculateContentQueryData @QueryProjection constructor( | ||||
|         } | ||||
|  | ||||
|         // 원화 = totalCoin * 100 ( 캔 1개 = 100원 ) | ||||
|         val totalKrw = totalCan * 100 | ||||
|         val totalKrw = BigDecimal(totalCan).multiply(BigDecimal(100)) | ||||
|  | ||||
|         // 결제수수료 : 6.6% | ||||
|         val paymentFee = totalKrw * 0.066f | ||||
|         val paymentFee = totalKrw.multiply(BigDecimal(0.066)) | ||||
|  | ||||
|         // 정산금액 = (원화 - 결제수수료) 의 70% | ||||
|         val settlementAmount = if (settlementRatio != null) { | ||||
|             (totalKrw.toFloat() - paymentFee) * (settlementRatio.toFloat() / 100.0f) | ||||
|             totalKrw.subtract(paymentFee).multiply(BigDecimal(settlementRatio).divide(BigDecimal(100.0))) | ||||
|         } else { | ||||
|             (totalKrw.toFloat() - paymentFee) * 0.7f | ||||
|             totalKrw.subtract(paymentFee).multiply(BigDecimal(0.7)) | ||||
|         } | ||||
|  | ||||
|         // 원천세 = 정산금액의 3.3% | ||||
|         val tax = settlementAmount * 0.033 | ||||
|         val tax = settlementAmount.multiply(BigDecimal(0.033)) | ||||
|  | ||||
|         // 입금액 | ||||
|         val depositAmount = settlementAmount - tax | ||||
|         val depositAmount = settlementAmount.subtract(tax) | ||||
|  | ||||
|         return GetCalculateContentResponse( | ||||
|             nickname = nickname, | ||||
| @@ -59,11 +59,11 @@ data class GetCalculateContentQueryData @QueryProjection constructor( | ||||
|             orderPrice = orderPrice, | ||||
|             numberOfPeople = numberOfPeople.toInt(), | ||||
|             totalCan = totalCan, | ||||
|             totalKrw = totalKrw, | ||||
|             paymentFee = paymentFee.roundToInt(), | ||||
|             settlementAmount = settlementAmount.roundToInt(), | ||||
|             tax = tax.roundToInt(), | ||||
|             depositAmount = depositAmount.roundToInt() | ||||
|             totalKrw = totalKrw.toInt(), | ||||
|             paymentFee = paymentFee.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             settlementAmount = settlementAmount.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             tax = tax.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             depositAmount = depositAmount.setScale(0, RoundingMode.HALF_UP).toInt() | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,8 @@ package kr.co.vividnext.sodalive.admin.calculate | ||||
|  | ||||
| import com.querydsl.core.annotations.QueryProjection | ||||
| import kr.co.vividnext.sodalive.can.use.CanUsage | ||||
| import kotlin.math.roundToInt | ||||
| import java.math.BigDecimal | ||||
| import java.math.RoundingMode | ||||
|  | ||||
| data class GetCalculateLiveQueryData @QueryProjection constructor( | ||||
|     val email: String, | ||||
| @@ -42,23 +43,23 @@ data class GetCalculateLiveQueryData @QueryProjection constructor( | ||||
|         } | ||||
|  | ||||
|         // 원화 = totalCoin * 100 ( 캔 1개 = 100원 ) | ||||
|         val totalKrw = totalAmount * 100 | ||||
|         val totalKrw = BigDecimal(totalAmount).multiply(BigDecimal(100)) | ||||
|  | ||||
|         // 결제수수료 : 6.6% | ||||
|         val paymentFee = totalKrw * 0.066f | ||||
|         val paymentFee = totalKrw.multiply(BigDecimal(0.066)) | ||||
|  | ||||
|         // 정산금액 = (원화 - 결제수수료) 의 70% | ||||
|         val settlementAmount = if (settlementRatio != null) { | ||||
|             (totalKrw.toFloat() - paymentFee) * (settlementRatio.toFloat() / 100.0f) | ||||
|             totalKrw.subtract(paymentFee).multiply(BigDecimal(settlementRatio).divide(BigDecimal(100.0))) | ||||
|         } else { | ||||
|             (totalKrw.toFloat() - paymentFee) * 0.7f | ||||
|             totalKrw.subtract(paymentFee).multiply(BigDecimal(0.7)) | ||||
|         } | ||||
|  | ||||
|         // 원천세 = 정산금액의 3.3% | ||||
|         val tax = settlementAmount * 0.033 | ||||
|         val tax = settlementAmount.multiply(BigDecimal(0.033)) | ||||
|  | ||||
|         // 입금액 | ||||
|         val depositAmount = settlementAmount - tax | ||||
|         val depositAmount = settlementAmount.subtract(tax) | ||||
|  | ||||
|         return GetCalculateLiveResponse( | ||||
|             email = email, | ||||
| @@ -69,11 +70,11 @@ data class GetCalculateLiveQueryData @QueryProjection constructor( | ||||
|             canUsageStr = canUsageStr, | ||||
|             numberOfPeople = numberOfPeople, | ||||
|             totalAmount = totalAmount, | ||||
|             totalKrw = totalKrw, | ||||
|             paymentFee = paymentFee.roundToInt(), | ||||
|             settlementAmount = settlementAmount.roundToInt(), | ||||
|             tax = tax.roundToInt(), | ||||
|             depositAmount = depositAmount.roundToInt() | ||||
|             totalKrw = totalKrw.toInt(), | ||||
|             paymentFee = paymentFee.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             settlementAmount = settlementAmount.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             tax = tax.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             depositAmount = depositAmount.setScale(0, RoundingMode.HALF_UP).toInt() | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,7 +3,8 @@ package kr.co.vividnext.sodalive.admin.calculate | ||||
| import com.fasterxml.jackson.annotation.JsonProperty | ||||
| import com.querydsl.core.annotations.QueryProjection | ||||
| import kr.co.vividnext.sodalive.content.order.OrderType | ||||
| import kotlin.math.roundToInt | ||||
| import java.math.BigDecimal | ||||
| import java.math.RoundingMode | ||||
|  | ||||
| data class GetCumulativeSalesByContentQueryData @QueryProjection constructor( | ||||
|     // 등록 크리에이터 닉네임 | ||||
| @@ -19,7 +20,9 @@ data class GetCumulativeSalesByContentQueryData @QueryProjection constructor( | ||||
|     // 인원 | ||||
|     val numberOfPeople: Long, | ||||
|     // 합계 | ||||
|     val totalCan: Int | ||||
|     val totalCan: Int, | ||||
|     // 정산비율 | ||||
|     val settlementRatio: Int? | ||||
| ) { | ||||
|     fun toCumulativeSalesByContentItem(): CumulativeSalesByContentItem { | ||||
|         val orderTypeStr = if (orderType == OrderType.RENTAL) { | ||||
| @@ -29,19 +32,23 @@ data class GetCumulativeSalesByContentQueryData @QueryProjection constructor( | ||||
|         } | ||||
|  | ||||
|         // 원화 = totalCoin * 100 ( 캔 1개 = 100원 ) | ||||
|         val totalKrw = totalCan * 100 | ||||
|         val totalKrw = BigDecimal(totalCan).multiply(BigDecimal(100)) | ||||
|  | ||||
|         // 결제수수료 : 6.6% | ||||
|         val paymentFee = totalKrw * 0.066f | ||||
|         val paymentFee = totalKrw.multiply(BigDecimal(0.066)) | ||||
|  | ||||
|         // 정산금액 = (원화 - 결제수수료) 의 70% | ||||
|         val settlementAmount = (totalKrw.toFloat() - paymentFee) * 0.7 | ||||
|         val settlementAmount = if (settlementRatio != null) { | ||||
|             totalKrw.subtract(paymentFee).multiply(BigDecimal(settlementRatio).divide(BigDecimal(100.0))) | ||||
|         } else { | ||||
|             totalKrw.subtract(paymentFee).multiply(BigDecimal(0.7)) | ||||
|         } | ||||
|  | ||||
|         // 원천세 = 정산금액의 3.3% | ||||
|         val tax = settlementAmount * 0.033 | ||||
|         val tax = settlementAmount.multiply(BigDecimal(0.033)) | ||||
|  | ||||
|         // 입금액 | ||||
|         val depositAmount = settlementAmount - tax | ||||
|         val depositAmount = settlementAmount.subtract(tax) | ||||
|  | ||||
|         return CumulativeSalesByContentItem( | ||||
|             nickname = nickname, | ||||
| @@ -51,11 +58,11 @@ data class GetCumulativeSalesByContentQueryData @QueryProjection constructor( | ||||
|             orderPrice = orderPrice, | ||||
|             numberOfPeople = numberOfPeople.toInt(), | ||||
|             totalCan = totalCan, | ||||
|             totalKrw = totalKrw, | ||||
|             paymentFee = paymentFee.roundToInt(), | ||||
|             settlementAmount = settlementAmount.roundToInt(), | ||||
|             tax = tax.roundToInt(), | ||||
|             depositAmount = depositAmount.roundToInt() | ||||
|             totalKrw = totalKrw.toInt(), | ||||
|             paymentFee = paymentFee.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             settlementAmount = settlementAmount.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             tax = tax.setScale(0, RoundingMode.HALF_UP).toInt(), | ||||
|             depositAmount = depositAmount.setScale(0, RoundingMode.HALF_UP).toInt() | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -33,6 +33,12 @@ class ChargeController(private val service: ChargeService) { | ||||
|         @AuthenticationPrincipal user: User | ||||
|     ) = ApiResponse.ok(service.verify(user, verifyRequest)) | ||||
|  | ||||
|     @PostMapping("/verify/hecto") | ||||
|     fun verifyHecto( | ||||
|         @RequestBody verifyRequest: VerifyRequest, | ||||
|         @AuthenticationPrincipal user: User | ||||
|     ) = ApiResponse.ok(service.verifyHecto(user, verifyRequest)) | ||||
|  | ||||
|     @PostMapping("/apple") | ||||
|     fun appleCharge( | ||||
|         @RequestBody chargeRequest: AppleChargeRequest, | ||||
|   | ||||
| @@ -45,6 +45,10 @@ class ChargeService( | ||||
|     private val bootpayApplicationId: String, | ||||
|     @Value("\${bootpay.private-key}") | ||||
|     private val bootpayPrivateKey: String, | ||||
|     @Value("\${bootpay.hecto-application-id}") | ||||
|     private val bootpayHectoApplicationId: String, | ||||
|     @Value("\${bootpay.hecto-private-key}") | ||||
|     private val bootpayHectoPrivateKey: String, | ||||
|     @Value("\${apple.iap-verify-sandbox-url}") | ||||
|     private val appleInAppVerifySandBoxUrl: String, | ||||
|     @Value("\${apple.iap-verify-url}") | ||||
| @@ -137,6 +141,46 @@ class ChargeService( | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Transactional | ||||
|     fun verifyHecto(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(bootpayHectoApplicationId, bootpayHectoPrivateKey) | ||||
|  | ||||
|             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") | ||||
|  | ||||
|                     applicationEventPublisher.publishEvent( | ||||
|                         ChargeSpringEvent( | ||||
|                             chargeId = charge.id!!, | ||||
|                             memberId = member.id!! | ||||
|                         ) | ||||
|                     ) | ||||
|                 } else { | ||||
|                     throw SodaException("결제정보에 오류가 있습니다.") | ||||
|                 } | ||||
|             } catch (e: Exception) { | ||||
|                 throw SodaException("결제정보에 오류가 있습니다.") | ||||
|             } | ||||
|         } else { | ||||
|             throw SodaException("결제정보에 오류가 있습니다.") | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Transactional | ||||
|     fun appleCharge(member: Member, request: AppleChargeRequest): ChargeResponse { | ||||
|         val charge = Charge(request.chargeCan, 0) | ||||
|   | ||||
| @@ -28,9 +28,9 @@ class ChargeTempService( | ||||
|  | ||||
|     private val objectMapper: ObjectMapper, | ||||
|  | ||||
|     @Value("\${bootpay.application-id}") | ||||
|     @Value("\${bootpay.hecto-application-id}") | ||||
|     private val bootpayApplicationId: String, | ||||
|     @Value("\${bootpay.private-key}") | ||||
|     @Value("\${bootpay.hecto-private-key}") | ||||
|     private val bootpayPrivateKey: String | ||||
| ) { | ||||
|  | ||||
|   | ||||
| @@ -176,12 +176,15 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac | ||||
|                     order.type, | ||||
|                     order.can, | ||||
|                     order.id.count(), | ||||
|                     order.can.sum() | ||||
|                     order.can.sum(), | ||||
|                     creatorSettlementRatio.contentSettlementRatio | ||||
|                 ) | ||||
|             ) | ||||
|             .from(order) | ||||
|             .innerJoin(order.audioContent, audioContent) | ||||
|             .innerJoin(audioContent.member, member) | ||||
|             .leftJoin(creatorSettlementRatio) | ||||
|             .on(member.id.eq(creatorSettlementRatio.member.id)) | ||||
|             .where( | ||||
|                 audioContent.member.id.eq(memberId) | ||||
|                     .and(order.isActive.isTrue) | ||||
|   | ||||
| @@ -301,11 +301,9 @@ class ExplorerService( | ||||
|         member: Member, | ||||
|         pageable: Pageable | ||||
|     ): GetFollowerListResponse { | ||||
|         val totalCount = queryRepository | ||||
|             .getFollowerListTotalCount(creatorId) | ||||
|         val totalCount = queryRepository.getFollowerListTotalCount(creatorId) | ||||
|  | ||||
|         val followerList = queryRepository.getFollowerList(creatorId, pageable.offset, pageable.pageSize.toLong()) | ||||
|             .asSequence() | ||||
|             .map { | ||||
|                 val isFollow = if (it.role == MemberRole.CREATOR) { | ||||
|                     queryRepository.isFollow(creatorId = it.userId, memberId = member.id!!) | ||||
| @@ -320,7 +318,6 @@ class ExplorerService( | ||||
|                     isFollow = isFollow | ||||
|                 ) | ||||
|             } | ||||
|             .toList() | ||||
|  | ||||
|         return GetFollowerListResponse(totalCount = totalCount, items = followerList) | ||||
|     } | ||||
|   | ||||
| @@ -11,6 +11,8 @@ logging: | ||||
| bootpay: | ||||
|     applicationId: ${BOOTPAY_APPLICATION_ID} | ||||
|     privateKey: ${BOOTPAY_PRIVATE_KEY} | ||||
|     hectoApplicationId: ${BOOTPAY_APPLICATION_HECTO_ID} | ||||
|     hectoPrivateKey: ${BOOTPAY_PRIVATE_HECTO_KEY} | ||||
|  | ||||
| apple: | ||||
|     iapVerifyUrl: https://buy.itunes.apple.com/verifyReceipt | ||||
|   | ||||
		Reference in New Issue
	
	Block a user