Söyle Gelir Geliştiriciler

İşletme ve POS API

İşletmenin kendi yazılımı ve işletmenin bağladığı POS firması siparişleri bu API ile okur, onaylar ve ilerletir; ürün fiyatını, stoğunu ve mağazanın açık / kapalı durumunu günceller.

  • Taban adres: https://soylegelir.com/api/v1/merchant
  • Kimlik: işletme anahtarı (Authorization: Bearer sg_live_…) ya da POS firmasının iki anahtarı (X-Api-Key + X-Api-Secret). Ayrıntı: Kimlik doğrulama.
  • Hız sınırı: işletme başına dakikada 120 istek.

Uçlar

Yöntem Yol Ne yapar
GET /orders Siparişleri listeler
GET /orders/{number} Tek sipariş
POST /orders/{number}/accept Siparişi onaylar
POST /orders/{number}/status Siparişi ilerletir, isterse kurye atar
GET /products Ürünler (menü), seçenekleriyle
GET /products/{id} Tek ürün
POST /products/{id} Fiyat, stok, satışta mı
POST /store/status Mağaza açık / yoğun / kapalı
GET /couriers Atanabilir kuryeler

Sipariş nesnesi

Sipariş dönen bütün uçlar ve webhook'lar aynı nesneyi kullanır.

{
  "number": "SG261114GCCE",
  "status": "placed",
  "payment_method": "cash",
  "fulfilment": "delivery",
  "dine_in": null,
  "scheduled_for": null,
  "customer": { "name": "Ayşe Yılmaz", "phone": "+905321234567" },
  "address": {
    "title": "Ev", "city": "Denizli", "district": "Merkezefendi", "neighborhood": "Sırakapılar",
    "street": "Saltak Cad.", "building": "12", "floor": "3", "apartment": "7", "directions": null,
    "lat": 37.779539, "lng": 29.079447,
    "line": "Sırakapılar Mah., Saltak Cad., No: 12, Kat: 3, Daire: 7 — Merkezefendi/Denizli"
  },
  "note": "Zili çalmayın",
  "items": [
    { "name": "Karışık Pide", "quantity": 1, "unit": "adet", "unit_price": 23500,
      "options": [{ "id": 41, "name": "Kaşar", "price": 1500 }], "note": "Az pişmiş", "total": 23500 }
  ],
  "subtotal": 23500,
  "delivery_fee": 1500,
  "deposit_total": 0,
  "discount": 0,
  "coupon_code": null,
  "discount_funded_by": null,
  "total": 25000,
  "courier": null,
  "delivery_partner": null,
  "created_at": "2026-11-14T12:00:00+00:00",
  "currency": "TRY",
  "amounts_in": "kurus"
}
Alan Açıklama
number Sipariş numarası; uçlarda bununla çalışılır
status Sipariş durumu: placed, accepted, preparing, ready, picked_up, delivered, rejected, cancelled, delivery_failed
payment_method cash (kapıda nakit), card (kapıda kart) ya da online
fulfilment delivery (teslimat), pickup (gel al) ya da dine_in (restoranda)
dine_in Yalnız restoranda siparişte: mode (at_table masada, arriving geliyorum), table, party_size
scheduled_for İleri saatli sipariş, gel al alış saati ya da restoranda geliş saati; yoksa null
customer name, phone
address Teslimat adresinin sipariş anındaki kopyası; gel al ve restoranda null
note Müşteri notu
items[] name, quantity (adet; tartılı üründe gram), unit (adet ya da g), unit_price (seçenekler dahil; tartılı üründe 1 kg fiyatı), options[] (id, name, price), note (kaleme yazılan not), total
subtotal, delivery_fee, deposit_total, discount, total Kuruş. total müşterinin ödediği toplamdır
coupon_code, discount_funded_by Uygulanan kupon ve indirimi kimin karşıladığı (platform ya da store)
courier Atanmış sistem kuryesi: id, name; yoksa null
delivery_partner Sipariş bağlı kurye firmasındaysa: id, name, courier_name, courier_phone; yoksa null. courier ile ikisi aynı anda dolu olmaz

Siparişleri listeleme

GET /api/v1/merchant/orders?status=placed

En yeni sipariş başta olmak üzere en çok 100 kayıt döner.

Parametre Açıklama
status Yalnız bu durumdakiler
since updated_at değeri bu andan eski olmayanlar (ör. 2026-11-14T12:00:00Z). Düzenli çekimde son çekim zamanınızı verin
curl -H "Authorization: Bearer sg_live_…" \
  "https://soylegelir.com/api/v1/merchant/orders?status=placed"

Yanıt: {"data": [<sipariş nesnesi>, …]}. Tek sipariş: GET /orders/{number} → {"data": <sipariş nesnesi>}.

Siparişi onaylama

POST /api/v1/merchant/orders/{number}/accept

placed → accepted. Gövde gerekmez. Sipariş onay beklemiyorsa 422 (errors.status). İşletme bir kurye firması bağladıysa onaylanan teslimat siparişi o firmaya kendiliğinden gider.

Siparişi ilerletme

POST /api/v1/merchant/orders/{number}/status
Content-Type: application/json

{ "action": "prepare" }
Alan Zorunlu Açıklama
action Evet Aşağıdaki geçişlerden biri
note reject, cancel, fail için evet En çok 200 karakter; gerekçe olarak saklanır ve müşteriye gösterilir
courier_id Hayır Atanacak kuryenin kimliği (GET /couriers). Atama ve geçiş birlikte uygulanır ya da hiçbiri uygulanmaz
courier_lat, courier_lng Hayır courier_id ile birlikte: kuryenin konumu
action Hangi durumdan Yeni durum Sipariş türü
accept placed accepted hepsi
reject placed rejected hepsi (note zorunlu)
prepare accepted preparing hepsi
ready accepted, preparing ready hepsi
pick_up accepted, preparing, ready picked_up teslimat
deliver picked_up delivered teslimat
fail picked_up delivery_failed teslimat (note zorunlu)
cancel placed, accepted, preparing, ready cancelled hepsi (note zorunlu)
hand_over ready delivered gel al
serve accepted, preparing, ready delivered restoranda
no_show accepted, preparing, ready cancelled gel al, restoranda (bekleme süresi dolduktan sonra)

Yanıt: geçiş sonrası sipariş, {"data": <sipariş nesnesi>}.

Durum Anahtar Ne zaman
404 Sipariş bu işletmede yok; ya da courier_id bu işletmeye hizmet veren bir kurye değil
422 errors.action Geçiş adı eksik ya da tanımsız
422 errors.note Gerekçe gerekli ama yazılmamış
422 errors.status Geçiş siparişin şu anki durumunda ya da türünde yapılamaz
422 errors.courier Gel al / restoranda siparişe ya da kapanmış siparişe kurye atanamaz

Sipariş bağlı kurye firmasındayken (delivery_partner dolu) courier_id ile kendi kuryenizi atarsanız sipariş firmadan geri alınır ve firmaya bildirilir.

Ürünler

GET /api/v1/merchant/products?available=1&page=1

Menü sırasıyla, sayfa başına 100 ürün. POS'unuzdaki ürünleri id ya da barcode ile eşleyin; seçenek kimlikleri siparişteki items[].options[].id ile aynıdır.

Parametre Açıklama
category_id Yalnız bu kategori
available 1 satışta olanlar, 0 olmayanlar
since Bu andan sonra değişenler
page Sayfa (1'den başlar)
{
  "data": [
    {
      "id": 812,
      "name": "Karışık Pide",
      "category": { "id": 34, "name": "Pideler" },
      "price": 22000,
      "compare_price": null,
      "deposit": 0,
      "unit": "adet",
      "unit_step": 1,
      "barcode": "8690000000017",
      "stock": 12,
      "is_available": true,
      "option_groups": [
        {
          "id": 9, "name": "Ekstra", "kind": "choice", "min_select": 0, "max_select": 2,
          "options": [
            { "id": 41, "name": "Kaşar", "price": 1500, "is_available": true, "is_default": false, "groups": [] }
          ]
        }
      ],
      "updated_at": "2026-11-14T09:30:00+00:00"
    }
  ],
  "meta": { "current_page": 1, "last_page": 1, "per_page": 100, "total": 1 }
}
Alan Açıklama
price, compare_price, deposit Kuruş. compare_price indirim öncesi fiyat; deposit ürün başına depozito (ör. damacana)
unit, unit_step adet ya da g (tartılı; price 1 kg fiyatı, unit_step gram adımı)
stock Stok; null = takip yok
option_groups[].kind choice (seçim; min_select / max_select, max_select: 0 sınırsız; seçenekte ek fiyat) ya da remove (çıkarılacak malzeme; kural ve fiyat yok)
options[].groups O seçenek seçilince açılan alt gruplar (tek düzey)

Tek ürün: GET /products/{id} → {"data": <ürün nesnesi>}; başka işletmenin ürünü 404.

Fiyat, stok ve satış durumu

POST /api/v1/merchant/products/{id}
Content-Type: application/json

{ "price": 23000, "stock": 40, "is_available": true }

Yalnız gönderilen alanlar değişir. price ve stock kuruş / adet cinsinden 0 ile 2.000.000.000 arası; stock: null stok takibini kapatır. Yanıt: {"data": {"id", "price", "stock", "is_available"}}.

Mağaza durumu

POST /api/v1/merchant/store/status
Content-Type: application/json

{ "status": "busy" }

open (açık), busy (yoğun) ya da closed (kapalı). Yanıt: {"data": {"status": "busy"}}.

Atanabilir kuryeler

GET /api/v1/merchant/couriers

POST /orders/{number}/status ucundaki courier_id bunlardan biri olmalıdır: işletmenin kendi kuryeleri ve anlaşmalı kurye firmalarının sisteme kayıtlı kuryeleri.

{
  "data": [
    {
      "id": 7, "name": "Mehmet K.", "employer": "store", "company": null,
      "is_online": true, "vehicle": "motorcycle", "active_orders": 1,
      "location": { "lat": 37.7786, "lng": 29.0822, "at": "2026-11-14T12:03:00+00:00" }
    }
  ]
}

employer: store (işletmenin kendi kuryesi) ya da company (anlaşmalı firmanın kuryesi; company alanında firma). location: cihazdan gelen son konum; hiç gelmediyse null. Kendi yazılımıyla çalışan entegre kurye firmalarının kuryeleri burada görünmez; o siparişler delivery_partner alanında yazar.