Skip to content

Offline / Balance Reclaim Callback ​

When a player exits a game, is force-kicked, or switches to another game in the same currency, VCT notifies the Agent to close the session and reconcile the final balance.

Environment URLs ​

EnvironmentBase URL
Productionhttps://hub-panel-api.v7stech.com
Staginghttps://hub-panel-api-dev.v7stech.com

Acknowledgement is required

The Agent must return a JSON response with status: "success". A missing status, any other status, or an unparsable response is recorded by VCT as a failed offline callback.

Endpoint ​

PropertyValue
PathPOST /api/v1/callback/offline
CallerVCT Platform → Agent
Content-Typeapplication/json

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) ​

ParameterTypeRequiredDescription
usernamestringYesPlayer username
currencystringYesCurrency code
session_idstringYesThe VCT session ID created at game launch
game_idstringNoGame GUID
game_codestringNoGame code
game_namestringNoGame name
game_typestringNoGame type
providerstringNoProvider code
reclaimed_amountdecimalYesAmount snapshot captured when Hub cleared its local wallet at cleared_at; for this Offline reconciliation only. It must not reapply a master-wallet transaction and is not the final master-wallet balance after all late logs are processed
wallet_cleared_totaldecimalNormal reclaimPhysical total cleared from every same-currency Hub wallet
mirrored_delta_totaldecimalNormal reclaimAdjustment total still present in both source and active wallets, capped by each source wallet's cleared amount
net_balance_to_reconciledecimalNormal reclaimwallet_cleared_total - mirrored_delta_total
wallet_breakdownarrayNormal reclaimPer-wallet amount plus session, game, Provider, and Brand snapshot
mirrored_adjustmentsarrayNormal reclaimMirrored events with event ID, source/target identity, and delta
cleared_atstringNo*Time when Hub actually cleared the local wallet, in RFC3339/RFC3339Nano format. New normal exit/kick/switch-game reclaims include it; historical records and launch_failed may omit it
actionstringYesexit_game, api_kick_exit, switch_game, or launch failure compensation launch_failed
signstringYesRequest signature
timestamplongYesRequest timestamp

Success Response (required) ​

json
{
  "status": "success",
  "message": "received",
  "username": "player001",
  "currency": "MYR",
  "session_id": "vct-session-uuid-001",
  "reclaimed_amount": 125.50,
  "cleared_at": "2026-10-04T23:30:12.123Z"
}

status must be exactly success. This confirms that the Agent processed the notification, marks the reclaim complete, and stops retries. Callback failure does not block the player from launching another game after Hub has atomically cleared the wallets.

Failure Response ​

json
{
  "status": "error",
  "message": "player not found"
}

Any failure response or non-2xx HTTP response is recorded by VCT as a failed callback. The Agent should verify sign, timestamp, and username, and implement idempotency.

When the Agent returns a failure, VCT marks the reclaim as callback_failed. VCT may resend the same Offline request, or an administrator may retry it manually. The Agent must process retries idempotently by session_id + action; the failed callback does not block a new game launch.

For normal Offline callbacks, VCT automatically retries failed deliveries up to 15 times with increasing backoff intervals: 1 minute, 5 minutes, 15 minutes, 30 minutes, 1 hour, and 2 hours. Automatic retries stop after the limit, but an administrator may still retry manually. Every actual HTTP attempt is recorded separately; the Agent must never apply the same wallet effect twice.

Notes ​

  • In Seamless mode, master-wallet debits, credits, and reversals are processed through /bet-push; reclaimed_amount is the amount snapshot captured when Hub cleared its local wallet, for this Offline reconciliation only, and must not cause duplicate wallet changes.
  • wallet_cleared_total may contain both a source wallet amount and the same event mirrored into the active wallet. Match mirrored_adjustments.event_id against the Agent ledger and reconcile with net_balance_to_reconcile; never credit the physical total directly.
  • cleared_at is the time Hub cleared the local wallet. It is not the Offline delivery time and does not mean that all late logs have finished processing. Logs received by Hub after this time may still exist; the Agent should continue applying /bet-push idempotently and use session_id plus cleared_at for audit.
  • VCT records both the request and response for reconciliation.
  • Use session_id + action (and the request signature when available) as the idempotency key to prevent duplicate credits.

Launch Failure Compensation (launch_failed) ​

If /balance succeeds but the game provider fails to launch the game, VCT calls this endpoint with the original session and amount:

json
{
  "username": "player001",
  "currency": "MYR",
  "session_id": "vct-session-uuid-001",
  "reclaimed_amount": 100.00,
  "action": "launch_failed",
  "sign": "9a2f64d0bcfa829...",
  "timestamp": 1783324700
}

The Agent must:

  • Preserve and match session_id exactly.
  • Release only the temporary launch session, balance lock, or pending record.
  • Keep launch_failed out of the normal enter_game and offline settlement flow.
  • Enforce a unique key for the same player, currency, and session_id.
  • Process duplicate launch_failed requests idempotently without duplicate credit or release.
  • Use the normal offline settlement flow only for actions such as exit_game, api_kick_exit, and switch_game.

AI Implementation Prompt (Copy Ready) ​

text
Implement the Agent endpoint POST /api/v1/callback/offline for VCT session closure and reconciliation.

Requirements:
1. Verify the three-part Authorization Token, require Header timestamp == Body timestamp, and verify Body sign as lowercase hex HMAC-SHA256(username + "." + timestamp, agent_api_secret) using constant-time comparison.
2. Enforce idempotency by Agent + username + currency + session_id + action because VCT may retry automatically or manually.
3. For exit_game, api_kick_exit, and switch_game, close the matching session and store wallet_breakdown plus mirrored_adjustments. Reconcile mirrored events by event_id; switch_game aggregates every Provider wallet for the currency.
4. Seamless funds are already processed by bet-push. wallet_cleared_total is the physical Hub total and net_balance_to_reconcile removes mirrored deltas; neither field should trigger another master-wallet credit or debit.
5. cleared_at is the Hub wallet-clear time, not callback-send time. Late bet-push records must still be processed idempotently.
6. launch_failed releases only that launch_pending state/lock. It must not create enter_game, run normal exit settlement, or move funds twice.
7. Return HTTP 2xx and {"status":"success"} only after the database transaction commits. Already-processed duplicates should return idempotent success.
8. Return non-2xx or status=error for transient failures so VCT retries. Redact Secret, Token, and sign from logs.
9. Test all normal actions, launch_failed, duplicates, out-of-order delivery, invalid/expired signatures, rollback, and no double wallet mutation after bet-push.

Reuse existing sessions, wallet ledger, transactions, locks, and authentication. Deliver route, service, idempotency constraint, and tests.

VCT Gaming Integration Platform