Appearance
Wallet Callbacks
Money flows through seamless-wallet callbacks that you implement. You expose a wallet base URL (configured with us at onboarding); when a player bets, wins, or has a bet cancelled, we POST to your wallet URL so you can move money on your own ledger.
There are three callbacks, all on your wallet base URL:
| We call | When | You do |
|---|---|---|
POST <WALLET_URL>/bet | A bet is placed | Debit the stake |
POST <WALLET_URL>/win | A ticket settles as a win | Credit the winnings |
POST <WALLET_URL>/rollback | A bet is cancelled or a settlement is rolled back | Reverse a prior debit/credit |
Callback request fields are snake_case (exactly as shown below).
Idempotency (required)
Every callback carries a unique transaction_ref. Your wallet MUST be idempotent: a repeated transaction_ref returns the same result and does not double-apply. We may retry a callback on network failure, so the same transaction_ref can arrive more than once — key your ledger writes on it.
A rollback additionally carries original_transaction_ref — the transaction_ref of the debit/credit being reversed.
Validate the caller
These endpoints move money. Authenticate that the caller is Oddyne (per the mechanism agreed at onboarding) and validate operator_id before applying anything.
POST <WALLET_URL>/bet
Debit the stake when a bet is placed.
json
{
"transaction_ref": "unique-tx-id",
"operator_id": "<SITE_ID>",
"ticket_id": 123456,
"user_id": "<PLAYER_ID>",
"stake": 10.00,
"currency": "USD",
"total_odds": 2.5,
"potential_win": 25.00,
"bet_type": "single",
"selections": [
{ "event_id": 1001, "market_id": 1, "outcome_id": 3, "price_version": "v2", "odds": 2.5 }
],
"created_at": "2026-08-09T12:00:00Z"
}POST <WALLET_URL>/win
Credit the winnings on settlement.
json
{
"transaction_ref": "unique-tx-id",
"operator_id": "<SITE_ID>",
"ticket_id": 123456,
"user_id": "<PLAYER_ID>",
"win_amount": 25.00,
"currency": "USD",
"total_odds": 2.5,
"bet_type": "single",
"selections": [
{ "event_id": 1001, "market_id": 1, "outcome_id": 3, "price_version": "v2", "odds": 2.5 }
],
"settled_at": "2026-08-09T13:00:00Z"
}POST <WALLET_URL>/rollback
Reverse a prior debit/credit — a bet cancel or a settlement rollback.
json
{
"transaction_ref": "unique-tx-id",
"original_transaction_ref": "the-tx-id-being-reversed",
"operator_id": "<SITE_ID>",
"ticket_id": 123456,
"user_id": "<PLAYER_ID>",
"amount": 10.00,
"currency": "USD",
"selections": [
{ "event_id": 1001, "market_id": 1, "outcome_id": 3, "price_version": "v2", "odds": 2.5 }
]
}The selections[] item
Every callback carries the ticket's selections. Each item is:
| Field | Type | Notes |
|---|---|---|
event_id | integer | The event (match) id. |
market_id | integer | The market id within the event. |
outcome_id | integer | The selected outcome id. |
price_version | string | The odds price version the bet was accepted at. |
odds | number | The decimal odds for this selection. |
Expected response
Every callback returns the same response shape. On success:
json
{ "status": "ok", "transaction_id": "operator-side-tx-id" }On failure:
json
{ "status": "error", "error_code": "INSUFFICIENT_FUNDS", "error_message": "..." }status— must be"ok"or"error".transaction_id— your own ledger transaction id (on success).error_code/error_message— a machine code and human message (on error), e.g.INSUFFICIENT_FUNDS.
Idempotency is keyed on transaction_ref; a rollback references original_transaction_ref.