E-pin ve top-up satışını kendi sisteminize bağlayın
Katalog ve bayi fiyatlarınızı çekin, oyuncu hesabını doğrulayın, sipariş verin, kodu saniyeler içinde alın. Bakiye ve cari hareketleriniz aynı API'de. Fiyat, stok ve teslim değişiklikleri size imzalı webhook ile gelir.
Bayi Paneli ile API AYNI çekirdeği kullanır: iki kanal hiçbir zaman farklı fiyat, farklı stok ya da farklı hata göstermez. Panelde gördüğünüz sayı, API'nin döndürdüğü sayıdır.
Hızlı başlangıç · 5 dakikada ilk sipariş
- Bayi Panelinden (Entegrasyon > API anahtarları) önce bir TEST anahtarı üret. Test anahtarı ile verilen siparişler para harcamaz ve TEST- önekli sahte kod döner.
- GET /bayi-api/v1/me ile anahtarın doğru hesaba bağlı olduğunu ve kapsamlarını teyit et.
- GET /bayi-api/v1/catalog/products ile ürün kimliklerini, fiyatları ve zorunlu alan şemasını çek. Kimlik ya da alan adı UYDURMA, hep bu uçtan oku.
- POST /bayi-api/v1/orders ile test siparişi ver (Idempotency-Key başlığını unutma). Aynı anahtarla tekrar dene: aynı yanıt döner, ikinci sipariş oluşmaz.
- Akış çalışınca panelden CANLI anahtar üret, jetonu değiştir. Kod aynı kalır; tek fark artık bakiyeden para düşmesi.
- Yoklamayı (polling) BIRAK: PUT /bayi-api/v1/webhooks ile adresini kaydet, imza sırrını sakla ve POST /bayi-api/v1/webhooks/test ile bağını doğrula. Sipariş sonucunu, fiyat değişimini ve bakiye yüklemesini olay olarak alırsın.
curl "https://oyuneks.com/bayi-api/v1/me" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
<?php
$ch = curl_init("https://oyuneks.com/bayi-api/v1/me");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"],
]);
$yanit = json_decode(curl_exec($ch), true);
$kod = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($kod >= 400) {
// Dallanmayi HER ZAMAN error.code uzerinden yap; message degisebilir.
throw new \RuntimeException($yanit["error"]["code"] . ": " . $yanit["error"]["message"]);
}
print_r($yanit["data"]);
const yanit = await fetch("https://oyuneks.com/bayi-api/v1/me", {
method: "GET",
headers: {
"Authorization": "Bearer oyxb_test_KENDI_ANAHTARIN"
}
});
const govde = await yanit.json();
if (!yanit.ok) {
// error.code sabittir; message insan icindir.
throw new Error(govde.error.code + ": " + govde.error.message);
}
console.log(govde.data);
curl -X POST "https://oyuneks.com/bayi-api/v1/orders" \
-H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: SIP-2026-0001-1" \
-d '{"externalRef":"SIP-2026-0001","waitForStock":true,"items":[{"productId":6,"quantity":2,"expectedPrice":"98.70"},{"productId":1421,"quantity":1,"fields":{"playerId":"5123456789"}}]}'
<?php
$ch = curl_init("https://oyuneks.com/bayi-api/v1/orders");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => ["Authorization: Bearer oyxb_test_KENDI_ANAHTARIN", "Content-Type: application/json", "Idempotency-Key: SIP-2026-0001-1"],
CURLOPT_POSTFIELDS => json_encode([
"externalRef" => "SIP-2026-0001",
"waitForStock" => true,
"items" => [
[
"productId" => 6,
"quantity" => 2,
"expectedPrice" => "98.70"
],
[
"productId" => 1421,
"quantity" => 1,
"fields" => [
"playerId" => "5123456789"
]
]
]
]),
]);
$yanit = json_decode(curl_exec($ch), true);
$kod = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($kod >= 400) {
// Dallanmayi HER ZAMAN error.code uzerinden yap; message degisebilir.
throw new \RuntimeException($yanit["error"]["code"] . ": " . $yanit["error"]["message"]);
}
print_r($yanit["data"]);
const yanit = await fetch("https://oyuneks.com/bayi-api/v1/orders", {
method: "POST",
headers: {
"Authorization": "Bearer oyxb_test_KENDI_ANAHTARIN",
"Content-Type": "application/json",
"Idempotency-Key": "SIP-2026-0001-1"
},
body: JSON.stringify({"externalRef":"SIP-2026-0001","waitForStock":true,"items":[{"productId":6,"quantity":2,"expectedPrice":"98.70"},{"productId":1421,"quantity":1,"fields":{"playerId":"5123456789"}}]})
});
const govde = await yanit.json();
if (!yanit.ok) {
// error.code sabittir; message insan icindir.
throw new Error(govde.error.code + ": " + govde.error.message);
}
console.log(govde.data);
Kimlik doğrulama
Her istekte Authorization: Bearer <anahtar> başlığı gönderilir. Anahtar Bayi Paneli'nden üretilir ve YALNIZ üretim anında bir kez gösterilir; veritabanında yalnız özeti (SHA-256) saklanır. Anahtar başına yetki kapsamı, IP kısıtı ve istek tavanı seçilir.
Anahtar sızarsa panelden "İptal et" deyin: anında geçersiz olur, eski anahtarla gelen istek 401 YETKISIZ alır ve girişim bayi denetim günlüğüne düşer. Kapsam SONRADAN EKLENEMEZ; yeni kapsam gerekiyorsa yeni anahtar üretilir (dar yetkili bir anahtarın sessizce genişlemesi, sızıntının etkisini büyütürdü).
Anahtar öneki modu söyler: oyxb_live_ canlı, oyxb_test_ test. Mod jetona gömülüdür, istek gövdesiyle değiştirilemez.
| Kapsam | Ne yapar |
|---|---|
| catalog:read | Katalog ve fiyat okuma |
| orders:read | Siparisleri ve kodlari okuma |
| orders:write | Siparis verme ve iptal (bakiyeden para duser) |
| balance:read | Bakiye ve cari hareket okuma |
| webhooks:manage | Webhook aboneligi yonetimi |
Test ortamı
Ayrı bir sunucu YOKTUR: aynı adres, oyxb_test_ anahtarıyla test modunda çalışır. Test modunda katalog ve fiyatlar gerçek, akış gerçek; ama Basket / Orders / Stocks / Customers tablolarına hiç dokunulmaz, bakiye düşmez, TEST- önekli sahte kod döner ve top-up yüklenmez.
Test siparişlerinin kimliği "test_12" biçimindedir ve GET /orders/{orderId} ucundan okunur. Webhook'lar test modunda da GERÇEKTEN gönderilir; gövdede "mode":"test" yazar, böylece kendi tarafınızda ayırabilirsiniz.
GB (type=goldbar) test siparişi GERÇEK AKIŞI taklit eder: yanıt processing döner, kalem kodsuz/makbuzsuzdur ve yaklaşık bir dakika sonra GET /orders/{orderId} teslim edilmiş gösterir (makbuz TEST-GB-...). order.delivered webhook mesaji da o anda gelir. Canlıda teslimatı operatör oyun içi yapar; bekleme durumunu test anahtarıyla denemeden canlıya çıkmayın.
Canlıya geçiş tek satır: jetonu değiştirin. Kod aynı kalır.
Genel kurallar
- Başarı zarfı her uçta aynı: {"data": ..., "mode": "live|test", "requestId": "..."}. Hata zarfı: {"error":{"code","message","retryable","requestId","details"}}.
- Para alanları METİN ve nokta ondalıklı: "411.50". Kayan noktalı sayı JSON'da 411.5 olur ve bazı istemcilerde 411.49999 görünür; muhasebe eşleşmesi bozulur. Para birimi her yerde TRY.
- Tarihler ISO-8601 ve Türkiye saati: "2026-08-28T14:05:00+03:00".
- Listeler İMLEÇLİ sayfalanır: yanıttaki nextCursor değerini ?cursor= ile geri gönderin. limit en çok 200 (sipariş listesinde 100). OFFSET sayfalama yoktur; araya yeni kayıt girdiğinde kalem atlar ya da tekrarlar.
- Her yanıtta X-Request-Id başlığı vardır; destek yazışmasında bu numarayı verin, istek tek sorguyla bulunur.
- Katalog uçları ETag döner; If-None-Match gönderirseniz gövde değişmediyse 304 alırsınız (gövde harcanmaz).
- Zorunlu alanlar (oyuncu ID, sunucu, karakter...) fields nesnesinde, ürünün requiredFields şemasına göre gönderilir. SIRA DEĞİL ANAHTAR ADI önemlidir.
- Bilinmeyen bir alan gönderirseniz yok sayılır; bilinmeyen bir OLAY adı gönderirseniz 400 alırsınız (sessizce düşürmek "abone oldum" yanılgısı yaratırdı).
İstek başlıkları
| Başlık | Anlamı |
|---|---|
| Authorization | Bearer oyxb_live_... ya da oyxb_test_... (ZORUNLU) |
| Idempotency-Key | POST /orders ucunda ZORUNLU; en fazla 64 karakter. Aynı anahtar + aynı gövde = aynı sipariş (iş tekrar çalışmaz), aynı anahtar + farklı gövde = 409. Anahtar 24 saat hatırlanır; bu süreden SONRA aynı anahtarla gelen istek YENİ sipariş oluşturur. |
| If-None-Match | Katalog uçlarında: gövde değişmediyse 304 döner, kota harcanmaz. |
| Content-Type | application/json (form-data da kabul edilir). |
Yanıt başlıkları
| Başlık | Anlamı |
|---|---|
| X-Request-Id | İsteğin kimliği (26 karakter). Destek kaydında bu numarayı verin, istek tek sorguyla bulunur. |
| X-RateLimit-Limit | Bu dakika için geçerli tavan (okuma ve yazma AYRI pencere). |
| X-RateLimit-Remaining | Bu dakika içinde kalan istek hakkı. |
| X-RateLimit-Reset | Pencerenin sıfırlanacağı zaman (unix saniye). |
| Retry-After | Yalnız 429 yanıtında: kaç saniye beklenmeli. |
| ETag | Katalog uçlarında: sonraki istekte If-None-Match ile geri gönderin. |
| Idempotent-Replayed | true ise bu yanıt ÖNCEKİ isteğin saklanan sonucudur; yeni sipariş OLUŞMADI. |
Hatalar
Tüm uçlarda aynı zarf. Dallanmayı code üzerinden yapın: message insan içindir ve zamanla değişebilir, code sabittir. retryable=true olan hatalarda aynı istek bir süre sonra tekrar denenebilir; false olanlarda istek düzeltilmeden tekrar denemek aynı sonucu verir.
details alanı hatanın makine tarafından okunabilir ayrıntısını taşır (gerekli/mevcut tutar, güncel fiyat, hatalı alanlar). Boşsa {} döner.
{
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "Bakiye yetersiz.",
"retryable": false,
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE",
"details": {
"required": "608.90",
"available": "120.00"
}
}
}
| HTTP | code | Anlamı · ne yapmalı | Tekrar |
|---|---|---|---|
| 503 | API_KAPALI | Bayi API servisi geçici olarak kapatıldı (bakım). Bir süre sonra tekrar deneyin; kod tarafında değişiklik gerekmez. | evet |
| 401 | YETKISIZ | Anahtar yok, geçersiz, iptal edilmiş, IP izinli değil ya da hesap bayi değil. Panelden anahtarı ve IP listesini kontrol edin. Anahtar sızdıysa iptal edip yenisini üretin. | hayır |
| 403 | BAYI_ASKIDA | Bayilik askıya alınmış. Destek ile görüşülmeli; tekrar denemek çözmez. | hayır |
| 403 | API_ERISIMI_KAPALI | Bayilik aktif ama hesapta API erişimi kapalı. Bayi temsilcinizle görüşün; erişim yönetim tarafından açılır. | hayır |
| 403 | KAPSAM_YOK | Anahtar geçerli ama bu uç için gereken yetki kapsamı seçilmemiş. Panelden bu kapsamı içeren yeni bir anahtar üretin (kapsam sonradan eklenemez). | hayır |
| 429 | RATE_LIMITED | İstek tavanı aşıldı. Retry-After başlığındaki saniye kadar bekleyin. Okuma ve yazma tavanları AYRI penceredir. | evet |
| 400 | BAD_REQUEST | İstek biçimi hatalı: eksik alan, geçersiz değer ya da Idempotency-Key yok. Mesajı okuyup gövdeyi düzeltin; aynı istek tekrarlanırsa aynı hatayı alır. | hayır |
| 404 | NOT_FOUND | Kayıt ya da uç bulunamadı. Kimliği ve adresi doğrulayın. Başka bayinin siparişi de "bulunamadı" döner (varlığını sızdırmayız). | hayır |
| 405 | METHOD_NOT_ALLOWED | Uç bu HTTP metodunu kabul etmiyor. Doğru metot bu sayfadaki uç listesinde yazıyor. | hayır |
| 422 | INSUFFICIENT_BALANCE | Bakiye yetersiz. details.required ve details.available tutarları yanıtta döner. Bakiye yükleyip tekrar deneyin. | hayır |
| 422 | PRICE_CHANGED | Gönderdiğiniz expectedPrice güncel fiyattan farklı; sipariş VERİLMEDİ. details.current güncel fiyatı taşır. Kataloğu tazeleyip yeni fiyatla tekrar deneyin. | hayır |
| 422 | OUT_OF_STOCK | Stok yetersiz (waitForStock=false gönderildi). Bir süre sonra tekrar deneyin ya da waitForStock=true ile kuyruğa alın. | evet |
| 422 | INVALID_FIELDS | Zorunlu alanlar eksik ya da uzunluk kısıtına uymuyor. details.fields hatalı alanları listeler. Şemayı GET /catalog/products/{productId} ucundan okuyun. | hayır |
| 422 | INVALID_PLAYER_ID | Oyuncu bilgisi tedarikçi tarafında doğrulanamadı. Sipariş öncesi POST /orders/validate ile kontrol edin; müşteriden doğru kimliği isteyin. | hayır |
| 422 | LIMIT_EXCEEDED | Günlük sipariş limiti ya da kalem başına adet tavanı aşıldı. GET /me ucundaki limits alanına bakın; günlük limit gece sıfırlanır. | hayır |
| 422 | PRODUCT_DISABLED | Ürün satışta değil ya da fiyatı tanımlı değil. Kataloğu tazeleyin; ürün geri açıldığında product.enabled olayı gelir. | hayır |
| 422 | PRODUCT_NOT_ALLOWED | Ürün bayi kanalından satılamaz. Bu ürünler katalog uçlarında da listelenmez; sipariş gövdesinden çıkarın. | hayır |
| 422 | NOT_CANCELLABLE | GB (oyun parası) kalemi bu uçtan iptal edilemez; teslimat elle yapılır. İptal için destek ekibine yazın. Aynı siparişteki e-pin/top-up kalemleri normal şekilde iptal edilir. | hayır |
| 422 | MIN_QTY | Ürünün asgari sipariş adedinin altında kalındı. Katalogdaki limits.minQty değerini kullanın. | hayır |
| 409 | IDEMPOTENCY_MISMATCH | Aynı Idempotency-Key daha önce FARKLI bir gövdeyle kullanıldı. Her yeni sipariş için yeni anahtar üretin (kendi sipariş numaranız + deneme sayacı iyi bir kalıp). | hayır |
| 409 | ORDER_IN_PROGRESS | Aynı anahtarla bir sipariş şu an işleniyor. Birkaç saniye bekleyip GET /orders/by-ref/{externalRef} ile sonucu okuyun. | evet |
| 501 | NOT_IMPLEMENTED | Uç ilan edildi ama henüz çalışmıyor. Şu anda bu kodu döndüren uç YOK; listede tarihsel bütünlük için duruyor. | hayır |
| 500 | INTERNAL | Beklenmeyen sunucu hatası. Tekrar deneyin; sürerse X-Request-Id ile destek kaydı açın. | evet |
İstek limitleri
Anahtar başına dakikalık tavan: okuma 300, yazma 60 (sipariş dahil). OKUMA VE YAZMA AYRI PENCEREDİR: toplu katalog çekimi sipariş verme hakkınızı yemez. HEAD istekleri okuma sayılır.
Her yanıtta X-RateLimit-Limit, X-RateLimit-Remaining ve X-RateLimit-Reset başlıkları döner. Aşımda 429 + Retry-After saniyesi gelir; bekleyip devam edin.
Tam kataloğu dakikada bir çekmeyin: ETag/If-None-Match ile 304 alın, fiyat değişimini price.changed olayından ya da GET /catalog/prices?since= deltasından okuyun.
Hesap & bakiye
Anahtarın hangi hesaba bağlı olduğu, limitler ve para.
Anahtar sağlık kontrolü #
Bayi kimliği, firma adı, kademe, kullanılabilir bakiye, günlük limit ve anahtarın kapsamları. mode alanı "live" ya da "test" döner; entegrasyonun ilk isteği bu olmalı. Kapsam İSTEMEZ: hangi kapsamla üretilmiş olursa olsun geçerli her anahtar kendini doğrulayabilir.
curl "https://oyuneks.com/bayi-api/v1/me" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"dealerId": 385841,
"company": "ÖRNEK BİLİŞİM LTD. ŞTİ.",
"tier": "Bronz",
"tierId": 1,
"balance": "48250.00",
"currency": "TRY",
"limits": {
"dailyPurchase": "250000.00",
"dailyUsed": "1200.00",
"maxQtyPerOrder": 500
},
"apiEnabled": true,
"key": {
"name": "Canlı anahtar",
"masked": "oyxb_live_a91f...3c0e",
"scopes": [
"catalog:read",
"orders:read",
"orders:write",
"balance:read"
],
"rateReadPerMin": 300,
"rateWritePerMin": 60
},
"apiVersion": "v1",
"serverTime": "2026-08-28T14:05:00+03:00"
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Kullanılabilir bakiye #
Kullanılabilir bakiye, bloke tutar, onay bekleyen havale toplamı ve kırılım (bakiye + iade edilebilir + bonus). available değeri SİPARİŞ KAPISININ okuduğu ile aynı sayıdır; başka bir toplama yazılsa bot "param var" der ama sipariş INSUFFICIENT_BALANCE yerdi.
curl "https://oyuneks.com/bayi-api/v1/balance" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"available": "48250.00",
"blocked": "0.00",
"breakdown": {
"balance": "46250.00",
"refundable": "1500.00",
"bonus": "500.00"
},
"pendingDeposits": "5000.00",
"currency": "TRY",
"asOf": "2026-08-28T14:05:00+03:00"
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Cari hareketler (imleçli) #
Cari hareket defteri. Sipariş hareketlerinde tutar EKSİ işaretli döner ve orderId + externalRef alanları dolar; balanceAfter ile mutabakat yapılır. Sayfalama imleçli: yanıttaki nextCursor değerini ?cursor= ile geri gönderin.
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| from | query | string | hayır | Başlangıç tarihi (dahil). Okunamayan tarih sessizce yok sayılır. |
| to | query | string | hayır | Bitiş tarihi (dahil). |
| type | query |
string
order | refund | deposit | adjustment | other |
hayır | Hareket tipi süzgeci. Listede olmayan tipler "other" döner ve typeId alanı ham değeri taşır. |
| cursor | query | string | hayır | Önceki yanıttaki nextCursor. Yalnız rakam kabul edilir. |
| limit | query |
integer
varsayılan: 50 |
hayır | Sayfa boyu (1-200). |
curl "https://oyuneks.com/bayi-api/v1/balance/transactions?from=2026-08-01&to=2026-08-28" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"items": [
{
"id": 3012402,
"type": "order",
"typeId": 1,
"amount": "-197.40",
"balanceAfter": "48052.60",
"orderId": 184213,
"externalRef": "SIP-2026-0001",
"description": "Sipariş ödemesi",
"createdAt": "2026-08-28T14:05:00+03:00"
},
{
"id": 3012301,
"type": "deposit",
"typeId": 2,
"amount": "25000.00",
"balanceAfter": "48250.00",
"orderId": null,
"externalRef": null,
"description": "Havale",
"createdAt": "2026-08-28T09:12:00+03:00"
}
],
"nextCursor": "3012301",
"currency": "TRY"
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 400 | BAD_REQUEST | İstek biçimi hatalı: eksik alan, geçersiz değer ya da Idempotency-Key yok. Mesajı okuyup gövdeyi düzeltin; aynı istek tekrarlanırsa aynı hatayı alır. | hayır |
Katalog & fiyat
Ürün kimliği, bayi fiyatınız, stok ve zorunlu alan şeması. Kimlik ve alan adı UYDURULMAZ, hep buradan okunur.
Oyun listesi #
Bayiye satılan ürünü olan oyunlar (üst kategoriler), her oyunun altındaki kategoriler (categories) ve ürün sayıları. Ürün listesinde category süzgecine categories[].category verilir. Ürün listesindeki game süzgecine BURADAKİ slug verilir, kategori kimliği değil: kimlikler yönetimde birleştirme sırasında değişebilir, slug adresin parçası olduğu için sabit kalmak zorundadır.
ETag döner. Sonraki istekte If-None-Match ile gönderin: gövde değişmediyse 304 alırsınız (gövde harcanmaz).
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| If-None-Match | header | string | hayır | Önceki yanıtın ETag değeri. Gövde değişmediyse 304 döner. |
curl "https://oyuneks.com/bayi-api/v1/catalog/games" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"items": [
{
"game": "pubg-mobile",
"name": "PUBG Mobile",
"categoryId": 25,
"productCount": 34,
"categories": [
{
"category": "pubg-mobile-uc",
"name": "PUBG Mobile UC",
"categoryId": 251,
"productCount": 34
}
]
},
{
"game": "knight-online",
"name": "Knight Online",
"categoryId": 12,
"productCount": 18,
"categories": []
}
]
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Ürün listesi (imleçli) #
Bayi fiyatı, liste fiyatı, stok durumu, adet sınırları, zorunlu alan şeması ve teslim tahmini. type=goldbar ürünlerde delivery.mode=manual gelir (kod dönmez, operatör oyun içi teslim eder) ve deliveryNote teslimat yerini yazar. price SİZİN fiyatınızdır (kademe + size özel istisna uygulanmış), listPrice sitedeki perakende fiyat. ETag döner: sonraki istekte If-None-Match ile gönderin, değişmediyse 304 alırsınız ve gövde harcanmaz.
ETag döner. Sonraki istekte If-None-Match ile gönderin: gövde değişmediyse 304 alırsınız (gövde harcanmaz).
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| type | query |
string
epin | topup | goldbar |
hayır | epin = kod teslim edilir, topup = oyuncu hesabına yükleme yapılır (kod yok, makbuz döner), goldbar = oyun parası (GB); karakter adına oyun içi elle teslim edilir, kod dönmez. Başka değer 400 döner. |
| game | query | string | hayır | Oyun slug'ı (GET /catalog/games listesinden). |
| category | query | string | hayır | Alt kategori slug'ı (GET /catalog/games içindeki categories[].category). game ile birlikte ya da tek başına kullanılabilir. |
| q | query | string | hayır | Ürün, oyun ya da kategori adında arama. |
| inStock | query | boolean | hayır | 1 gönderilirse yalnız stokta olanlar döner ("0", "false", "no", "off" ve boş değer kapalı sayılır). |
| updatedSince | query | string | hayır | HENÜZ UYGULANMIYOR: üründe güncelleme damgası tutulmadığı için tam liste döner ve yanıtta note alanı bunu açıkça söyler. Artımlı senkron için ETag ya da GET /catalog/prices?since= kullanın. |
| cursor | query | string | hayır | Önceki yanıttaki nextCursor (son ürün kimliği). |
| limit | query |
integer
varsayılan: 50 |
hayır | Sayfa boyu (1-200). |
| If-None-Match | header | string | hayır | Önceki yanıtın ETag değeri. |
curl "https://oyuneks.com/bayi-api/v1/catalog/products?type=epin&game=pubg-mobile" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"items": [
{
"productId": 6,
"name": "Knight Online 1020 Cash",
"type": "epin",
"game": "knight-online",
"category": "knight-online-cash",
"region": null,
"listPrice": "105.00",
"price": "98.70",
"currency": "TRY",
"vatIncluded": true,
"stock": {
"mode": "count",
"count": 420
},
"limits": {
"minQty": 1,
"maxQty": 500
},
"requiredFields": [],
"delivery": {
"mode": "instant",
"etaSeconds": 5
},
"enabled": true,
"updatedAt": null
},
{
"productId": 1421,
"name": "PUBG Mobile 660 UC",
"type": "topup",
"game": "pubg-mobile",
"category": "pubg-mobile-uc",
"region": null,
"listPrice": "428.90",
"price": "411.50",
"currency": "TRY",
"vatIncluded": true,
"stock": {
"mode": "instant"
},
"limits": {
"minQty": 1,
"maxQty": 500
},
"requiredFields": [
{
"key": "playerId",
"label": "Oyuncu ID",
"type": "string",
"minLength": 8,
"maxLength": 12,
"required": true,
"pattern": "^.{8,12}$",
"placeholder": null
}
],
"delivery": {
"mode": "instant",
"etaSeconds": 30
},
"enabled": true,
"updatedAt": null
}
],
"nextCursor": "1421",
"count": 2
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 400 | BAD_REQUEST | İstek biçimi hatalı: eksik alan, geçersiz değer ya da Idempotency-Key yok. Mesajı okuyup gövdeyi düzeltin; aynı istek tekrarlanırsa aynı hatayı alır. | hayır |
Tek ürün #
Tek ürünün tam görünümü. Ürün başına zorunlu alan ŞEMASI burada yayınlanır: alan anahtarları (playerId, server, zoneId, character...) ürün başlıklarından türetilir. Bot bunları uydurmaz, buradan okur; sıra değil ANAHTAR ADI önemlidir.
ETag döner. Sonraki istekte If-None-Match ile gönderin: gövde değişmediyse 304 alırsınız (gövde harcanmaz).
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| productId | path | integer | evet | Ürün kimliği (yalnız rakam). |
| If-None-Match | header | string | hayır | Önceki yanıtın ETag değeri. |
curl "https://oyuneks.com/bayi-api/v1/catalog/products/1421" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"productId": 1421,
"name": "PUBG Mobile 660 UC",
"type": "topup",
"game": "pubg-mobile",
"category": "pubg-mobile-uc",
"region": null,
"listPrice": "428.90",
"price": "411.50",
"currency": "TRY",
"vatIncluded": true,
"stock": {
"mode": "instant"
},
"limits": {
"minQty": 1,
"maxQty": 500
},
"requiredFields": [
{
"key": "playerId",
"label": "Oyuncu ID",
"type": "string",
"minLength": 8,
"maxLength": 12,
"required": true,
"pattern": "^.{8,12}$",
"placeholder": null
}
],
"delivery": {
"mode": "instant",
"etaSeconds": 30
},
"enabled": true,
"updatedAt": null
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 404 | NOT_FOUND | Kayıt ya da uç bulunamadı. Kimliği ve adresi doğrulayın. Başka bayinin siparişi de "bulunamadı" döner (varlığını sızdırmayız). | hayır |
Fiyat/stok dökümü ve delta #
Ürün listesinin hafif sürümü: yalnız productId, fiyat, stok, satışta mı. Fiyat senkronu yapan botlar için. ?since verilirse GERÇEK DELTA döner (o tarihten sonra fiyatı/stoğu/durumu değişen ürünler, her satırda gerçek updatedAt). Anlık görüntü henüz oluşmamış bir hesapta süzgeç UYGULANMAZ: tam liste + uyarı notu döner, çünkü boş liste botun "değişim yok" sanıp fiyat senkronunu hiç yapmaması demek olurdu.
ETag döner. Sonraki istekte If-None-Match ile gönderin: gövde değişmediyse 304 alırsınız (gövde harcanmaz).
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| since | query | string | hayır | Bu andan sonra değişen ürünler. Okunamayan değerde tam liste + note döner. |
| cursor | query | string | hayır | Önceki yanıttaki nextCursor. |
| limit | query |
integer
varsayılan: 200 |
hayır | Sayfa boyu (1-200). |
| If-None-Match | header | string | hayır | Önceki yanıtın ETag değeri. |
curl "https://oyuneks.com/bayi-api/v1/catalog/prices?since=2026-08-28T09%3A00%3A00%2B03%3A00&limit=200" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"items": [
{
"productId": 6,
"listPrice": "105.00",
"price": "96.20",
"currency": "TRY",
"stock": {
"mode": "count",
"count": 418
},
"enabled": true,
"updatedAt": "2026-08-28T14:30:00+03:00"
}
],
"nextCursor": null,
"count": 1,
"asOf": "2026-08-28T14:35:00+03:00"
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Hesap doğrulama
Top-up ürünlerinde oyuncu bilgisini yüklemeden ÖNCE sorun.
Oyuncu bilgisini önceden doğrula #
Top-up ürünlerinde oyuncu bilgisini tedarikçiye ÖNCEDEN sorar; para düşmez. supported=false ise üründe önceden doğrulama yoktur (sipariş vermeyi engellemez). valid=null "şu an kontrol edilemedi" demektir: teknik hata satışı ENGELLEMEZ, aynı kontrol sipariş sırasında çekirdekte tekrar çalışır. Yanıtta requiredFields şeması da döner, böylece hangi alanları göndereceğinizi tek istekte öğrenirsiniz.
İstek gövdesi
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| productId | integer | evet | Ürün kimliği. |
| fields | object | hayır | Ürünün requiredFields şemasındaki anahtarlar ve değerleri. |
curl -X POST "https://oyuneks.com/bayi-api/v1/orders/validate" \
-H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN" \
-H "Content-Type: application/json" \
-d '{"productId":1421,"fields":{"playerId":"5123456789","server":"7012"}}'
{
"data": {
"supported": true,
"valid": true,
"nickname": "OyuncuAdi",
"validUntil": "2026-08-28T14:10:00+03:00",
"requiredFields": [
{
"key": "playerId",
"label": "Oyuncu ID",
"type": "string",
"minLength": 8,
"maxLength": 12,
"validate": true
}
],
"message": null
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 400 | BAD_REQUEST | İstek biçimi hatalı: eksik alan, geçersiz değer ya da Idempotency-Key yok. Mesajı okuyup gövdeyi düzeltin; aynı istek tekrarlanırsa aynı hatayı alır. | hayır |
| 404 | NOT_FOUND | Kayıt ya da uç bulunamadı. Kimliği ve adresi doğrulayın. Başka bayinin siparişi de "bulunamadı" döner (varlığını sızdırmayız). | hayır |
Sipariş
Sipariş verme, okuma ve bekleyen kalem iptali. Panel ile API AYNI çekirdeği kullanır: iki kanal hiçbir zaman farklı fiyat/stok/hata göstermez.
Sipariş ver #
Sipariş verir; tutar bakiyeden düşer. Idempotency-Key başlığı ZORUNLUDUR. Tek istekte en fazla 50 kalem. expectedPrice gönderilirse fiyat değişmişse sipariş VERİLMEZ (PRICE_CHANGED). waitForStock=false ise stok yetmiyorsa hiç başlamaz. Yanıt 201 (sonuç kesin) ya da 202 (teslimat sürüyor). Aynı anahtarla tekrar denerseniz aynı yanıt + Idempotent-Replayed: true başlığı döner, YENİ SİPARİŞ OLUŞMAZ; ağ koptuğunda tekrar göndermek güvenlidir.
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| Idempotency-Key | header | string | evet | Sizin benzersiz referansınız, en fazla 64 karakter. Her YENİ sipariş için yeni anahtar üretin. Anahtar 24 saat hatırlanır. |
İstek gövdesi
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| externalRef | string | hayır | Kendi sipariş numaranız. Raporlarda, cari harekette ve webhook gövdesinde geri döner. |
| waitForStock |
boolean
varsayılan: true |
hayır | true: stok yoksa kuyruğa alınır ve sağlanınca teslim edilir. false: stok yetmiyorsa sipariş hiç başlamaz (OUT_OF_STOCK). |
| items | array | evet | Kalemler (en az 1, en fazla 50). Her kalem: productId (zorunlu), quantity (zorunlu), fields (top-up ürünlerinde şemaya göre), expectedPrice (isteğe bağlı fiyat kilidi). |
curl -X POST "https://oyuneks.com/bayi-api/v1/orders" \
-H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: SIP-2026-0001-1" \
-d '{"externalRef":"SIP-2026-0001","waitForStock":true,"items":[{"productId":6,"quantity":2,"expectedPrice":"98.70"},{"productId":1421,"quantity":1,"fields":{"playerId":"5123456789"}}]}'
{
"data": {
"orderId": 184213,
"externalRef": "SIP-2026-0001",
"channel": "dealer-api",
"status": "delivered",
"mode": "live",
"total": "608.90",
"balanceAfter": "47641.10",
"createdAt": "2026-08-28T14:05:00+03:00",
"items": [
{
"itemId": "184213-1",
"productId": 6,
"name": "Knight Online 1020 Cash",
"quantity": 2,
"unitPrice": "98.70",
"status": "delivered",
"codes": [
{
"code": "KO10-2XQ4-9WPA",
"serial": null,
"expiresAt": null
},
{
"code": "KO10-7MTB-3VZC",
"serial": null,
"expiresAt": null
}
],
"receipt": null,
"failCode": null,
"failReason": null
},
{
"itemId": "184213-2",
"productId": 1421,
"name": "PUBG Mobile 660 UC",
"quantity": 1,
"unitPrice": "411.50",
"status": "delivered",
"codes": [],
"receipt": "TOPUP-9F31A2",
"failCode": null,
"failReason": null
}
]
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
HTTP 202 - En az bir kalem stok bekliyor ya da tedarikçiden çekiliyor (status=processing). Sonucu webhook ile ya da GET /orders/{orderId} ile öğrenin.
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 400 | BAD_REQUEST | İstek biçimi hatalı: eksik alan, geçersiz değer ya da Idempotency-Key yok. Mesajı okuyup gövdeyi düzeltin; aynı istek tekrarlanırsa aynı hatayı alır. | hayır |
| 422 | INSUFFICIENT_BALANCE | Bakiye yetersiz. details.required ve details.available tutarları yanıtta döner. Bakiye yükleyip tekrar deneyin. | hayır |
| 422 | PRICE_CHANGED | Gönderdiğiniz expectedPrice güncel fiyattan farklı; sipariş VERİLMEDİ. details.current güncel fiyatı taşır. Kataloğu tazeleyip yeni fiyatla tekrar deneyin. | hayır |
| 422 | OUT_OF_STOCK | Stok yetersiz (waitForStock=false gönderildi). Bir süre sonra tekrar deneyin ya da waitForStock=true ile kuyruğa alın. | evet |
| 422 | INVALID_FIELDS | Zorunlu alanlar eksik ya da uzunluk kısıtına uymuyor. details.fields hatalı alanları listeler. Şemayı GET /catalog/products/{productId} ucundan okuyun. | hayır |
| 422 | INVALID_PLAYER_ID | Oyuncu bilgisi tedarikçi tarafında doğrulanamadı. Sipariş öncesi POST /orders/validate ile kontrol edin; müşteriden doğru kimliği isteyin. | hayır |
| 422 | LIMIT_EXCEEDED | Günlük sipariş limiti ya da kalem başına adet tavanı aşıldı. GET /me ucundaki limits alanına bakın; günlük limit gece sıfırlanır. | hayır |
| 422 | PRODUCT_DISABLED | Ürün satışta değil ya da fiyatı tanımlı değil. Kataloğu tazeleyin; ürün geri açıldığında product.enabled olayı gelir. | hayır |
| 422 | PRODUCT_NOT_ALLOWED | Ürün bayi kanalından satılamaz. Bu ürünler katalog uçlarında da listelenmez; sipariş gövdesinden çıkarın. | hayır |
| 422 | MIN_QTY | Ürünün asgari sipariş adedinin altında kalındı. Katalogdaki limits.minQty değerini kullanın. | hayır |
| 409 | IDEMPOTENCY_MISMATCH | Aynı Idempotency-Key daha önce FARKLI bir gövdeyle kullanıldı. Her yeni sipariş için yeni anahtar üretin (kendi sipariş numaranız + deneme sayacı iyi bir kalıp). | hayır |
| 409 | ORDER_IN_PROGRESS | Aynı anahtarla bir sipariş şu an işleniyor. Birkaç saniye bekleyip GET /orders/by-ref/{externalRef} ile sonucu okuyun. | evet |
| 422 | PRODUCT_NOT_ALLOWED | Ürün bayi kanalından satılamaz. Bu ürünler katalog uçlarında da listelenmez; sipariş gövdesinden çıkarın. | hayır |
Sipariş detayı ve kodlar #
Sipariş detayı + teslim edilen kodlar. Kodlar YALNIZ bu uçta ve sipariş yanıtında döner; webhook gövdesinde asla gönderilmez. Test modunda verilen siparişlerin kimliği "test_12" biçimindedir ve aynı uçtan okunur. Başka bayinin siparişi 404 döner.
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| orderId | path | string | evet | Sipariş numarası ya da test siparişi kimliği (test_12). |
curl "https://oyuneks.com/bayi-api/v1/orders/184213" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"orderId": 184213,
"externalRef": "SIP-2026-0001",
"channel": "dealer-api",
"status": "partially_delivered",
"mode": "live",
"total": "608.90",
"balanceAfter": "47641.10",
"createdAt": "2026-08-28T14:05:00+03:00",
"items": [
{
"itemId": "184213-1",
"productId": 6,
"name": "Knight Online 1020 Cash",
"quantity": 2,
"unitPrice": "98.70",
"status": "delivered",
"codes": [
{
"code": "KO10-2XQ4-9WPA",
"serial": null,
"expiresAt": null
}
],
"receipt": null,
"failCode": null,
"failReason": null
},
{
"itemId": "184213-2",
"productId": 1421,
"name": "PUBG Mobile 660 UC",
"quantity": 1,
"unitPrice": "411.50",
"status": "failed",
"codes": [],
"receipt": null,
"failCode": "TIMEOUT",
"failReason": "ZAMAN_ASIMI: stok 15 dk icinde saglanamadi"
}
]
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 404 | NOT_FOUND | Kayıt ya da uç bulunamadı. Kimliği ve adresi doğrulayın. Başka bayinin siparişi de "bulunamadı" döner (varlığını sızdırmayız). | hayır |
Kendi referansınızla sipariş bul #
Bayinin kendi referansıyla sipariş bulur (aynı referansla birden fazla kayıt varsa EN SON kayıt). Ağ hatasından sonra "sipariş düştü mü" sorusunun en hızlı yanıtı budur. Test siparişleri de bu uçtan bulunur.
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| externalRef | path | string | evet | Sipariş gövdesinde gönderdiğiniz externalRef (1-64 karakter, / içeremez). |
curl "https://oyuneks.com/bayi-api/v1/orders/by-ref/SIP-2026-0001" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"orderId": 184213,
"externalRef": "SIP-2026-0001",
"channel": "dealer-api",
"status": "delivered",
"mode": "live",
"total": "608.90",
"balanceAfter": "47641.10",
"createdAt": "2026-08-28T14:05:00+03:00",
"items": []
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 404 | NOT_FOUND | Kayıt ya da uç bulunamadı. Kimliği ve adresi doğrulayın. Başka bayinin siparişi de "bulunamadı" döner (varlığını sızdırmayız). | hayır |
Sipariş listesi (imleçli) #
Bayinin siparişleri; panel ve API siparişleri aynı listede (ikisi aynı caridir), channel ile ayrılabilir. productId süzgeci YALNIZ DÖNEN SAYFAYA uygulanır: sipariş içeriği JSON anlık görüntü içinde durduğu için SQL ile aranamaz. Bu durumda yanıtta note alanı çıkar; bot "ürün yok" sanmasın diye susmuyoruz.
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| from | query | string | hayır | Başlangıç tarihi (dahil). |
| to | query | string | hayır | Bitiş tarihi (dahil). |
| status | query |
string
processing | delivered | partially_delivered | cancelled | failed |
hayır | Durum süzgeci. Geçersiz değer 400 döner (sessizce yok sayılmaz). |
| channel | query |
string
dealer-api | dealer-panel |
hayır | Kanal süzgeci. Boş bırakılırsa iki kanal birlikte döner. |
| productId | query | integer | hayır | Yalnız dönen sayfa içinde süzer; sonraki sayfalar için nextCursor ile devam edin. |
| cursor | query | string | hayır | Önceki yanıttaki nextCursor (son sipariş numarası). |
| limit | query |
integer
varsayılan: 25 |
hayır | Sayfa boyu (1-100). |
curl "https://oyuneks.com/bayi-api/v1/orders?from=2026-08-01&to=2026-08-28" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"items": [
{
"orderId": 184213,
"externalRef": "SIP-2026-0001",
"channel": "dealer-api",
"status": "delivered",
"mode": "live",
"total": "608.90",
"balanceAfter": "47641.10",
"createdAt": "2026-08-28T14:05:00+03:00",
"items": [
{
"itemId": "184213-1",
"productId": 6,
"name": "Knight Online 1020 Cash",
"quantity": 2,
"unitPrice": "98.70",
"status": "delivered",
"codes": [],
"receipt": null,
"failCode": null,
"failReason": null
}
]
}
],
"nextCursor": "184213",
"count": 1
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 400 | BAD_REQUEST | İstek biçimi hatalı: eksik alan, geçersiz değer ya da Idempotency-Key yok. Mesajı okuyup gövdeyi düzeltin; aynı istek tekrarlanırsa aynı hatayı alır. | hayır |
Bekleyen kalemleri iptal et #
Yalnız BEKLEYEN (processing) kalemleri iptal eder ve tutarı iade alır. Teslim edilmiş kaleme dokunulmaz: kod sizde, kullanılmamış kod iadesi destek kararıdır. İade ve muhasebe işini kanonik teslimat yolu yapar, bu uç ayrı bir iade yolu açmaz. GB (oyun parası) kalemi bu uçtan iptal EDİLEMEZ (NOT_CANCELLABLE): teslimat elle yapıldığı için iade de elle yapılır, destek ekibine yazın.
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| orderId | path | integer | evet | Sipariş numarası (yalnız rakam; test siparişi iptal edilmez). |
İstek gövdesi
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| reason | string | hayır | İptal gerekçesi (kayda geçer, müşteriye gösterilmez). |
curl -X POST "https://oyuneks.com/bayi-api/v1/orders/184219/cancel" \
-H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN" \
-H "Content-Type: application/json" \
-d '{"reason":"Müşteri vazgeçti"}'
{
"data": {
"orderId": 184219,
"externalRef": "SIP-2026-0007",
"channel": "dealer-api",
"status": "cancelled",
"mode": "live",
"total": "41.90",
"balanceAfter": "48250.00",
"createdAt": "2026-08-28T14:20:00+03:00",
"items": [
{
"itemId": "184219-1",
"productId": 1421,
"name": "PUBG Mobile 660 UC",
"quantity": 1,
"unitPrice": "41.90",
"status": "cancelled",
"codes": [],
"receipt": null,
"failCode": "CANCELLED",
"failReason": "Müşteri vazgeçti"
}
]
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 400 | BAD_REQUEST | İstek biçimi hatalı: eksik alan, geçersiz değer ya da Idempotency-Key yok. Mesajı okuyup gövdeyi düzeltin; aynı istek tekrarlanırsa aynı hatayı alır. | hayır |
| 404 | NOT_FOUND | Kayıt ya da uç bulunamadı. Kimliği ve adresi doğrulayın. Başka bayinin siparişi de "bulunamadı" döner (varlığını sızdırmayız). | hayır |
| 422 | NOT_CANCELLABLE | GB (oyun parası) kalemi bu uçtan iptal edilemez; teslimat elle yapılır. İptal için destek ekibine yazın. Aynı siparişteki e-pin/top-up kalemleri normal şekilde iptal edilir. | hayır |
Raporlar
Ekstre ve fatura. Panel ekstresi, API ekstresi ve fatura AYNI rakamları verir.
Dönem ekstresi (json/csv) #
Açılış bakiyesi, yükleme/sipariş/iade toplamları, kapanış bakiyesi ve hareket satırları. format=csv doğrudan muhasebe programına verilebilecek dosya döner (BOM ile, noktalı virgül ayırıcı, zarf YOK). Dönemde 5000 satır tavanına ulaşılırsa yanıtta note çıkar; aralığı daraltın.
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| from | query |
string
varsayılan: ayın 1'i |
hayır | Başlangıç tarihi. Boşsa içinde bulunulan ayın 1'i. |
| to | query |
string
varsayılan: bugün |
hayır | Bitiş tarihi. from > to ise 400 döner. |
| format | query |
string
json | csv varsayılan: json |
hayır | csv seçilirse dosya indirmesi döner (text/csv). |
curl "https://oyuneks.com/bayi-api/v1/reports/statement?from=2026-08-01&to=2026-08-28" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"from": "2026-08-01",
"to": "2026-08-28",
"currency": "TRY",
"openingBalance": "12500.00",
"deposits": "75000.00",
"orders": "39250.00",
"refunds": "0.00",
"other": "0.00",
"closingBalance": "48250.00",
"count": 2,
"items": [
{
"id": 3012301,
"date": "2026-08-28T09:12:00+03:00",
"typeId": 2,
"amount": "25000.00",
"balanceAfter": "48250.00",
"orderId": null,
"description": "Havale"
},
{
"id": 3012402,
"date": "2026-08-28T14:05:00+03:00",
"typeId": 1,
"amount": "-608.90",
"balanceAfter": "47641.10",
"orderId": 184213,
"description": "Sipariş ödemesi"
}
]
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 400 | BAD_REQUEST | İstek biçimi hatalı: eksik alan, geçersiz değer ya da Idempotency-Key yok. Mesajı okuyup gövdeyi düzeltin; aynı istek tekrarlanırsa aynı hatayı alır. | hayır |
Fatura listesi #
Kesilen faturalar: numara, tarih, tutar, KDV ve panel adresi. PDF/UBL indirme bağlantısı henüz API üzerinden VERİLMİYOR (pdfUrl null): sitedeki fatura görüntüleme ucu oturumlu, imzalı ve süresi kısıtlı bir indirme bağlantısı üretmek yeni bir yetkilendirme yüzeyi açmak demek ve bu sürümün kapsamında değil. Belge panelUrl adresinden görüntülenir.
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| from | query | string | hayır | Başlangıç tarihi (dahil). |
| to | query | string | hayır | Bitiş tarihi (dahil). |
curl "https://oyuneks.com/bayi-api/v1/invoices?from=2026-08-01&to=2026-08-28" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"items": [
{
"invoiceId": 90124,
"number": "OYN2026000012345",
"numbers": [
"OYN2026000012345"
],
"date": "2026-08-01T10:00:00+03:00",
"type": "satis",
"orderNo": "184213",
"total": "608.90",
"vat": "0.00",
"currency": "TRY",
"pdfUrl": null,
"panelUrl": "/faturalarim/90124"
}
],
"count": 1,
"note": "PDF indirme baglantisi henuz API uzerinden verilmiyor; belge panelUrl adresinden (oturumlu) goruntulenir."
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Webhook'lar
Yoklamayı (polling) bırakın: sipariş sonucu, fiyat değişimi ve bakiye yüklemesi imzalı olay olarak size gelir. Bayi başına TEK adres olduğu için PUT /webhooks bir "upsert"tir.
Abonelik durumu #
Adres, abone olunan olaylar, durum (active|suspended), son başarı/hata damgası, üst üste hata sayacı ve MASKELENMİŞ imza sırrı. Ham sır BU UÇTA DÖNMEZ: jetonu okuyabilen biri sırrı da okuyabilseydi imzanın anlamı kalmazdı. Yanıtta abone olunabilecek olayların katalogu da döner.
curl "https://oyuneks.com/bayi-api/v1/webhooks" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"configured": true,
"webhook": {
"id": 214,
"url": "https://bayi.example.com/oyuneks-hook",
"events": [
"order.delivered",
"order.failed",
"price.changed",
"balance.low"
],
"status": "active",
"secretMasked": "whsec_a91f3c********9d0e",
"failStreak": 0,
"lastSuccessAt": "2026-08-28T14:05:00+03:00",
"lastFailureAt": null
},
"availableEvents": {
"order.delivered": "Siparis teslim edildi (kismi teslim de bu olayla gelir)"
}
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Gönderim kaydı (imleçli) #
Olay adı, kanal (webhook|email), durum (pending|sent|dead), deneme sayısı, HTTP kodu, süre ve hata metni. Olay GÖVDESİ döndürülmez; gövdeyi ikinci bir yerden yayınlamak gereksiz yüzey olurdu. Yeniden gönderim şu an yalnız Bayi Panelinden yapılır. Yanıtta yeniden deneme tablosu da döner.
| Ad | Yer | Tip | Zorunlu | Açıklama |
|---|---|---|---|---|
| cursor | query | string | hayır | Önceki yanıttaki nextCursor. |
| limit | query |
integer
varsayılan: 50 |
hayır | Sayfa boyu (1-200). |
curl "https://oyuneks.com/bayi-api/v1/webhooks/deliveries?limit=50" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"items": [
{
"id": 9214,
"eventId": "evt_o184213_d",
"type": "order.delivered",
"channel": "webhook",
"mode": "live",
"status": "sent",
"attempts": 1,
"httpCode": 200,
"durationMs": 184,
"error": null,
"createdAt": "2026-08-28T14:05:01+03:00",
"nextAttemptAt": null,
"sentAt": "2026-08-28T14:05:02+03:00"
}
],
"nextCursor": "9214",
"count": 1,
"retry": {
"maxAttempts": 8,
"backoffMinutes": [
2,
4,
8,
16,
32,
64,
128
],
"note": "Tavan 720 dakikadir. 8 denemede cevap alinamazsa olay olu sayilir."
}
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Aboneliği oluştur/güncelle #
Bayi başına TEK adres olduğu için bu bir "upsert"tir. Adres yalnız https olabilir; localhost ve özel ağ adresleri reddedilir (SSRF). İLK KAYITTA imza sırrı yanıtta BİR KEZ döner, bir daha gösterilmez. Adres değiştirilirse askı (varsa) kalkar. Bilinmeyen olay adı sessizce düşürülmez, 400 ile söylenir: yoksa bot "abone oldum" sanıp olayı beklerdi. events boş gönderilirse varsayılan set uygulanır. POST /webhooks aynı işe bağlıdır.
Eş adresler (aynı işi yapar):
POST /bayi-api/v1/webhooks
İstek gövdesi
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| url | string | evet | https adresi. Yönlendirme (3xx) İZLENMEZ, nihai adresi yazın. |
| events | array | hayır | Olay adları. Boş bırakılırsa varsayılan set (order.delivered, order.failed, price.changed, balance.low). |
curl -X PUT "https://oyuneks.com/bayi-api/v1/webhooks" \
-H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN" \
-H "Content-Type: application/json" \
-d '{"url":"https://bayi.example.com/oyuneks-hook","events":["order.delivered","order.failed","price.changed","balance.low"]}'
{
"data": {
"webhook": {
"id": 214,
"url": "https://bayi.example.com/oyuneks-hook",
"events": [
"order.delivered",
"order.failed",
"price.changed",
"balance.low"
],
"status": "active",
"secretMasked": "whsec_a91f3c********9d0e",
"failStreak": 0,
"lastSuccessAt": null,
"lastFailureAt": null
},
"signature": {
"header": "X-Oyuneks-Signature",
"format": "t=<unix>,v1=<hex>",
"algorithm": "HMAC-SHA256"
},
"secret": "whsec_a91f3c7d2b8e4f16a05c9d0e",
"secretNote": "Bu sir yalniz bu yanitta doner."
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 400 | BAD_REQUEST | İstek biçimi hatalı: eksik alan, geçersiz değer ya da Idempotency-Key yok. Mesajı okuyup gövdeyi düzeltin; aynı istek tekrarlanırsa aynı hatayı alır. | hayır |
İmza sırrını yenile #
Yeni imza sırrı üretir ve BİR KEZ döndürür. Eski sır ANINDA geçersizdir: iki geçerli sır tutmak, sızan sırrı iptal etmeyi anlamsız kılardı. Yeni sırrı yazana kadar gelen olayların imzası doğrulanamaz, bu yüzden dağıtımı hemen yapın.
curl -X POST "https://oyuneks.com/bayi-api/v1/webhooks/rotate-secret" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"secret": "whsec_2f7c81a94de0b3c65a1f8d42",
"secretNote": "Eski sir ANINDA gecersizdir.",
"webhook": {
"id": 214,
"url": "https://bayi.example.com/oyuneks-hook",
"events": [
"order.delivered"
],
"status": "active",
"secretMasked": "whsec_2f7c81********8d42"
},
"signature": {
"header": "X-Oyuneks-Signature",
"format": "t=<unix>,v1=<hex>",
"algorithm": "HMAC-SHA256"
}
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 400 | BAD_REQUEST | İstek biçimi hatalı: eksik alan, geçersiz değer ya da Idempotency-Key yok. Mesajı okuyup gövdeyi düzeltin; aynı istek tekrarlanırsa aynı hatayı alır. | hayır |
Test olayı gönder (ping) #
"ping" olayını ANINDA gönderir (kuyruğa girmez, yeniden denenmez) ve HTTP sonucunu döndürür. Adres cevap vermezse yanıt YİNE 200 olur, gövdedeki delivered=false bakılır: istek doğru işlendi, gönderim başarısız. 502 döndürmek botu "benim isteğim hatalı" sanmaya iterdi. POST /webhooks/{webhookId}/test aynı işe bağlıdır.
Eş adresler (aynı işi yapar):
POST /bayi-api/v1/webhooks/{webhookId}/test
curl -X POST "https://oyuneks.com/bayi-api/v1/webhooks/test" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"delivered": true,
"eventId": "evt_01K3QF6ZC2M9V0X7NB4TDHR8YE",
"httpCode": 200,
"durationMs": 184,
"error": null
},
"mode": "test",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 400 | BAD_REQUEST | İstek biçimi hatalı: eksik alan, geçersiz değer ya da Idempotency-Key yok. Mesajı okuyup gövdeyi düzeltin; aynı istek tekrarlanırsa aynı hatayı alır. | hayır |
Aboneliği sil #
Aboneliği siler; kuyrukta bekleyen olaylar ölü işaretlenir. DELETE /webhooks/{webhookId} de kabul edilir; kimlik başka bayiye aitse 404 döner (varlığını sızdırmayız). Silmek yerine olay listesini daraltmak genelde daha iyidir: adres silindiğinde teslim bildirimlerini de kaybedersiniz.
Eş adresler (aynı işi yapar):
DELETE /bayi-api/v1/webhooks/{webhookId}
curl -X DELETE "https://oyuneks.com/bayi-api/v1/webhooks" \ -H "Authorization: Bearer oyxb_test_KENDI_ANAHTARIN"
{
"data": {
"deleted": true
},
"mode": "live",
"requestId": "01K3QF6ZC2M9V0X7NB4TDHR8YE"
}
Bu uca özel hatalar
| HTTP | code | Anlamı | Tekrar |
|---|---|---|---|
| 404 | NOT_FOUND | Kayıt ya da uç bulunamadı. Kimliği ve adresi doğrulayın. Başka bayinin siparişi de "bulunamadı" döner (varlığını sızdırmayız). | hayır |
MCP ile bağlanma
MCP (Model Context Protocol), yapay zeka istemcilerinin bir sisteme araçlarla bağlandığı açık protokoldür: Claude gibi bir istemciye Oyuneks bayi hesabınızı bağlar, "60 UC fiyatı ne, 5 tane sipariş ver, dünkü siparişlerimi göster" gibi işleri kod yazmadan yaptırırsınız.
Adres tek: /bayi-api/mcp (JSON-RPC 2.0, oturumsuz). Kimlik /bayi-api/v1 ile AYNI anahtardır; mod anahtarın önekinden gelir (oyxb_test_ / oyxb_live_) ve her araç yanıtında "mode" alanı döner. Araçlar bu API'nin üstünde ince bir çeviricidir: her çağrı gerçek /bayi-api/v1 ucuna gider, aynı kapsam, aynı istek tavanı, aynı denetim kaydı.
Yapay zeka fiyatı kendi yazamaz: ürün kimliği, fiyat ve zorunlu alanlar katalog araçlarından okunur. Para harcayan iki araçta (sipariş verme, sipariş iptali) İKİ ADIMLI ONAY vardır: araç ilk çağrıldığında hiçbir şey yapılmaz, ürün/adet/birim ve toplam fiyat/bakiye sonrası/mod özeti ile 5 dakikalık bir onay jetonu döner; siz onaylarsanız araç aynı jetonla tekrar çağrılır ve sipariş o zaman verilir.
Teslim edilen kodlar araç yanıtlarında MASKELİDİR (son 4 hane). Açık kod ancak siz istediğinizde döner. Sipariş tekrarına karşı onay jetonundan türeyen Idempotency-Key kullanılır: aynı onayla tekrarlanan çağrı aynı siparişi döndürür, ikinci sipariş oluşmaz.
claude mcp add --transport http oyuneks-bayi https://oyuneks.com/bayi-api/mcp --header "Authorization: Bearer <anahtar>"
| Araç | Uç | Kapsam | İki adım | Ne yapar |
|---|---|---|---|---|
| bayi_bilgim | GET /bayi-api/v1/me | (herhangi) + balance:read | hayır | Bayi kimliği, firma, kademe, kullanılabilir bakiye, günlük limit ve anahtarın modu (canlı/test). |
| katalog_ara | GET /bayi-api/v1/catalog/products | catalog:read | hayır | Ürün arar: productId, bayi fiyatı, stok, zorunlu alan şeması ve adet sınırları. Sipariş öncesi zorunlu keşif adımı. |
| fiyat_degisiklikleri | GET /bayi-api/v1/catalog/prices | catalog:read | hayır | Verilen tarihten bu yana fiyatı, stoğu ya da satış durumu değişen ürünler (fiyat senkronu). |
| hesap_dogrula | POST /bayi-api/v1/orders/validate | orders:write | hayır | Top-up ürününde oyuncu hesabını tedarikçiye sorar, hesap adını döner. |
| siparis_ver | POST /bayi-api/v1/orders | orders:write | evet | Sipariş verir. İKİ ADIMLI: önce ürün/adet/fiyat/bakiye özeti + onay jetonu, onaydan sonra sipariş. |
| siparislerim | GET /bayi-api/v1/orders | orders:read | hayır | Siparişleri listeler (durum, kaynak, tarih süzgeci). Kodlar bu listede her zaman maskelidir. |
| siparis_detayi | GET /bayi-api/v1/orders/{siparisNo} | orders:read | hayır | Tek siparişin detayı; sipariş numarası ya da kendi referansınızla. Kod isteğe bağlı olarak açık gösterilir. |
| siparis_iptal | POST /bayi-api/v1/orders/{siparisNo}/cancel | orders:write | evet | Bekleyen kalemleri iptal eder ve tutarı bakiyeye iade eder. İKİ ADIMLI onay ister. |
| ekstre | GET /bayi-api/v1/reports/statement | balance:read | hayır | Dönem ekstresi: açılış/kapanış bakiyesi, yükleme, sipariş, iade toplamları ve hareket satırları. |
| webhook_ayarim | GET /bayi-api/v1/webhooks | webhooks:manage | hayır | Webhook aboneliğini gösterir (adres, olaylar, durum). Adres değiştirme panelden yapılır. |
| webhook_test | POST /bayi-api/v1/webhooks/test | webhooks:manage | hayır | Kayıtlı webhook adresine imzalı bir ping olayı gönderir ve sonucu döner. |
- claude.ai özel bağlayıcı (web ve telefon): bağlayıcı adresi olarak https://oyuneks.com/bayi-api/mcp yazın ve "OAuth ile giriş" akışını izleyin. Oyuneks'e yönlendirilirsiniz, hangi yetkileri vereceğinizi ve CANLI mı TEST mi anahtar verileceğini seçersiniz. Varsayılan test.
- OAuth ile bağlanmak için hesabınızda İKİ ADIMLI DOĞRULAMA açık olmalı (Google Authenticator, SMS ya da e-posta kodu). Açık değilse onay ekranı izin vermez: Hesabım > Güvenlik ve Bildirim ekranından açın.
- OAuth ile verilen erişim, panelde sıradan bir API anahtarı olarak görünür (adı "OAuth: <uygulama>"). Bağlantıyı kesmek için o anahtarı iptal etmek yeterlidir.
- Önce TEST anahtarıyla bağlanın: akış gerçek, para düşmez, kodlar TEST- öneklidir. Canlıya geçiş sadece anahtarı değiştirmektir.
- Program yazıyorsanız MCP'ye gerek yok: /bayi-api/v1 uçlarını doğrudan çağırmak daha hızlı ve daha ucuzdur. MCP, aradaki insanın yapay zeka ile çalıştığı durum için.
Durum makinesi
Kalem durumu ile sipariş durumu ayrıdır: teslim/iptal kalem bazında olur, sipariş durumu kalemlerden türetilir. Bekleyen kalem 15 dakika içinde teslim edilemezse otomatik başarısız sayılır ve tutarı iade edilir (failCode=TIMEOUT).
| Sipariş | Kalem | Anlamı | Son durum? |
|---|---|---|---|
| processing | processing | Ödendi, teslimat sürüyor: stok bekleniyor ya da tedarikçiden çekiliyor. HTTP 202 ile döner. | hayır |
| delivered | delivered | Tüm kalemler teslim edildi (e-pin'de kod, top-up'ta makbuz). | evet |
| partially_delivered | — | Bazı kalemler teslim, bazıları iptal/iade edildi. İade tutarı cari harekette refund olarak görünür. | evet |
| cancelled | cancelled | Bekleyen kalemler iptal edildi ve tutar iade alındı (siz iptal ettiniz ya da destek iptal etti). | evet |
| failed | failed | Zaman aşımı: stok verilen süre içinde sağlanamadı, tutar iade edildi. Kalemde failCode=TIMEOUT. | evet |
Olay katalogu
Panelden ya da webhooks:manage kapsamıyla API'den bir https adresi ve olay listesi kaydedersiniz. Her olay imzalı POST ile size gönderilir.
| Olay | Ne zaman |
|---|---|
| order.delivered | Siparis teslim edildi (kismi teslim de bu olayla gelir) |
| order.failed | Siparis basarisiz/iptal: tutar bakiyeye iade edildi |
| price.changed | Bayi fiyatin degisti |
| stock.changed | Urunun stok durumu degisti |
| product.enabled | Urun yeniden satista |
| product.disabled | Urun satistan cikti |
| balance.low | Bakiye esigin altina dustu |
| balance.credited | Bakiyene yukleme yapildi |
| ping | Panelden/API'den "test et" denildiğinde gönderilir. Abonelik gerektirmez, kuyruğa girmez, yeniden denenmez. mode alanı "test" gelir. |
Gönderdiğimiz başlıklar
| Başlık | Değer |
|---|---|
| X-Oyuneks-Event | Olay adı (order.delivered, price.changed, ping...). |
| X-Oyuneks-Event-Id | Olay kimliği. AYNI KİMLİK İKİ KEZ GELEBİLİR (ağ hatası sonrası yeniden deneme); ikinci gelişi yok sayın. |
| X-Oyuneks-Signature | t=<unix saniye>,v1=<hex HMAC-SHA256> |
| User-Agent | Oyuneks-Bayi-Webhook/1.0 |
| Content-Type | application/json |
{
"id": "evt_o184213_d",
"type": "order.delivered",
"mode": "live",
"createdAt": "2026-08-28T14:05:02+03:00",
"data": {
"orderId": 184213,
"externalRef": "SIP-2026-0001",
"channel": "dealer-api",
"status": "delivered",
"total": "197.40",
"currency": "TRY",
"createdAt": "2026-08-28T14:05:00+03:00",
"items": [
{
"itemId": "184213-1",
"productId": 6,
"name": "1020 Cash",
"quantity": 2,
"status": "delivered",
"unitPrice": "98.70",
"codeCount": 2
}
]
}
}
İmza
- Algoritma: HMAC-SHA256
- İmzalanan:
t + "." + HAM istek gövdesi - Anahtar: Panelden ya da rotate-secret ucundan alınan sır (whsec_ ile başlar).
- Tolerans: 300 saniyeden eski t değerini reddedin (tekrar oynatma koruması).
- JSON'i çözüp yeniden serileştirirseniz imza TUTMAZ; ham gövdeyi kullanın (PHP: file_get_contents("php://input")).
<?php
// HAM govde sart: json_decode + json_encode ile imza TUTMAZ.
$ham = file_get_contents("php://input");
$imza = $_SERVER["HTTP_X_OYUNEKS_SIGNATURE"] ?? "";
$t = null; $v1 = null;
foreach (explode(",", $imza) as $parca) {
list($ad, $deger) = array_pad(explode("=", trim($parca), 2), 2, null);
if ($ad === "t") { $t = $deger; }
if ($ad === "v1") { $v1 = $deger; }
}
// 5 dakikadan eski istegi reddet (tekrar oynatma korumasi).
if ($t === null || abs(time() - (int) $t) > 300) { http_response_code(400); exit; }
$beklenen = hash_hmac("sha256", $t . "." . $ham, "whsec_SIZIN_SIRRINIZ");
if (!hash_equals($beklenen, (string) $v1)) { http_response_code(401); exit; }
$olay = json_decode($ham, true);
// Ayni olay iki kez gelebilir: id ile tekillestir, isi ASENKRON yap.
kuyrugaAl($olay["id"], $olay["type"], $olay["data"]);
http_response_code(200);
import crypto from "node:crypto";
// express: app.post("/oyuneks-hook", express.raw({ type: "application/json" }), ...)
function dogrula(hamGovde, imzaBasligi, sir) {
const parcalar = Object.fromEntries(
String(imzaBasligi).split(",").map((p) => p.trim().split("="))
);
const t = Number(parcalar.t);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;
const beklenen = crypto
.createHmac("sha256", sir)
.update(t + "." + hamGovde)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(beklenen), Buffer.from(parcalar.v1));
}
Yanıtınız ve yeniden deneme
- 2xx. Gövde okunmaz, boş yanıt yeterlidir. Bağlantı 3 saniye, toplam 5 saniye. İşi ASENKRON yapın: olayı kaydedip hemen 200 dönün.
- 3xx izlenmez (302 ile iç ağa yönlendirme girişimlerine kapalı). Nihai adresi yazın.
-
Yeniden deneme aralıkları (dakika):
2, 4, 8, 16, 32, 64, 128. 8 denemede 2xx alınamazsa olay "ölü" sayılır ve gönderim kaydında öyle görünür. - Üst üste 8 ölü olayda adres ASKIYA alınır: gönderim durur, bayiye e-posta + site içi bildirim gider, panelden "Yeniden etkinleştir" gerekir.
Mutabakat
Webhook yardımcıdır, KAYNAK DEĞİLDİR. Gün sonunda GET /bayi-api/v1/balance/transactions ile defteri çekin: her order satırı bir orderId ve varsa externalRef taşır, balanceAfter ile bakiye zinciri kontrol edilir.
Aynı olay birden fazla gelebilir (ağ hatası sonrası yeniden deneme): olayları id alanı ile tekilleştirin. Sıra garanti edilmez; siparişin SON hâli için GET /bayi-api/v1/orders/{orderId} okunur.
Panel ekstresi, API ekstresi ve fatura aynı rakamları verir. 1 kuruş fark görürseniz X-Request-Id ile destek kaydı açın.
Sürüm & değişiklikler
Sürüm ADRESTEDİR (/v1). Yeni alan eklemek kırıcı değişiklik SAYILMAZ: bilmediğiniz alanları yok sayacak şekilde kod yazın. Alan kaldırma ya da anlam değişikliği yeni sürümde yapılır ve eski sürüm en az 6 ay yaşar.
Değişiklikler bu bölümde tarihli duyurulur; makine tarafında openapi.json dosyasının info.version alanından izlenebilir.
28.08.2026 · v1 · Bayi API yayinda
- Katalog, bayi fiyati, stok ve zorunlu alan semasi uclari.
- Siparis verme (Idempotency-Key zorunlu), okuma, referansla arama ve bekleyen kalem iptali.
- Bakiye, cari hareket, donem ekstresi (json/csv) ve fatura listesi.
- Imzali webhook aboneligi: 8 olay + ping testi, gonderim kaydi, imza yenileme.
- Test anahtari (oyxb_test_): gercek katalog, gercek akis, para dusmez, TEST- onekli kod doner.
- Bu dokuman, OpenAPI 3.1 ve Postman koleksiyonu ayni kaynaktan uretiliyor.
- MCP sunucusu (/bayi-api/mcp): yapay zeka istemcileri icin 11 arac. Para harcayan araclar iki adimli onay ister.
Bu doküman herkese açık: oyuneks.com/bayi-api/docs. Makine okuyucular için: openapi.json, postman.json, llms.txt.