Debit & Credit Users
Server to Server Callbacks
To receive messages on when to deduct and credit user balances based on the outcomes of matches, you should implement the following endpoints.
Pay Entry Fee
Method: POST /thndr/pay
Description: When you receive this post request from us:
Deduct the bet amount from the user's balance.
Associate the
depositId
with theamount
in your database to allow for potential refunds.Use
depositId
as the idempotency key to ensure the same payment is not processed twice.
Body:
{
"userId": "123",
"depositId": "abc",
"amount": 50
}

Payment Errors
If you need to notify your client about any payment errors, such as "Insufficient Balance", you can return errors in the response with a status code 4XX. These errors will be sent to the client sdk via the handleError callback for your front end to handle.
Note: You must pass "isClientSafe": true
in the response for it to be passed to the client.
Example 4XX response:
{
"errors": [
{
"code": "INSUFFICIENT_BALANCE",
"isClientSafe": true
}
]
}
Handle Match Results
Method: POST /thndr/results
Description: Upon receiving this POST request from us, take the appropriate action based on the match outcome:
WIN or DRAW: Credit the user's balance by
amount
.LOSE: No action required.
REFUND: Retrieve the
amount
from your database and refund the user.
Note: Use depositId
as the idempotency key to ensure the same result is not processed twice.
Important: If a system crash occurs before receiving a response from the /thndr/pay
webhook, you may receive refund requests for deposit IDs that were never persisted in your database (i.e., the user was not credited). These requests must be ignored, and a 200 status code must be returned.
Body (WIN or DRAW):
{
"result": "WIN" | "DRAW"",
"userId": "123",
"depositId": "abc",
"roomId": "xyz",
"gameId": "solitaire" | "blocks" | "blackjack",
"amount": 100
}
Body (LOSE):
{
"result": "LOSE",
"userId": "123",
"depositId": "abc",
"gameId": "solitaire" | "blocks" | "blackjack",
"roomId": "xyz"
}
Body (REFUND):
{
"result": "REFUND",
"userId": "123",
"depositId": "abc",
"gameId": "solitaire" | "blocks" | "blackjack" | null,
"roomId": "xyz" | null,
"amount": 100
}

Request Signing
To ensure the integrity and authenticity of API requests, our system signs each request payload using an HMAC (Hash-based Message Authentication Code) with the SHA-256 algorithm. Integrators must verify the signature to authenticate requests and prevent tampering.
Verification Process
To verify the request's authenticity, the integrator should:
Recompute the signature using the shared secret and the received payload.
Compare the computed signature with the
x-server-authorization
header value.Reject the request if the signatures do not match.
Example Verification in Node.js:
const crypto = require("crypto");
function verifySignature(receivedSignature, requestPayload, SERVER_SECRET) {
const computedSignature = crypto
.createHmac("sha256", SERVER_SECRET)
.update(requestPayload)
.digest("hex");
return computedSignature === receivedSignature;
}
The SERVER_SECRET
is a pre-shared secret key known only to THNDR server and the integrator.
Example Signed Payload
Server secret: DUMMY_SECRET
Payload: {"userId":"alice","depositId":"depositA","amount":100}
x-server-authorization: 1bb9edf6131931e29957844f176dc9eaf090e9ccee5ece6ab5fb4c4fa7389513
Last updated