Bayilər üçün
API sənədləri
Öz saytınızdan və ya panelinizdən ZTopup kataloqunu oxuyun, oyunçu hesabını yoxlayın və sifarişi birbaşa yaradın. Ödəniş bayi balansından çıxılır, təhvil avtomatikdir.
Başlanğıc
API bayi hesabınızın adından işləyir: gördüyünüz qiymətlər sizin bayi qiymətlərinizdir, sifarişlər sizin balansınızdan ödənilir. Açar hesabınıza bağlıdır — onu paylaşmayın, sızdığını düşünürsünüzsə dərhal bizə yazın.
1. API açarı alın
Bayi hesabınız təsdiqləndikdən sonra panelinizdən açar yaradılır. Açar bir dəfə göstərilir, saxlanmır — itirsəniz yenisini yaradın, köhnəsi dərhal etibarsız olur.
2. Hər sorğuya açarı əlavə edin
curl https://ztopup.store/api/v1/me \ -H "X-API-Key: sizin_açarınız" \ -H "Accept: application/json"
3. Balansı doldurun
Sifariş yaratmaq üçün balansınız kifayət etməlidir — API balansı özü doldurmur. Balans panelin Balansım bölməsindən artırılır; kart məlumatları orada göstərilir.
4. İlk sifariş
Ardıcıllıq həmişə eynidir: kataloqdan paket seçin, oyunçu hesabını yoxlayın, sifarişi yaradın, nəticəni webhook ilə və ya sorğu ilə izləyin.
Ümumi qaydalar
Ünvan və format
Bütün endpointlər https://ztopup.store/api/v1 altındadır və
yalnız HTTPS qəbul edir. Sorğu və cavab gövdəsi JSON, kodlaşdırma UTF-8-dir.
Cavab qabığı
Hər cavab ok sahəsi ilə gəlir. Uğurlu
cavabda məlumat data içindədir, xətada
isə error.
{
"ok": true,
"data": { }
}
Məbləğlər
Bütün məbləğlər AZN və iki onluq
işarə ilə, mətn kimi göndərilir
("1.91"). Sürüşən nöqtə xətası
olmasın deyə rəqəm tipi işlədilmir.
Tarixlər
ISO 8601, Bakı vaxtı ilə: 2026-09-21T14:05:31+04:00.
Idempotensiya
Sifariş yaradan sorğuda Idempotency-Key
başlığı məcburidir. Eyni açarla
təkrar göndərilən sorğu yeni sifariş yaratmır — ilk sifarişin cavabını
qaytarır. Şəbəkə kəsiləndə sorğunu təhlükəsiz təkrarlamağın yolu budur.
Açar 24 saat saxlanır və hesabınıza aiddir.
Eyni açarla fərqli gövdə göndərsəniz sorğu
409 qaytarır — səhvən eyni açarın iki
ayrı sifarişə yapışdırılması beləcə tutulur.
Səhifələmə
Siyahı qaytaran endpointlər page və
per_page (ən çox 100, standart 25)
qəbul edir. Cavabda meta olur.
"meta": {
"page": 1,
"per_page": 25,
"total": 134,
"last_page": 6
}
Hesab və balans
/me
Hesab məlumatı
{
"ok": true,
"data": {
"id": 42,
"name": "Nümunə MMC",
"dealer_tier": "Gümüş",
"balance": "184.50",
"currency": "AZN"
}
}
/balance
Yalnız balans
{
"ok": true,
"data": { "balance": "184.50", "currency": "AZN" }
}
Kataloq
Kataloq iki səviyyəlidir: məhsul (oyun və region, məsələn «Free Fire Almaz — Azərbaycan») və onun altındakı paketlər. Sifariş həmişə paketə verilir.
/products
Məhsul siyahısı
category
ilə süzgəcləyə bilərsiniz.{
"ok": true,
"data": [
{
"id": 1,
"slug": "free-fire-almaz-azerbaycan",
"name": "Free Fire Almaz — Azərbaycan",
"category": "Free Fire",
"region": "AZ",
"requires_player_id": true,
"player_id_label": "Player ID"
}
],
"meta": { "page": 1, "per_page": 25, "total": 18, "last_page": 1 }
}
/products/{id}/packages
Paketlər
list_price pərakəndə qiymətdir — öz
saytınızda fərqi göstərmək istəsəniz işinizə yarayar.{
"ok": true,
"data": [
{
"id": 1,
"name": "110 Almaz",
"price": "1.64",
"list_price": "1.91",
"currency": "AZN",
"available": true,
"stock": null
}
]
}
stock dəyəri null
olanda limit yoxdur. available
false olan paketə sifariş verilə bilməz —
paketin özü bağlıdır və ya təchizat müvəqqəti dayanıb.
Oyunçu yoxlaması
requires_player_id olan məhsullarda
sifarişdən əvvəl oyunçu hesabı
yoxlanmalıdır. Yoxlama sizə oyunçunun adını qaytarır və
player_token verir; sifariş həmin
token olmadan qəbul edilmir.
Səbəbi sadədir: səhv Player ID-yə yüklənmiş almaz geri qayıtmır. Token 5 dəqiqə etibarlıdır və yalnız yoxlandığı paket + Player ID cütü üçün işləyir.
/players/validate
Oyunçunu yoxla
curl -X POST https://ztopup.store/api/v1/players/validate \
-H "X-API-Key: sizin_açarınız" \
-H "Content-Type: application/json" \
-d '{
"package_id": 1,
"player_id": "5012345678"
}'
{
"ok": true,
"data": {
"valid": true,
"player_name": "OyuncuAZ",
"player_token": "pv_9f2c1a...",
"expires_at": "2026-09-21T14:10:31+04:00"
}
}
Bəzi oyunlarda ad sorğulanmır; belə hallarda
player_name
null gəlir, token yenə verilir.
Yanlış ID-də cavab 422 olur və sifariş
yaradılmır — pul tutulmur.
Sifarişlər
/orders
Sifariş yarat
paid statusu ilə açılır. Balans
çatmırsa sifariş ümumiyyətlə yaradılmır.curl -X POST https://ztopup.store/api/v1/orders \
-H "X-API-Key: sizin_açarınız" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 7b1f0c94-2d3a-4e55-9f10-8c2b6de41a77" \
-d '{
"package_id": 1,
"quantity": 1,
"player_id": "5012345678",
"player_token": "pv_9f2c1a...",
"reference": "sizin-sifaris-1042"
}'
{
"ok": true,
"data": {
"id": "ord_8412",
"order_no": "GX260921ABCD",
"status": "paid",
"reference": "sizin-sifaris-1042",
"package": { "id": 1, "name": "110 Almaz" },
"player_id": "5012345678",
"player_name": "OyuncuAZ",
"quantity": 1,
"unit_price": "1.64",
"total": "1.64",
"currency": "AZN",
"balance_after": "182.86",
"items": [
{ "id": "itm_9103", "fulfillment_status": "pending", "delivered_at": null }
],
"created_at": "2026-09-21T14:05:31+04:00"
}
}
reference sizin öz sifariş nömrənizdir —
istəyə bağlıdır, cavablarda və webhook-da geri qaytarılır, hesablaşmanı
asanlaşdırır. Idempotensiya üçün isə reference
yox, Idempotency-Key istifadə olunur.
/orders/{id}
Sifarişin vəziyyəti
ord_8412, həm də
GX260921ABCD qəbul edilir./orders
Sifariş siyahısı
status, from,
to və reference
ilə süzgəclənir. Yeni sifariş əvvəldə gəlir.Təhvil ani deyil
paid ödənişin alındığı deməkdir,
məhsulun oyun hesabına düşdüyü yox. Təhvil adətən saniyələr çəkir, amma
təchizatçı gecikəndə uzana bilər. Sifarişi
dövrə vurub sorğulamaq əvəzinə
webhook-a abunə olun; sorğu lazımdırsa 10 saniyədən tez-tez etməyin.
Webhook
Sifariş statusu dəyişəndə göstərdiyiniz ünvana
POST göndərilir. Ünvanı və imza açarını
paneldən təyin edirsiniz.
{
"event": "order.completed",
"sent_at": "2026-09-21T14:05:47+04:00",
"data": {
"id": "ord_8412",
"order_no": "GX260921ABCD",
"reference": "sizin-sifaris-1042",
"status": "completed",
"items": [
{ "id": "itm_9103", "fulfillment_status": "delivered", "delivered_at": "2026-09-21T14:05:47+04:00" }
]
}
}
Hadisələr
| Hadisə | Nə vaxt |
|---|---|
order.completed | Bütün sətirlər təhvil verildi |
order.failed | Təhvil mümkün olmadı, məbləğ balansa qaytarıldı |
order.cancelled | Sifariş ləğv edildi |
İmzanı yoxlayın
Hər sorğuda X-ZTopup-Signature başlığı olur:
gövdənin imza açarınızla hesablanmış HMAC-SHA256 dəyəri (hex).
Gövdəni JSON-a çevirmədən əvvəl, xam
haldaca yoxlayın — yenidən kodlaşdırma imzanı pozur.
$raw = file_get_contents('php://input');
$expected = hash_hmac('sha256', $raw, $secret);
if (! hash_equals($expected, $_SERVER['HTTP_X_ZTOPUP_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
Təkrar göndəriş olur
Cavabınız 2xx olmasa, sorğu artan
aralıqlarla 24 saat ərzində təkrarlanır. Ona görə emalınız
idempotent olmalıdır: eyni
id ikinci dəfə gələndə heç nə
dəyişməməlidir. Uzun iş görməyin — əvvəlcə 200
qaytarın, sonra növbəyə salın.
Sorğu limitləri
| Qrup | Endpointlər | Dəqiqədə |
|---|---|---|
| Kataloq | /products, /products/{id}/packages | 120 |
| Hesab | /me, /balance | 60 |
| Oyunçu yoxlaması | /players/validate | 30 |
| Sifariş yaratma | POST /orders | 30 |
| Sifariş oxuma | GET /orders, GET /orders/{id} | 60 |
Limit aşılanda cavab 429 olur və
Retry-After başlığında neçə saniyə
gözləməli olduğunuz yazılır. Qalan haqqınız hər cavabda
X-RateLimit-Remaining ilə gəlir.
Statuslar və xətalar
Sifariş statusu
| Dəyər | Mənası |
|---|---|
paid | Ödənildi, təhvil gözlənilir |
completed | Bütün sətirlər təhvil verildi |
cancelled | Ləğv edildi, məbləğ balansa qaytarıldı |
Sətir statusu
| Dəyər | Mənası |
|---|---|
pending | Təhvil davam edir |
delivered | Oyun hesabına yükləndi |
failed | Təhvil mümkün olmadı; məbləğ balansa qaytarılır |
HTTP kodları
| Kod | Mənası |
|---|---|
200 | Uğurlu |
201 | Sifariş yaradıldı |
401 | Açar yoxdur və ya yanlışdır |
402 | Balans kifayət etmir |
404 | Tapılmadı |
409 | Eyni idempotensiya açarı, fərqli gövdə |
422 | Məlumat düzgün deyil (Player ID, paket, miqdar) |
429 | Limit aşıldı |
500 | Bizim tərəfdə xəta — sorğunu təkrarlaya bilərsiniz |
Xəta gövdəsi
{
"ok": false,
"error": {
"code": "insufficient_balance",
"message": "Balans kifayət etmir.",
"details": { "required": "1.64", "balance": "0.80" }
}
}
code sabitdir və proqramla yoxlanmaq
üçündür; message insan üçündür və
dəyişə bilər — şərtlərinizi mesaja görə yazmayın.
Vaxt aşımı uğursuzluq deyil
POST /orders cavabsız qalsa, sifariş
yaranmış ola bilər. Yenidən yaratmayın —
eyni Idempotency-Key ilə təkrar
göndərin, cavab ilk sifarişi qaytaracaq.
Sual var?
İnteqrasiya zamanı ilişdiyiniz yer olsa yazın — sorğu və cavab nümunəsi ilə birlikdə göndərsəniz daha tez kömək edə bilərik.
Tez-tez verilən suallar