Crypto Casino Cashback System Development
Cashback is a refund of a portion of losses to the player. It's one of the most player-friendly bonus mechanisms: it reduces actual losses and creates a "safety net" that encourages continued play.
Cashback Models
Net Loss Cashback — a percentage of net losses for a period. Example: 10% cashback. Lost $1000, won $700 — net loss $300, cashback = $30.
Gross Bet Cashback — percentage of total bet volume, regardless of outcome. Rare format, used in VIP programs.
Weekly/Monthly Cashback — calculated based on a fixed period.
Real-time Cashback — credited immediately after each lost bet. More complex to implement, but better UX.
Cashback Calculation
class CashbackCalculator:
async def calculate_period_cashback(
self,
user_id: str,
cashback_config: CashbackConfig,
period_start: datetime,
period_end: datetime,
) -> CashbackResult:
# Load all bets for the period
bets = await self.bet_repo.get_settled_bets(
user_id=user_id,
from_time=period_start,
to_time=period_end,
eligible_games=cashback_config.eligible_games,
)
# Calculate P&L
total_wagered = sum(b.amount for b in bets)
total_won = sum(b.winnings for b in bets if b.result == "WIN")
total_lost = sum(b.amount for b in bets if b.result == "LOSS")
net_loss = total_lost - total_won
if net_loss <= 0:
return CashbackResult(amount=Decimal(0), reason="No net losses")
# Account for bonuses already received (exclude from base)
bonuses_received = await self.bonus_repo.get_bonuses_in_period(
user_id, period_start, period_end
)
# Some casinos reduce cashback by received bonuses
adjusted_loss = net_loss - sum(b.amount for b in bonuses_received)
if adjusted_loss <= 0:
return CashbackResult(amount=Decimal(0), reason="Losses covered by bonuses")
# Calculate cashback amount
cashback_amount = adjusted_loss * Decimal(str(cashback_config.percentage / 100))
# Apply limits
if cashback_config.max_cashback:
cashback_amount = min(cashback_amount, cashback_config.max_cashback)
if cashback_config.min_cashback and cashback_amount < cashback_config.min_cashback:
return CashbackResult(amount=Decimal(0), reason="Below minimum cashback threshold")
return CashbackResult(
amount=cashback_amount,
net_loss=net_loss,
total_wagered=total_wagered,
bets_count=len(bets),
)
Configuration by VIP Tiers
CASHBACK_TIERS = {
"bronze": CashbackConfig(percentage=5, max_cashback=Decimal("100"), wagering=1),
"silver": CashbackConfig(percentage=10, max_cashback=Decimal("500"), wagering=1),
"gold": CashbackConfig(percentage=15, max_cashback=Decimal("2000"), wagering=1),
"platinum": CashbackConfig(percentage=20, max_cashback=None, wagering=0),
}
Automatic Accrual
class WeeklyCashbackJob:
"""Runs every Monday to calculate cashback for the previous week"""
async def run(self):
period_end = get_last_monday_midnight()
period_start = period_end - timedelta(weeks=1)
# Get all users with active cashback
eligible_users = await self.user_repo.get_cashback_eligible()
for user in eligible_users:
try:
config = CASHBACK_TIERS[user.vip_level]
result = await self.calculator.calculate_period_cashback(
user.id, config, period_start, period_end
)
if result.amount > 0:
await self.bonus_service.credit_cashback(
user_id=user.id,
amount=result.amount,
period_start=period_start,
period_end=period_end,
wagering_multiplier=config.wagering,
)
except Exception as e:
logger.error(f"Cashback calculation failed for user {user.id}: {e}")
Wagering on Cashback
Most casinos set a wagering requirement on cashback (1x–5x) to protect against abuse. A player cannot simply receive cashback and withdraw without playing. At "platinum" VIP level, cashback is often without wagering as a privilege.
Important nuance: cashback is positioned as money, not a bonus, so the wagering requirement should be minimal (1x) to maintain trust. High wagering requirements on cashback — bad reputation for the casino.







