Разработка системы фрибетов крипто-казино

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка системы фрибетов крипто-казино
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1062
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Разработка системы фрибетов крипто-казино

Фрибет (free bet) — это бесплатная ставка, которую казино предоставляет игроку. В отличие от депозитного бонуса, фрибет не требует внесения средств. Пользователь получает возможность сыграть бесплатно, но при выигрыше получает только чистую прибыль (net winnings), а не полную сумму ставки + прибыль.

Механика фрибета

Стандартная механика:

  • Игрок получает free bet на $10
  • Ставит фрибет на событие с коэффициентом 2.0
  • При выигрыше получает $10 (прибыль), не $20 (возврат ставки + прибыль)
  • При проигрыше — ничего не теряет (ставка была бесплатной)

Free Spin (слоты) — аналог фрибета для слот-машин. Определённое количество прокруток без использования реального баланса.

Модель данных

class FreeBet(BaseModel):
    id: str
    user_id: str
    type: str           # 'SPORTS_BET', 'CASINO_BET', 'FREE_SPIN'
    status: str         # 'AVAILABLE', 'USED', 'EXPIRED', 'WON', 'LOST'

    amount: Decimal     # сумма фрибета
    currency: str

    # Для free spins
    spin_count: int = 0
    spins_used: int = 0
    eligible_games: list[str] = []  # game IDs

    # Для sports bets
    min_odds: Optional[Decimal]  # минимальный коэффициент
    eligible_markets: list[str] = []  # типы рынков

    # Результаты
    bet_id: Optional[str]     # ID использованной ставки
    winnings: Decimal = Decimal(0)   # только чистая прибыль

    # Wagering на выигрыш
    wagering_required: bool = True
    wagering_multiplier: int = 1     # 1x для sports, до 30x для casino

    expires_at: datetime
    issued_at: datetime
    source: str  # 'WELCOME', 'PROMO', 'REWARD', 'REFERRAL'

Применение фрибета к ставке

class FreeBetService:
    async def apply_free_bet(
        self,
        user_id: str,
        free_bet_id: str,
        bet_params: BetRequest,
    ) -> BetResult:
        free_bet = await self.freebet_repo.get(free_bet_id)

        # Валидация
        if free_bet.user_id != user_id:
            raise AuthorizationError()
        if free_bet.status != "AVAILABLE":
            raise InvalidStatusError(f"Free bet status: {free_bet.status}")
        if datetime.utcnow() > free_bet.expires_at:
            raise ExpiredError()

        # Проверяем eligibility
        if free_bet.min_odds and bet_params.odds < free_bet.min_odds:
            raise ValidationError(f"Minimum odds: {free_bet.min_odds}")

        # Помечаем как используемый (атомарно)
        async with self.db.transaction():
            updated = await self.freebet_repo.claim(free_bet_id, bet_params.bet_id)
            if not updated:
                raise ConflictError("Free bet already used")

        # Создаём ставку без списания с реального баланса
        bet = await self.bet_service.place_bet(
            user_id=user_id,
            amount=free_bet.amount,
            is_free_bet=True,
            free_bet_id=free_bet_id,
            **bet_params.dict(),
        )

        return bet

    async def settle_free_bet(self, bet: Bet, outcome: str):
        """Расчёт выигрыша по фрибету"""
        free_bet = await self.freebet_repo.get(bet.free_bet_id)

        if outcome == "WIN":
            # Выигрыш = прибыль (без возврата суммы ставки)
            winnings = bet.potential_profit  # (bet.amount * odds) - bet.amount

            # Применяем wagering если нужно
            if free_bet.wagering_required:
                # Зачисляем как заблокированные средства с wagering requirement
                await self.bonus_service.create_winnings_bonus(
                    user_id=free_bet.user_id,
                    amount=winnings,
                    wagering_multiplier=free_bet.wagering_multiplier,
                    reference=f"FREEBET_WIN:{free_bet.id}",
                )
            else:
                # Прямое зачисление
                await self.balance_service.credit(
                    user_id=free_bet.user_id,
                    amount=winnings,
                    reference=f"FREEBET_WIN:{free_bet.id}",
                )

            await self.freebet_repo.update_status(free_bet.id, "WON", winnings=winnings)
        else:
            await self.freebet_repo.update_status(free_bet.id, "LOST")

Free Spins механика

class FreeSpinService:
    async def use_free_spin(self, user_id: str, free_bet_id: str, game_id: str) -> SpinResult:
        free_bet = await self.freebet_repo.get(free_bet_id)

        if game_id not in free_bet.eligible_games:
            raise ValidationError("Game not eligible for this free spin")
        if free_bet.spins_used >= free_bet.spin_count:
            raise ValidationError("All spins already used")

        # Атомарно увеличиваем счётчик использованных спинов
        remaining = await self.freebet_repo.consume_spin(free_bet_id)
        if remaining < 0:
            raise ConflictError("Race condition: spin already consumed")

        # Запускаем игровой движок без реальных денег
        result = await self.game_engine.spin(
            game_id=game_id,
            bet_amount=free_bet.amount / free_bet.spin_count,
            is_free=True,
        )

        if result.winnings > 0:
            await self.credit_free_spin_winnings(user_id, free_bet, result.winnings)

        # Если все спины использованы
        if remaining == 0:
            await self.freebet_repo.update_status(free_bet_id, "USED")

        return result

Маркетинговая аналитика

Фрибеты — маркетинговый инструмент, поэтому нужна аналитика эффективности:

  • Conversion rate: % пользователей, получивших фрибет и совершивших реальный депозит
  • LTV uplift: сравнение LTV пользователей с фрибетом vs без
  • Cost per acquisition: стоимость привлечения через фрибет vs другие каналы
  • Abuse rate: % пользователей, злоупотребляющих фрибетами без намерения депонировать