Skip to content

(Operator implements) Process one or more gameround transactions

POST
/doTransactions

The wallet call. One or more transactions belonging to a single gameround are submitted; the operator applies them and returns the resulting balance(s). Every transaction must be processed idempotently on its hash.

Rules:

  • Process transactions in the order received. A void may arrive
    before the debit it refers to — in that case the debit must still
    be treated as voided when it arrives.
  • If a debit fails, subsequent credits in the same request (and in
    following requests) must be declined. If at least one operation
    fails, the HTTP status must not be 200.
  • If the initial debit (isFirstDebit = true) fails, the round is
    closed and no further debits/credits may be accepted.
  • If a follow-up debit (isFirstDebit = false) fails, the round stays
    open — the game may continue with a smaller stake.
  • A second initial debit for the same gameround must be answered with
    error id 12 (GAMEROUNDALREADYSTARTED).
  • Debits/credits for a closed round that were not processed before must
    be answered with an error; void calls are processed regardless of
    round state. Transactions for an already voided round must be
    answered with HTTP 400.
  • You will never receive a debit after an end in the same call. * transactionCount must equal the length of transactions; otherwise
    reject with HTTP 400 and error id 16.

Retry behaviour on the hizi.io side: a 4xx or 5xx on a call containing a debit is not retried and the round is marked cancelled (a void is sent in the 5xx/network case). A call containing a credit but no debit is retried on every error condition until it succeeds or the round is stranded — so a credit must never fail with a 5xx. If a credit is answered with a non-repeatable error, earlier debits are voided and the round is treated as voided; if an earlier credit had already succeeded, nothing is voided and the round is treated as crashed and has to be reconciled.

Fields to sign (in order): secret, X-H-AUTH-ID, X-H-TIMESTAMP, playerId, gameCode, gameRound, then — in exactly the order the transactions appear in the payload — each transaction's hash followed by its amount (the amount is omitted when there is none or it is 0, e.g. for end, void, or a debit paid with a ticket).

Authorizations

hiziAuthId

Operator ID. Sent on every request in both directions, and part of every signature.

Type
API Key (header: X-H-AUTH-ID)
+
hiziAuthSignature

Signature of the request, sent on every request in both directions.

OpenAPI cannot express an HMAC-over-computed-string scheme natively, so this is modelled as an apiKey header. The value is not a static key: it is the base64-encoded SHA-256 HMAC digest of a defined, ordered set of request fields joined with a hash character (#).

The first three fields are always the shared secret, the X-H-AUTH-ID header and the X-H-TIMESTAMP header; the remaining fields differ per operation and are listed in each operation's description under "Fields to sign". For doTransactions the per- transaction hashes (and non-zero amounts) are appended in exactly the order the transactions appear in the payload.

The secret is retrieved by logging in to the hizi.io backoffice, which also provides sample implementations. Including the timestamp in the signature is what makes it safe to share the secret without ever sending it.

Type
API Key (header: X-H-AUTH-SIG)
+
hiziTimestamp

ISO 8601 timestamp of the request (UTC recommended, e.g. 2020-01-21T14:48:04Z). Sent on every request in both directions and always included in the signature.

Type
API Key (header: X-H-TIMESTAMP)

Request Body

application/json
JSON
{
  
"playerId": "sampleplayer",
  
"gameCode": "testgame",
  
"gameRound": "04d4e7fc-092b-459e-bd32-c41343b4af2a",
  
"transactions": [
  
  
{
  
  
  
"type": "debit",
  
  
  
"isFirstDebit": true,
  
  
  
"currency": "EUR",
  
  
  
"hash": "13536977-5cfa-430b-a019-18430d61b48f",
  
  
  
"amount": 200,
  
  
  
"timestamp": "2020-01-21T14:48:04Z",
  
  
  
"reason": "spin"
  
  
},
  
  
{
  
  
  
"type": "end",
  
  
  
"hash": "b92f866a-5fe9-4ac1-ae0d-9f403dfe1a12",
  
  
  
"timestamp": "2020-01-21T14:48:04Z"
  
  
}
  
],
  
"transactionCount": 2
}

Responses

All submitted transactions were processed. The balances reflect the state after processing.

application/json
JSON
{
  
"balances": [
  
  
{
  
  
  
"type": "string",
  
  
  
"amount": 1200,
  
  
  
"currency": "EUR"
  
  
}
  
],
  
"discountInfo": {
  
  
"text": "happy hour",
  
  
"currency": "EUR",
  
  
"discounts": [
  
  
  
{
  
  
  
  
"stake": 1200,
  
  
  
  
"absoluteDiscountAmount": 1200,
  
  
  
  
"spinsRemaining": 0
  
  
  
}
  
  
],
  
  
"campaignId": "string",
  
  
"validFrom": "2020-01-21T14:48:04Z",
  
  
"validTo": "2020-01-21T14:48:04Z"
  
},
  
"useBonusFirst": true,
  
"errorCode": {
  
  
"id": 1,
  
  
"msg": "player id unknown",
  
  
"clientmsg": "You reached your daily betting limit!"
  
},
  
"clientMessage": {
  
  
"title": "string",
  
  
"msg": "string",
  
  
"buttons": [
  
  
  
{
  
  
  
  
"label": "string",
  
  
  
  
"url": "string"
  
  
  
}
  
  
],
  
  
"stopAutoPlay": true
  
},
  
"hashesProcessed": [
  
  
{
  
  
  
"hash": "123e4567-e89b-12d3-a456-426655440000",
  
  
  
"errorCode": {
  
  
  
  
"id": 1,
  
  
  
  
"msg": "player id unknown",
  
  
  
  
"clientmsg": "You reached your daily betting limit!"
  
  
  
}
  
  
}
  
]
}

Samples

Powered by VitePress OpenAPI