Разработка системы бонусов крипто-казино
Бонусная система — ключевой инструмент привлечения и удержания игроков крипто-казино. Welcome bonuses, reload bonuses, free spins — всё это требует точного учёта wagering requirements и защиты от злоупотреблений.
Типы бонусов
Welcome Bonus — бонус за первый депозит. Стандартная формула: 100% match до 1 BTC + X free spins. Wagering requirement: 35-40x от суммы бонуса.
Reload Bonus — регулярные бонусы на повторные депозиты. Меньший размер, стимулирует активность.
No-Deposit Bonus — бонус без депозита для новых пользователей. Маркетинговый инструмент, строгие wagering requirements.
Cashback — % от проигрышей возвращается игроку. Снижает риск, повышает лояльность.
Модель данных
class Bonus(BaseModel):
id: str
user_id: str
template_id: str # ссылка на тип бонуса
type: str # 'DEPOSIT_MATCH', 'FREE_SPINS', 'CASHBACK', 'NO_DEPOSIT'
status: str # 'PENDING', 'ACTIVE', 'WAGERING', 'COMPLETED', 'EXPIRED', 'CANCELLED'
# Суммы
bonus_amount: Decimal # начисленный бонус
deposit_amount: Decimal # сумма депозита (для match bonuses)
wagering_requirement: Decimal # сколько нужно проставить
wagered_amount: Decimal # сколько проставлено
locked_funds: Decimal # бонусные средства, заблокированные до выполнения wagering
# Ограничения
eligible_games: list[str] # список игр, где засчитывается wagering
contribution_pct: dict[str, float] # {'slots': 100, 'blackjack': 10, 'roulette': 20}
max_bet_while_bonus: Decimal # максимальная ставка во время active bonus
expires_at: datetime
# Источник
triggered_by: str # 'DEPOSIT', 'PROMO_CODE', 'REFERRAL', 'VIP_REWARD'
promo_code: Optional[str]
Wagering Tracking
class WageringTracker:
async def on_bet_settled(self, bet: BetResult):
"""Вызывается при каждой закрытой ставке"""
# Получаем активные бонусы пользователя
active_bonuses = await self.bonus_repo.get_active_bonuses(bet.user_id)
for bonus in active_bonuses:
if not self.is_bet_eligible(bet, bonus):
continue
# Рассчитываем вклад этой ставки в wagering
contribution_pct = bonus.contribution_pct.get(bet.game_type, 100.0)
wagered = bet.amount * Decimal(str(contribution_pct / 100))
# Проверяем лимит ставки
if bonus.max_bet_while_bonus and bet.amount > bonus.max_bet_while_bonus:
# Ставка превысила лимит — нарушение условий
await self.cancel_bonus_for_violation(bonus, reason="MAX_BET_EXCEEDED")
continue
async with self.db.transaction():
bonus.wagered_amount += wagered
if bonus.wagered_amount >= bonus.wagering_requirement:
await self.complete_bonus(bonus)
else:
await self.bonus_repo.update_wagered(bonus.id, bonus.wagered_amount)
async def complete_bonus(self, bonus: Bonus):
"""Выполнение wagering requirement — разблокировываем средства"""
async with self.db.transaction():
# Разблокируем бонусные средства
await self.balance_service.unlock_funds(
user_id=bonus.user_id,
currency="BTC",
amount=bonus.locked_funds,
reference=f"BONUS_COMPLETE:{bonus.id}",
)
bonus.status = "COMPLETED"
await self.bonus_repo.save(bonus)
await self.notifier.send_bonus_complete(bonus.user_id, bonus.locked_funds)
Защита от бонус-абьюза
Бонус-охотники (bonus hunters) — реальная проблема для казино. Они берут бонусы, выполняют wagering с минимальным риском (ставки на чёрное/красное в рулетке) и выводят средства.
Ограничения по играм — запрещаем выполнять wagering в low-edge играх. Только слоты (100% вклад), настольные игры с высоким домашним преимуществом.
Max bet rule — нельзя ставить больше €5-10 при активном бонусе.
IP/Device fingerprinting — несколько аккаунтов с одного IP/устройства — блокировка бонусов.
Velocity checks — слишком быстрое выполнение wagering требует проверки.
Linked account detection — детектирование связанных аккаунтов для получения welcome bonus несколько раз.
| Тип нарушения | Действие |
|---|---|
| Max bet exceeded | Аннулирование бонуса |
| Multiple accounts | Блокировка всех аккаунтов |
| Eligible game abuse | Пересчёт wagering contribution |
| Chargeback | Аннулирование всех бонусов + блокировка |







