Change Player Balance

This API changes a player's balance. It is provided by the merchant (operator) and called by the game platform.

The API is called once for each operation, such as placing a bet, canceling a bet, issuing a payout, or ending a game.

The value of the changeType field differs for each operation.

Request URL

POST {API_URL_ROOT}/player/changeBalance

Note: This URL can be configured in the merchant backend, but the request and response parameters must meet the requirements below.

Request Parameters

Field Required Type Description
sign YES string Signature calculated using the Signature Algorithm.
timestamp YES int Timestamp in seconds since January 1, 1970, e.g. 1741837297.
Accept-Language YES string Accepted language code. See the Language List, e.g. zh or en. This is used to return localized error messages.
Content-Type YES string application/json; charset=utf-8

BODY

Field Required Type Description
recordId YES string Game record ID that uniquely identifies each game played by a player.
txId YES string Transaction ID that uniquely identifies each request.
tenantId YES int Merchant ID: a unique integer assigned by the platform.
userId YES string Merchant's player ID that uniquely identifies each player.
gameId YES int Game ID.
changeType YES int Balance change type. See the changeType value list below.
betType YES int Bet type. See the betType value list below.
betAmount YES double Bet amount.
bonus YES double Payout amount.
multiple NO double Payout multiplier. This value may sometimes differ slightly from bonus / betAmount. For example, this can happen when a preset multiplier is used for a payout and the payout amount reaches the maximum payout limit.
roundId NO string Round ID. Primarily used in multiplayer games to uniquely identify each game round.
area NO int Area ID. The default is 0. Some games support bets in different areas, and this field distinguishes those areas.
currency NO string Currency code.
isCompleted NO bool Whether the game round is complete. This field is required for a payout. For the final payout, set this field to true to avoid an additional end-game request (changeType=4).
isRetry NO bool Whether this request is a retry. If a request times out or does not return a valid result, up to six retries may be triggered until a successful response is received. This value is true for retry requests.
parentId NO string Parent record ID. A slot game may trigger free spins. If the current record is for a free spin, parentId is the record ID of the original bet. In this case, betType=3 and betAmount=0 identify the free spin.

The values of the fields vary according to changeType. The following six scenarios are supported:

  1. Bet and payout: changeType=0

    • betAmount has a value.
    • A bonus value greater than 0 indicates a payout; bonus=0 indicates no payout.
    • multiple is the payout multiplier. If it is provided, the system uses it; otherwise, the system calculates it using bonus / betAmount.
    • isCompleted=true ends the bet immediately.
  2. Normal bet: changeType=1

    • betAmount has a value and bonus=0.
  3. Cancel bet: changeType=2

    • betAmount is the amount of the original bet.
  4. Payout: changeType=3

    • betAmount=0 and bonus has a value.
    • Some games may issue multiple payout calls.
    • multiple is the payout multiplier. If it is provided, the system uses it; otherwise, the system calculates it using bonus / betAmount.
    • For the final payout, set isCompleted=true to indicate that the game round has ended. This has the same effect as making another call with changeType=4.
  5. End game: changeType=4

    • betAmount=0 and bonus=0.
  6. Free spins triggered in a slot game: changeType=0

    • betType=3 identifies the bet as a free spin.
    • parentId contains the record ID of the original bet that triggered the free spin.
    • A free-spin feature may issue multiple payouts, and each payout has a different recordId.

Example

Six Scenarios

// Bet and payout scenario:
{
  "recordId": "682ed6edce1c812d736c4876",
  "txId": "682ed6edce1c812d736c4877",
  "tenantId": 2317,
  "userId": "t20339",
  "gameId": 2001,
  "changeType": 0,
  "betType": 0,
  "betAmount": 100.00,
  "bonus": 30,
  "multiple": 0.30,
  "roundId": "12353",
  "area": 0,
  "currency": "BRL",
  "details": null,
  "isCompleted": true
}
// Normal bet scenario:
{
  "recordId": "682ed6edce1c812d736c4876",
  "tenantId": 2317,
  "userId": "t20339",
  "gameId": 2001,
  "changeType": 1,
  "betType": 1,
  "betAmount": 100.00,
  "bonus": 0,
  "multiple": 0,
  "roundId": "12353",
  "area": 0,
  "currency": "BRL",
  "details": null,
  "isCompleted": false
}

// Cancel bet scenario:
{
  "recordId": "682ed6edce1c812d736c4876",
  "tenantId": 2317,
  "userId": "t20339",
  "gameId": 2001,
  "changeType": 2,
  "betType": 1,
  "betAmount": 100.00,
  "bonus": 0,
  "multiple": 0,
  "roundId": "12353",
  "area": 0,
  "currency": "BRL",
  "details": null,
  "isCompleted": false
}

// Payout scenario:
{
  "recordId": "682ed6edce1c812d736c4876",
  "tenantId": 2317,
  "userId": "t20339",
  "gameId": 2001,
  "changeType": 3,
  "betType": 1,
  "betAmount": 0,
  "bonus": 50.00,
  "currency": "BRL",
  "details": null,
  "isCompleted": true
}

// End-game scenario:
{
  "recordId": "682ed6edce1c812d736c4876",
  "tenantId": 2317,
  "userId": "t20339",
  "gameId": 2001,
  "changeType": 4,
  "betType": 1,
  "betAmount": 0,
  "bonus": 0,
  "multiple": 0,
  "roundId": "12353",
  "area": 0,
  "currency": "BRL",
  "details": null,
  "isCompleted": true
}

// Slot-game free-spin scenario:
{
  "recordId": "682ed6edce1c812d73ac2899",
  "tenantId": 2317,
  "userId": "t20339",
  "gameId": 2001,
  "changeType": 0,
  "betType": 3,
  "betAmount": 0,
  "bonus": 0,
  "multiple": 0,
  "roundId": "12353",
  "area": 0,
  "currency": "BRL",
  "details": null,
  "isCompleted": true,
  "parentId": "682ed6edce1c812d736c4876"
}

Response Parameters

Field Required Type Description
tenantId YES int Merchant ID: a unique integer assigned by the platform.
userId YES string Merchant's user ID that uniquely identifies each player.
balance NO double Player balance. Regardless of whether the deduction succeeds, the current account balance must be returned correctly so that the account balance can be updated.
currency NO string Game currency code.

Important: Regardless of whether isSuccess is true or false, the current account balance must be returned correctly. The system updates the current account balance using the balance value. If the account status is abnormal and the player cannot play, balance must be 0.

Merchants may encounter various unforeseen errors while processing a request. To keep the platform's processing status consistent with the merchant's status, several error codes have been predefined. If a similar error occurs, return the corresponding error code below:

isSuccess code message data Scenario Description
true 0 null {"tenantId":1,"userId":"276682","balance":100000,"currency":"BRL"} The request was processed successfully and returned normally.
false 1 For example: Invalid request or parameter validation error. The content can be customized. {"tenantId":1,"userId":"276682","balance":100000,"currency":"BRL"} Request parameter validation or the merchant's own business validation failed. Return the user's balance if it is available. The message can be customized according to the merchant's business requirements; there is no fixed message.
false 2 Failed to retrieve user balance None The player's balance could not be retrieved or returned.
false 3 Insufficient player balance {"tenantId":1,"userId":"276682","balance":0.5,"currency":"BRL"} The player's balance is less than the bet amount.
false 4 Failed to update balance {"tenantId":1,"userId":"276682","balance":0.5,"currency":"BRL"} The balance update failed. The returned balance is the balance after the last successful update.
false 5 Order already exists or duplicate bet {"tenantId":1,"userId":"276682","balance":0.5,"currency":"BRL"} The recordId already exists and changeType=0 or changeType=1 was called again. The same recordId can be used to place a bet only once; this is an idempotency check.
false 6 Order does not exist {"tenantId":1,"userId":"276682","balance":100000,"currency":"BRL"} No order with the specified recordId was found when canceling a bet, issuing a payout, or ending a game.
false 7 Order already canceled; duplicate cancellation {"tenantId":1,"userId":"276682","balance":100000,"currency":"BRL"} The order has already been canceled. This error is returned if it is canceled again.
false 8 Order already settled; duplicate payout or game end {"tenantId":1,"userId":"276682","balance":100000,"currency":"BRL"} The order has already received a payout or ended. This error is returned if payout, end game, or the combined changeType=0 mode is called again.
false 9 Abnormal order status {"tenantId":1,"userId":"276682","balance":100000,"currency":"BRL", changeType: 4} This error is returned when attempting to issue a payout for or end an order that has already been canceled, or when attempting to cancel an order that has already received a payout or ended. The order's current changeType must also be returned. This can occur when a call to the merchant API times out or returns an error, so the platform cannot determine the order's current status.
false 500 System error None Internal server error. Merchants are advised to handle exceptions uniformly at the outermost level of the entire order-processing flow.

The platform handles all scenarios listed above with codes from 0 through 9. Other scenarios are not handled.

Example

{
  "isSuccess": true,
  "code": 0,
  "data": {
    "tenantId": 1,
    "userId": "t1_276682",
    "balance": 100000,
    "currency": "BRL"
  }
}
// Insufficient balance scenario:
{
  "isSuccess": false,
  "code": xxx, // Merchant's insufficient-balance error code, e.g. 2012
  "message": "Insufficient balance; bet failed",
  "data": {
    "tenantId": 1,
    "userId": "t1_276682",
    "balance": 1.0, // Current balance
    "currency": "BRL"
  }
}
// Player disabled scenario:
{
  "isSuccess": false,
  "code": xxx, // Merchant's abnormal-status error code, e.g. 2013
  "message": "Player disabled; bet failed",
  "data": {
    "tenantId": 1,
    "userId": "t1_276682",
    "balance": 0.0, // Must be 0
    "currency": "BRL"
  }
}

betType Value List

Value Description
1 Normal bet
2 Cascade
3 Free spin
4 Respin

changeType Value List

Value Description
0 Bet and payout
1 Normal bet
2 Cancel bet
3 Payout
4 End game

Game Flow Examples

For scenarios that do not combine a bet and payout into a single request, the following flows may occur:

  1. Normal bet and payout

    Game bet -> Game payout (isCompleted=true): the corresponding changeType values are 1 -> 3. The player places a bet, wins, and the result is settled; the game round then ends. This flow applies to most games. Setting isCompleted=true for the final payout is recommended because it avoids one additional API call.

    Game bet -> Game payout -> Game round ends: the corresponding changeType values are 1 -> 3 -> 4. The player places a bet, wins, and the result is settled; the game round then ends. This flow also applies to most games.

  2. Cancel bet

    Game bet -> Cancel bet: the corresponding changeType values are 1 -> 2. The player places a bet and voluntarily cancels it before the round starts. This generally applies to multiplayer games and mini-games. The recordId of the cancellation must be the same as the recordId of the original bet.

  3. No payout

    Game bet -> No win -> Game round ends: the corresponding changeType values are 1 -> 4. The player places a bet but does not win the round, and the end of the round is then confirmed.

  4. Multiple payouts for one bet

    This generally applies to cascading-reel slot games, slot games that enter a special feature, and lottery games. The player places one bet and wins multiple times during the round before it ends.

    Game bet -> Game payout -> Game payout -> Game payout -> ... -> Game payout (isCompleted=true): the corresponding changeType values are 1 -> 3 -> 3 -> ... -> 3. Setting isCompleted=true for the final payout is recommended because it avoids one additional API call.

    Game bet -> Game payout -> Game payout -> Game payout -> ... -> Game round ends: the corresponding changeType values are 1 -> 3 -> 3 -> ... -> 4.

results matching ""

    No results matching ""