Skip to content
Wallet integration / Idempotency & retries
Wallet integration

Idempotency & retries

How we retry, and what your wallet must do so that a retry never moves money twice.

  • The same transaction_id twice is the same movement once. Answer the second call with the body of the first and touch nothing. A retry carries the same body, with a new timestamp and signature.
  • Only silence is retried. A 4xx is an answer; asking again after being told no would turn one refusal into several attempts at the same balance.
  • A rollback for a movement you never saw is answered with the current balance, and the id is remembered as cancelled. If the bet arrives afterwards, refuse it.
  • Currency is fixed by the session. A mismatch is ours to fix, not yours to convert.
  • Answer fast. The player is waiting on the spin. Aim for well under a second and do the bookkeeping asynchronously.

Retry timeline

silence on a bet or win
t = 0 s      attempt 1   → timeout (your wallet_timeout, 10 s by default, 1–60 s)
+ 2 s        attempt 2   → timeout
+ 8 s        attempt 3   → timeout
             rollback    transaction_id "<id>:rollback", reference_transaction_id "<id>"
             the movement is recorded as failed; the provider is told the wallet is unreachable
Your answerRetried?
2xx with a string balanceno: done
4xx except 408 and 429no: refused
5xx, 408, 429yes
No answer within the timeout, connection erroryes
2xx whose body cannot be readyes
Our own rollback is best effort. If it too goes unanswered, the provider's later rollback or our reconciliation settles the round; GET /v1/transactions/{id} shows the final status.

A round, as you will see it

sequence
bet        transaction_id "pragmatic:5501934"   round 7200311   amount "1.50"   → balance "98.50"
win        transaction_id "pragmatic:5501935"   round 7200311   amount "3.00"   → balance "101.50"
rollback   transaction_id "pragmatic:rb-8812"   reference "pragmatic:5501934"   → balance "103.00"   (only if the provider cancels)

Ids

Every id starts with the game provider's code so that two providers counting from one never collide in your books.