BETT.GURU
PRODUCT DECISIONS

Why it is built this way — and what it would take to ship.

The commercial objective of each step of the customer journey, the platform decisions behind it, the trade-offs accepted, and an honest account of the gap to production.

01

Customer journey and commercial objective

Every step has a commercial goal and a failure mode. The platform is designed around the failure modes.

STEPGOALRISK IF WRONG
01RegisterLowest-friction entry that still proves age and state.Abandonment; unlicensed-state exposure.
02KYCVerify once, unlock everything.Drop-off; false rejects; manual-review leak.
03First depositConvert verified to funded within the session.Declines; limit friction.
04Browse & selectFast path to a first bet.Stale prices; suspended markets.
05PlaceAtomic debit + record at an accepted price.Duplicates; wrong-price disputes.
06SettleExactly-once payout, visible immediately.Late or double payouts.
07Withdraw / RGMoney out as easy as in; controls that hold.Failed transfers; weak exclusion.
02

Product trade-offs

Each decision is visible in the lab and named in the architecture.

ELIGIBILITY

Identity and eligibility are centralised

One function answers “may this account do this now?” for deposits, bets and withdrawals: age, licence, KYC, cooling-off, exclusion.

Trade-off: A single choke point needs an owning team and a fast read path.

See component →
LEDGER

The wallet is a ledger

Balance is a sum of integer-cent entries, each with type, reference and creating key. Any balance is explainable from entries alone.

Trade-off: Forbids “just fix the balance” — the discipline that makes it trustworthy.

See component →
IDEMPOTENCY

Every money command is idempotent

Client key + canonical payload fingerprint: retries replay, reused key with a different payload conflicts. Settlement and reversals derive keys from bet / withdrawal ids.

Trade-off: Clients must generate and persist keys; cheap now, prohibitive to retrofit.

See component →
PRICING

Odds changes need customer acceptance

Accepted price travels with the leg and must equal the live price at placement.

Trade-off: Lower acceptance in fast markets — chosen over silent repricing disputes.

See component →
SAFETY

Responsible gaming shapes the product

Limits at deposit; breaks and exclusions on every command; decreases immediate, increases wait 24h; withdrawals stay open under exclusion.

Trade-off: Revenue deliberately refused; the bet is that trusted books retain.

See component →
POLICY

No same-game parlays

Correlated legs overpay when multiplied. Without a correlation model the honest answer is to refuse — in placement and in reconciliation.

Trade-off: A major US revenue line, sequenced after a pricing model exists.

See component →
03

Wallet and transaction integrity

A bet is placed through a fixed pipeline. Any refusal happens before money moves; any success is one debit and one record.

  1. 1Idempotency
  2. 2Eligibility
  3. 3Market state
  4. 4Price match
  5. 5Stake bounds
  6. 6Funds
  7. 7Atomic commit (debit + record)
  8. 8Exactly-once settlement keyed by bet id

The ledger, not a balance field

  • Money is integer minor units (cents) end to end.
  • Balance = sum of entries; entries carry type, reference, creating key and time.
  • Every money command needs a client idempotency key; the key stores a canonical payload fingerprint.
  • Payout and reversal keys derive from the bet / withdrawal id, so they can only happen once.
  • Limits: deposit $10.00–$5,000.00, stake $1.00–$1,000.00, withdrawal from $20.00.

13 reconciliation checks, run on every state change

  • Balance derived from ledger
  • Running balance never negative
  • All amounts are integer minor units
  • Ledger ids unique
  • Idempotency keys unique
  • Exactly one stake debit per bet
  • Exactly one payout per winning bet, none otherwise
  • Payout amounts match bet records
  • Withdrawal holds and reversals exactly-once
  • Identity: deposits − stakes + payouts − withdrawals + reversals = balance
  • Every deposit was within the limit in force at the time
  • Bet records well-formed (legs, prices, odds, potential, no correlated legs)
  • Settled statuses agree with recorded results
04

Eligibility and responsible gaming

One choke point decides every money command. Responsible gaming is enforced there — not hidden in the app.

Order of checks

No user → self-exclusion → licensed state → KYC verified → cooling-off. The first failing rule returns its reason code.

Withdrawals stay open

Self-excluded and cooling-off customers can always take their money out.

Limits are asymmetric

Decreases apply immediately; increases wait 24 hours. Each deposit records the limit in force.

Restrictions follow the person

Breaks and exclusions live on a platform register that survives sign-out and re-binds on return. They can never be shortened.

05

Operational failure scenarios

Each scenario loads deterministically in the lab. The platform’s response is traced to reason codes and automated tests.

Price moves between tap and submit

Denver ML taken at 1.80, now trading 1.65.

Placement refused until the customer accepts the new price; the accepted price becomes a new intent with a new key.

PRICE_CHANGEDBP-04BP-05JT-02
Run in lab →

Market suspended with a selection in the slip

Trading suspends EV-2091 after the customer picked it.

Refused before any money moves; reopening the market allows the same bet.

MARKET_SUSPENDEDBP-06JT-03
Run in lab →

Stake exceeds balance

$10 balance, $50 stake.

Refused with the derived balance quoted; the customer is offered a deposit.

INSUFFICIENT_FUNDSBP-09
Run in lab →

Double-tap and tampered retry

The same command arrives twice, or the same key with a different amount.

Exact replay returns the original result; a changed payload conflicts. No second debit or credit.

DUPLICATE_IGNOREDIDEMPOTENCY_CONFLICTML-07ML-08BP-13
Run in lab →

Hostile client payloads

Four bets the UI could never build: unknown side, missing price, correlated legs, fractional cents.

Each refused with a reason code; zero ledger movement; reconciliation stays 13/13.

UNKNOWN_SIDEACCEPTED_PRICE_REQUIREDCORRELATED_LEGSBAD_STAKEBP-10BP-11HD-03
Run in lab →

Bank rejects a withdrawal

$75 held; the transfer fails at the bank.

Hold reversed exactly once (key rev:WD-…); repeated failure notices are ignored.

WITHDRAW_FAILEDREVERSAL_OKML-11
Run in lab →

Customer on a break

24h cooling-off active.

Deposits and bets refused centrally; withdrawals stay open; lifts when the clock passes.

COOLING_OFFRG-03
Run in lab →

Self-exclusion register match

Sam is on the register at registration.

365-day exclusion applied; only withdrawals available; restriction re-binds after sign-out.

SELF_EXCLUSION_MATCHSELF_EXCLUDEDRG-06RG-07
Run in lab →

Underage applicant

Casey, 19, in PA.

Account never created; decision code shown and logged.

AGE_BLOCKIE-02
Run in lab →

Unlicensed state

Taylor lives in NY.

Blocked centrally at registration.

STATE_BLOCKIE-03
Run in lab →

KYC rejected

Identity records do not match.

Browse-only; deposits and bets refused until manual review.

KYC_REQUIREDIE-04
Run in lab →

KYC referred to manual review

Watchlist near-hit.

Browse-only until an operator approves or declines from the Control Room.

KYC_REQUIREDKYC_MANUALIE-04
Run in lab →
06

Product KPI scorecard

Simulated values from this browser’s lab session sit next to the production metric they stand in for. They are deliberately kept separate.

KPISIMULATEDthis browserPRODUCTION METRIC (not measured here)WHY IT MATTERS
Onboarding conversion…Visitors → verified accounts by state and channelBlocked registrations are a cost of compliance; measure them so they are not “fixed” the wrong way.
KYC completion…% verified within 10 min; auto-approve vs manual reviewManual review is the largest onboarding leak in US books.
First-deposit conversion…Verified → funded within 24h; decline rate by methodFunded-in-session predicts 90-day value.
First-bet conversion…Funded → first settled bet within 7 daysA deposit without a bet is a refund waiting to happen.
Transaction success…Accepted ÷ attempted by reason code; duplicate incidents (target 0)Reason codes separate healthy refusals from defects.
Settlement accuracy…Resettlements per 10k bets; payout varianceResettlements are the public face of data quality.
Wallet reconciliation…Daily ledger-vs-processor breaks and $ variance (target 0)If not zero, nothing else can be trusted.
Responsible-gaming outcomes…Limit adoption, exclusions honoured (100%), retention of limit-settersWhere “safety and retention move together” is proven or falsified.

Simulated values come from one persona in one browser and are illustrative; they prove the instrumentation exists, not a forecast. They are never production metrics.

07

Independent review findings — resolved

Findings from the v4 review and how they were resolved; each is covered by a named regression test.

#FINDINGRESOLUTIONTESTS
F1Malformed selections reached the wallet pathvalidateLeg() before eligibility and funds; coded refusals touch nothing.
F2Missing accepted price bypassed odds checkAccepted price must be a finite number > 1 on every leg.
F3Later exclusion could shorten an earlier oneCooling-off and exclusion are monotonic; shortening is a logged no-op.
F4Idempotency replayed unrelated transactionsKey stores a canonical payload fingerprint; mismatch → IDEMPOTENCY_CONFLICT.
F5Lowering a limit failed reconciliation retroactivelyDeposits record the limit in force; reconciliation checks against that.
F6Correlated same-event legs undefinedPolicy: one selection per event, enforced in placement and reconciliation.
E1Deposits/withdrawals accepted empty keysNon-empty idempotency key required on all money commands.
E2Identity change could carry KYC and balanceAccount isolation: REGISTER refused over an active account; SIGN_OUT discards all account-scoped state.
E3Unknown event settlement threwUNKNOWN_EVENT returned without exception; MARKET_SET validated too.
E4Price moves on invalid selections threwSelection, price range and settled-market checks; coded refusals.
E5Invalid RG durations acceptedPositive finite integer durations only; limits and clock advances validated.
08

Production limitations

What this prototype is not, and what production would add.

What this prototype is not

  • Single-user, single-browser: no concurrency; races shown via replay.
  • No real KYC, payments, geolocation or odds feed — persona-encoded and hashed by design.
  • Settlement is manual; no event clock drives fixtures.
  • No cash-out, bonuses, multi-currency or tax withholding.
  • RG covers deposit limit, cooling-off and self-exclusion only.
  • Browser localStorage persistence only. No server, database or authentication.

Not proven by these tests: concurrency (single-writer reducer; races are simulated by replay), persistence durability beyond a localStorage round-trip, vendor integrations (KYC, payments, odds are persona-encoded or hashed).

What production would add

Identity & KYC —
Document + database vendors, watchlists, per-state geolocation
Payments —
Card/ACH rails, processor reconciliation, chargebacks
Odds & trading —
Live feed, suspension automation, liability limits
Durable ledger —
Append-only store, double-entry, snapshots, recon job
Concurrency —
Account-bound keys with TTL, serialised wallet writes
Settlement —
Official results, resettlement audit, W-2G
Responsible gaming —
Loss/wager/session limits, affordability, state registers
Operations —
Trading desk, support tooling, compliance exports