Wallet Callback (Seamless)
In Seamless Mode the player balance lives in your system. Mangoplay calls the Call back endpoint you supplied on the Request Form every time a bet is placed or settled.
This page is the contract for that endpoint. Getting the idempotency rules right is what keeps money correct on both sides.
Request
Mangoplay sends POST with a JSON body. Every request carries these headers:
The action field tells you what happened:
Fields
Every action carries the same envelope:
info dealId differs between bet and settle
The bet carries ..._B and its settlement carries ..._S — the same bill, two distinct
de-duplication keys. Store both.
Money fields
winLose is what you credit. winLoseWithOutTurnOver is the player's net result, for
your reporting. Both are decided by gameResult:
The last row is not a zero-value transaction. BET_RETURN and CANCEL_SETTLE ask you to
reverse a transaction you already applied, identified by dealId — and for
CANCEL_SETTLE, additionally by the id we echo back (see below). The amount to reverse
is the one from that original transaction, not from this payload.
Examples
Player bets 100 on Hilo:
{
"action": "BET",
"type": "BET",
"id": 1786615539367226,
"username": "0tonebx4",
"dealId": "HL-B20260813100522-1786615539334-QGF2BP31_B",
"betId": "HL-B20260813100522-HL-B",
"roundId": "HL-B20260813100522",
"game": "Hilo",
"providerName": "Hilo",
"gameType": "CASINO",
"betDetail": "HOLE_3_5",
"validBet": 100,
"turnOver": 100,
"winLose": -100,
"winLoseWithOutTurnOver": -100,
"gameResult": "Wait",
"betTime": 1786615539334,
"reportDate": "13-08-2026",
"ip": "127.0.0.1",
"remark": "Waiting for settlement"
}
The bet wins and pays even money — profit 100 on a stake of 100. Note the _S deal id:
{
"action": "SETTLE",
"type": "SETTLE",
"id": 1786615800702941,
"username": "0tonebx4",
"dealId": "HL-B20260813100522-1786615539334-QGF2BP31_S",
"betId": "HL-B20260813100522-HL-B",
"roundId": "HL-B20260813100522",
"game": "Hilo",
"providerName": "Hilo",
"gameType": "CASINO",
"betDetail": "HOLE_3_5",
"validBet": 100,
"turnOver": 100,
"winLose": 200,
"winLoseWithOutTurnOver": 100,
"gameResult": "WIN",
"betTime": 1786615539334,
"settleTime": 1786615800000,
"reportDate": "13-08-2026",
"ip": "127.0.0.1"
}
Reversals
BET_RETURN and CANCEL_SETTLE both target a bill you already processed.
BET_RETURN— the stake goes back to the player. Sent with the bet's_Bdeal id.CANCEL_SETTLE— a settlement is being undone, usually because a round result was corrected. Theidfield is not generated by us for this action: we echo back the transaction id you returned when you accepted the original settle. Use it to locate the transaction to reverse.
If a corrected result produces a new payout, a fresh SETTLE follows the
CANCEL_SETTLE with a new id.
Response
Return code 0 (also accepted: 200, 201) for success. Always include the balance:
{ "code": 0, "balanceBefore": 1000, "balanceAfter": 900 }
warning Balance is required on every successful response
This includes responses where you reject the call as a duplicate. Without
balanceBefore / balanceAfter we cannot show the player their balance.
On failure, return a non-success code and an errorType:
{ "code": 4000, "errorType": "INSUFFICIENT_BALANCE", "message": "Insufficient balance" }
A timeout, a connection error, or a 5xx is always retried — we cannot tell from those
whether you applied the transaction.
Idempotency — the important part
De-duplicate by dealId.
dealId is unique per bet. Every retry of the same logical transaction reuses the same
dealId and the same id, so either field is a safe de-duplication key.
danger Do not de-duplicate by betId
betId identifies the round, not the bet. When a player places several bets in one
round, every one of them carries the same betId. De-duplicating on it would silently
reject all bets after the first.
When you receive a dealId you have already applied, return
errorType: "DUPLICATE_TRANSACTION" together with the balance from the original
transaction. Do not apply it a second time.
Retries and timeouts
If your system is consistently slower than these defaults we can raise the timeout for your agent — tell us your realistic p99 response time for bet and for settle separately.
info Why the timeout matters
If we time out on a call you actually processed, our records and yours disagree: you debited the player, we recorded the bet as failed. Raising the settle timeout to match your real response time is the single most effective way to prevent bills stuck on "awaiting payment".
Per-agent options
These are configured by Mangoplay on request, once the behaviour is confirmed with your team. Every one of them defaults to off, so nothing changes unless you ask.
When something goes wrong
Do not raise a ticket for a single stuck bill. Use the Reconciliation APIs instead:
-
POST /api/v1/open/seamLess/betInfo— shows the bet status, the settle status, and the last request/response we exchanged with you for that deal. -
POST /api/v1/open/seamLess/reSettle— flips a bet we marked failed to success and settles it. Idempotent, and safe to call again. Call it only after the round closed.
Both use your AgentPrefixId and Security headers and only reach your own deals.