diff --git a/src/main/java/com/honey/honey/service/PaymentService.java b/src/main/java/com/honey/honey/service/PaymentService.java index b5164b8..8764ecf 100644 --- a/src/main/java/com/honey/honey/service/PaymentService.java +++ b/src/main/java/com/honey/honey/service/PaymentService.java @@ -13,10 +13,12 @@ import com.honey.honey.model.CryptoDepositMethod; import com.honey.honey.model.Payment; import com.honey.honey.model.UserA; import com.honey.honey.model.UserB; +import com.honey.honey.model.UserD; import com.honey.honey.repository.CryptoDepositMethodRepository; import com.honey.honey.repository.PaymentRepository; import com.honey.honey.repository.UserARepository; import com.honey.honey.repository.UserBRepository; +import com.honey.honey.repository.UserDRepository; import com.honey.honey.util.IpUtils; import com.honey.honey.util.TelegramTokenRedactor; import lombok.Data; @@ -47,6 +49,7 @@ public class PaymentService { private final PaymentRepository paymentRepository; private final UserARepository userARepository; private final UserBRepository userBRepository; + private final UserDRepository userDRepository; private final CryptoDepositMethodRepository cryptoDepositMethodRepository; private final TelegramProperties telegramProperties; private final TransactionService transactionService; @@ -74,6 +77,11 @@ public class PaymentService { /** When false, Telegram Stars payment webhooks are ignored (no balance credited). Invoice creation for Stars is already rejected. */ private static final boolean TELEGRAM_STARS_PAYMENTS_ENABLED = false; + /** Referral commission as fraction of base deposit (no bonus). Level 1 = referer_1, level 2 = referer_2, level 3 = referer_3. */ + private static final double REFERRER_LEVEL1_PERCENT = 0.12; + private static final double REFERRER_LEVEL2_PERCENT = 0.06; + private static final double REFERRER_LEVEL3_PERCENT = 0.02; + /** * Creates a payment invoice for the user. * Validates the stars amount and creates a pending payment record. @@ -409,9 +417,54 @@ public class PaymentService { log.error("Error creating deposit transaction: userId={}, amount={}", userId, playBalance, e); } + // Referral commissions: % of base deposit (no bonus), credited to referer balanceB and tracked in UserD + applyReferralCommissions(userId, basePlayBalance); + log.info("External deposit completed: orderId={}, userId={}, usdAmount={}, playBalance={}, firstDeposit={}", orderId, userId, usdAmountBd, playBalance, firstDeposit); } + /** + * Applies referral commissions on deposit: referer_1 gets REFERRER_LEVEL1_PERCENT, referer_2 gets REFERRER_LEVEL2_PERCENT, referer_3 gets REFERRER_LEVEL3_PERCENT of base play balance (no bonus). + * Updates: referer's balanceB, depositor's to_referer_N, referer's from_referals_N. + */ + private void applyReferralCommissions(Integer depositorUserId, long basePlayBalance) { + if (basePlayBalance <= 0) return; + UserD depositorUserD = userDRepository.findById(depositorUserId).orElse(null); + if (depositorUserD == null) return; + + long commission1 = Math.round(basePlayBalance * REFERRER_LEVEL1_PERCENT); + long commission2 = Math.round(basePlayBalance * REFERRER_LEVEL2_PERCENT); + long commission3 = Math.round(basePlayBalance * REFERRER_LEVEL3_PERCENT); + + applyReferralLevel(depositorUserD, depositorUserId, 1, depositorUserD.getRefererId1(), commission1, + UserD::getToReferer1, UserD::setToReferer1, UserD::getFromReferals1, UserD::setFromReferals1); + applyReferralLevel(depositorUserD, depositorUserId, 2, depositorUserD.getRefererId2(), commission2, + UserD::getToReferer2, UserD::setToReferer2, UserD::getFromReferals2, UserD::setFromReferals2); + applyReferralLevel(depositorUserD, depositorUserId, 3, depositorUserD.getRefererId3(), commission3, + UserD::getToReferer3, UserD::setToReferer3, UserD::getFromReferals3, UserD::setFromReferals3); + + userDRepository.save(depositorUserD); + } + + private void applyReferralLevel(UserD depositorUserD, Integer depositorUserId, int level, Integer refererId, long commission, + java.util.function.Function getToReferer, java.util.function.BiConsumer setToReferer, + java.util.function.Function getFromReferals, java.util.function.BiConsumer setFromReferals) { + if (refererId == null || refererId <= 0 || commission <= 0) return; + + setToReferer.accept(depositorUserD, (getToReferer.apply(depositorUserD) != null ? getToReferer.apply(depositorUserD) : 0L) + commission); + + userBRepository.findById(refererId).ifPresent(refererB -> { + refererB.setBalanceB(refererB.getBalanceB() + commission); + userBRepository.save(refererB); + }); + userDRepository.findById(refererId).ifPresent(refererD -> { + setFromReferals.accept(refererD, (getFromReferals.apply(refererD) != null ? getFromReferals.apply(refererD) : 0L) + commission); + userDRepository.save(refererD); + }); + + log.debug("Referral commission applied: depositor={}, refererLevel={}, refererId={}, commission={}", depositorUserId, level, refererId, commission); + } + /** USD range 3–20000 and at most 2 decimal places. */ private void validateUsd(double usdAmount) { if (usdAmount < MIN_USD || usdAmount > MAX_USD) {