MAS4GAMES

Geliştiriciler · Sürüm v1

Mas4games Bayi API'si

Ürünlerimizi kendi sitenizde, uygulamanızda ya da panelinizde otomatik satın. Siparişler bakiyenizden anında ödenir, kodlar saniyeler içinde gelir; her adım öngörülebilir, belgelenmiş ve test edilebilir.

API adresi

Base URL
https://api.mas4games.com/v1
Bu sayfada

Hızlı başlangıç

Üç adımda ilk siparişinizi verin.

  1. 1

    Anahtarlarınızı alın

    Destek ekibimiz hesabınız için bir test anahtarı (m4gc_test_…) ve bir canlı anahtar (m4gc_live_…) oluşturur; her birinin bir webhook imza anahtarı (whsec_…) vardır.

  2. 2

    Test ortamında deneyin

    Test anahtarıyla gerçek katalog ve fiyatlar gelir, siparişler ise para ya da stok hareket etmeden sahte kodlarla teslim edilir.

  3. 3

    Canlıya geçin

    Aynı kodu canlı anahtarla çalıştırın. Siparişler bakiyenizden ödenir ve gerçek kodlar GET /orders/{id} ile ve webhook'la gelir.

İstek
curl https://api.mas4games.com/v1/me \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY"
Cevap
{
  "object": "account",
  "id": 18452,
  "name": "Örnek Bayi",
  "email": "[email protected]",
  "email_verified": true,
  "customer_type": "Bayi",
  "created_at": "2024-03-12T09:41:00Z",
  "currency": "TRY",
  "currency_decimals": 2,
  "balances": [
    { "amount": 1245075, "currency": "TRY", "decimals": 2 }
  ],
  "key": {
    "mode": "live",
    "created_at": "2026-11-06T08:00:00Z",
    "allowed_ips": ["203.0.113.10/32"],
    "webhook_url": "https://bayi.example.com/webhooks/mas4games"
  }
}

Kimlik doğrulama

Her istekte gizli anahtarınızı Authorization başlığında gönderin:

HTTP
Authorization: Bearer m4gc_live_YOUR_SECRET_KEY
  • Anahtarın başı ortamını söyler: m4gc_live_ gerçek siparişler, m4gc_test_ test ortamı. İki ortamın siparişleri birbirinden ayrıdır.
  • Anahtarı yalnızca sunucunuzda saklayın; tarayıcıya, mobil uygulamaya ya da kod deposuna koymayın.
  • İsterseniz anahtarınızı sunucularınızın IP adresleriyle sınırlarız; başka bir adresten gelen istek 401 ile reddedilir.
  • Anahtar sızdıysa hemen yenilettirin: yeni anahtar verildiği an eskisi çalışmaz olur. Webhook imza anahtarı da yenilenir ve webhook adresi silinir; adresi yeni anahtarla PUT /webhook ile yeniden ayarlayın.

Test ortamı

Test anahtarıyla yapılan istekler gerçek katalog, fiyat ve kuralları kullanır; siparişler ise taklit edilir: bakiye düşmez, stok değişmez.

Kod ürünleri, açıkça işaretli sahte kodlarla anında teslim edilir: TEST-7F3A-91C2-0D44.

Test anahtarıyla GET /me, anahtarın para biriminde tek bir sahte bakiye gösterir: en küçük birimde 1000000 (iki basamaklı bir para biriminde 10.000,00) ve hiç değişmez. GET /balance/transactions boş liste döner.

Hata ve durumları denemek için siparişin reference alanını şöyle başlatın:

referenceAnlamı ve yapılacak
test_insufficient_balance…Sipariş 402 insufficient_balance ile reddedilir.
test_cancelled…Satırlar iptal edilmiş (cancelled) olarak gelir.
test_processing…Satırlar işlemde (processing) kalır; iptal uç noktasını denemek için.

Webhook'lar test siparişleri için de gönderilir; olaylardaki mode alanı test olur.

Bir test anahtarı 24 saatte en çok 500 test siparişi verebilir; fazlasında POST /orders 429 rate_limited döner ve Retry-After, son 24 saatteki en eski test siparişiniz bir günü doldurup yeni bir siparişe yer açılana kadar kaç saniye bekleneceğini söyler. Bu yüzden reddedilen bir Idempotency-Key o zaman yeniden gönderilebilir.

İstekler ve cevaplar

API, REST kurallarına uyar ve her yerde aynı biçimi kullanır.

  • Gövdeler JSON'dur, alan adları snake_case'tir. Başarılı cevap doğrudan kaynağı döner; hata cevapları error nesnesidir.
  • Tutarlar en küçük birimde tam sayıdır: {"amount": 41990, "currency": "TRY"} 419,90 TL demektir. Kesirli sayı hiç kullanılmaz, yuvarlama hatası olmaz. Basamak sayısı GET /me'deki currency_decimals'tadır.
  • Tarihler UTC ve ISO-8601'dir: 2026-11-06T08:12:40Z.
  • Listeler object: "list", data, has_more ve next_cursor döner. Sonraki sayfa için next_cursor'ı cursor olarak gönderin; limit 1–200'dür (varsayılan 50).
  • Her cevabın X-Request-Id başlığı vardır; destek talebinizde bu numarayı iletin.
  • Anahtar başına dakikada 120 istek yapılabilir. Kalan hak X-RateLimit-Remaining başlığındadır; aşılırsa 429 ve Retry-After döner. Bazı isteklerin ayrıca kendi sınırı vardır: POST /webhook/test anahtar başına saatte 30 kez, test anahtarının siparişleri 24 saatte 500 (ikisi de 429 rate_limited ve Retry-After döner).

Tekrar güvenliği (Idempotency)

Ağ koptuğunda bir sipariş isteğini güvenle yeniden gönderebilmeniz için POST isteklerinde Idempotency-Key başlığını kullanın.

  • Her yeni işlem için benzersiz bir değer (örneğin bir UUID) üretin. Aynı anahtarla gelen ikinci istek yeni bir sipariş açmaz; ilk cevabı aynen döner ve Idempotent-Replayed: true başlığını taşır.
  • Anahtarlar 24 saat saklanır. Aynı anahtarı farklı bir gövdeyle gönderirseniz 422 idempotency_key_reused, ilk istek henüz sürüyorsa 409 request_in_progress döner.
  • Siparişin reference alanı da benzersizdir: aynı reference ile ikinci bir sipariş 409 duplicate_reference döner ve hata order_id alanında ilk siparişi söyler.
HTTP
Idempotency-Key: 4f9c1d2e-8a7b-4c3d-9e1f-2a3b4c5d6e7f

Hatalar

Hatalar doğru HTTP durumu ve sabit bir code ile gelir. Mantığınızı mesaja değil code'a göre kurun; param, sorunlu alanı gösterir.

HTTP
HTTP/1.1 402 Payment Required
X-Request-Id: req_8c4f2a1e9b7d6c5a4b3e2f1d

{
  "error": {
    "type": "balance_error",
    "code": "insufficient_balance",
    "message": "Your balance in this currency does not cover the order.",
    "request_id": "req_8c4f2a1e9b7d6c5a4b3e2f1d"
  }
}
422 JSON
{
  "error": {
    "type": "order_error",
    "code": "field_invalid",
    "message": "\"playerId\" is missing or not valid for this product (see its type, min_length, max_length and options).",
    "param": "items[0].fields.playerId",
    "request_id": "req_0b1c2d3e4f5a6b7c8d9e0f1a"
  }
}
KodHTTPAnlamı ve yapılacak
invalid_api_key401Anahtar yok, yanlış, kapatılmış ya da bu IP'den kullanılamaz.
rate_limited429İstek sınırı aşıldı: anahtar başına dakikada 120 istek, saatte 30 webhook denemesi ya da test anahtarıyla 24 saatte 500 sipariş. Üçünde de Retry-After kaç saniye bekleneceğini söyler.
route_not_found404Böyle bir uç nokta yok; adresi kontrol edin.
invalid_json400Gövde geçerli JSON değil.
body_too_large413Gövde 256 KB'den büyük.
parameter_missing400Zorunlu bir parametre eksik (param söyler).
parameter_invalid400Bir parametrenin değeri geçersiz (param söyler).
field_unknown400Ürünün istemediği bir alan gönderildi; ürünün fields listesine bakın.
field_invalid422Bir alan eksik ya da kurallarına uymuyor (type, min_length, max_length, options).
product_not_found404Ürün yok ya da size satışta değil.
product_unavailable409Ürün şu an satışta değil.
out_of_stock409Bu adet için stok yetmiyor.
quantity_out_of_range422Adet, ürünün min_quantity ve max_quantity aralığı dışında.
outside_sale_hours422Ürün bu saatte satılmıyor (sale_hours).
daily_limit_reached422Bu ürün için günlük alım sınırına ulaşıldı.
spending_limit_reached422Bakiyeden ödemenin tutar ya da günlük sınırına ulaşıldı.
insufficient_balance402Bakiyeniz siparişi karşılamıyor; bakiye yükleyin.
account_restricted403Hesabınız bu ürünü alamıyor.
email_unverified403Hesabın e-posta adresi doğrulanmamış.
billing_details_required422Bu sipariş için fatura bilgisi (T.C. kimlik ya da vergi numarası) gerekli.
balance_payment_unavailable403Bu para biriminde bakiyeden ödeme hesabınıza açık değil.
duplicate_reference409Bu reference ile bir sipariş zaten var (order_id).
idempotency_key_reused422Idempotency-Key başka bir istekle kullanılmış.
request_in_progress409Aynı Idempotency-Key ile ilk istek hâlâ sürüyor; biraz sonra deneyin.
order_not_found404Sipariş yok ya da size ait değil.
item_not_found404Bu sipariş satırı yok.
order_not_cancellable409Sipariş ya da adı verilen satırlar iptal edilemiyor; message nedenini söyler: satır teslim edilmiş, iptal edilmiş ya da tedarikçiden alınıyor; satırları birbirine bağlı bir sipariş (kupon, paket, birlikte al fiyatı, hediye) yalnızca bir kısmıyla ya da teslim edilmiş bir satırıyla iptal edilmek istenmiş; ya da sipariş ödeme incelemesinde veya ekibimiz tarafından işleniyor.
webhook_not_set409Önce bir webhook adresi tanımlayın.
order_failed422Sipariş oluşturulamadı; request_id ile destek ekibine yazın.
maintenance503Mağaza bakımda; biraz sonra yeniden deneyin.
service_unavailable503Hizmet geçici olarak yanıt vermiyor; yeniden deneyin.
internal_error500Bizim tarafta beklenmeyen bir hata oldu; request_id ile destek ekibine yazın. Sipariş isteğinde yeniden denerken aynı Idempotency-Key'i gönderin.

Siparişin yaşamı

Bir sipariş satırlardan oluşur; her satırın kendi durumu vardır, siparişin durumu satırlarından çıkar.

Satır durumları

processing
Teslimat sürüyor. Çoğu kod ürünü saniyeler içinde teslim edilir; ID ile yüklemeler birkaç dakika sürebilir.
delivered
Teslim edildi. Kodlar codes alanında; delivery_note teslimatın notudur (ör. ID ile yüklemenin işlem numarası), yoksa null. Test ortamında ID ile yüklemeler TEST-TX-… biçiminde bir not alır.
cancelled
İptal edildi; tutarı bakiyenize döndü (cancel_reason).

Sipariş durumları

processing
En az bir satır işlemde.
completed
Bütün satırlar teslim edildi.
partially_completed
Bazı satırlar teslim edildi, diğerleri iptal edildi.
cancelled
Bütün satırlar iptal edildi.

Güvenliğiniz için kodlar yalnızca GET /orders/{id} cevabında ve webhook'larda yer alır; sipariş oluşturma ve liste cevaplarında codes null olur, codes_count ise kaç kod olduğunu söyler.

Uç noktalar

Tüm adresler API adresinin altındadır.

Hesap

Hesap bilgileri

GET/v1/me

Hesabınızı, bakiyelerinizi ve kullandığınız anahtarın bilgilerini (ortam, izinli IP'ler, webhook adresi) döner. Test anahtarıyla bakiye, test ortamının sahte bakiyesidir (anahtarın para biriminde 1000000).

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
İstek
curl https://api.mas4games.com/v1/me \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY"
Cevap
{
  "object": "account",
  "id": 18452,
  "name": "Örnek Bayi",
  "email": "[email protected]",
  "email_verified": true,
  "customer_type": "Bayi",
  "created_at": "2024-03-12T09:41:00Z",
  "currency": "TRY",
  "currency_decimals": 2,
  "balances": [
    { "amount": 1245075, "currency": "TRY", "decimals": 2 }
  ],
  "key": {
    "mode": "live",
    "created_at": "2026-11-06T08:00:00Z",
    "allowed_ips": ["203.0.113.10/32"],
    "webhook_url": "https://bayi.example.com/webhooks/mas4games"
  }
}

Olası hatalar:invalid_api_keyrate_limited

Katalog

Kategorileri listele

GET/v1/categories

Size açık kategorileri döner. Alt kategoriler parent_id ile üst kategorilerine bağlanır.

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
İstek
curl https://api.mas4games.com/v1/categories \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY"
Cevap
{
  "object": "list",
  "data": [
    { "id": 3, "slug": "pubg-mobile", "name": "PUBG Mobile", "parent_id": null, "image_url": "https://www.mas4games.com/uploads/catalog/pubg.webp" },
    { "id": 5, "slug": "google-play", "name": "Google Play", "parent_id": null, "image_url": "https://www.mas4games.com/uploads/catalog/google-play.webp" }
  ],
  "has_more": false,
  "next_cursor": null
}

Olası hatalar:invalid_api_keyrate_limited

Ürünleri listele

GET/v1/products

Size açık ürünleri size özel fiyatlarıyla, ürün numarasına göre sıralı döner. updated_since ile yalnızca fiyatı, stoğu ya da durumu değişenleri alırsınız (değişiklikler beş dakikada bir işlenir).

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
limitisteğe bağlısorgu · integerSayfadaki kayıt sayısı, 1–200 (varsayılan 50)
cursoristeğe bağlısorgu · stringÖnceki cevabın next_cursor değeri
category_idisteğe bağlısorgu · integerYalnızca bu kategorinin (ve alt kategorilerinin) ürünleri
idsisteğe bağlısorgu · stringVirgülle ayrılmış ürün numaraları (en çok 200)
updated_sinceisteğe bağlısorgu · date-timeYalnızca bu tarihten sonra değişenler (ISO-8601)
İstek
curl https://api.mas4games.com/v1/products?limit=100 \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY"
Cevap
{
  "object": "list",
  "data": [
    {
      "object": "product",
      "id": 241,
      "sku": "pubg-mobile-660-uc",
      "name": "PUBG Mobile 660 UC",
      "names": { "tr": "PUBG Mobile 660 UC", "en": "PUBG Mobile 660 UC", "ar": "PUBG Mobile 660 UC" },
      "category": { "id": 3, "name": "PUBG Mobile" },
      "type": "topup",
      "region": "global",
      "price": { "amount": 41990, "currency": "TRY" },
      "list_price": { "amount": 44990, "currency": "TRY" },
      "available": true,
      "stock": null,
      "min_quantity": 1,
      "max_quantity": 10,
      "sale_hours": null,
      "fields": [
        {
          "key": "playerId",
          "labels": { "tr": "Oyuncu ID", "en": "Player ID", "ar": "معرّف اللاعب" },
          "type": "digits",
          "required": true,
          "min_length": 5,
          "max_length": 64,
          "options": null
        }
      ],
      "image_url": "https://www.mas4games.com/uploads/catalog/pubg.webp",
      "description": null,
      "updated_at": "2026-11-06T07:55:00Z"
    }
  ],
  "has_more": true,
  "next_cursor": "MjQx"
}

Olası hatalar:invalid_api_keyrate_limitedparameter_invalid

Ürün ayrıntısı

GET/v1/products/{id}

Tek bir ürünü döner. Yüksek tutarlı siparişlerden önce fiyatı ve durumu buradan doğrulayın.

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
idzorunluyol · integerÜrünün numarası
İstek
curl https://api.mas4games.com/v1/products/241 \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY"
Cevap
{
  "object": "product",
  "id": 241,
  "sku": "pubg-mobile-660-uc",
  "name": "PUBG Mobile 660 UC",
  "names": { "tr": "PUBG Mobile 660 UC", "en": "PUBG Mobile 660 UC", "ar": "PUBG Mobile 660 UC" },
  "category": { "id": 3, "name": "PUBG Mobile" },
  "type": "topup",
  "region": "global",
  "price": { "amount": 41990, "currency": "TRY" },
  "list_price": { "amount": 44990, "currency": "TRY" },
  "available": true,
  "stock": null,
  "min_quantity": 1,
  "max_quantity": 10,
  "sale_hours": null,
  "fields": [
    {
      "key": "playerId",
      "labels": { "tr": "Oyuncu ID", "en": "Player ID", "ar": "معرّف اللاعب" },
      "type": "digits",
      "required": true,
      "min_length": 5,
      "max_length": 64,
      "options": null
    }
  ],
  "image_url": "https://www.mas4games.com/uploads/catalog/pubg.webp",
  "description": null,
  "updated_at": "2026-11-06T07:55:00Z"
}

Olası hatalar:invalid_api_keyrate_limitedproduct_not_found

Siparişler

Sipariş oluştur

POST/v1/orders

Siparişi bakiyenizden anında öder ve teslimata başlatır; 201 ile siparişi döner. Bir satır sipariş edilemezse hiçbir sipariş açılmaz ve hata, sorunlu satırı param'da söyler. Test anahtarı 24 saatte en çok 500 test siparişi verebilir (429 rate_limited ve Retry-After).

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
Idempotency-Keyisteğe bağlıbaşlık · stringBu işleme özgü benzersiz değer (1–255 karakter); yeniden gönderimde aynısı
referenceisteğe bağlıgövde · stringKendi sipariş numaranız; anahtar başına benzersiz (1–100 karakter)
itemszorunlugövde · arraySipariş satırları (1–20)
items[].product_idzorunlugövde · integerÜrünün numarası
items[].quantityisteğe bağlıgövde · integerAdet (varsayılan 1; ürünün min_quantity–max_quantity aralığında)
items[].fieldsisteğe bağlıgövde · objectÜrünün fields listesindeki alanların değerleri, anahtarlarıyla
İstek
curl -X POST https://api.mas4games.com/v1/orders \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1d2c8e-SIP-10045" \
  -d '{
  "reference": "SIP-10045",
  "items": [
    {
      "product_id": 241,
      "quantity": 1,
      "fields": { "playerId": "5123456789" }
    },
    {
      "product_id": 77,
      "quantity": 2
    }
  ]
}'
Cevap
{
  "object": "order",
  "id": "M4G105146",
  "reference": "SIP-10045",
  "mode": "live",
  "source": "api",
  "status": "processing",
  "currency": "TRY",
  "total": { "amount": 61990, "currency": "TRY" },
  "refunded": { "amount": 0, "currency": "TRY" },
  "created_at": "2026-11-06T08:12:40Z",
  "items": [
    {
      "id": 5614,
      "product_id": 241,
      "product_name": "PUBG Mobile 660 UC",
      "quantity": 1,
      "unit_price": { "amount": 41990, "currency": "TRY" },
      "amount": { "amount": 41990, "currency": "TRY" },
      "gift": false,
      "status": "processing",
      "fields": { "playerId": "5123456789" },
      "codes": null,
      "codes_count": 0,
      "delivery_note": null,
      "delivered_at": null,
      "cancel_reason": null
    },
    {
      "id": 5615,
      "product_id": 77,
      "product_name": "Xbox 100 TL Hediye Kartı",
      "quantity": 2,
      "unit_price": { "amount": 10000, "currency": "TRY" },
      "amount": { "amount": 20000, "currency": "TRY" },
      "gift": false,
      "status": "delivered",
      "fields": {},
      "codes": null,
      "codes_count": 2,
      "delivery_note": null,
      "delivered_at": "2026-11-06T08:12:41Z",
      "cancel_reason": null
    }
  ]
}

Olası hatalar:invalid_api_keyrate_limitedinvalid_jsonparameter_missingparameter_invalidfield_unknownfield_invalidproduct_not_foundproduct_unavailableout_of_stockquantity_out_of_rangeoutside_sale_hoursdaily_limit_reachedspending_limit_reachedinsufficient_balanceaccount_restrictedemail_unverifiedbilling_details_requiredbalance_payment_unavailableduplicate_referenceidempotency_key_reusedrequest_in_progressorder_failedmaintenance

Siparişi getir

GET/v1/orders/{id}

Siparişi, teslim edilmiş satırların kodlarıyla birlikte döner. Webhook kullanmıyorsanız teslimatı bu uç noktayla izleyin.

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
idzorunluyol · stringSiparişin numarası (M4G…; test ortamında TST…)
İstek
curl https://api.mas4games.com/v1/orders/M4G105146 \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY"
Cevap
{
  "object": "order",
  "id": "M4G105146",
  "reference": "SIP-10045",
  "mode": "live",
  "source": "api",
  "status": "completed",
  "currency": "TRY",
  "total": { "amount": 61990, "currency": "TRY" },
  "refunded": { "amount": 0, "currency": "TRY" },
  "created_at": "2026-11-06T08:12:40Z",
  "items": [
    {
      "id": 5614,
      "product_id": 241,
      "product_name": "PUBG Mobile 660 UC",
      "quantity": 1,
      "unit_price": { "amount": 41990, "currency": "TRY" },
      "amount": { "amount": 41990, "currency": "TRY" },
      "gift": false,
      "status": "delivered",
      "fields": { "playerId": "5123456789" },
      "codes": [],
      "codes_count": 0,
      "delivery_note": "L8RZvemd2K2d39qfS7",
      "delivered_at": "2026-11-06T08:13:05Z",
      "cancel_reason": null
    },
    {
      "id": 5615,
      "product_id": 77,
      "product_name": "Xbox 100 TL Hediye Kartı",
      "quantity": 2,
      "unit_price": { "amount": 10000, "currency": "TRY" },
      "amount": { "amount": 20000, "currency": "TRY" },
      "gift": false,
      "status": "delivered",
      "fields": {},
      "codes": ["XB1A-7KQ2-PL9D-3M2X", "XB1A-8LR3-QM0E-4N3Y"],
      "codes_count": 2,
      "delivery_note": null,
      "delivered_at": "2026-11-06T08:12:41Z",
      "cancel_reason": null
    }
  ]
}

Olası hatalar:invalid_api_keyrate_limitedorder_not_found

Siparişleri listele

GET/v1/orders

Siparişlerinizi en yeniden eskiye döner (sitedeki siparişleriniz de source: store ile gelir). Kodlar listede yer almaz.

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
limitisteğe bağlısorgu · integerSayfadaki kayıt sayısı, 1–200 (varsayılan 50)
cursoristeğe bağlısorgu · stringÖnceki cevabın next_cursor değeri
statusisteğe bağlısorgu · stringprocessing, completed, partially_completed ya da cancelled
referenceisteğe bağlısorgu · stringBu reference ile verilen sipariş
created_afteristeğe bağlısorgu · date-timeBu tarihten (dahil) sonra oluşturulanlar
created_beforeisteğe bağlısorgu · date-timeBu tarihten önce oluşturulanlar
İstek
curl "https://api.mas4games.com/v1/orders?status=completed&created_after=2026-11-01T00:00:00Z&limit=50" \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY"
Cevap
{
  "object": "list",
  "data": [
    { "object": "order", "id": "M4G105146", "reference": "SIP-10045", "status": "completed", "…": "…" }
  ],
  "has_more": false,
  "next_cursor": null
}

Olası hatalar:invalid_api_keyrate_limitedparameter_invalid

Siparişi iptal et

POST/v1/orders/{id}/cancel

Henüz teslim edilmemiş satırları iptal eder ve tutarlarını bakiyenize hemen iade eder. items verilmezse iptal edilebilir bütün satırlar iptal edilir. Satırları birbirine bağlı bir sipariş (siparişte kupon, paket ürün, birlikte al fiyatı, hediye satırı ya da hediyeyi kazandıran satır) ya tümüyle iptal edilir ya da hiç: items göndermeyin (ya da bütün satırlarını gönderin); yalnızca bazı satırlarını vermek ya da satırlarından birinin teslim edilmiş veya tedarikçiden alınıyor olması 409 order_not_cancellable döner ve message nedenini söyler. Ödeme incelemesindeki ya da ekibimizin işlediği siparişler API ile hiç iptal edilmez; destek ekibimize yazın. Diğer siparişlerde satır satır iptal sürer. Yalnızca bakiyeden ödenmiş siparişler (API siparişlerinin hepsi) iptal edilebilir.

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
Idempotency-Keyisteğe bağlıbaşlık · stringBu işleme özgü benzersiz değer (1–255 karakter); yeniden gönderimde aynısı
idzorunluyol · stringSiparişin numarası (M4G…; test ortamında TST…)
itemsisteğe bağlıgövde · arrayİptal edilecek satır numaraları; verilmezse iptal edilebilir hepsi (satırları birbirine bağlı bir siparişte ya hepsi ya hiçbiri). Boş liste parameter_invalid ile reddedilir
reasonisteğe bağlıgövde · stringİptal sebebi (en çok 200 karakter)
İstek
curl -X POST https://api.mas4games.com/v1/orders/M4G105146/cancel \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: cancel-M4G105146" \
  -d '{ "items": [5614], "reason": "Customer changed their mind" }'
Cevap
{
  "object": "order",
  "id": "M4G105146",
  "status": "partially_completed",
  "refunded": { "amount": 41990, "currency": "TRY" },
  "items": [
    { "id": 5614, "status": "cancelled", "cancel_reason": "Customer changed their mind", "…": "…" },
    { "id": 5615, "status": "delivered", "…": "…" }
  ]
}

Olası hatalar:invalid_api_keyrate_limitedinvalid_jsonparameter_invalidorder_not_founditem_not_foundorder_not_cancellableidempotency_key_reusedrequest_in_progress

Bakiye

Bakiye hareketleri

GET/v1/balance/transactions

Bakiyenizin hareketlerini (alışlar, iadeler, yüklemeler) en yeniden eskiye döner; mutabakat için. Test anahtarıyla liste her zaman boştur: test ortamı para hareket ettirmez.

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
limitisteğe bağlısorgu · integerSayfadaki kayıt sayısı, 1–200 (varsayılan 50)
cursoristeğe bağlısorgu · stringÖnceki cevabın next_cursor değeri
currencyisteğe bağlısorgu · stringPara birimi (varsayılan: anahtarınızın para birimi)
İstek
curl "https://api.mas4games.com/v1/balance/transactions?limit=20" \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY"
Cevap
{
  "object": "list",
  "data": [
    {
      "object": "balance_transaction",
      "id": 90211,
      "type": "purchase",
      "amount": { "amount": -61990, "currency": "TRY" },
      "balance_after": { "amount": 1183085, "currency": "TRY" },
      "order_id": "M4G105146",
      "created_at": "2026-11-06T08:12:40Z"
    }
  ],
  "has_more": true,
  "next_cursor": "OTAyMTE"
}

Olası hatalar:invalid_api_keyrate_limitedparameter_invalid

Webhook adresi

Webhook adresini gör

GET/v1/webhook

Tanımlı webhook adresini ve imza anahtarınızın son karakterlerini döner.

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
İstek
curl https://api.mas4games.com/v1/webhook \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY"
Cevap
{
  "object": "webhook_endpoint",
  "url": "https://bayi.example.com/webhooks/mas4games",
  "secret_hint": "whsec_…Q3xZ",
  "events": ["order.item.delivered", "order.item.cancelled", "product.updated", "ping"]
}

Olası hatalar:invalid_api_keyrate_limited

Webhook adresini ayarla

PUT/v1/webhook

Olayların gönderileceği https adresini ayarlar; null webhook'ları durdurur. Yeni adrese gönderim hemen başlar (eski adres hatalar yüzünden bekletiliyor olsa bile).

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
urlzorunlugövde · stringhttps adresi, en çok 300 karakter; null webhook'ları durdurur
İstek
curl -X PUT https://api.mas4games.com/v1/webhook \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://bayi.example.com/webhooks/mas4games" }'

# then send a test event:
curl -X POST https://api.mas4games.com/v1/webhook/test -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY"
Cevap
{
  "object": "webhook_endpoint",
  "url": "https://bayi.example.com/webhooks/mas4games",
  "secret_hint": "whsec_…Q3xZ",
  "events": ["order.item.delivered", "order.item.cancelled", "product.updated", "ping"]
}

Olası hatalar:invalid_api_keyrate_limitedinvalid_jsonparameter_invalid

Deneme olayı gönder

POST/v1/webhook/test

Adresinize imzalı bir ping olayı gönderir ve sonucunu söyler; alıcınızı kurarken kullanın. Başarılı bir deneme, hatalar yüzünden bekletilen adresinizi hemen yeniden açar. Anahtar başına saatte en çok 30 kez; fazlası 429 rate_limited ve Retry-After döner.

Parametreler

AdYerAçıklama
Authorizationzorunlubaşlık · stringBearer ve gizli anahtarınız
İstek
curl -X POST https://api.mas4games.com/v1/webhook/test \
  -H "Authorization: Bearer m4gc_live_YOUR_SECRET_KEY"
Cevap
{
  "object": "webhook_test",
  "event_id": "evt_5d4c3b2a1f0e9d8c7b6a5f4e",
  "delivered": true,
  "response_status": 200,
  "error": null
}

Olası hatalar:invalid_api_keyrate_limitedwebhook_not_set

Webhook'lar

Siparişleri sorgulamak yerine olayları bekleyin: bir satır teslim edildiğinde ya da iptal edildiğinde ve ürünleriniz değiştiğinde adresinize imzalı bir POST isteği göndeririz.

OlaylarAnlamı ve yapılacak
order.item.deliveredBir sipariş satırı teslim edildi; data.order kodlarla birlikte bütün siparişi, data.item_id satırı verir.
order.item.cancelledBir sipariş satırı iptal edildi ve tutarı bakiyenize döndü.
product.updatedFiyatı, stoğu ya da durumu değişen ürünler (beş dakikada bir, en çok 100'er); satıştan kalkan ürün status: removed ile gelir.
pingPOST /webhook/test ile gönderilen deneme olayı.
order.item.delivered
POST /webhooks/mas4games HTTP/1.1
Host: bayi.example.com
Content-Type: application/json
Mas4games-Signature: t=1793952765,v1=5f0b3c…e91a
Mas4games-Event-Id: evt_2c1a9f0e8b7d6c5a4b3e2f1d
Mas4games-Event-Type: order.item.delivered

{
  "id": "evt_2c1a9f0e8b7d6c5a4b3e2f1d",
  "object": "event",
  "type": "order.item.delivered",
  "mode": "live",
  "api_version": "v1",
  "created_at": "2026-11-06T08:12:45Z",
  "data": {
    "item_id": 5615,
    "order": {
      "object": "order",
      "id": "M4G105146",
      "reference": "SIP-10045",
      "status": "processing",
      "items": [
        { "id": 5615, "status": "delivered", "codes": ["XB1A-7KQ2-PL9D-3M2X", "XB1A-8LR3-QM0E-4N3Y"], "delivery_note": null, "…": "…" }
      ],
      "…": "…"
    }
  }
}
product.updated
{
  "id": "evt_9a8b7c6d5e4f3a2b1c0d9e8f",
  "object": "event",
  "type": "product.updated",
  "mode": "live",
  "api_version": "v1",
  "created_at": "2026-11-06T09:00:00Z",
  "data": {
    "products": [
      { "object": "product", "id": 241, "price": { "amount": 40990, "currency": "TRY" }, "available": true, "stock": null, "…": "…" },
      { "object": "product", "id": 312, "sku": "old-product", "available": false, "status": "removed" }
    ]
  }
}

İmzayı doğrulama

Her isteğin Mas4games-Signature başlığı vardır: t=1793952765,v1=5f0b3c…. v1, ham gövdenin önüne zaman ve nokta eklenmiş metnin (t.gövde) whsec_ anahtarınızla HMAC-SHA256 özetidir.

  1. 1Ham gövdeyi JSON'a çevirmeden okuyun.
  2. 2Başlıktan t ve v1'i ayırın; HMAC-SHA256(gizli, t + "." + gövde) hesaplayın.
  3. 3Sonucu v1 ile sabit zamanlı karşılaştırın ve t'nin şimdiden en çok 300 saniye uzak olduğunu kontrol edin.
  4. 4Uyuşmazsa 400 dönün ve olayı işlemeyin.
import crypto from "node:crypto";
import express from "express";

const app = express();
// The signature is over the raw body: read it before any JSON parsing.
app.post("/webhooks/mas4games", express.raw({ type: "application/json" }), (req, res) => {
  const header = req.get("Mas4games-Signature") ?? "";
  const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=")));
  const t = Number(parts.t);
  const expected = crypto.createHmac("sha256", process.env.MAS4GAMES_WEBHOOK_SECRET)
    .update(`${t}.${req.body.toString("utf8")}`).digest("hex");
  const ok = parts.v1 && parts.v1.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected)) &&
    Math.abs(Date.now() / 1000 - t) <= 300;
  if (!ok) return res.status(400).end();

  const event = JSON.parse(req.body.toString("utf8"));
  if (alreadyHandled(event.id)) return res.status(200).end(); // the same event can arrive twice
  queue(event); // handle it after answering
  res.status(200).end();
});

Olayı aldığınızı 8 saniye içinde 2xx ile bildirin, işi sonra yapın: daha uzun süren istek başarısız sayılır ve cevabınızın gövdesi okunmaz. 2xx dışındaki cevaplar 1, 5, 15 dakika, sonra saatlik ve altı saatlik aralıklarla yeniden denenir (en çok 12 kez).

Adresiniz üst üste 3 kez başarısız olursa 5 dakika bekletilir; her yeni hatada bu süre iki katına çıkar, en çok 1 saat. Bu sürede olaylarınız bekler. Yeni bir adres ayarlamak (PUT /webhook) ya da başarılı bir POST /webhook/test gönderimi hemen yeniden başlatır.

Aynı olay birden fazla gelebilir ve bir siparişin satırları ayrı ayrı, birkaç turda bildirilebilir (test siparişleri de); bir olayın id'si her gönderimde aynıdır: id'leri saklayın ve tekrarları yok sayın. Olayların sırası garanti değildir; kesin durum için GET /orders/{id} kullanın.

Adresinizi PUT /webhook ile kendiniz ayarlayın; imza anahtarı anahtarınızla birlikte verilir. Anahtar yenilenince adres silinir: yeni anahtarla yeniden ayarlayın.

İyi uygulamalar

  • Her POST isteğine yeni bir Idempotency-Key ekleyin; zaman aşımında aynı anahtarla yeniden gönderin.
  • Her siparişe kendi reference'ınızı verin; sipariş sizde mi bizde mi, her zaman bulursunuz.
  • Webhook'ları kullanın, kaçanlar için GET /orders/{id} ile kontrol edin.
  • Kataloğu bir kez tam çekin, sonra updated_since ya da product.updated ile güncel tutun.
  • Önce test anahtarıyla bütün akışı (hatalar dahil) deneyin, sonra canlıya geçin.
  • Anahtar ve webhook imza anahtarını yalnızca sunucuda, ortam değişkeninde saklayın.

Yardım

Takıldığınız bir nokta olursa destek ekibimize yazın; cevabın X-Request-Id değerini ve hata kodunu eklerseniz daha hızlı yardımcı oluruz.

Sürüm notları

  • 6 Kasım 2026 (güncelleme 2): delivery_note artık teslimatın kendi notunu taşır (ör. ID ile yüklemenin işlem numarası; test ortamında TEST-TX-…), yoksa null. Önceki sabit topup_completed değeri kaldırıldı: ID ile yüklemenin tamamlandığını status: delivered ve codes_count: 0 söyler.
  • 6 Kasım 2026 (güncelleme): test anahtarının GET /me cevabında test bakiyesi yer alır, bakiye hareketleri boştur; satırları birbirine bağlı siparişler tümüyle iptal edilir, incelemedeki ya da ekibimizin işlediği siparişler API ile iptal edilmez; test siparişleri (24 saatte 500) ve webhook denemeleri (saatte 30) için Retry-After ile 429 sınırı; webhook istekleri 8 saniyede zaman aşımına uğrar ve üst üste başarısız olan adres bekletilir; anahtar yenilenince webhook adresi silinir.
  • v1 (6 Kasım 2026): ilk sürüm. Hesap, katalog, siparişler, iptal, bakiye hareketleri, imzalı webhook'lar, Idempotency-Key ve test ortamı.