Balance Query Callback
VCT Platform queries the player's available balance on the Agent (Operator) side while processing a game launch request.
Note
VCT calls this API after a player requests a game launch and before game entry is confirmed, to query the available balance and create a temporary launch_pending record. The Agent must implement this endpoint for VCT.
A successful /balance response means only that the balance query and launch preparation succeeded; it does not mean the player entered the game. The game becomes enterable only after VCT returns code=0, a non-empty game_url, and the matching session_id is confirmed.
Environment URLs
| Environment | Base URL |
|---|---|
| Production | https://hub-panel-api.v7stech.com |
| Staging | https://hub-panel-api-dev.v7stech.com |
Endpoint
| Property | Value |
|---|---|
| Path | POST /api/v1/callback/balance |
| Caller | VCT Platform → Agent (Operator) |
Authentication and Signature
See Authentication for the common Header Token rule. This endpoint's Body sign is HMAC-SHA256(username + "." + timestamp, agent_api_secret); the Header and Body timestamps must match exactly.
Request Parameters (from VCT)
| Parameter | Type | Required | Description |
|---|---|---|---|
username | string | Yes | Player username |
currency | string | Yes | Currency code |
session_id | string | Yes | Unique session ID generated by Hub for this game launch |
game_id | string | Yes | Hub game-directory GUID; use it to look up the Brand in the synced directory |
provider | string | No | Provider code for cross-checking only |
brand_guid | string | Yes | Stable Hub Brand identifier for linkage and auditing |
brand_code | string | Yes | Current Brand business code for audit display |
brand_name | string | Yes | Current Brand display name for audit display |
sign | string | Yes | Request signature |
timestamp | long | Yes | Request timestamp |
Session, Game, and Brand Identity
The Agent must use session_id + game_id as the primary identity of this balance request, then look up brand_guid from its synced game directory using game_id. provider is only a cross-check and must not be the sole key for a game, session, or Brand. Hub's brand_guid is for linkage and audit; brand_code and brand_name are display snapshots and must not merge Brands with different GUIDs.
Response Fields
| Field | Type | Required | Description |
|---|---|---|---|
status | string | Yes | Processing status: success / player_not_found / error |
balance | decimal | Yes | Player's current available balance (only valid when status is success) |
currency | string | Yes | Currency code (required when status is success) |
username | string | Yes | Player username (required when status is success) |
Example Request
{
"username": "player001",
"currency": "MYR",
"session_id": "vct-session-uuid-001",
"game_id": "hub-game-guid-001",
"provider": "gsc",
"brand_guid": "3d3e51ba-1a7d-47b8-9dc8-3b9d99ef68fc",
"brand_code": "YB",
"brand_name": "YB Brand",
"sign": "9a2f64d0bcfa829...",
"timestamp": 1783324700
}Example Response
Success Response
{
"status": "success",
"username": "player001",
"currency": "MYR",
"balance": 100.00
}Player Not Found (Abort login)
{
"status": "player_not_found"
}Validation Logic & Processing Recommendations
1. Strict Authentication Verification
- The
AuthorizationHeader is mandatory; verifying only the Bodysignis not sufficient. - The
agent_api_keymust resolve to the matchingagent_api_secret; do not try multiple Secrets. - Reject the request when the Header and Body timestamps differ.
2. Strict Status Verification
- Status Field is Mandatory: The response returned by the Agent system must contain the
statusfield. - Reject Game Access: If
statusis missing, or its value is not"success"(e.g."player_not_found","error", etc.), VCT Platform will immediately terminate the game launching process and throw a login exception. This prevents invalid or non-existent players from entering the game and causing subsequent wallet reclaim failures.
3. Player Account Checks
- It is recommended that the Agent system evaluates the player's account status (e.g., whether it is suspended, locked, etc.) during a
/balancequery. If the player is not allowed to play, return{"status": "player_not_found"}or{"status": "error"}to abort the launch.
Provider Source Mapping
| Provider | Callback Path | Request Format |
|---|---|---|
| BG | open.operator.user.balance | JSON-RPC 2.0 (sn/sign/random) |
| GSC | seamless/balance | JSON (operator_code/sign/request_time) |
| SA | GetUserBalance | Encrypted URL-encoded body |
| WM | webhook (cmd=CallBalance) | form-data (cmd/signature/user) |
AI Implementation Prompt (Copy Ready)
Implement the Agent endpoint POST /api/v1/callback/balance for Hub balance queries. The request includes username, currency, session_id, game_id, provider, brand_guid, brand_code, brand_name, sign, and timestamp.
Requirements:
1. Verify Authorization Bearer {agent_api_key}.{timestamp}.{header_signature}, where header_signature is lowercase hex HMAC-SHA256(agent_api_key + "." + timestamp, agent_api_secret).
2. Header timestamp must exactly equal Body timestamp and be within the accepted window. Compare signatures in constant time.
3. Verify Body sign as lowercase hex HMAC-SHA256(username + "." + timestamp, agent_api_secret). Never try another Agent's Secret.
4. Query the exact username + currency wallet, validate player/currency/account state, and use decimal money types.
5. Use session_id + game_id as the launch identity. Persist session_id unchanged and enforce a unique launch_pending record for Agent + username + currency + session_id. Look up brand_guid from game_id in the synced directory; provider is only a cross-check. Persist Hub brand_guid, brand_code, and brand_name as audit snapshots without merging Brands by code or name.
6. Return status=success with balance and currency only after success. Return player_not_found/error to stop launch when invalid.
7. Balance success is preparation only: do not record enter_game until Game Launch succeeds with the same session_id.
8. Process repeated session_id requests idempotently without duplicate locks or records.
9. Redact Secret, Token, and signatures from logs. Test auth/body signatures, timestamp mismatch/expiry, player/currency/account errors, duplicates, and decimal precision.
Reuse the project's auth, wallet, transaction, and error components. Deliver route, service, idempotent storage, and tests.