Platform
Four services, each doing one job properly.
The feed keeps the prices honest, the engine decides what stands, the widget puts it on your page, and the backoffice is where the business is run. They share a store and nothing else.
The path a bet takes
Nothing in the player’s way.
The player’s browser only ever talks to one host. Prices arrive over a socket from the engine; bets go back the same way. The feed writes into the shared store the engine reads, and the backoffice reads and writes the same store from the other side. Nothing in the player path waits on the backoffice.
The four services and the path a bet takes through them.
Where prices come from
Feed
A service that consumes the upstream odds feed and keeps the catalogue and the prices current — sports, competitions, fixtures, markets, outcomes, and every change to them as the game moves.
- Live and pre-match, running as one service or as separate ones
- Settlement handled as the results arrive
- Configurable per deployment rather than per build
- Prices held in memory for the engine to read without a database round trip
What decides whether a bet stands
Betting engine
The service the player’s browser talks to. It serves the catalogue, prices each selection at the moment of placement, applies your risk rules, moves money through the operator’s wallet and pushes every odds change back down the socket.
- Live prices preferred for events in play, so a frozen pre-match price is never taken
- Risk limits applied before a bet is accepted, not after
- Coupons over the limit held for a trader instead of refused
- Every selection recorded against the brand it was placed on
- Wallet calls retried automatically, with a manual resend when they cannot be
What the player sees
Player frontend
A self-contained widget — one JavaScript file, CSS included — that mounts into a div on the operator’s page. It carries the whole betting experience: the event list, the match view, the betslip and the player’s open bets.
- One script tag, no build step on the operator’s side
- Styled per brand from the backoffice, not per release
- Odds move in the list, the match view and the betslip together
- Acceptance and refusal reported back to the player, not left silent

Where the business is run
Backoffice
The control room. Trading, risk, compliance, brand configuration and access, in five languages, with every account confined to exactly what it should see.
- Live activity, turnover and open liability on one screen
- A liability watch that proposes and never acts on its own
- Per-brand geoblocking, styling, domains and limits
- Roles scoped to one organisation, enforced server-side
- An audit trail with no way to edit it

Built on
Boring technology, chosen on purpose.
Nothing here is novel. That is the point: a sportsbook runs at three in the morning, and the parts that fail should be the parts somebody has already written about.
Java 17 · Spring Boot
Feed, engine and backoffice API.
PostgreSQL
The record of everything, with schema migrations versioned in the repository.
Redis
Live prices and sessions, where a database round trip would be too slow.
React · TypeScript
The backoffice and the player widget.
The detail is in the backoffice.
Every screen described, one at a time — including the ones that only matter when something has gone wrong.
Every screen, explained