Betting Platform - Production-Ready Architecture
A Tier-1 betting platform built for Kenya, Nigeria, and Ghana with support for:
- Sports Betting (Single, Multi, System bets)
- Crash Games (Aviator-style with Provably Fair algorithm)
- M-Pesa & Flutterwave payment integration
- Real-time odds via WebSocket
- BCLB Compliance (KYC via Smile ID, Tax calculations, Geolocation)
- Event-driven architecture with NATS messaging
Architecture Overview
Multi-Tenant Microservices
┌─────────────────────────────────────────────────────────────┐
│ API GATEWAY (Port 8080) │
│ HTTP/REST + WebSocket | Authentication | Rate Limiting │
└─────────────────────────────────────────────────────────────┘
│ │ │ │
┌────▼────┐ ┌───▼────┐ ┌───▼─────┐ ┌───▼─────┐
│ WALLET │ │ ENGINE │ │ GAMES │ │SETTLEMENT│
│ Service │ │Service │ │ Service │ │ Service │
└────┬────┘ └───┬────┘ └───┬─────┘ └───┬─────┘
│ │ │ │
┌────▼──────────────▼──────────────▼──────────────▼────┐
│ PostgreSQL (Multi-tenant with country_code) │
└───────────────────────────────────────────────────────┘
│
┌───────────┼───────────┐
│ │ │
┌────▼────┐ ┌───▼────┐ ┌───▼─────┐
│ Redis │ │ NATS │ │Cloudflare│
│ (Cache) │ │ (Queue)│ │ (CDN) │
└─────────┘ └────────┘ └──────────┘
Tech Stack
- Backend: Go 1.26+ (high concurrency, low latency)
- Database: PostgreSQL 15 (ACID transactions with optimistic locking)
- Cache: Redis 7 (live odds, sessions, leaderboards)
- Queue: NATS (event-driven architecture with JetStream support)
- WebSocket: Gorilla WebSocket (real-time crash games)
- Payments: Safaricom Daraja API (M-Pesa), Flutterwave (NG/GH)
- KYC: Smile ID SDK (Kenya identity verification)
- Observability: Prometheus metrics, structured logging
- Geolocation: MaxMind GeoLite2 + CDN header fallback
Project Structure
betting-platform/
|-- cmd/ # Service entry points
| |-- gateway/ # Public-facing API (HTTP + WebSocket)
| |-- wallet/ # Balance, deposits, withdrawals
| |-- engine/ # Betting logic and odds processing
| |-- settlement/ # Winner payouts
| `-- games/ # Crash game engine
|-- internal/
| |-- core/ # GLOBAL CORE (country-agnostic)
| | |-- domain/ # Entities (User, Bet, Transaction, Game)
| | `-- usecase/ # Business logic (PlaceBet, ProvablyFair, Tax, Wallet)
| |-- infrastructure/ # Shared infrastructure
| | |-- config/ # Environment-based configuration
| | |-- database/ # PostgreSQL connection & migrations
| | |-- http/ # HTTP handlers, middleware, validation
| | |-- events/ # NATS event bus wrapper
| | |-- kyc/ # Smile ID integration
| | |-- logging/ # Structured logging
| | |-- metrics/ # Prometheus RED metrics
| | `-- server/ # Graceful HTTP server
| |-- tenant/ # COUNTRY-SPECIFIC ADAPTERS
| | `-- ke/ # Kenya: M-Pesa, BCLB tax (15% GGR + 20% WHT)
| `-- migrations/ # Database migration files
|-- deployments/ # Docker + Kubernetes
| `-- docker/ # Multi-service Dockerfile
|-- docker-compose.yml # Local development environment
|-- go.mod
|-- go.sum
|-- Makefile
`-- README.md
Key Features
Core Betting Engine
- Atomic Wallet Service: Transaction-safe balance operations with optimistic locking
- PlaceBet State Machine: Validate user, apply tax, reserve funds, persist bet in single transaction
- Tax Engine: Country-aware tax calculations (Kenya: 15% stake tax + 20% WHT)
- Provably Fair: Cryptographically secure crash game with verification endpoints
Payment & Compliance
- M-Pesa Integration: STK Push deposits + B2C withdrawals with callback handling
- KYC Verification: Smile ID SDK integration for Kenyan identity verification
- Geolocation: MaxMind GeoLite2 + CDN header fallback with country fencing
- Event Bus: NATS messaging for inter-service communication
Observability & Reliability
- Prometheus Metrics: RED metrics per handler with Go/process collectors
- Structured Logging: JSON-formatted logs with context propagation
- Health Checks: Liveness + readiness with Postgres/Redis dependency checks
- Graceful Shutdown: Signal-driven with 15s drain window
Development Experience
- Configuration Management: Environment-based config with validation
- Middleware Stack: Request ID, recovery, logging, CORS, rate limiting, metrics
- Hot Reload: Support for live configuration updates where applicable
- Docker Support: Multi-service builds with GeoLite2 database included
Quick Start
1. Prerequisites
- Go 1.26+
- Docker & Docker Compose
- PostgreSQL 15 (via Docker)
- Redis 7 (via Docker)
- NATS Server (via Docker)
2. Local Development Setup
# Clone the repository
git clone https://github.com/nutcas3/lets-bet.git
cd lets-bet
# Start infrastructure (Postgres, Redis, NATS)
docker-compose up -d
# Run database migrations (up)
./bin/migrate -dir ./migrations -action up
# Or use Makefile
make migrate-up
# Build all services
go build ./...
# Start gateway service (example)
PORT=8080 go run cmd/gateway/main.go
# Start wallet service (example)
PORT=8081 go run cmd/wallet/main.go
# Start games service (example)
PORT=8082 go run cmd/games/main.go
3. Test the API
# Health check
curl http://localhost:8080/healthz
# Metrics endpoint
curl http://localhost:8080/metrics
# KYC verification (Smile ID)
curl -X POST http://localhost:8080/api/kyc/verify-user \
-H "Content-Type: application/json" \
-d '{"user_id":"uuid","id_type":"ALIEN_ID","id_number":"12345678"}'
# Provably fair commitment
curl -X POST http://localhost:8080/api/fairness/commitment \
-H "Content-Type: application/json" \
-d '{"server_seed":"your-server-seed"}'
# Place a bet
curl -X POST http://localhost:8080/api/bets \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <jwt>" \
-d '{"bet_type":"single","stake":100,"selections":[{"odds":2.5}]}'
4. Connect to Crash Game WebSocket
const ws = new WebSocket('ws://localhost:8080/ws/games/crash-game-id');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Multiplier:', data.current_multiplier);
};
// Place a bet
ws.send(JSON.stringify({
action: 'place_bet',
amount: 100
}));
// Cashout
ws.send(JSON.stringify({
action: 'cashout'
}));
M-Pesa Integration (Kenya)
Deposit Flow (STK Push)
// User requests deposit of KES 500
mpesaClient.InitiateDeposit(ctx, "0712345678", 500, "DEP-123")
// M-Pesa sends prompt to user's phone
// User enters PIN
// Callback received at /api/mpesa/callback
// Wallet credited automatically
Withdrawal Flow (B2C)
// User requests withdrawal of KES 1000
mpesaClient.InitiateWithdrawal(ctx, "0712345678", 1000, "WTD-456")
// Wallet debited immediately
// M-Pesa processes payout
// Money sent to user's M-Pesa in ~30 seconds
Configuration
# Environment variables for M-Pesa
MPESA_CONSUMER_KEY=your_consumer_key
MPESA_CONSUMER_SECRET=your_consumer_secret
MPESA_SHORTCODE=174379 # Your Paybill/Till number
MPESA_PASSKEY=your_passkey
MPESA_ENVIRONMENT=sandbox # or production
BCLB Compliance (Kenya)
Required Features
- KYC Verification: Smile ID integration for National ID validation
- Self-Exclusion: Users can ban themselves for 1-12 months
- Deposit Limits: Daily/weekly/monthly caps enforced
- Tax Deduction: 15% stake tax + 20% WHT on winnings
- Audit Log: Every transaction stored with balance snapshots
- Geolocation: Country fencing with MaxMind + CDN headers
Tax Engine Implementation
// Kenya Tax Regime (15% GGR + 20% WHT)
taxEngine := tax.Default()
// Stake tax collected upfront
stakeBreak := taxEngine.ApplyStakeTax("KE", decimal.NewFromInt(1000))
// StakeTax: KES 150, NetStake: KES 850
// Winnings tax on payout
payoutBreak := taxEngine.ApplyPayoutTax("KE", grossPayout, stake)
// WinningsTax: 20% of (winnings - threshold)
Database Migrations
This project uses golang-migrate for database schema management.
Migration Format
Migrations follow the golang-migrate naming convention:
- Up migrations:
YYYYMMDDHHMMSS_description.up.sql - Down migrations:
YYYYMMDDHHMMSS_description.down.sql
Running Migrations
# Apply all pending migrations
./bin/migrate -dir ./migrations -action up
# Rollback one migration
./bin/migrate -dir ./migrations -action down -steps 1
# Check current migration version
./bin/migrate -dir ./migrations -action version
# Apply specific number of migrations
./bin/migrate -dir ./migrations -action up -steps 2
Using Makefile
make migrate-up # Apply all pending migrations
make migrate-down # Rollback one migration
make migrate-version # Check current version
Using golang-migrate CLI
# Install golang-migrate CLI
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
# Run migrations directly
migrate -path ./migrations -database "postgres://user:pass@localhost:5432/dbname?sslmode=disable" up
Creating New Migrations
- Create up migration:
YYYYMMDDHHMMSS_new_feature.up.sql - Create down migration:
YYYYMMDDHHMMSS_new_feature.down.sql - Place both files in
./migrations/directory
Database Schema Highlights
Atomic Wallet Operations
-- Wallet updates use FOR UPDATE + optimistic locking
BEGIN;
SELECT id, balance, version FROM wallets
WHERE user_id = '...' FOR UPDATE;
UPDATE wallets
SET balance = balance - 100, version = version + 1
WHERE id = '...' AND version = 5;
INSERT INTO transactions (...)
VALUES (balance_before, balance_after, ...);
COMMIT;
Transaction Audit Trail
-- Every movement creates an audit record
SELECT amount, balance_before, balance_after, type
FROM transactions
WHERE user_id = '...'
ORDER BY created_at DESC;
Multi-Tenant Design
-- Every table has country_code for isolation
SELECT * FROM bets WHERE country_code = 'KE';
SELECT * FROM transactions WHERE country_code = 'NG';
Deployment
Production (AWS)
# Build Docker images
make docker-build
# Deploy to Kenya region (af-south-1)
cd deployments/ke-prod
terraform apply
# Deploy to Nigeria region (eu-west-2)
cd deployments/ng-prod
terraform apply
Environment Variables
# Service Configuration
SERVICE_NAME=gateway
ENVIRONMENT=development
PORT=8080
# Database
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_NAME=betting_db
DATABASE_USER=postgres
DATABASE_PASSWORD=postgres
DATABASE_SSL_MODE=disable
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
# NATS
NATS_URL=nats://localhost:4222
# KYC (Smile ID)
SMILE_ID_API_KEY=your_api_key
SMILE_ID_PARTNER_ID=your_partner_id
SMILE_ID_ENV=sandbox
# M-Pesa (Kenya)
MPESA_CONSUMER_KEY=your_consumer_key
MPESA_CONSUMER_SECRET=your_consumer_secret
MPESA_SHORTCODE=174379
MPESA_PASSKEY=your_passkey
MPESA_ENVIRONMENT=sandbox
# Tax Configuration
TAX_GGR_RATE=0.15
TAX_WHT_RATE=0.20
TAX_THRESHOLD=500
# Geolocation
ALLOWED_COUNTRIES=KE,NG,GH
# Logging
LOG_LEVEL=info
LOG_FORMAT=json
Performance Benchmarks
| Metric | Target | Status |
|---|---|---|
| Bet Placement | < 200ms | Implemented |
| Wallet Update | < 50ms | Implemented |
| WebSocket Latency | < 100ms | Implemented |
| Concurrent Users | 100,000+ | Implemented |
| M-Pesa Payout | < 60s | Implemented |
| KYC Verification | < 500ms | Implemented |
| Provably Fair Verify | < 100ms | Implemented |
Implementation Status
Phase 1: Core Infrastructure (Completed)
- [x] Multi-tenant architecture with country isolation
- [x] Database schema with optimistic locking
- [x] M-Pesa integration with callbacks
- [x] Crash game engine with provably fair algorithm
- [x] Atomic wallet service with transaction support
- [x] Tax engine (15% GGR + 20% WHT)
- [x] KYC integration via Smile ID SDK
- [x] Geolocation middleware with MaxMind
- [x] NATS event bus with JetStream support
- [x] Prometheus metrics and structured logging
- [x] Graceful shutdown and health checks
Phase 2: Production Hardening (Completed)
- [x] PostgreSQL repository implementations
- [x] Redis caching layer
- [x] JWT authentication middleware
- [x] Redis-backed distributed rate limiting
- [x] Load testing infrastructure
- [x] OpenTelemetry tracing integration
- [x] Security vulnerability fixes (XSS, integer overflow)
- [x] Code quality improvements (131 commits of refactoring)
Phase 3: Advanced Features (Completed)
- [x] Live sports betting with real-time odds
- [x] Flutterwave integration (Nigeria & Ghana)
- [x] Jackpot system with automated draws
- [x] Virtual sports simulation engine
- [x] Admin dashboard with compliance monitoring
- [x] Multi-tenant payment processing
Phase 4: Regulatory & Security (Completed)
- [x] BCLB compliance framework
- [x] Security audit implementation
- [x] Penetration testing tools
- [x] GDPR compliance suite
- [x] Responsible gaming controls
- [x] AML monitoring system
Recent Security & Code Quality Improvements
Security Enhancements (Latest Release)
- XSS Protection: Fixed cross-site scripting vulnerabilities in HTTP handlers using secure JSON encoding
- Integer Overflow: Added bounds checking for score conversions to prevent overflow attacks
- Input Validation: Enhanced request validation middleware across all endpoints
- Audit Logging: Complete audit trails for compliance and security monitoring
Code Quality Improvements
- 131 Commits of Refactoring: Systematic code organization and cleanup
- Clean Architecture: Separated concerns with domain-driven design
- Type Safety: Enhanced type definitions and interface contracts
- Error Handling: Consistent error patterns and proper error propagation
- Documentation: Updated inline documentation and API specifications
Development Infrastructure
- Go 1.26.1: Updated to latest Go version with modern features
- CI/CD Pipeline: Automated testing, security scanning, and deployment
- Docker Optimization: Multi-stage builds with distroless runtime
- Monitoring: Enhanced observability with metrics and structured logging
Support
For technical questions or deployment assistance, open an issue or contact the development team.
License
Proprietary - All rights reserved