Skip to content

Wallet / Trade Callbacks

Wallet / Trade callbacks (during gameplay)

Once the iFrame is loaded, gameplay drives four callbacks from TS into your wallet API.

The three wallet callbacks are HMAC-SHA256 signed (/authenticate is unsigned — the launch token is the credential) — see "Message Integrity" below. Every request carries X-Sig-Version: v2, X-Timestamp, X-Nonce, X-Signature headers.

/getbalance

Called before /opentrade to verify sufficient funds.

Request:

json
{
 "token": "<walletToken>",
 "amount": "100",
 "currency": "USD"
}

Response:

json
{ "balance": "2180", "currency": "USD", "status": "Ok" }

If the player has insufficient funds, you can still return status:"Ok" with the real balance — TS will do the comparison and refuse the trade. Alternatively, return {status:"InsufficientFunds", balance, currency} if you want to fail fast.

/opentrade — Tap

Request:

json
{
 "token": "<walletToken>",
 "amount": "10",
 "currency": "USD",
 "externalTradeType": "tap",
 "externalTradeId": "12345",
 "data": [{
 "userID": "alice",
 "currency": "USD",
 "instrumentID": "139",
 "tStart": "2026-05-13T12:00:00.000Z",
 "tEnd": "2026-05-13T12:00:02.000Z",
 "pMin": "65430.00",
 "pMax": "65432.00",
 "stake": "10",
 "payoutRatio": "1.7"
 }]
}

Field reference:

FieldMeaning
tokenwalletToken from Step 2
amountStake to reserve from the player's wallet (matches data[0].stake)
currencyISO alpha currency code (always lowercase for Tap)
externalTradeTypeAlways "tap"
externalTradeIdTS's trade ID. Use as the idempotency key.
data[0].userIDYour userId for this player
data[0].currencySame as top-level currency
data[0].instrumentIDNumeric instrument ID (e.g., 30102 = Bitcoin, see asset list TS provides)
data[0].tStart / data[0].tEndISO-8601 UTC with ms precision. tEnd − tStart is the tap size the player chose (2 / 4 / 8 s)
data[0].pMin / data[0].pMaxThe cell's price band (pMax − pMin is the cell height set by TS's σ-adaptive engine). Opaque to you — for audit only.
data[0].stakeStake amount
data[0].payoutRatioThe profit multiplier shown to the player when they tapped. Locked at open time. Grid changes after open do not affect this number.

Response:

json
{ "balance": "990", "currency": "USD", "status": "Ok" }

balance is the new balance after reserving the stake.

/closetrade — Tap

Request:

json
{
 "token": "<walletToken>",
 "amount": "17.00",
 "currency": "USD",
 "externalTradeType": "tap",
 "externalTradeId": "12345",
 "data": [{
 "tradeID": "12345",
 "userID": "alice",
 "stake": "10.0000000000",
 "payout": "70",
 "rebate": "0",
 "instrumentID": "139",
 "expiryPrice": "65431.50",
 "touchPrice": "65431.40",
 "pnl": "7.00",
 "returnedAmount":"17.00"
 }]
}

Settlement math — TS computes amount based on outcome:

Outcomeamount
Win (price touched the cell)stake + payout = stake × (1 + payoutRatio − 1)
Tie (cancelled / window-boundary)stake (refund)
Loss0

Always update balance from the amount field — don't recompute from pnl, don't read returnedAmount. TS has done the math.

data.touchPrice is informational only — use it for player history / reporting. NEVER feed it into wallet math.

Response: same shape as /opentrade:

json
{ "balance": "1007", "currency": "USD", "status": "Ok" }

Balance consistency rules

  • Pre-trade: TS calls /getbalance before /opentrade.
  • Open: reduce available balance by amount. Place a reservation.
  • Close:
  • Win: credit amount (which equals stake + payout).
  • Tie: credit amount (which equals stake — refund of the reservation).
  • Loss: credit 0 (release the reservation without crediting).
  • Atomicity: /opentrade and /closetrade MUST be atomic on your side. Use row-level locking, optimistic versioning, or whatever fits your stack.
  • Idempotency: externalTradeId is the idempotency key. TS may retry on timeout / network error — your handler MUST return the same response without double-applying.
  • Cancellations: occasional cancelled settlements with no prior open signal are normal at trading-window boundaries. Treat them as no-ops.

Error handling

Return a JSON body with status and optional code / message:

json
{ "status": "InsufficientFunds", "balance": "9.50", "currency": "USD", "code": "W001" }

Suggested status enum:

StatusWhen to use
OkOperation accepted
InsufficientFundsBalance below requested amount
UnauthorizedBad / unknown walletToken
InvalidDigestHMAC signature mismatch (verifier rejected)
InvalidTokenToken well-formed but unrecognized (e.g. expired walletToken)
RateLimitedThrottled
TemporaryErrorRetryable upstream condition (DB down, etc.) — TS will retry with backoff

For TemporaryError, TS retries with exponential backoff for a bounded window (~30 s). Anything else TS treats as terminal and surfaces to the player.