Team project at BotCalm · 2024 – present · under NDA
iGaming Platform: Go Microservices, Payments and Compliance
A real-money gaming platform with live wallets, crypto and card deposits, withdrawals, bonuses and an operator admin panel. I'm a core member of the team moving it from a Node.js/MongoDB monolith to 20 Go services behind an API gateway. My own pieces are the notification/WebSocket service, the NOWPayments crypto integration, the vault service, the Vesant and GeoComply compliance gates, and the support chat.
Production · code under NDAContact Janindu Gayanga
The problem
- Balances, notifications and game state have to update live for players connected to different pods, and a balance must never be credited twice.
- The old backend was a Node.js/Express/MongoDB monolith. Rebuilding it on Go and Postgres meant moving live data (12,299 users and about 584K transaction records) without losing withdrawals that were still in flight.
- Money movement is regulated. Deposits, withdrawals and logins need location, identity and anti-money-laundering checks, on the crypto rail and the card rail alike.
Architecture and key decisions
- The platform (team-built): 20 Go services behind one API gateway with JWT auth, a circuit breaker and rate limits. PostgreSQL is the system of record, Redis holds balances, locks and pub/sub, and Kafka connects the services.
- Mine: the notification service. Kafka in, WebSocket out, with Redis pub/sub so a message reaches whichever pod holds the player's socket, plus scheduled and broadcast notifications and FCM push. The client pings every 25 s because Cloudflare closes idle WebSockets after about 100 s.
- Mine: the NOWPayments crypto integration in the early payment service. IPN webhooks are checked with HMAC-SHA512 over the key-sorted body, and a retry job picks up any webhook step that failed instead of dropping it.
- Mine: the vault service, where players lock coins away. A per-user Redis lock (10 s TTL) stops two withdrawals from both passing the balance check.
- Mine: the compliance gates. I put geolocation and KYC behind Go interfaces so we could switch from GeoComply to Vesant with an env var, then built shared KYC and face re-check gates used by both payment rails, and AML decisions that freeze the account. Every gate runs before a row is written or a balance moves.
- Mine: an in-house support chat that replaced Intercom. A partial unique index allows one open conversation per player, client message ids stop retries from duplicating, and replies go out over the same WebSocket fan-out.
- Player app in Next.js 16 with next-intl (21 locales), TanStack Query, Zustand and PWA support; admin panel in Next.js 15 with granular RBAC. Deploys go through GitHub Actions and ArgoCD to K3s on AWS.
Results
- QA logged 13 compliance bugs against the Vesant rollout. I worked through them on both payment rails.
- Fixed security holes in the gateway and the WebSocket layer, including client-IP spoofing and connecting as another user.
- Fixed an admin dashboard that under-reported deposits because it counted only one of the two payment rails.
- About 410 of my commits and 87 test files in the Go backend. The platform has no formal load test yet, so I don't quote concurrency numbers.
Tech stack
- Go
- Next.js
- React
- TypeScript
- WebSockets
- Kafka
- PostgreSQL
- Redis
- TanStack Query
- Zustand
- PWA
- Node.js
- Docker
- Kubernetes (K3s)
- ArgoCD
- GitHub Actions
- AWS
Links
- The code belongs to my employer's client and is under NDA, so I can't share it. I'm happy to walk through the architecture on request.
- Case study by Janindu Gayanga, full-stack software engineer in Colombo, Sri Lanka
- Profile on GitHub and LinkedIn
Other projects
- AskLK: Bilingual AI Assistant with RAG, Agents and MCP: Multi-tenant RAG assistant that answers in Sinhala or English, with citations
- BookLK: Event-Driven Service Booking Marketplace: Multi-vendor booking with Kafka, a Go realtime service, payments and Kubernetes
- QueueLK: Real-Time Queue Management for Clinics: Live queue display, phone page and Expo patient app in Sinhala, Tamil and English
- ApplyWise: CV Tailoring Where Every Line Cites a Fact: Each line of a tailored CV cites a fact from your own CV, and a verifier removes the rest