> For the complete documentation index, see [llms.txt](https://docs.hub88.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hub88.io/developer-docs/supplier-api-reference/wallet-api.md).

# Wallet API

The Wallet API is called by the Supplier. The Supplier sends wallet transactions to Hub88, which are processed and then send forwards to the Operators.&#x20;

{% hint style="info" %}

#### ⚡ Hand this to your AI agent for Supplier API Integration

One prompt covering every endpoint you host and every call you make, the request signing scheme, the `RS_*` statuses, and the rollback-on-bet / retry-on-win rules. Paste it into your AI tool with your stack appended and it scaffolds a working integration.

{% file src="/files/wKSzRtb7jdjkpHUDH4gs" %}

{% endhint %}

### Request consistency&#x20;

**Wallet API** requests have to be idempotent. All requests contain a `request_uuid` field. Hub88 will ensure that requests with the same `request_uuid` are not processed twice, while the response will be the same for all duplicate requests, excluding the `/supplier/generic/v2/user/balance` call.

***

## Wallet API Reference - Supplier API&#x20;

***

### Get a user's balance

***

{% hint style="info" %}
**Requires an active session**

This endpoint requires a valid, active session token. The session is activated only after the Supplier returns a successful [`/game/url`](/developer-docs/supplier-api-reference/games-api.md#get-a-game-url) response to Hub88.

If `/user/balance` is called before `/game/url` has returned successfully, Hub88 will respond with `RS_ERROR_INVALID_TOKEN`. Make sure your integration calls this endpoint only after the game URL has been returned and the player has been redirected to the game.

See the [Real gameplay flow](https://docs.hub88.io/developer-docs/supplier-api-reference/supplier-api-overview#real-gameplay) for the expected sequence.
{% endhint %}

## POST /supplier/generic/v2/user/balance

> The endpoint should be called when a user's balance is needed by the Supplier. Hub88 will return user's current balance. Game identifier is provided to help Hub88 with user's activity statistics.

```json
{"openapi":"3.1.1","info":{"title":"Hub88","version":"2.0"},"tags":[{"name":"Wallet API","description":"Hub88 is expected to provide API for Game Provider's calls. API will process the described requests from Game Provider."}],"paths":{"/supplier/generic/v2/user/balance":{"post":{"tags":["Wallet API"],"summary":"","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}}}}},"parameters":[{"schema":{"type":"string"},"required":true,"name":"X-Hub88-Signature","in":"header","description":"RSA-SHA256 is used to sign the request body using the private key. The signature is validated using the public key associated with the provided `operator_id`."}],"operationId":"/supplier/generic/v2/user/balance","description":"The endpoint should be called when a user's balance is needed by the Supplier. Hub88 will return user's current balance. Game identifier is provided to help Hub88 with user's activity statistics.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["game_code","token","request_uuid"],"properties":{"supplier_user":{"$ref":"#/components/schemas/supplier_user"},"token":{"type":"string","description":"The game session token that was passed within `/game/url` endpoint request."},"request_uuid":{"$ref":"#/components/schemas/request_uuid"},"game_code":{"$ref":"#/components/schemas/game_code"}}}}},"required":true,"description":""}}}},"components":{"schemas":{"Response":{"type":"object","title":"Response","required":["user","status","request_uuid","balance"],"properties":{"user":{"$ref":"#/components/schemas/user"},"status":{"$ref":"#/components/schemas/status"},"request_uuid":{"$ref":"#/components/schemas/request_uuid"},"currency":{"$ref":"#/components/schemas/currency"},"balance":{"$ref":"#/components/schemas/money_amount"}},"description":"Wallet API response"},"user":{"type":"string","description":"The unique user ID in the Hub88's system. In case of DEMO gameplay, this parameter may be omitted."},"status":{"type":"string","enum":["RS_OK","RS_ERROR_UNKNOWN","RS_ERROR_INVALID_PARTNER","RS_ERROR_INVALID_TOKEN","RS_ERROR_INVALID_GAMERS_ERROR_WRONG_CURRENCY","RS_ERROR_NOT_ENOUGH_MONEY","RS_ERROR_USER_DISABLED","RS_ERROR_INVALID_SIGNATURE","RS_ERROR_TOKEN_EXPIRED","RS_ERROR_WRONG_SYNTAX","RS_ERROR_WRONG_TYPES","RS_ERROR_DUPLICATE_TRANSACTION","RS_ERROR_TRANSACTION_DOES_NOT_EXIST","RS_ERROR_LIMIT_REACHED"],"description":"The response status."},"request_uuid":{"type":"string","description":"A standard 16-byte unique user identifier. The ID can be used as network layer action. An ID of an action that is generated for each game Supplier's call to Hub88. It's Used to sync Hub88 and game Supplier's sides for debugging purposes. Hub88 has to respond with the same request_uuid as the one that was received in request."},"currency":{"type":"string","enum":["BSD","TTD","ZMW","BMD","USD","UGX","HKD","MGA","GIP","UZS","MKD","mLTC","EGP","AWG","CZK","ILS","MZN","TND","XPF","SOS","DOP","RUB","KRW","BTN","KGS","BAM","AOA","BND","RSD","FKP","PEN","EOS","GHS","JPY","TRY","SBD","UAH","FJD","GNF","MDL","AFN","ZAR","MOP","TJS","BOB","JMD","QAR","IRR","SYP","XXX","NAD","MYR","CUP","NOK","KPW","MNT","NZD","uETH","SGD","PYG","OMR","DZD","EUR","TMT","MMK","TZS","CRC","VES","ETB","THB","LYD","CHF","MVR","KES","CVE","LSL","KMF","SZL","KYD","BRL","AED","WST","YER","ALL","TRX","HUF","GTQ","uBTC","IDR","MWK","DKK","TWD","XCD","BBD","LRD","KZT","JOD","BYN","BIF","PLN","SDG","VUV","SEK","BDT","HNL","BWP","VND","ISK","BHD","HTG","USDT","ADA","MUR","ERN","uLTC","LKR","COP","GEL","AUD","GBP","CAD","PHP","PAB","DJF","GMD","PKR","NIO","AMD","RWF","RON","NGN","TOP","UYU","AZN","SRD","KWD","PGK","CDF","SAR","IQD","XRP","SCR","mETH","MAD","GYD","INR","LBP","ARS","MXN","CLP","BNB","CNY","KHR","LAK","BZD","SSP","XOF","NPR","mBTC"],"description":"The ISO 4217 currency code. The following list contains all currencies supported by the Hub88 system. Note that native game play support with these currencies may vary per Provider. "},"money_amount":{"type":"integer","description":"The amount of money is displayed in integers **(Int64)**. To convert real float value to integer Hub88 multiplys it by 100000. Example: `$3.56` must be represented as `356000`"},"supplier_user":{"type":"string","description":"The user ID in the Supplier's system. If the Supplier renames Hub88's user IDs in any way(prefixes, etc.), the Supplier should send changed user IDs in this field to inform Hub88 about the renaming."},"game_code":{"type":"string","description":"The unique game identifier in Provider's system in the form of a string. `game_code` can be obtained from the `/game/list` endpoint and is a required parameter."}}}}
```

***

### Update a user's balance based on transaction bet

***

## POST /supplier/generic/v2/transaction/bet

> The endpoint should be called when the user places a bet (debit). Hub88  decrease users balance by \`amount\` and respond with the updated user balance.\
> &#x20;Each bet has a \`transaction\_uuid\` which is a unique identifier for this transaction. Before altering the user's balance, Hub88 has to check that the transaction with such \`transaction\_uuid\` hasn't been processed previously. \
> &#x20;Retry Policy: In case of a network failure (HTTP 502, timeout, nxdomain, etc.) or unsuccessful status (excluding \`RS\_ERROR\_NOT\_ENOUGH\_MONEY\` and \`RS\_ERROR\_LIMIT\_REACHED\`), the Supplier should roll back the transaction.

```json
{"openapi":"3.1.1","info":{"title":"Hub88","version":"2.0"},"tags":[{"name":"Wallet API","description":"Hub88 is expected to provide API for Game Provider's calls. API will process the described requests from Game Provider."}],"paths":{"/supplier/generic/v2/transaction/bet":{"post":{"tags":["Wallet API"],"summary":"","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}}}}},"parameters":[{"schema":{"type":"string"},"required":true,"name":"X-Hub88-Signature","in":"header","description":"RSA-SHA256 is used to sign the request body using the private key. The signature is validated using the public key associated with the provided `operator_id`."}],"operationId":"/supplier/generic/v2/transaction/bet","description":"The endpoint should be called when the user places a bet (debit). Hub88  decrease users balance by `amount` and respond with the updated user balance.\n Each bet has a `transaction_uuid` which is a unique identifier for this transaction. Before altering the user's balance, Hub88 has to check that the transaction with such `transaction_uuid` hasn't been processed previously. \n Retry Policy: In case of a network failure (HTTP 502, timeout, nxdomain, etc.) or unsuccessful status (excluding `RS_ERROR_NOT_ENOUGH_MONEY` and `RS_ERROR_LIMIT_REACHED`), the Supplier should roll back the transaction.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["game_code","round_closed","round","currency","amount","token","transaction_uuid","request_uuid"],"properties":{"supplier_user":{"$ref":"#/components/schemas/supplier_user"},"transaction_uuid":{"$ref":"#/components/schemas/transaction_uuid"},"token":{"type":"string","description":"The game session token that was passed within `/game/url` endpoint request."},"round_closed":{"$ref":"#/components/schemas/round_closed"},"round":{"$ref":"#/components/schemas/round"},"reward_uuid":{"type":"string","description":"The unique identifier for a reward on Hub88 side in standard 16-byte UUID format. `reward_uuid` is required when freespins are issued through the API."},"request_uuid":{"$ref":"#/components/schemas/request_uuid"},"is_free":{"$ref":"#/components/schemas/is_free"},"is_aggregated":{"description":"","$ref":"#/components/schemas/is_aggregated"},"game_code":{"$ref":"#/components/schemas/game_code"},"currency":{"$ref":"#/components/schemas/currency"},"bet":{"$ref":"#/components/schemas/bet"},"amount":{"$ref":"#/components/schemas/money_amount"},"is_billable":{"type":"boolean","description":"Indicates whether Hub88 includes this bet in GGR. Optional. When omitted, the bet is processed as a regular BET and the `amount` field is contributed to GGR. When `true`, the bet behaves like a regular bet and contributes the `amount` field to GGR. In this case, if `billable_amount` is sent, it must equal the `amount` field. When `false`, the bet is excluded from GGR. The player's balance is still debited by the `amount` field. Use this for a debit that is not part of the game result, for example a shipping fee. Ignored when `is_free` is `true`: a free bet is never billable."},"billable_amount":{"type":"integer","format":"int64","minimum":0,"description":"The GGR contribution of the bet, in the same currency and Int64 format as the `amount` field. Optional. For a BET, Hub88 always uses the `amount` field as the GGR contribution. When `is_billable` is `true`, GGR is calculated from the `amount` field. When `is_billable` is `false`, this field is ignored. If sent, it must equal the `amount` field, because Hub88 forwards it to the Operator as the GGR contribution. Must be 0 or positive."},"meta":{"$ref":"#/components/schemas/meta"}}}}},"required":true,"description":""}}}},"components":{"schemas":{"Response":{"type":"object","title":"Response","required":["user","status","request_uuid","balance"],"properties":{"user":{"$ref":"#/components/schemas/user"},"status":{"$ref":"#/components/schemas/status"},"request_uuid":{"$ref":"#/components/schemas/request_uuid"},"currency":{"$ref":"#/components/schemas/currency"},"balance":{"$ref":"#/components/schemas/money_amount"}},"description":"Wallet API response"},"user":{"type":"string","description":"The unique user ID in the Hub88's system. In case of DEMO gameplay, this parameter may be omitted."},"status":{"type":"string","enum":["RS_OK","RS_ERROR_UNKNOWN","RS_ERROR_INVALID_PARTNER","RS_ERROR_INVALID_TOKEN","RS_ERROR_INVALID_GAMERS_ERROR_WRONG_CURRENCY","RS_ERROR_NOT_ENOUGH_MONEY","RS_ERROR_USER_DISABLED","RS_ERROR_INVALID_SIGNATURE","RS_ERROR_TOKEN_EXPIRED","RS_ERROR_WRONG_SYNTAX","RS_ERROR_WRONG_TYPES","RS_ERROR_DUPLICATE_TRANSACTION","RS_ERROR_TRANSACTION_DOES_NOT_EXIST","RS_ERROR_LIMIT_REACHED"],"description":"The response status."},"request_uuid":{"type":"string","description":"A standard 16-byte unique user identifier. The ID can be used as network layer action. An ID of an action that is generated for each game Supplier's call to Hub88. It's Used to sync Hub88 and game Supplier's sides for debugging purposes. Hub88 has to respond with the same request_uuid as the one that was received in request."},"currency":{"type":"string","enum":["BSD","TTD","ZMW","BMD","USD","UGX","HKD","MGA","GIP","UZS","MKD","mLTC","EGP","AWG","CZK","ILS","MZN","TND","XPF","SOS","DOP","RUB","KRW","BTN","KGS","BAM","AOA","BND","RSD","FKP","PEN","EOS","GHS","JPY","TRY","SBD","UAH","FJD","GNF","MDL","AFN","ZAR","MOP","TJS","BOB","JMD","QAR","IRR","SYP","XXX","NAD","MYR","CUP","NOK","KPW","MNT","NZD","uETH","SGD","PYG","OMR","DZD","EUR","TMT","MMK","TZS","CRC","VES","ETB","THB","LYD","CHF","MVR","KES","CVE","LSL","KMF","SZL","KYD","BRL","AED","WST","YER","ALL","TRX","HUF","GTQ","uBTC","IDR","MWK","DKK","TWD","XCD","BBD","LRD","KZT","JOD","BYN","BIF","PLN","SDG","VUV","SEK","BDT","HNL","BWP","VND","ISK","BHD","HTG","USDT","ADA","MUR","ERN","uLTC","LKR","COP","GEL","AUD","GBP","CAD","PHP","PAB","DJF","GMD","PKR","NIO","AMD","RWF","RON","NGN","TOP","UYU","AZN","SRD","KWD","PGK","CDF","SAR","IQD","XRP","SCR","mETH","MAD","GYD","INR","LBP","ARS","MXN","CLP","BNB","CNY","KHR","LAK","BZD","SSP","XOF","NPR","mBTC"],"description":"The ISO 4217 currency code. The following list contains all currencies supported by the Hub88 system. Note that native game play support with these currencies may vary per Provider. "},"money_amount":{"type":"integer","description":"The amount of money is displayed in integers **(Int64)**. To convert real float value to integer Hub88 multiplys it by 100000. Example: `$3.56` must be represented as `356000`"},"supplier_user":{"type":"string","description":"The user ID in the Supplier's system. If the Supplier renames Hub88's user IDs in any way(prefixes, etc.), the Supplier should send changed user IDs in this field to inform Hub88 about the renaming."},"transaction_uuid":{"type":"string","description":"The unique transaction identifier. An ID of business logic action (transaction) that <b>needs to be stored</b> on both sides for <b>at least 4 months</b> (for reconciliation purposes). Hub88 has to respond on each `transaction_uuid`. An action with same `transaction_uuid` must not be processed more than once."},"round_closed":{"type":["boolean","null"],"description":"Denotes when the round is closed."},"round":{"nullable":false,"type":"string","description":"The game round ID used to relate all bets and wins made in one round. All transactions related to the same round have the same value in this field. The ID is not unique through whole system. The value depends on Supplier's RGS logic, as it is created from game + user + round combination, resulting in uniqueness."},"is_free":{"type":["boolean","null"],"description":"The flag which indicates that the transaction is tied to a reward issued via Hub88’s Freebets API and if promo transaction contributes to GGR calculation or not. Set to `true` when the transaction is the result of a previously created reward and does not contribute to GGR calculation. When `false`, the transaction is not connected to a Hub88 Freebets API (e.g. the transaction is a regular gameplay or supplier-managed promotions), and contributes to GGR calculation."},"is_aggregated":{"type":["boolean","null"],"description":"The flag which shows that related freebet transactions identified in the field `reward_uuid` have been aggregated into one single transaction. For example, a player was rewarded ten (10) freespins, but the Supplier sends one single transaction request with field `is_aggregated` set to true."},"game_code":{"type":"string","description":"The unique game identifier in Provider's system in the form of a string. `game_code` can be obtained from the `/game/list` endpoint and is a required parameter."},"bet":{"type":["string","null"],"description":"The field for metadata related to transaction, such as type of bet, value, time, etc. Differs from game to game. Not relevant for transaction processing procedure but could be useful for statistics or activity backtracking."},"meta":{"type":["object","null"],"description":"The transaction metadata, enriches the transaction payload for processing. In cases where `is_supplier_promo: true`, in `meta` object `meta.supplier_promo_info.promo_reference` string should be included. It's an optional promotion reference identifier provided by the supplier, used for tracking, audit, or reconciliation of supplier-managed promotions. It can also carry a direct fee, see `direct_fee_value` and `direct_fee_reason`.","properties":{"direct_fee_value":{"type":"integer","format":"int64","description":"The amount the Operator pays back to the Supplier in full for this transaction, outside GGR, for example a shipping fee the player paid or the value of a physical item the player keeps. Same currency and Int64 format as `amount`. It does not change the GGR contribution or the player's balance movement. Hub88 invoices it separately from GGR. Only send it on transactions that carry `is_billable` (`true` or `false`, for example `is_billable: false` for a shipping fee bet or `is_billable: true` for a redemption win). Always send it together with `direct_fee_reason`."},"direct_fee_reason":{"type":"string","maxLength":255,"description":"A short, stable identifier for the type of direct fee, for example `shipping_fee` or `redemption`. Maximum 255 characters. Hub88 groups direct fees by this value when invoicing, so use the same identifier for every fee of the same type. Passed to the Operator in `meta`. Required when `direct_fee_value` is sent."}}}}}}
```

***

### Update a user's balance based on transaction win

***

## POST /supplier/generic/v2/transaction/win

> The endpoint should be called when the user wins (credit). Hub88 will increase the user's balance by \`amount\` and respond with the updated user balance. \`reference\_transaction\_uuid\` shows which bet this win is related to.\
> &#x20;Each win has a \`transaction\_uuid\` which is a unique identifier for this transaction. Before altering user's balance, Hub88 will check that the win hasn't been processed previously. \
> &#x20;Retry Policy: In case of a network failure (HTTP 502, timeout, nxdomain, etc.) or unsuccessful status, the Supplier must retry the transaction.

```json
{"openapi":"3.1.1","info":{"title":"Hub88","version":"2.0"},"tags":[{"name":"Wallet API","description":"Hub88 is expected to provide API for Game Provider's calls. API will process the described requests from Game Provider."}],"paths":{"/supplier/generic/v2/transaction/win":{"post":{"tags":["Wallet API"],"summary":"","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}}}}},"parameters":[{"schema":{"type":"string"},"required":true,"name":"X-Hub88-Signature","in":"header","description":"RSA-SHA256 is used to sign the request body using the private key. The signature is validated using the public key associated with the provided `operator_id`."}],"operationId":"/supplier/generic/v2/transaction/win","description":"The endpoint should be called when the user wins (credit). Hub88 will increase the user's balance by `amount` and respond with the updated user balance. `reference_transaction_uuid` shows which bet this win is related to.\n Each win has a `transaction_uuid` which is a unique identifier for this transaction. Before altering user's balance, Hub88 will check that the win hasn't been processed previously. \n Retry Policy: In case of a network failure (HTTP 502, timeout, nxdomain, etc.) or unsuccessful status, the Supplier must retry the transaction.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["game_code","round_closed","round","currency","amount","token","reference_transaction_uuid","transaction_uuid","request_uuid"],"properties":{"supplier_user":{"$ref":"#/components/schemas/supplier_user"},"transaction_uuid":{"$ref":"#/components/schemas/transaction_uuid"},"token":{"type":"string","description":"The game session token that was passed within `/game/url` endpoint request."},"round_closed":{"$ref":"#/components/schemas/round_closed"},"round":{"$ref":"#/components/schemas/round"},"reward_uuid":{"type":"string","description":"The unique identifier for a reward on Hub88 side in standard 16-byte UUID format. `reward_uuid` is required when freespins are issued through the API."},"request_uuid":{"$ref":"#/components/schemas/request_uuid"},"reference_transaction_uuid":{"$ref":"#/components/schemas/reference_transaction_uuid"},"is_free":{"$ref":"#/components/schemas/is_free"},"is_aggregated":{"description":"","$ref":"#/components/schemas/is_aggregated"},"is_supplier_promo":{"type":"boolean","description":"Indicates whether the game Supplier has granted a promotion either on their own side or through Hub88 Freebets API.\n    \n  If `true`, the transaction should be treated as a promotion (i.e. `is_supplier_promo: true` ).\n    \n  If `false`, the transaction should be treated either as a normal transaction or as a transaction from a reward. The `is_free` flag dictates the behaviour in combination with `is_supplier_promo` as follows:\n    \n  `is_free: false` | `is_supplier_promo: true` Transaction related to a promotion on the Supplier's side, and will contribute to GGR. \n    \n  `is_free: true` | `is_supplier_promo: true` Transaction related to a promotion on the Supplier's side, and it won’t contribute into GGR. In this case, Hub88 does not require a reference to the original bet. For these transactions: `amount` should be set to zero for a Bet, and `amount` must be a positive number for a Win.\n    \n  `is_free: true` | `is_supplier_promo: false` Transaction related to a previous Reward issued via Hub88’s Freebets API.\n    \n  `is_free: false` | `is_supplier_promo: false` (or null, or omitted) Transaction related to a normal gameplay."},"game_code":{"$ref":"#/components/schemas/game_code"},"currency":{"$ref":"#/components/schemas/currency"},"bet":{"$ref":"#/components/schemas/bet"},"amount":{"$ref":"#/components/schemas/money_amount"},"is_billable":{"type":"boolean","description":"Indicates whether Hub88 includes this win in GGR. Optional. When omitted, the win is processed as a regular WIN and contributes `amount` to GGR. When `true` and `amount` is greater than 0, the win behaves like a regular WIN and contributes `amount` to GGR. If `billable_amount` is sent, it must equal `amount`. When `true` and `amount` is 0 with a positive `billable_amount`, the win is a redemption: the player's balance is not credited and `billable_amount` is the GGR contribution. Use this when the player receives value outside the wallet, for example a physical item. When `false`, the win is excluded from GGR. The player's balance is still credited by `amount`. Ignored when `is_free` is `true`: a free win is never billable."},"billable_amount":{"type":"integer","format":"int64","minimum":0,"description":"The GGR contribution of this win when it is a redemption (`amount` 0), in the same currency and Int64 format as `amount`. Optional. Used only when `is_billable` is `true`; when omitted, Hub88 uses `amount`. For a regular win (`amount` greater than 0) it must equal `amount`, because Hub88 bills `amount` and forwards `billable_amount` to the Operator. A win with `amount` 0 and a positive `billable_amount` means the player received value outside the wallet (for example a physical item): Hub88 counts `billable_amount` in GGR and the player's balance is not credited, since `amount` is set to 0. Must be 0 or positive."},"meta":{"$ref":"#/components/schemas/meta"}}}}},"required":true,"description":""}}}},"components":{"schemas":{"Response":{"type":"object","title":"Response","required":["user","status","request_uuid","balance"],"properties":{"user":{"$ref":"#/components/schemas/user"},"status":{"$ref":"#/components/schemas/status"},"request_uuid":{"$ref":"#/components/schemas/request_uuid"},"currency":{"$ref":"#/components/schemas/currency"},"balance":{"$ref":"#/components/schemas/money_amount"}},"description":"Wallet API response"},"user":{"type":"string","description":"The unique user ID in the Hub88's system. In case of DEMO gameplay, this parameter may be omitted."},"status":{"type":"string","enum":["RS_OK","RS_ERROR_UNKNOWN","RS_ERROR_INVALID_PARTNER","RS_ERROR_INVALID_TOKEN","RS_ERROR_INVALID_GAMERS_ERROR_WRONG_CURRENCY","RS_ERROR_NOT_ENOUGH_MONEY","RS_ERROR_USER_DISABLED","RS_ERROR_INVALID_SIGNATURE","RS_ERROR_TOKEN_EXPIRED","RS_ERROR_WRONG_SYNTAX","RS_ERROR_WRONG_TYPES","RS_ERROR_DUPLICATE_TRANSACTION","RS_ERROR_TRANSACTION_DOES_NOT_EXIST","RS_ERROR_LIMIT_REACHED"],"description":"The response status."},"request_uuid":{"type":"string","description":"A standard 16-byte unique user identifier. The ID can be used as network layer action. An ID of an action that is generated for each game Supplier's call to Hub88. It's Used to sync Hub88 and game Supplier's sides for debugging purposes. Hub88 has to respond with the same request_uuid as the one that was received in request."},"currency":{"type":"string","enum":["BSD","TTD","ZMW","BMD","USD","UGX","HKD","MGA","GIP","UZS","MKD","mLTC","EGP","AWG","CZK","ILS","MZN","TND","XPF","SOS","DOP","RUB","KRW","BTN","KGS","BAM","AOA","BND","RSD","FKP","PEN","EOS","GHS","JPY","TRY","SBD","UAH","FJD","GNF","MDL","AFN","ZAR","MOP","TJS","BOB","JMD","QAR","IRR","SYP","XXX","NAD","MYR","CUP","NOK","KPW","MNT","NZD","uETH","SGD","PYG","OMR","DZD","EUR","TMT","MMK","TZS","CRC","VES","ETB","THB","LYD","CHF","MVR","KES","CVE","LSL","KMF","SZL","KYD","BRL","AED","WST","YER","ALL","TRX","HUF","GTQ","uBTC","IDR","MWK","DKK","TWD","XCD","BBD","LRD","KZT","JOD","BYN","BIF","PLN","SDG","VUV","SEK","BDT","HNL","BWP","VND","ISK","BHD","HTG","USDT","ADA","MUR","ERN","uLTC","LKR","COP","GEL","AUD","GBP","CAD","PHP","PAB","DJF","GMD","PKR","NIO","AMD","RWF","RON","NGN","TOP","UYU","AZN","SRD","KWD","PGK","CDF","SAR","IQD","XRP","SCR","mETH","MAD","GYD","INR","LBP","ARS","MXN","CLP","BNB","CNY","KHR","LAK","BZD","SSP","XOF","NPR","mBTC"],"description":"The ISO 4217 currency code. The following list contains all currencies supported by the Hub88 system. Note that native game play support with these currencies may vary per Provider. "},"money_amount":{"type":"integer","description":"The amount of money is displayed in integers **(Int64)**. To convert real float value to integer Hub88 multiplys it by 100000. Example: `$3.56` must be represented as `356000`"},"supplier_user":{"type":"string","description":"The user ID in the Supplier's system. If the Supplier renames Hub88's user IDs in any way(prefixes, etc.), the Supplier should send changed user IDs in this field to inform Hub88 about the renaming."},"transaction_uuid":{"type":"string","description":"The unique transaction identifier. An ID of business logic action (transaction) that <b>needs to be stored</b> on both sides for <b>at least 4 months</b> (for reconciliation purposes). Hub88 has to respond on each `transaction_uuid`. An action with same `transaction_uuid` must not be processed more than once."},"round_closed":{"type":["boolean","null"],"description":"Denotes when the round is closed."},"round":{"nullable":false,"type":"string","description":"The game round ID used to relate all bets and wins made in one round. All transactions related to the same round have the same value in this field. The ID is not unique through whole system. The value depends on Supplier's RGS logic, as it is created from game + user + round combination, resulting in uniqueness."},"reference_transaction_uuid":{"type":"string","description":"The unique identifier of the transaction which is referenced. In case of a rollback, this field will contain the transaction_uuid of the transaction which needs to be rolled back. In case of win, there will be transaction_uuid of the bet to which the win is related to."},"is_free":{"type":["boolean","null"],"description":"The flag which indicates that the transaction is tied to a reward issued via Hub88’s Freebets API and if promo transaction contributes to GGR calculation or not. Set to `true` when the transaction is the result of a previously created reward and does not contribute to GGR calculation. When `false`, the transaction is not connected to a Hub88 Freebets API (e.g. the transaction is a regular gameplay or supplier-managed promotions), and contributes to GGR calculation."},"is_aggregated":{"type":["boolean","null"],"description":"The flag which shows that related freebet transactions identified in the field `reward_uuid` have been aggregated into one single transaction. For example, a player was rewarded ten (10) freespins, but the Supplier sends one single transaction request with field `is_aggregated` set to true."},"game_code":{"type":"string","description":"The unique game identifier in Provider's system in the form of a string. `game_code` can be obtained from the `/game/list` endpoint and is a required parameter."},"bet":{"type":["string","null"],"description":"The field for metadata related to transaction, such as type of bet, value, time, etc. Differs from game to game. Not relevant for transaction processing procedure but could be useful for statistics or activity backtracking."},"meta":{"type":["object","null"],"description":"The transaction metadata, enriches the transaction payload for processing. In cases where `is_supplier_promo: true`, in `meta` object `meta.supplier_promo_info.promo_reference` string should be included. It's an optional promotion reference identifier provided by the supplier, used for tracking, audit, or reconciliation of supplier-managed promotions. It can also carry a direct fee, see `direct_fee_value` and `direct_fee_reason`.","properties":{"direct_fee_value":{"type":"integer","format":"int64","description":"The amount the Operator pays back to the Supplier in full for this transaction, outside GGR, for example a shipping fee the player paid or the value of a physical item the player keeps. Same currency and Int64 format as `amount`. It does not change the GGR contribution or the player's balance movement. Hub88 invoices it separately from GGR. Only send it on transactions that carry `is_billable` (`true` or `false`, for example `is_billable: false` for a shipping fee bet or `is_billable: true` for a redemption win). Always send it together with `direct_fee_reason`."},"direct_fee_reason":{"type":"string","maxLength":255,"description":"A short, stable identifier for the type of direct fee, for example `shipping_fee` or `redemption`. Maximum 255 characters. Hub88 groups direct fees by this value when invoicing, so use the same identifier for every fee of the same type. Passed to the Operator in `meta`. Required when `direct_fee_value` is sent."}}}}}}
```

***

### Update a user's balance based on transaction rollback

***

## POST /supplier/generic/v2/transaction/rollback

> The endpoint should be called when the Supplier receives any status other than \`RS\_OK\`,\`RS\_ERROR\_LIMIT\_REACHED\` , \`RS\_ERROR\_NOT\_ENOUGH\_MONEY\`. Hub88 will then find the referenced transaction, roll back its effects and return the users new balance.\
> &#x20;Retry Policy: In case of a network failure (HTTP 502, timeout, nxdomain, etc.) or unsuccessful status, the Supplier should retry the transaction.

```json
{"openapi":"3.1.1","info":{"title":"Hub88","version":"2.0"},"tags":[{"name":"Wallet API","description":"Hub88 is expected to provide API for Game Provider's calls. API will process the described requests from Game Provider."}],"paths":{"/supplier/generic/v2/transaction/rollback":{"post":{"tags":["Wallet API"],"summary":"","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Response"}}}}},"parameters":[{"schema":{"type":"string"},"required":true,"name":"X-Hub88-Signature","in":"header","description":"RSA-SHA256 is used to sign the request body using the private key. The signature is validated using the public key associated with the provided `operator_id`."}],"operationId":"/supplier/generic/v2/transaction/rollback","description":"The endpoint should be called when the Supplier receives any status other than `RS_OK`,`RS_ERROR_LIMIT_REACHED` , `RS_ERROR_NOT_ENOUGH_MONEY`. Hub88 will then find the referenced transaction, roll back its effects and return the users new balance.\n Retry Policy: In case of a network failure (HTTP 502, timeout, nxdomain, etc.) or unsuccessful status, the Supplier should retry the transaction.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["game_code","token","reference_transaction_uuid","transaction_uuid","request_uuid"],"properties":{"supplier_user":{"$ref":"#/components/schemas/supplier_user"},"transaction_uuid":{"$ref":"#/components/schemas/transaction_uuid"},"token":{"type":"string","description":"The game session token that was passed within `/game/url` endpoint request."},"round_closed":{"$ref":"#/components/schemas/round_closed"},"round":{"$ref":"#/components/schemas/round"},"request_uuid":{"$ref":"#/components/schemas/request_uuid"},"reference_transaction_uuid":{"$ref":"#/components/schemas/reference_transaction_uuid"},"game_code":{"$ref":"#/components/schemas/game_code"},"meta":{"$ref":"#/components/schemas/meta"}}}}},"required":true,"description":""}}}},"components":{"schemas":{"Response":{"type":"object","title":"Response","required":["user","status","request_uuid","balance"],"properties":{"user":{"$ref":"#/components/schemas/user"},"status":{"$ref":"#/components/schemas/status"},"request_uuid":{"$ref":"#/components/schemas/request_uuid"},"currency":{"$ref":"#/components/schemas/currency"},"balance":{"$ref":"#/components/schemas/money_amount"}},"description":"Wallet API response"},"user":{"type":"string","description":"The unique user ID in the Hub88's system. In case of DEMO gameplay, this parameter may be omitted."},"status":{"type":"string","enum":["RS_OK","RS_ERROR_UNKNOWN","RS_ERROR_INVALID_PARTNER","RS_ERROR_INVALID_TOKEN","RS_ERROR_INVALID_GAMERS_ERROR_WRONG_CURRENCY","RS_ERROR_NOT_ENOUGH_MONEY","RS_ERROR_USER_DISABLED","RS_ERROR_INVALID_SIGNATURE","RS_ERROR_TOKEN_EXPIRED","RS_ERROR_WRONG_SYNTAX","RS_ERROR_WRONG_TYPES","RS_ERROR_DUPLICATE_TRANSACTION","RS_ERROR_TRANSACTION_DOES_NOT_EXIST","RS_ERROR_LIMIT_REACHED"],"description":"The response status."},"request_uuid":{"type":"string","description":"A standard 16-byte unique user identifier. The ID can be used as network layer action. An ID of an action that is generated for each game Supplier's call to Hub88. It's Used to sync Hub88 and game Supplier's sides for debugging purposes. Hub88 has to respond with the same request_uuid as the one that was received in request."},"currency":{"type":"string","enum":["BSD","TTD","ZMW","BMD","USD","UGX","HKD","MGA","GIP","UZS","MKD","mLTC","EGP","AWG","CZK","ILS","MZN","TND","XPF","SOS","DOP","RUB","KRW","BTN","KGS","BAM","AOA","BND","RSD","FKP","PEN","EOS","GHS","JPY","TRY","SBD","UAH","FJD","GNF","MDL","AFN","ZAR","MOP","TJS","BOB","JMD","QAR","IRR","SYP","XXX","NAD","MYR","CUP","NOK","KPW","MNT","NZD","uETH","SGD","PYG","OMR","DZD","EUR","TMT","MMK","TZS","CRC","VES","ETB","THB","LYD","CHF","MVR","KES","CVE","LSL","KMF","SZL","KYD","BRL","AED","WST","YER","ALL","TRX","HUF","GTQ","uBTC","IDR","MWK","DKK","TWD","XCD","BBD","LRD","KZT","JOD","BYN","BIF","PLN","SDG","VUV","SEK","BDT","HNL","BWP","VND","ISK","BHD","HTG","USDT","ADA","MUR","ERN","uLTC","LKR","COP","GEL","AUD","GBP","CAD","PHP","PAB","DJF","GMD","PKR","NIO","AMD","RWF","RON","NGN","TOP","UYU","AZN","SRD","KWD","PGK","CDF","SAR","IQD","XRP","SCR","mETH","MAD","GYD","INR","LBP","ARS","MXN","CLP","BNB","CNY","KHR","LAK","BZD","SSP","XOF","NPR","mBTC"],"description":"The ISO 4217 currency code. The following list contains all currencies supported by the Hub88 system. Note that native game play support with these currencies may vary per Provider. "},"money_amount":{"type":"integer","description":"The amount of money is displayed in integers **(Int64)**. To convert real float value to integer Hub88 multiplys it by 100000. Example: `$3.56` must be represented as `356000`"},"supplier_user":{"type":"string","description":"The user ID in the Supplier's system. If the Supplier renames Hub88's user IDs in any way(prefixes, etc.), the Supplier should send changed user IDs in this field to inform Hub88 about the renaming."},"transaction_uuid":{"type":"string","description":"The unique transaction identifier. An ID of business logic action (transaction) that <b>needs to be stored</b> on both sides for <b>at least 4 months</b> (for reconciliation purposes). Hub88 has to respond on each `transaction_uuid`. An action with same `transaction_uuid` must not be processed more than once."},"round_closed":{"type":["boolean","null"],"description":"Denotes when the round is closed."},"round":{"nullable":false,"type":"string","description":"The game round ID used to relate all bets and wins made in one round. All transactions related to the same round have the same value in this field. The ID is not unique through whole system. The value depends on Supplier's RGS logic, as it is created from game + user + round combination, resulting in uniqueness."},"reference_transaction_uuid":{"type":"string","description":"The unique identifier of the transaction which is referenced. In case of a rollback, this field will contain the transaction_uuid of the transaction which needs to be rolled back. In case of win, there will be transaction_uuid of the bet to which the win is related to."},"game_code":{"type":"string","description":"The unique game identifier in Provider's system in the form of a string. `game_code` can be obtained from the `/game/list` endpoint and is a required parameter."},"meta":{"type":["object","null"],"description":"The transaction metadata, enriches the transaction payload for processing. In cases where `is_supplier_promo: true`, in `meta` object `meta.supplier_promo_info.promo_reference` string should be included. It's an optional promotion reference identifier provided by the supplier, used for tracking, audit, or reconciliation of supplier-managed promotions. It can also carry a direct fee, see `direct_fee_value` and `direct_fee_reason`.","properties":{"direct_fee_value":{"type":"integer","format":"int64","description":"The amount the Operator pays back to the Supplier in full for this transaction, outside GGR, for example a shipping fee the player paid or the value of a physical item the player keeps. Same currency and Int64 format as `amount`. It does not change the GGR contribution or the player's balance movement. Hub88 invoices it separately from GGR. Only send it on transactions that carry `is_billable` (`true` or `false`, for example `is_billable: false` for a shipping fee bet or `is_billable: true` for a redemption win). Always send it together with `direct_fee_reason`."},"direct_fee_reason":{"type":"string","maxLength":255,"description":"A short, stable identifier for the type of direct fee, for example `shipping_fee` or `redemption`. Maximum 255 characters. Hub88 groups direct fees by this value when invoicing, so use the same identifier for every fee of the same type. Passed to the Operator in `meta`. Required when `direct_fee_value` is sent."}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.hub88.io/developer-docs/supplier-api-reference/wallet-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
