Bayi API (Reseller API) Belgeleri
Ürünlerimizi kendi sitenizde, botunuzda ya da panelinizde satın. AI Store Plus Bayi API'si, Telegram mağazamızdaki katalogu, fiyatları ve otomatik teslimatı sade bir JSON API ile size açar. Siparişler ayrı API bakiyenizden ödenir.
https://api.aistoreplus.com/v1Authorization: Bearer rk_…JSON · UTF-8 · yalnızca HTTPSUSD (tutarlar metin olarak)1. Başlarken
- Telegram mağazamız @aistoreplus_bot'u açın ve Başlat'a dokunun.
- Cüzdan'dan normal bakiyenize yükleme yapın (USDT TRC20 / BEP20 ya da Binance Pay).
- Profil → Bayi API'ye gidin (ya da
/apiyazın), API bakiyesine aktar'a dokunun ve API'de kullanacağınız tutarı aktarın. API siparişleri yalnızca API bakiyesinden ödenir; anahtar sızsa bile normal bakiyenize dokunulamaz. Aktarma tek yönlüdür: API bakiyesi geri aktarılamaz. - Aynı ekranda Yeni anahtar oluştur'a dokunun.
- Anahtarı hemen kopyalayın. Anahtar yalnızca bir kez gösterilir: sistemde yalnızca şifreli özeti saklanır, biz de göremeyiz. Sonra altındaki düğmeyle mesajı silin.
- Her şeyin çalıştığını görmek için anahtarınızla
GET https://api.aistoreplus.com/v1/meisteği atın.
Aynı anda en fazla 3 etkin anahtarınız olabilir (ör. biri canlı, biri deneme için) ve 24 saatte en fazla 5 anahtar oluşturabilirsiniz. Anahtarı aynı ekrandan istediğiniz an iptal edersiniz; iptal anında geçerlidir.
2. Kimlik doğrulama
Anahtarı Authorization başlığında gönderin. Alternatif olarak X-API-Key başlığı da kabul edilir.
Authorization: Bearer rk_ANAHTARINIZ
# ya da
X-API-Key: rk_ANAHTARINIZEksik, yanlış ya da iptal edilmiş anahtar 401 unauthorized döner. Her yanıtta X-Request-Id başlığı vardır; destekle yazışırken bu kimliği paylaşın.
IP kısıtı (önerilir)
Bayi API → IP kısıtı ile anahtarı yalnızca sunucunuzun IP adreslerinden ya da aralıklarından kullanılabilir yaparsınız (IPv4/IPv6, en fazla 10; ör. 203.0.113.7, 198.51.100.0/24). Başka bir adresten gelen istek 403 ip_not_allowed alır; sızan bir anahtar başka yerde kullanılamaz.
3. Sınırlar
| İstek | Anahtar başına dakikada 60. Her yanıtta X-RateLimit-Limit ve X-RateLimit-Remaining vardır. Sınır aşılırsa 429 rate_limited ve Retry-After: 60. |
|---|---|
| Hatalı anahtar | Aynı IP'den bir dakikada 20 hatalı anahtarlı istekten sonra o IP bir dakika 429 too_many_failed_attempts alır. |
| Adet | Sipariş başına 1 ile ürünün max_quantity değeri arası (çoğu üründe 25; müşteri bilgisi isteyen üründe 1). |
| İstek gövdesi | En fazla 64 KB. |
4. Hesap ve bakiye
GET/meHesap, bakiye ve anahtar bilgisi
API bakiyenizi (balance), toplam harcamanızı, üyelik kademenizi ve kullanılan anahtarı döner. Bottaki normal bakiyeniz burada görünmez. /balance aynı veriyi verir.
{
"customer": "CUS-7K2M9QX4",
"balance": "125.5000",
"currency": "USD",
"total_spent": "310.0000",
"tier": "Silver",
"tier_discount": "0.0300",
"api_key": {
"prefix": "rk_AbCdEfGh",
"label": "API key 1",
"rate_limit_per_minute": 60,
"ip_restricted": true
}
}tier_discount her siparişe kendiliğinden uygulanır; katalog liste fiyatını, sipariş yanıtı gerçekten ödediğiniz tutarı gösterir.
GET/v1API durumu (anahtar gerekmez)
{
"name": "AI Store Plus Reseller API",
"version": "v1",
"status": "ok",
"base_url": "https://api.aistoreplus.com/v1",
"documentation": "https://aistoreplus.com/en/reseller-api/"
}5. Ürünler
GET/productsSipariş verebileceğiniz her şey
Liste, Telegram mağazamızda o an satılan ürünlerin birebir aynısıdır. Gizli, mağazaya henüz eklenmemiş ya da ekibimizin elle teslim ettiği ürünler listede yoktur ve API'den sipariş edilemez.
{
"total": 2,
"currency": "USD",
"products": [
{
"id": 127,
"name": "Example Pro · 18 Months",
"category": "AI",
"price": "0.7000",
"currency": "USD",
"stock": 1581,
"in_stock": true,
"product_type": "code",
"warranty_days": 0,
"min_quantity": 1,
"max_quantity": 25,
"required_inputs": []
},
{
"id": 2210,
"name": "Example Team Seat · 1 Month",
"category": "AI",
"price": "14.0000",
"currency": "USD",
"stock": null,
"in_stock": true,
"product_type": "service",
"warranty_days": 0,
"min_quantity": 1,
"max_quantity": 1,
"required_inputs": [
{ "key": "customer_email", "label": "Email address (the invitation is sent here)" }
]
}
]
}| price | Birim liste fiyatı (USD), 4 ondalıklı metin. Para hesabında float'a çevirmeyin. |
|---|---|
| stock | Satılabilir adet. null = stok bildirilmiyor (ürün yine sipariş edilebilir); 0 = tükendi. |
| in_stock | Şu an sipariş verilebiliyorsa true. |
| product_type | ready_account, code, coupon ya da service. |
| required_inputs | Ürünün müşterinizden istediği bilgiler (Müşteri bilgisi). Çoğu üründe boştur. |
| max_quantity | Tek siparişte izin verilen en yüksek adet. |
Fiyat ve stok gün içinde değişir. Katalogu birkaç dakikada bir yenileyin ve satmadan hemen önce in_stock ile price'a bakın.
GET/products/{id}Tek ürün ve açıklaması
Aynı alanlar ve ek olarak description. Mağazada olmayan ürün 404 product_not_found döner.
6. Sipariş verme
POST/ordersAPI bakiyesinden satın alma
| product_id | Tam sayı, zorunlu. /products'tan. |
|---|---|
| quantity | Tam sayı, zorunlu. 1 ile ürünün max_quantity değeri arası. |
| idempotency_key | Metin, zorunlu, 1–64 karakter. Bu siparişe ait sizin benzersiz kimliğiniz (ör. kendi sipariş numaranız). |
| inputs | Nesne, yalnızca required_inputs olan ürünlerde: {"customer_email": "alici@ornek.com"}. |
{"product_id": 127, "quantity": 2, "idempotency_key": "my-order-10045"}{
"order": {
"order_code": "ORD-C19QV1RX",
"status": "completed",
"status_detail": "delivered",
"product_id": 127,
"product_name": "Example Pro · 18 Months",
"quantity": 2,
"delivered_quantity": 2,
"unit_price": "0.7000",
"total": "1.4000",
"refunded": "0.0000",
"currency": "USD",
"created_at": "2026-10-28T10:15:02.123456+00:00",
"delivered_at": "2026-10-28T10:15:03.004512+00:00",
"items": [
"https://example.com/activate/AAAA-BBBB",
"https://example.com/activate/CCCC-DDDD"
],
"instructions": "Open the link while signed in to your own account.",
"outcome": "delivered"
},
"replay": false
}Idempotency: güvenli tekrar deneme
Bağlantınız koparsa aynı isteği aynı idempotency_key ile tekrar gönderin. İlk sipariş 200 ve "replay": true ile geri döner; iki kez ücret alınmaz. Her yeni sipariş için yeni bir anahtar kullanın; bir anahtarı başka ürün ya da adet için asla tekrar kullanmayın.
Paranıza ne olur?
- Sipariş oluşturulurken tutar API bakiyenizden düşer; yetmezse normal bakiyenize geçilmez.
402 insufficient_balancehiçbir ücret alınmadı demektir. - Ürünlerin çoğu anında teslim edilir: teslim edilen hesap, kod ya da bağlantılar
items'ta, varsa etkinleştirme notuinstructions'tadır. - Bazı ürünleri (davet, yükseltme) tedarik tarafı biraz sonra tamamlar: sipariş
processingkalır; sipariş durumunu sorgulayın. - Karşılanamayan siparişin tutarı API bakiyenize kendiliğinden iade edilir ve
refunded'da görünür. Bir kısmı teslim edilirse kalan iade edilir (partial).
| outcome | delivered hepsi teslim · partial bir kısmı teslim, kalan iade · failed teslim edilemedi, tamamı iade · supplier kabul edildi, sonra tamamlanacak · needs_review sonuç belirsiz, ekibimiz kontrol ediyor (henüz iade yok) · replay aynı idempotency_key, ilk sipariş döndü |
|---|
7. Sipariş durumu ve geçmiş
GET/orders/{order_code}Tek sipariş ve teslim edilenler
Siparişi, sipariş yanıtıyla aynı biçimde (items ve instructions dahil) döner. Başka bir hesabın siparişi 404 not_found alır.
| status | processing sürüyor · completed teslim edildi · partial bir kısmı teslim, kalan iade · refunded tamamı iade · failed teslim edilemedi · cancelled iptal |
|---|---|
| status_detail | İç durum; kayıt ve destek içindir. Mantığınızı status üzerine kurun. |
Sipariş processing iken 1–2 dakikada bir sorgulayın. Sonradan tamamlanan siparişlerin çoğu dakikalar içinde biter; davetler birkaç saat sürebilir.
GET/orders?limit=20&offset=0Siparişleriniz, yeniden eskiye
limit 1–100 (varsayılan 20). Liste teslim edilenleri içermez; onlar için tek siparişi çağırın.
{
"total": 37,
"limit": 20,
"offset": 0,
"orders": [
{
"order_code": "ORD-C19QV1RX",
"status": "completed",
"status_detail": "delivered",
"product_id": 127,
"product_name": "Example Pro · 18 Months",
"quantity": 2,
"delivered_quantity": 2,
"unit_price": "0.7000",
"total": "1.4000",
"refunded": "0.0000",
"currency": "USD",
"created_at": "2026-10-28T10:15:02.123456+00:00",
"delivered_at": "2026-10-28T10:15:03.004512+00:00"
}
]
}8. Webhook (sipariş durumu bildirimi)
Sipariş durumunu sürekli sorgulamak yerine, API siparişiniz sonuçlandığında sunucunuza biz haber verelim. Hesabınıza bir HTTPS adresi kaydedin; API'den verdiğiniz her sipariş sonuçlandığında o adrese imzalı bir POST göndeririz.
PUT/webhookWebhook adresini kaydet (ya da değiştir)
{"url": "https://example.com/aistore/webhook"}{
"webhook": {
"url": "https://example.com/aistore/webhook",
"created_at": "2026-10-28T13:05:12+00:00",
"last_success_at": null,
"last_failure_at": null,
"last_error": null,
"consecutive_failures": 0
},
"secret": "whsec_k3Jx9Qm2LpV7tR8wYz4AbCdEfGhIjKlMnOpQrStUvWx"
}secret yalnızca webhook ilk oluşturulduğunda, bir kez döner. İmzayı doğrulamak için gerekir; güvenli bir yerde saklayın. Yeni sır için "rotate_secret": true gönderin (eskisi hemen geçersiz olur). Yalnızca adresi değiştirmek sırrı korur.
GET/webhookKayıtlı adres ve gönderim durumu
POST/webhook/testŞimdi imzalı bir ping gönder
{"delivered": true, "status": 200, "error": null}DELETE/webhookWebhook kaydını sil
Olaylar
| order.completed | Bütün adetler teslim edildi; order.items içinde. |
|---|---|
| order.partial | Bir kısmı teslim edildi, kalanı API bakiyenize iade edildi. |
| order.refunded | Teslim edilmedi, tamamı iade edildi. |
| order.failed | Teslim edilmedi. |
| order.cancelled | İptal edildi. |
| ping | Yalnızca POST /webhook/test gönderir; order değeri null. |
Gövdedeki sipariş, GET /orders/{order_code} yanıtıyla birebir aynı biçimdedir:
{
"id": "evt_1842",
"event": "order.completed",
"created_at": "2026-10-28T13:10:41+00:00",
"order": {
"order_code": "ORD-C19QV1RX",
"status": "completed",
"status_detail": "delivered",
"product_id": 127,
"product_name": "Example Pro · 18 Months",
"quantity": 1,
"delivered_quantity": 1,
"unit_price": "0.7000",
"total": "0.7000",
"refunded": "0.0000",
"currency": "USD",
"created_at": "2026-10-28T13:10:38+00:00",
"delivered_at": "2026-10-28T13:10:39+00:00",
"items": ["https://example.com/activate/AbC123"],
"instructions": "Open the link and sign in with your own account."
}
}Başlıklar ve imza
| X-AIStore-Event | Olay adı, örneğin order.completed. |
|---|---|
| X-AIStore-Delivery | Olayın tekil kimliği (evt_…). Aynı olay birden fazla gelebilir; işlediğiniz kimlikleri atlayın. |
| X-AIStore-Timestamp | İsteği imzaladığımız an (Unix saniye). |
| X-AIStore-Signature | v1= + sırrınızla timestamp + "." + ham gövde üzerinden hex HMAC-SHA256. |
import hashlib, hmac, time
def verify(secret: str, headers: dict, raw_body: bytes) -> bool:
timestamp = headers["X-AIStore-Timestamp"]
if abs(time.time() - int(timestamp)) > 300: # older than 5 minutes
return False
expected = "v1=" + hmac.new(
secret.encode(), timestamp.encode() + b"." + raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, headers["X-AIStore-Signature"])<?php
$secret = getenv('AISTORE_WEBHOOK_SECRET');
$raw = file_get_contents('php://input'); // raw body, before json_decode
$timestamp = $_SERVER['HTTP_X_AISTORE_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_AISTORE_SIGNATURE'] ?? '';
$expected = 'v1=' . hash_hmac('sha256', $timestamp . '.' . $raw, $secret);
if (abs(time() - (int) $timestamp) > 300 || !hash_equals($expected, $signature)) {
http_response_code(401);
exit;
}
$event = json_decode($raw, true); // $event['event'], $event['order']
http_response_code(200);Teslim ve yeniden deneme
- 10 saniye içinde herhangi bir
2xxile cevap verin. Yanıt gövdesi okunmaz, yönlendirme izlenmez. - Aksi halde 30 sn, 2 dk, 10 dk, 30 dk, 2 sa, 6 sa ve 12 sa sonra yeniden deneriz (toplam 8 deneme), sonra bırakırız. Son hatayı
GET /webhookgösterir. - Yalnızca webhook'u kaydettikten sonra API'den verilen siparişler gönderilir. Her siparişi
GET /orders/{order_code}ile her zaman sorgulayabilirsiniz. - Adres
https://olmalı ve genel bir IP'ye çözülmeli; yerel, özel ve iç ağ adresleri reddedilir. - İmzası tutmayan ya da zaman damgası 5 dakikadan eski istekleri reddedin.
9. Deneme siparişi
Entegrasyonunuzu baştan sona denemek için /products listesindeki API Test Order ürününü sipariş edin. Fiyatı 0,01 $; anında teslim edilir ve items içinde API-TEST-3F9A1C2B7D10 gibi tek kullanımlık sahte bir kod döner. Gerçek bir sipariştir: tutar API bakiyenizden düşer, sipariş /orders listesinde görünür ve webhook'unuz order.completed alır. Test ürünü yalnızca API'de görünür, Telegram mağazamızda yoktur.
10. Müşteri bilgisi isteyen ürünler
Bazı ürünler müşterinizin kendi hesabına teslim edilir (ör. ekip daveti). Bu ürünlerin required_inputs listesi inputs'ta ne göndereceğinizi söyler. Bu siparişler tek adettir. Şifre asla istenmez.
| customer_email | E-posta adresi (davet buraya gider) |
|---|---|
| customer_gmail | Gmail adresi (davet buraya gider) |
| customer_account | Yükseltilecek hesabın e-postası ya da kimliği |
| customer_account_gmail | Yükseltilecek hesabın Gmail adresi |
| customer_username | Yükseltilecek hesabın kullanıcı adı |
| customer_phone | Uluslararası biçimde telefon (+905551112233) |
| full_name | Ad soyad |
| country | Ülke |
Eksik bilgi 422 input_required döner, eksik alanlar error.fields'tadır; ücret alınmaz.
11. Hatalar
Hatalar her zaman aynı biçimdedir. Mantığınızı code'a göre kurun; message insanlar içindir ve değişebilir.
{
"error": {
"code": "insufficient_balance",
"message": "Insufficient balance."
}
}| HTTP | code | Anlamı |
|---|---|---|
| 400 | invalid_json · missing_field · invalid_field · invalid_quantity | İstek hatalı. Ücret alınmadı. |
| 401 | unauthorized | Anahtar eksik, yanlış ya da iptal edilmiş. |
| 402 | insufficient_balance | Botta API bakiyenize aktarın (Bayi API → API bakiyesine aktar). |
| 403 | ip_not_allowed | Anahtarın IP kısıtı var ve IP'niz listede değil. |
| 404 | product_not_found · not_found | Ürün mağazada yok / sipariş bulunamadı. |
| 409 | out_of_stock · price_changed · product_unavailable · order_refused | Şu an satılamıyor. Katalogu yenileyip tekrar deneyin. Ücret alınmadı. |
| 422 | input_required · invalid_input | Gerekli müşteri bilgisi eksik ya da geçersiz. |
| 429 | rate_limited · too_many_failed_attempts | Yavaşlayın; Retry-After'a bakın. |
| 503 | api_disabled | Kısa bakım. Sonra tekrar deneyin. |
12. Kod örnekleri
# Products
curl https://api.aistoreplus.com/v1/products \
-H "Authorization: Bearer rk_YOUR_KEY"
# Place an order (use a unique idempotency_key per order)
curl -X POST https://api.aistoreplus.com/v1/orders \
-H "Authorization: Bearer rk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"product_id": 127, "quantity": 1, "idempotency_key": "my-order-10045"}'import requests
API = "https://api.aistoreplus.com/v1"
HEADERS = {"Authorization": "Bearer rk_YOUR_KEY"}
products = requests.get(f"{API}/products", headers=HEADERS, timeout=30).json()["products"]
item = next(p for p in products if p["id"] == 127 and p["in_stock"])
resp = requests.post(
f"{API}/orders",
headers=HEADERS,
json={"product_id": item["id"], "quantity": 1, "idempotency_key": "my-order-10045"},
timeout=90,
)
data = resp.json()
if resp.status_code in (200, 201):
order = data["order"]
print(order["order_code"], order["status"], order.get("items"))
else:
print("Error:", data["error"]["code"], data["error"]["message"])<?php
$api = 'https://api.aistoreplus.com/v1';
$key = 'rk_YOUR_KEY';
$ch = curl_init("$api/orders");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 90,
CURLOPT_HTTPHEADER => ["Authorization: Bearer $key", 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'product_id' => 127,
'quantity' => 1,
'idempotency_key' => 'my-order-10045',
]),
]);
$body = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status === 200 || $status === 201) {
echo $body['order']['order_code'], ' ', $body['order']['status'], PHP_EOL;
} else {
echo 'Error: ', $body['error']['code'], PHP_EOL;
}const API = "https://api.aistoreplus.com/v1";
const headers = { Authorization: "Bearer rk_YOUR_KEY", "Content-Type": "application/json" };
const res = await fetch(`${API}/orders`, {
method: "POST",
headers,
body: JSON.stringify({ product_id: 127, quantity: 1, idempotency_key: "my-order-10045" }),
});
const data = await res.json();
if (res.ok) {
console.log(data.order.order_code, data.order.status, data.order.items);
} else {
console.error(data.error.code, data.error.message);
}13. Güvenlik
- Anahtarı sunucunuzda tutun. Web sitesine, tarayıcı eklentisine, mobil uygulamaya ya da herkese açık bir depoya asla koymayın.
- Canlı anahtarlarda IP kısıtı kullanın.
- Anahtarın sızmış olabileceğinden şüphelenirseniz botta iptal edip yenisini oluşturun. İptal anında geçerlidir.
- Anahtarınızın yalnızca şifreli özetini saklıyoruz. Ekibimiz sizden asla anahtarınızı ya da şifrenizi istemez.
- Teslim edilen hesap ve kodlar yalnızca API yanıtlarındadır. Onları güvenli saklayın ve müşterinize güvenli bir kanaldan iletin.
14. Destek
Sorunuz ya da bir siparişle ilgili sorununuz mu var? Telegram'da @aistoreplus'a order_code ve yanıttaki X-Request-Id ile yazın.
API sürümü v1 · son güncelleme 28 Ekim 2026.


