Authentication
A-ZPay’s public integration authentication is the signed partner API. Partner portal login and player handoff flows are not machine-to-machine API routes; casino integrations should only sign the partner endpoints documented here.
Partner API signature
Every partner API request must include:
X-Api-Key: pk_live_xxx
X-Timestamp: 1778940000
X-Signature: <hex hmac>
Each casino receives three integration values in its partner portal:
apiKey: sent asX-Api-Key.apiSecret: HMAC key.hashSecret: appended as the final canonical-string segment.
The signature is HMAC-SHA256 over:
<timestamp>.<METHOD>.<path>.<raw_body>.<hashSecret>
For GET requests, the raw body is an empty string, so the canonical string still ends with .<hashSecret>.
Example canonical string:
1778940000.POST./v1/deposits.{"amount":"100.00"}.hs_live_xxx
Legacy signatures that omit hashSecret are rejected.
Reusable request signer
import crypto from 'node:crypto';
const apiKey = process.env.AZPAY_API_KEY;
const apiSecret = process.env.AZPAY_API_SECRET;
const hashSecret = process.env.AZPAY_HASH_SECRET;
export function signAZPayRequest(method, path, rawBody = '') {
const timestamp = Math.floor(Date.now() / 1000).toString();
const canonical = [timestamp, method.toUpperCase(), path, rawBody, hashSecret].join('.');
const signature = crypto.createHmac('sha256', apiSecret).update(canonical).digest('hex');
return {
'content-type': 'application/json',
'x-api-key': apiKey,
'x-timestamp': timestamp,
'x-signature': signature,
};
}
const body = JSON.stringify({ amount: '100.00', currency: 'TRY' });
const headers = signAZPayRequest('POST', '/v1/deposits', body);<?php
function signAZPayRequest(string $method, string $path, string $rawBody = ''): array {
$apiKey = getenv('AZPAY_API_KEY');
$apiSecret = getenv('AZPAY_API_SECRET');
$hashSecret = getenv('AZPAY_HASH_SECRET');
$timestamp = (string) time();
$canonical = implode('.', [$timestamp, strtoupper($method), $path, $rawBody, $hashSecret]);
$signature = hash_hmac('sha256', $canonical, $apiSecret);
return [
'content-type: application/json',
'x-api-key: ' . $apiKey,
'x-timestamp: ' . $timestamp,
'x-signature: ' . $signature,
];
}
$body = json_encode(['amount' => '100.00', 'currency' => 'TRY'], JSON_UNESCAPED_SLASHES);
$headers = signAZPayRequest('POST', '/v1/deposits', $body);Timestamp skew
X-Timestamp is a Unix timestamp in seconds. Requests outside the allowed clock-skew window are rejected, so partner servers should keep NTP time synchronized.
Signed GET request example
const path = '/partner/balance';
const response = await fetch('https://api.azpay.example' + path, {
method: 'GET',
headers: signAZPayRequest('GET', path, ''),
});
if (!response.ok) {
throw new Error('A-ZPay rejected request: ' + response.status);
}
const balance = await response.json();<?php
$path = '/partner/balance';
$ch = curl_init('https://api.azpay.example' . $path);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => signAZPayRequest('GET', $path, ''),
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status < 200 || $status >= 300) {
throw new RuntimeException('A-ZPay rejected request: ' . $status);
}
$balance = json_decode($response, true);