Appearance
(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
voidmay 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;voidcalls 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
endin the same call. *transactionCountmust equal the length oftransactions; 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!" } } ]
{
}