Lezzet35
Giriş yap
İçindekiler

Belgeler

Lezzet35 API

İzmir yemek pazaryeri Lezzet35’in HTTP API’si. Üç bölge: herkese açık JSON uçları (sağlık, kimlik, bölge), SiparişMatik kasa uyumluluk katmanı /api/v1 (canlı) ve Partner API /api/v2 (Faz 6). Tüm tutarlar sunucuda hesaplanır; istemciden fiyat/indirim alanı kabul edilmez.

Sürüm:
1.0.0
Uçlar:
29 hazır · 8 planlandı
Makine biçimi:
/api/openapi.json

Hızlı başlangıç

Örneklerde $LEZZET35_URL sunucu kökünü temsil eder. Yanıt zarfı her JSON ucunda aynıdır: başarıda { success: true, data }, hatada { success: false, message, errors? }. Tüm tarih/saatler ISO 8601 (UTC); tutarlar kuruş; v1 katmanı WPSipariş biçimlerini (TL ondalık, dd.MM.yyyy HH:mm) korur.

bash
export LEZZET35_URL="http://localhost:3000"
curl "$LEZZET35_URL/api/health"

Rehberler: SiparişMatik kurulumu · Partner API v2 taslağı

Sağlık

Sağlık kontrolü ve belge keşfi (kimlik gerekmez)

get/api/healthHazır

Sağlık kontrolü

Coolify ve izleme araçları için sağlık ucu. Veritabanı ve Redis ayrı raporlanır; biri hatalıysa 503 döner. Bu uç standart {success, data} zarfını kullanmaz (izleme araçları düz alan bekler). Yanıt cache-control: no-store ile gelir; her bağımlılık kontrolü 2 sn zaman aşımlıdır.

Kimlik:
gerekmez

Yanıtlar

200Her iki bağımlılık sağlıklı

AlanTipZorunluAçıklama
durumenum(ok | sorunlu)evetİki bağımlılık da ok ise ok
dbenum(ok | hata)evet
redisenum(ok | hata)evet
surumstringevetpackage.json sürümü
zamanstring (date-time)evetSunucu saati (ISO 8601, UTC)
Örnek 200
{
  "durum": "ok",
  "db": "ok",
  "redis": "ok",
  "surum": "0.1.0",
  "zaman": "2026-09-16T09:00:00.000Z"
}

503db ya da redis hatalı; gövde aynı şekil, durum: sorunlu

Örnek 503
{
  "durum": "sorunlu",
  "db": "ok",
  "redis": "hata",
  "surum": "0.1.0",
  "zaman": "2026-09-16T09:00:00.000Z"
}
curl
curl -X GET "$LEZZET35_URL/api/health"

Kaynak: src/app/api/health/route.ts

get/api/openapi.jsonHazır

OpenAPI belgesi

Bu belgenin makine biçimi (OpenAPI 3.1). 5 dakika önbelleklenir (cache-control: public, max-age=300). Kod üretimi ve sözleşme testleri bu ucu kullanır.

Kimlik:
gerekmez

Yanıtlar

200OpenAPI 3.1 belgesi

AlanTipZorunluAçıklama
(gövde)nesneevetOpenAPI 3.1.0 belgesi; openapi, info, paths, components anahtarları
curl
curl -X GET "$LEZZET35_URL/api/openapi.json"

Kaynak: src/app/api/openapi.json/route.ts

Kimlik

OTP ile giriş/kayıt (D1). Şifre yok; oturum HttpOnly çerez

post/api/auth/otp/istekHazır

OTP kodu iste

Telefona 6 haneli tek kullanımlık kod gönderir (SMS: MasGSM; geliştirmede konsol). Kod düz metin saklanmaz, sha256 özeti 5 dk geçerlidir ve 5 deneme hakkı vardır. Aynı numara için OTP_BEKLEME_SN (60 sn) dolmadan yeni istek 429 döner. Üye olmayan numara doğrulamada otomatik kaydedilir (şifre yok).

Kimlik:
gerekmez
Hız sınırı:
Telefon başına 3 / 10 dk (`OTP_TEL_LIMIT`), IP başına 21 / 10 dk; ardışık istek 60 sn bekleme

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
telefonstringevetTürkiye cep telefonu; 05xx, 5xx ya da +905xx biçimleri kabul edilir, sunucu E.164’e çevirir
amacenum(giris | kayit | panel-token)hayırKodun amacı; varsayılan giris

Yanıtlar

200Kod gönderildi

AlanTipZorunluAçıklama
success= trueevetHer zaman true
datanesneevet
data.gonderildi= trueevet
data.bitisSnintegerevetKodun geçerlilik süresi (saniye)
Örnek 200
{
  "success": true,
  "data": {
    "gonderildi": true,
    "bitisSn": 300
  }
}

400Doğrulama hatası (alan bazlı errors) ya da geçersiz Türkiye numarası

Örnek 400
{
  "success": false,
  "message": "Geçerli bir Türkiye cep telefonu numarası girin",
  "errors": {
    "telefon": [
      "biçim"
    ]
  }
}

429Hız sınırı aşıldı; retry-after başlığı ve yenidenSn alanı kaç saniye sonra denenebileceğini söyler

Örnek 429
{
  "success": false,
  "message": "Çok fazla istek; lütfen biraz sonra tekrar deneyin",
  "yenidenSn": 412
}

500Beklenmeyen sunucu hatası; ayrıntı yalnız sunucu logunda

Örnek 500
{
  "success": false,
  "message": "Sunucu hatası"
}
curl
curl -X POST "$LEZZET35_URL/api/auth/otp/istek" \
  -H "Content-Type: application/json" \
  -d '{"telefon":"0532 123 45 67","amac":"giris"}'

Kaynak: src/app/api/auth/otp/istek/route.ts

post/api/auth/otp/dogrulaHazır

OTP kodunu doğrula

Kodu doğrular; başarılıysa kullanıcı kimliğini döner ve numara ilk kez doğrulanıyorsa hesabı oluşturur. Oturum çerezi bu uçta açılmaz: tarayıcı akışı /giris sayfasındaki Server Action ile HttpOnly l35_oturum çerezi açar. Mobil/PWA için token tabanlı oturum ucu Faz 5’te (D1). Hatalı kod neden alanıyla ayrıştırılır: bulunamadi | suresi_doldu | deneme_asildi | yanlis.

Kimlik:
gerekmez
Hız sınırı:
Telefon başına 10 / 10 dk

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
telefonstringevetTürkiye cep telefonu; 05xx, 5xx ya da +905xx biçimleri kabul edilir, sunucu E.164’e çevirir
kodstring /^\d{6}$/evetSMS ile gelen 6 haneli kod

Yanıtlar

200Kod doğru

AlanTipZorunluAçıklama
success= trueevetHer zaman true
datanesneevet
data.userIdstringevetKullanıcı kimliği (cuid)
data.yeniKullanicibooleanevetNumara ilk kez doğrulandıysa true (otomatik kayıt)
Örnek 200
{
  "success": true,
  "data": {
    "userId": "cmfl3k9x40000abcd1234efgh",
    "yeniKullanici": false
  }
}

400Doğrulama hatası, geçersiz numara ya da yanlış/süresi dolmuş kod (neden)

Örnek 400
{
  "success": false,
  "message": "Kod hatalı",
  "neden": "yanlis"
}

429Hız sınırı aşıldı; retry-after başlığı ve yenidenSn alanı kaç saniye sonra denenebileceğini söyler

Örnek 429
{
  "success": false,
  "message": "Çok fazla istek; lütfen biraz sonra tekrar deneyin",
  "yenidenSn": 412
}

500Beklenmeyen sunucu hatası; ayrıntı yalnız sunucu logunda

Örnek 500
{
  "success": false,
  "message": "Sunucu hatası"
}
curl
curl -X POST "$LEZZET35_URL/api/auth/otp/dogrula" \
  -H "Content-Type: application/json" \
  -d '{"telefon":"0532 123 45 67","kod":"123456"}'

Kaynak: src/app/api/auth/otp/dogrula/route.ts

Bölge

İzmir ilçe/mahalle ve servis alanı (M04)

get/api/bolge/mahalle-araHazır

Mahalle ara

İzmir mahallelerinde arama (adres formu ve vitrin konum seçici için). Önek eşleşmesi önce, sonra trigram benzerliği (pg_trgm, eşik 0,3); Türkçe karakterden bağımsız (alsan → Alsancak). En fazla 8 sonuç; 2 karakterden kısa sorgu boş liste döner. Yanıt 60 sn herkese açık önbelleklenir. Bu uç ilçe filtresi almaz; istemci ilceId alanına göre sıralar.

Kimlik:
gerekmez
Hız sınırı:
IP başına 60 / dk

Parametreler

AdKonumZorunluTipAçıklama
qqueryhayırstringArama metni (en az 2 karakter; 60 karakterden sonrası kırpılır) Örnek: alsan

Yanıtlar

200Eşleşen mahalleler (boş dizi olabilir)

AlanTipZorunluAçıklama
success= trueevetHer zaman true
datadizi<MahalleSonucu>evetEn fazla 8 sonuç; önek eşleşmesi önce
data[].idintegerevetMahalle kimliği (kaynak veri mahalle_id)
data[].adstringevetBaşlık biçiminde ad
data[].ilceIdintegerevet
data[].ilceAdstringevet
Örnek 200
{
  "success": true,
  "data": [
    {
      "id": 61033,
      "ad": "Alsancak Mahallesi",
      "ilceId": 3513,
      "ilceAd": "Konak"
    }
  ]
}

429Hız sınırı aşıldı; retry-after başlığı ve yenidenSn alanı kaç saniye sonra denenebileceğini söyler

Örnek 429
{
  "success": false,
  "message": "Çok fazla istek; lütfen biraz sonra tekrar deneyin",
  "yenidenSn": 412
}

500Beklenmeyen sunucu hatası; ayrıntı yalnız sunucu logunda

Örnek 500
{
  "success": false,
  "message": "Sunucu hatası"
}
curl
curl -X GET "$LEZZET35_URL/api/bolge/mahalle-ara?q=alsan"

Kaynak: src/app/api/bolge/mahalle-ara/route.ts · modules/M04-bolge/servis-alani.ts mahalleAra

SiparişMatik v1 (iki sistem: WhatsApp/markalı site · Pazaryeri)

SiparişMatik kasa uyumluluk katmanı — yollar ve alanlar WPSipariş ile birebir (Faz 6, canlı); entegrasyon belgesi docs/api/siparismatik.md

get/api/v1/poolHazır

Havuz: bağlantıya hazır firmalar

Exe açılışta yerelde Lezzet35 kaydı yoksa çağırır; havuz[] içinde siparismatik_id eşleşen firmanın api_token’ını alır. Lezzet35’te HAZIR penceresi (KARAR-9): admin "bağlantıya hazırla" der → firma POOL_HAZIR_PENCERE_SAAT (24 sa) boyunca havuzda görünür → PUT /pool/connect ile BAGLI olur ya da süre dolunca düşer. WPSipariş’in "tüm HAZIR firmaların token’ı döner" davranışı böyle daraltılır; exe değişmez.

Kimlik:
X-Pool-Secret
Hız sınırı:
IP başına 30 / dk

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
successbooleanevetJSON boolean; exe "True" metniyle karşılaştırır
messagestringhayırBilgi mesajı
havuz[].idintegerevetFirma kimliği (Firma.v1Id); exe pool seçiminde kullanır
havuz[].domain_idintegerhayırAna marka kimliği
havuz[].siparismatik_idintegerevetSiparişMatik firmaid; exe Registry("firmaid") ile eşler
havuz[].adstringevetFirma adı
havuz[].subdomainstringevetMarka slug’ı (eski alt alan adı)
havuz[].baglanti_durumustringevetHer zaman HAZIR (pencere içindeki firmalar)
havuz[].api_tokenstringevetFirma Bearer anahtarı — yalnız HAZIR penceresinde döner (KARAR-9)
toplamintegerhayırListedeki firma sayısı
curl
curl -X GET "$LEZZET35_URL/api/v1/pool" \
  -H "X-Pool-Secret: $POOL_SECRET_KEY"

Kaynak: wpsiparis-api-contract.md §4.1 · Entegrasyon.cs:7905-7921

put/api/v1/pool/connectHazır

Havuz: bağlan

Gövde yok. Firma BAGLI olur, havuzdan düşer; firma.* alanları exe’nin entegrasyon kaydına yazılır. Token rotasyonu bu uçta mümkün değil (exe token’ı değiştirmez).

Kimlik:
Bearer (firma anahtarı)

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

404Firma/kayıt yok ya da başka firmaya ait (varlık sızdırmaz)

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
successbooleanevet
firma.idintegerevetFirma kimliği
firma.domain_idintegerevetAna şube kimliği; exe ana entegrasyon kaydına yazar
firma.adstringevet
firma.subdomainstringevet
firma.baglanti_durumustringevetconnect → BAGLI, disconnect → HAZIR
firma.baglanti_zamanistringevetdd.MM.yyyy HH:mm
firma.baglantistringevetONLINE | OFFLINE
curl
curl -X PUT "$LEZZET35_URL/api/v1/pool/connect" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: §4.2 · Entegrasyon.cs:7945-7961

put/api/v1/pool/disconnectHazır

Havuz: bağlantıyı kopar

Exe çağırmaz; admin "bağlantıyı kopar" ile aynı işlev. Firma yeniden HAZIR olur ve pencere baştan başlar.

Kimlik:
Bearer (firma anahtarı)

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

404Firma/kayıt yok ya da başka firmaya ait (varlık sızdırmaz)

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
successbooleanevet
firma.idintegerevetFirma kimliği
firma.adstringevet
firma.baglanti_durumustringevetconnect → BAGLI, disconnect → HAZIR
firma.baglantistringevetONLINE | OFFLINE
curl
curl -X PUT "$LEZZET35_URL/api/v1/pool/disconnect" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: §4.2 · PoolController.php:194-230

post/api/v1/pool/categories/syncHazır

Kategori senkronu (exe → Lezzet35)

Kodda var, zamanlanmamış (Form_KasaService.cs:1207 yorumda). Yeni kategori PASIF olarak eklenir ve moderasyon kuyruğuna düşer; sp_kategori_id eşleşende yalnız ad güncellenir; silme yok. İdempotent: (firma, sp_kategori_id) tekil.

Kimlik:
Bearer (firma anahtarı)

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
categoriesdizi<nesne>evet
categories[].sp_kategori_idstringhayır
categories[].adstringevet
categories[].siraintegerhayır
categories[].aciklamastringhayır
categories[].durumenum(AKTIF | PASIF)hayır

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

422Doğrulama hatası: {success:false, message:"Doğrulama hatası: …"}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
categories[].sp_kategori_idstringevetKasa kategori kimliği (eşleme anahtarı)
categories[].adstringevetASCIITemizle uygulanmış ad
categories[].siraintegerevet
categories[].aciklamastringevet
categories[].durumAKTIF | PASIFhayır
successbooleanevet
messagestringevetExe ürün senkronunda okur
summary.createdintegerhayır
summary.updatedintegerhayır
summary.skippedintegerhayırİdempotent tekrar → skipped artar
summary.totalintegerhayır
curl
curl -X POST "$LEZZET35_URL/api/v1/pool/categories/sync" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI" \
  -H "Content-Type: application/json" \
  -d '{"categories":[{"sp_kategori_id":"12","ad":"Kumrular","sira":1,"aciklama":""}]}'

Kaynak: §4.2 · PoolController.php:305-406 · Entegrasyon.cs:8094-8128

post/api/v1/pool/products/syncHazır

Ürün senkronu (exe/Pro → Lezzet35)

10 sn’de bir, yalnız guncelle='Y' ürünler. Exe bayrağı yanıt gelmeden temizler (Entegrasyon.cs:8233) → ağ hatasında güncelleme kaybolur; telafi: admin "tam senkron iste" komutu ve Faz 6 v2 webhook. Yeni ürün PASIF eklenir; sp_urun_id eşleşende ad/fiyat/varyant güncellenir ve restoran panelinde "SiparişMatik’ten geldi" etiketiyle görünür. urunweb='N' → PASIF; çarpan tipi varyantta fiyat = urun_fiyat × carpan.

Kimlik:
Bearer (firma anahtarı)
Hız sınırı:
Token başına 120 / dk (tüm firma uçları ortak)

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
productsdizi<nesne>evet
products[].sp_urun_idstringhayır
products[].sp_kategori_idstringhayır
products[].kategori_adstringhayır
products[].adstringevet
products[].fiyatnumberevet
products[].aciklamastringhayır
products[].siraintegerhayır
products[].durumenum(AKTIF | PASIF)hayır
products[].kdvenum(0 | 1 | 10 | 20)hayır
products[].ekstralardizi<nesne>hayır
products[].ekstralar[].adstringhayır
products[].ekstralar[].fiyatnumberhayır
products[].foto_urlstringhayır
products[].salon_fiyatnumberhayır
products[].alerjenlerdizi<string>hayır
products[].etiketlerdizi<string>hayır
products[].silindibooleanhayır
products[].guncellendi_atstring (date-time)hayır
products[].varyantlardizi<nesne>hayır
products[].varyantlar[].adstringevet
products[].varyantlar[].fiyatnumberevet

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

422Doğrulama hatası: {success:false, message:"Doğrulama hatası: …"}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
products[].sp_urun_idstringevetKasa ürün kimliği (eşleme anahtarı)
products[].sp_kategori_idstringevet
products[].kategori_adstringevet
products[].adstringevet
products[].fiyatnumberevetTL, ondalık
products[].aciklamastringevet
products[].siraintegerevet
products[].durumAKTIF | PASIFeveturunweb='N' → PASIF
products[].varyantlar[].adstringevet
products[].varyantlar[].fiyatnumberevetÇarpanlı varyantta hesaplanmış fiyat
products[].kdv0 | 1 | 10 | 20hayırPro ek alanı (sözleşme §1.2)
products[].ekstralar[]{ad, fiyat}[]hayırPro ek alanı; tek grup "Ekstralar", ek ücret
products[].foto_urlstringhayırYalnız Lezzet35 yükleme adresi (…/foto ucu)
products[].salon_fiyatnumberhayırMasa (xQR) fiyatı TL (K-44 §4); verilmezse değişmez, null → paket fiyatı
products[].alerjenlerstring[]hayır14 yönetmelik kodu (bilinmeyen kod → 422): gluten, kabuklu_deniz, yumurta, balik, fistik, soya, sut, kabuklu_yemis, kereviz, hardal, susam, sulfit, aci_bakla, yumusakca
products[].etiketlerstring[]hayırvejetaryen, vegan, glutensiz, laktozsuz, helal, aci (bilinmeyen → 422)
products[].silindibooleanhayırtrue → PASIF (silinmez)
products[].guncellendi_atdate-timehayırÇakışma kuralı: Lezzet35 updatedAt'ten eskiyse satır uygulanmaz
successbooleanevet
messagestringevetExe ürün senkronunda okur
summary.createdintegerhayır
summary.updatedintegerhayır
summary.skippedintegerhayırİdempotent tekrar → skipped artar
summary.totalintegerhayır
errors[]string[]hayırSatır bazlı hata mesajları
conflicts[]string[]hayırÇakışma nedeniyle atlanan sp_urun_id'ler (Pro)
curl
curl -X POST "$LEZZET35_URL/api/v1/pool/products/sync" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI" \
  -H "Content-Type: application/json" \
  -d '{"products":[{"sp_urun_id":"1001","sp_kategori_id":"12","kategori_ad":"Kumrular","ad":"Klasik Kumru","fiyat":120,"aciklama":"","sira":1,"durum":"AKTIF","varyantlar":[{"ad":"Büyük","fiyat":145}]}]}'

Kaynak: §4.2 · PoolController.php:415-584 · Entegrasyon.cs:8163-8243

post/api/v1/pool/products/{sp_urun_id}/fotoHazır

Ürün görseli (Pro → Lezzet35)

SiparişMatik Pro menü senkronu (docs/pro-menu-senkron-sozlesmesi.md §1.3): multipart dosya (JPEG/PNG/WebP, ≤ 3 MB) → WebP ≤ 1200 px; ürün sp_urun_id ile bulunur (önce products/sync). Yanıt data.foto_url mutlak adres.

Kimlik:
Bearer (firma anahtarı)
Hız sınırı:
Firma başına 30 / dk

Parametreler

AdKonumZorunluTipAçıklama
sp_urun_idpathevetstringPro ürün kimliği (metin; sayı da kabul) Örnek: 41

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

404Ürün yok (önce products/sync)

422Doğrulama hatası: {success:false, message:"Doğrulama hatası: …"}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
dosyafileevetmultipart
successbooleanevet
data.foto_urlstringevetMutlak adres; products/sync foto_url olarak geri gönderilebilir
curl
curl -X POST "$LEZZET35_URL/api/v1/pool/products/41/foto" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: Pro sözleşmesi §1.3

post/api/v1/pool/sms/logHazır

SMS kazanım logu (api.siparismatik.net → Lezzet35)

Exe değil, SiparişMatik merkez sunucusu çağırır (function.php:522-560 Lezzet35_SMSLog): içinde Lezzet35 adresi geçen SMS’lerin adedini raporlar. İdempotency: siparismatik_id + tarih + tip + adet + aciklama özeti; aynı kayıt iki kez sayılmaz (M08/M13 raporu).

Kimlik:
X-Pool-Secret

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
siparismatik_idintegerevet
sms_logsdizi<nesne>evet
sms_logs[].tarihstring (date)evet
sms_logs[].tipenum(tek | toplu)evet
sms_logs[].adetintegerevet
sms_logs[].aciklamastringhayır

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

404Firma/kayıt yok ya da başka firmaya ait (varlık sızdırmaz)

422Doğrulama hatası: {success:false, message:"Doğrulama hatası: …"}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
siparismatik_idintegerevet
sms_logs[].tarihdateevet
sms_logs[].tiptek | topluevet
sms_logs[].adetinteger ≥ 1evet
sms_logs[].aciklamastringhayır
data.firma_idintegerhayır
data.firma_adstringhayır
data.kaydedilenintegerhayırBu çağrıda kaydedilen satır sayısı
curl
curl -X POST "$LEZZET35_URL/api/v1/pool/sms/log" \
  -H "X-Pool-Secret: $POOL_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"siparismatik_id":9001,"sms_logs":[{"tarih":"2026-09-16","tip":"toplu","adet":120,"aciklama":"Kampanya"}]}'

Kaynak: §4.1 · PoolController.php:766-825

get/api/v1/Hazır

Keşif ucu

Firma özeti ve uç listesi (restaurant, endpoints). Exe çağırmaz; zararsız keşif.

Kimlik:
Bearer (firma anahtarı)

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
restaurant.idintegerhayır
restaurant.namestringhayır
restaurant.subdomainstringhayır
restaurant.online_aktifbooleanhayır
restaurant.statusstringhayır
restaurant.markalar[]object[]hayır
endpointsobjecthayırUç adı → yol
curl
curl -X GET "$LEZZET35_URL/api/v1/" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: §4.3 · ApiController.php:17-57

get/api/v1/statusHazır

Firma durumu

Firma ve markaların açık/kapalı durumu.

Kimlik:
Bearer (firma anahtarı)

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
data.idintegerhayır
data.namestringhayır
data.online_aktifbooleanhayır
data.statusstringhayır
data.urlstringhayır
data.markalar[].idintegerhayır
data.markalar[].marka_adistringhayır
data.markalar[].aktifbooleanhayır
data.markalar[].statusstringhayır
curl
curl -X GET "$LEZZET35_URL/api/v1/status" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: §4.3 · ApiController.php:62-99

post/api/v1/statusHazır

Firmayı aç/kapat

Exe’de yorumda (8051). Lezzet35’te firmanın tüm şubelerini açar/kapatır (WPSipariş yalnız online_aktif bayrağını değiştiriyordu, vitrinde etkisizdi).

Kimlik:
Bearer (firma anahtarı)

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
statusenum(online | offline)evet

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
statusonline | offlineevetİstek
curl
curl -X POST "$LEZZET35_URL/api/v1/status" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI" \
  -H "Content-Type: application/json" \
  -d '{"status":"online"}'

Kaynak: §4.3 · ApiController.php:104-131

get/api/v1/branchesHazır

Şubeler (alt markalar)

Ana şube hariç şubeler; exe her satır için ayrı entegrasyon kaydı açar (entegrasyonresid = data[].id). Ana şube connect.firma.domain_id ile ayrıca kaydedilir — Lezzet35 aynı ayrımı korur.

Kimlik:
Bearer (firma anahtarı)

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
successbooleanevet
data[].idintegerevetŞube kimliği
data[].marka_adistringevet
data[].subdomainstringevet
data[].urlstringevetVitrin adresi
data[].aktifbooleanevet
data[].statusstringhayır
curl
curl -X GET "$LEZZET35_URL/api/v1/branches" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: §4.3 · ApiController.php:136-160 · Entegrasyon.cs:7990-8009

post/api/v1/branches/{id}/statusHazır

Şubeyi aç/kapat

10 sn’de bir, yalnız yerel durum değişince. Kiracı sınırı: token firması ≠ şube firması → 403. Yanıttaki data.online_aktif gönderilenle eşitse exe yerel durumu günceller.

Kimlik:
Bearer (firma anahtarı)

Parametreler

AdKonumZorunluTipAçıklama
idpathevetintegerŞube kimliği (branches → data[].id; ana şube kimliği de kabul) Örnek: 1042

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
statusenum(online | offline)evet

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

403Başka firmanın şubesi

404Şube yok

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
statusonline | offlineevetİstek
successbooleanevet
data.domain_idintegerhayır
data.marka_adistringhayır
data.online_aktifbooleanevetExe "True" karşılaştırması
data.ana_markabooleanhayır
curl
curl -X POST "$LEZZET35_URL/api/v1/branches/1042/status" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI" \
  -H "Content-Type: application/json" \
  -d '{"status":"offline"}'

Kaynak: §4.3 · ApiController.php:165-249 · Entegrasyon.cs:8046-8072

get/api/v1/menuHazır

Menü aynası (Lezzet35 → exe)

Açılışta bir kez. Kategori ve ürünler kasaya aynalanır; exe urun.kategori.id == kategori.id ile eşler, siparismatik_id alanlarıyla yerel tablolara bağlar. `marka` nesnesi asla null dönmez (exe null kontrolsüz okur: Entegrasyon.cs:8508, 8521).

Kimlik:
Bearer (firma anahtarı)

Parametreler

AdKonumZorunluTipAçıklama
sincequeryhayırstringISO-8601 UTC; verilirse yalnız updatedAt >= since kayıtlar (silinmişler silindi:true). Pro artımlı çekme; bir sonraki değer summary.sunucu_zamani

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
successbooleanevet
data.firma.idintegerevet
data.firma.adstringevet
data.firma.siparismatik_idintegerevet
data.markalar[]object[]evet{id, ad, subdomain, ana_marka, aktif}
data.kategoriler[].idintegerevet
data.kategoriler[].siparismatik_idstringevetKasa kategori kimliği (eşleme)
data.kategoriler[].adstringevet
data.kategoriler[].siraintegerevet
data.kategoriler[].durumstringhayır
data.kategoriler[].marka.idintegerevetAsla null
data.kategoriler[].marka.adstringhayır
data.urunler[].idintegerevet
data.urunler[].siparismatik_idstringevet
data.urunler[].adstringevet
data.urunler[].kategori.idintegerevetKategori eşleme anahtarı
data.urunler[].fiyatnumberevet
data.urunler[].indirimli_fiyatnumber | nullhayır
data.urunler[].aciklamastringevet
data.urunler[].fotostring | nullhayır
data.urunler[].siraintegerhayır
data.urunler[].durumstringhayır
data.urunler[].varyantlar[]object[]hayır{ad, fiyat} mutlak fiyat
data.urunler[].ekstralar[]object[]hayır{ad, fiyat} ek ücret (Pro)
data.urunler[].kdvintegerhayırPro
data.urunler[].guncellendi_atdate-timehayırUTC ISO (Pro çakışma kuralı)
data.urunler[].salon_fiyatnumber | nullhayırMasa (xQR) fiyatı TL; null → paket fiyatı (K-44 §4)
data.urunler[].alerjenlerstring[]hayır14 yönetmelik kodu: gluten, kabuklu_deniz, yumurta, balik, fistik, soya, sut, kabuklu_yemis, kereviz, hardal, susam, sulfit, aci_bakla, yumusakca
data.urunler[].etiketlerstring[]hayırvejetaryen, vegan, glutensiz, laktozsuz, helal, aci
data.urunler[].silindibooleanhayırYalnız since ile gelebilir
data.urunler[].marka.idintegerevetAsla null
summaryobjecthayırSayımlar + sunucu_zamani (bir sonraki since) + since
curl
curl -X GET "$LEZZET35_URL/api/v1/menu" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: §4.3 · MenuController.php:20-128 · Entegrasyon.cs:8490-8531

get/api/v1/iptal-nedenleriHazır

İptal/ret nedenleri (v2.0)

Admin'in yönettiği hazır neden listesi; exe/köprü kodları gömmez, açılışta ve günde bir çeker. PUT …/durum gövdesinde iptal_nedeni olarak gönderilir. Her iki akışta aynı liste.

Kimlik:
Bearer (firma anahtarı)

Yanıtlar

200Liste

AlanTipZorunluAçıklama
successbooleanhayır
datadizi<nesne>hayır
data[].kodstringhayır
data[].metinstringhayır
data[].aciklama_zorunlubooleanhayır
Örnek 200
{
  "success": true,
  "message": "İptal nedenleri",
  "data": [
    {
      "kod": "URUN_YOK",
      "metin": "Ürün / malzeme kalmadı",
      "aciklama_zorunlu": false
    },
    {
      "kod": "DIGER",
      "metin": "Diğer",
      "aciklama_zorunlu": true
    }
  ]
}

401Kimlik başlığı eksik/yanlış: {success:false, message}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
kodstringevetSabit kod
metinstringevetMüşteriye gösterilen metin (admin düzenler)
aciklama_zorunlubooleanevettrue ise durum_aciklama zorunlu
curl
curl -X GET "$LEZZET35_URL/api/v1/iptal-nedenleri" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: sözleşme v2.0 §3

get/api/v1/firma/siparislerHazır

Aktif siparişler (exe 10 sn’de bir çeker)

Exe parametresiz çağırır ve yalnız ilk sayfayı işler. WPSipariş 20’lik sayfalıyordu → 21. sipariş kayboluyordu. Lezzet35: parametresiz çağrıda günün tüm aktif siparişleri tek yanıtta (meta.last_page = 1); durum not in (TESLIM_EDILDI, IPTAL, REDDEDILDI). Exe siparis_no ile tekilleştirir (websiparisid), marka.id ile hangi entegrasyon kaydına düşeceğini bulur.

Kimlik:
Bearer (firma anahtarı)
Hız sınırı:
Token başına 120 / dk (exe 10 sn’de ≤ 4 çağrı yapar)

Parametreler

AdKonumZorunluTipAçıklama
durumqueryhayırstring (BEKLEMEDE | ONAYLANDI | HAZIRLANIYOR | YOLDA | TESLIM_EDILDI | IPTAL | REDDEDILDI)v1 durum filtresi; exe göndermez
tarih_baslangicqueryhayırstringYYYY-MM-DD
tarih_bitisqueryhayırstringYYYY-MM-DD
per_pagequeryhayırintegerYalnız parametreli çağrıda; varsayılan 20
pagequeryhayırinteger

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
successbooleanevet
data[].idintegerevetSipariş v1Id; exe messageid — durum güncellemesinde {id}
data[].siparis_nostringevetL35-YYYYMMDD-XXXXXX; exe websiparisid (tekilleştirme anahtarı)
data[].musteri_idintegerevet
data[].musteri_adistringevet
data[].musteri_telefonstringevetUlusal biçim
data[].musteri_adresstringevetTam metin: sokak/bina/kat/daire, mahalle, ilçe (+tarif); eski exe için
data[].musteri_adres_kisastringevetYalnız sokak/bina/kat/daire (+tarif); mahalle/ilçe ayrı alanlarda (26.10)
data[].musteri_enlemnumber | nullevetTeslimat pini WGS84 (26.10); yoksa null → metin yedeği
data[].musteri_boylamnumber | nullevet
data[].musteri_ilstringevetİzmir
data[].musteri_ilcestringevet
data[].musteri_semtstringevetBoş dize olabilir
data[].musteri_mahallestringevet
data[].siparis_tipistringevetSabit "WP" (exe → "Y")
data[].teslimat_tipistringevetPAKET | GEL_AL | MASA (xQR masa siparişi, K-44 Faz 2: YOLDA yok, hazır olunca servis; ödeme masada)
data[].masa_nostring | nullevetMASA siparişinde masa numarası/adı (QR'daki özgün yazım); diğerlerinde null
data[].odeme_turustringevetNAKIT | KAPIDA_KART | ONLINE_KART | YEMEK_KARTI — kasa tahsilat kararı bununla
data[].odendibooleanevetYalnız ONLINE_KART’ta true (iyzico’da tahsil edildi)
data[].odeme_yontemistringevetGörünen ad / yemek kartı markası (Multinet, Sodexo, Edenred, Setcard, Metropol, Tokenflex, Paycell, iWallet); katalog 26.10
data[].para_ustunumber | nullevetNakitte müşterinin vereceği tutar (TL); yoksa null (26.10)
data[].ara_toplamnumberevetTL (Σ urunler[].toplam_fiyat, ödenen fiyatlarla)
data[].indirim_oraninumberhayırMarka/site yüzde indirimi
data[].indirim_tutarinumberevetMarka/site indirimi tutarı
data[].urun_indiriminumberevetΣ adet × urunler[].indirim (ürün indirimleri); indirim_tutari’na eklenmez (26.10)
data[].teslimat_ucretinumberevet
data[].toplam_tutarnumberevetara_toplam − indirim_tutari + teslimat_ucreti
data[].durumstringevetv1 görünümü: BEKLEMEDE | ONAYLANDI | YOLDA | TESLIM_EDILDI | IPTAL (HAZIRLANIYOR → ONAYLANDI, REDDEDILDI → IPTAL)
data[].durum_textstringevetTürkçe etiket
data[].siparis_zamanistringevetdd.MM.yyyy HH:mm — başka biçim exe’de istisna (DateTime.ParseExact)
data[].teslim_tahministring | nullevetHH:mm
data[].siparis_notustringhayır
data[].marka.idintegerevetŞube/marka kimliği (v1Id); exe entegrasyonresid ile eşler
data[].marka.marka_adistringevet
data[].marka.subdomainstringhayır
data[].marka.ana_markabooleanhayır
data[].urunler[].product_idintegerevetLezzet35 ürün v1Id
data[].urunler[].siparismatik_idstringhayırKasa ürün kimliği (eşleme)
data[].urunler[].kategori_siparismatik_idstringhayır
data[].urunler[].urun_adistringevetSipariş anındaki ad
data[].urunler[].adetintegerevet
data[].urunler[].birim_fiyatnumberevetÖDENEN birim fiyat (seçimler dahil)
data[].urunler[].liste_fiyatnumber | nullevetİndirimsiz birim fiyat; indirim yoksa null (26.10)
data[].urunler[].indirimnumberevetBirim başına ürün indirimi; yoksa 0 (26.10)
data[].urunler[].toplam_fiyatnumberevet
data[].urunler[].varyantlar[].idintegerevet
data[].urunler[].varyantlar[].adstringevet
data[].urunler[].varyantlar[].fiyatnumberevet
data[].urunler[].ekstralar[].idintegerevet
data[].urunler[].ekstralar[].adstringevet
data[].urunler[].ekstralar[].fiyatnumberevet
data[].urunler[].ozel_notstringevetKalem notu; boş dize olabilir
data[].urunler[].menuobject | nullevetMenü seçimi: {id, ad, fiyat, secilenler[]}
data[].urunler[].menu.secilenler[].urunstringevet
data[].urunler[].menu.secilenler[].fiyatnumberevet
meta.current_pageintegerhayırParametresiz çağrıda her zaman 1
meta.last_pageintegerhayırParametresiz çağrıda 1 (günün tüm aktif siparişleri tek sayfa)
meta.per_pageintegerhayır
meta.totalintegerhayır
curl
curl -X GET "$LEZZET35_URL/api/v1/firma/siparisler" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: §4.3 · SiparisController.php:597-768 · Entegrasyon.cs:8281-8417

get/api/v1/firma/siparisler/{id}Hazır

Tek sipariş (24.10, Pro: fiş yeniden basımı)

Liste satırıyla aynı şekil (data:{…}); teslim edilen / iptal edilen sipariş de okunur. Başka firmanın siparişi ya da yok → 404; sayı olmayan id → 422.

Kimlik:
Bearer (firma anahtarı)

Parametreler

AdKonumZorunluTipAçıklama
idpathevetintegerSipariş v1Id (data[].id) Örnek: 1042

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

404Sipariş bulunamadı

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
data.idintegerevetSipariş v1Id; exe messageid — durum güncellemesinde {id}
data.siparis_nostringevetL35-YYYYMMDD-XXXXXX; exe websiparisid (tekilleştirme anahtarı)
data.musteri_idintegerevet
data.musteri_adistringevet
data.musteri_telefonstringevetUlusal biçim
data.musteri_adresstringevetTam metin: sokak/bina/kat/daire, mahalle, ilçe (+tarif); eski exe için
data.musteri_adres_kisastringevetYalnız sokak/bina/kat/daire (+tarif); mahalle/ilçe ayrı alanlarda (26.10)
data.musteri_enlemnumber | nullevetTeslimat pini WGS84 (26.10); yoksa null → metin yedeği
data.musteri_boylamnumber | nullevet
data.musteri_ilstringevetİzmir
data.musteri_ilcestringevet
data.musteri_semtstringevetBoş dize olabilir
data.musteri_mahallestringevet
data.siparis_tipistringevetSabit "WP" (exe → "Y")
data.teslimat_tipistringevetPAKET | GEL_AL | MASA (xQR masa siparişi, K-44 Faz 2: YOLDA yok, hazır olunca servis; ödeme masada)
data.masa_nostring | nullevetMASA siparişinde masa numarası/adı (QR'daki özgün yazım); diğerlerinde null
data.odeme_turustringevetNAKIT | KAPIDA_KART | ONLINE_KART | YEMEK_KARTI — kasa tahsilat kararı bununla
data.odendibooleanevetYalnız ONLINE_KART’ta true (iyzico’da tahsil edildi)
data.odeme_yontemistringevetGörünen ad / yemek kartı markası (Multinet, Sodexo, Edenred, Setcard, Metropol, Tokenflex, Paycell, iWallet); katalog 26.10
data.para_ustunumber | nullevetNakitte müşterinin vereceği tutar (TL); yoksa null (26.10)
data.ara_toplamnumberevetTL (Σ urunler[].toplam_fiyat, ödenen fiyatlarla)
data.indirim_oraninumberhayırMarka/site yüzde indirimi
data.indirim_tutarinumberevetMarka/site indirimi tutarı
data.urun_indiriminumberevetΣ adet × urunler[].indirim (ürün indirimleri); indirim_tutari’na eklenmez (26.10)
data.teslimat_ucretinumberevet
data.toplam_tutarnumberevetara_toplam − indirim_tutari + teslimat_ucreti
data.durumstringevetv1 görünümü: BEKLEMEDE | ONAYLANDI | YOLDA | TESLIM_EDILDI | IPTAL (HAZIRLANIYOR → ONAYLANDI, REDDEDILDI → IPTAL)
data.durum_textstringevetTürkçe etiket
data.siparis_zamanistringevetdd.MM.yyyy HH:mm — başka biçim exe’de istisna (DateTime.ParseExact)
data.teslim_tahministring | nullevetHH:mm
data.siparis_notustringhayır
data.marka.idintegerevetŞube/marka kimliği (v1Id); exe entegrasyonresid ile eşler
data.marka.marka_adistringevet
data.marka.subdomainstringhayır
data.marka.ana_markabooleanhayır
data.urunler[].product_idintegerevetLezzet35 ürün v1Id
data.urunler[].siparismatik_idstringhayırKasa ürün kimliği (eşleme)
data.urunler[].kategori_siparismatik_idstringhayır
data.urunler[].urun_adistringevetSipariş anındaki ad
data.urunler[].adetintegerevet
data.urunler[].birim_fiyatnumberevetÖDENEN birim fiyat (seçimler dahil)
data.urunler[].liste_fiyatnumber | nullevetİndirimsiz birim fiyat; indirim yoksa null (26.10)
data.urunler[].indirimnumberevetBirim başına ürün indirimi; yoksa 0 (26.10)
data.urunler[].toplam_fiyatnumberevet
data.urunler[].varyantlar[].idintegerevet
data.urunler[].varyantlar[].adstringevet
data.urunler[].varyantlar[].fiyatnumberevet
data.urunler[].ekstralar[].idintegerevet
data.urunler[].ekstralar[].adstringevet
data.urunler[].ekstralar[].fiyatnumberevet
data.urunler[].ozel_notstringevetKalem notu; boş dize olabilir
data.urunler[].menuobject | nullevetMenü seçimi: {id, ad, fiyat, secilenler[]}
data.urunler[].menu.secilenler[].urunstringevet
data.urunler[].menu.secilenler[].fiyatnumberevet
curl
curl -X GET "$LEZZET35_URL/api/v1/firma/siparisler/1042" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: modules/M11-entegrasyon/v1-siparis.ts v1SiparisGetir

put/api/v1/firma/siparisler/{id}/durumHazır

Sipariş durumu (exe → Lezzet35)

tbl_siparis.guncelle='Y' olan WEB siparişleri için. Exe eşlemesi: BEKLIYOR→ONAYLANDI, ONAY→YOLDA, TESLIM→TESLIM_EDILDI, IPTAL/RED→IPTAL. Lezzet35 M06 durum makinesini uygular; geçersiz geçişte de `success:true` döner (aksi halde exe sonsuza kadar tekrar eder) ve olayı IntegrationLog’a "reddedildi" yazar. Exe success="True" görünce bayrağı temizler.

Kimlik:
Bearer (firma anahtarı)

Parametreler

AdKonumZorunluTipAçıklama
idpathevetintegerSipariş v1Id (data[].id, exe messageid) Örnek: 1042

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
durumenum(BEKLEMEDE | ONAYLANDI | HAZIRLANIYOR | YOLDA | TESLIM_EDILDI | IPTAL | REDDEDILDI)evet
iptal_nedenistringhayırv2.0: iptal/ret nedeni kodu (GET /iptal-nedenleri); bilinmeyen kod 422
durum_aciklamastringhayır
tahmini_sure_dkintegerhayır

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

404Başka firmanın siparişi ya da yok

422Geçersiz durum değeri

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
durumstringevetİstek; 7 değer kabul, exe 4’ünü gönderir
iptal_nedenistringhayırİstek (v2.0): iptal/ret nedeni kodu — GET /iptal-nedenleri listesinden; DIGER'de durum_aciklama zorunlu
durum_aciklamastringhayırİstek; iptal/ret sebebi (≤ 500)
tahmini_sure_dkintegerhayırİstek (24.10): teslim_tahmini = şimdi + dk; uç durumda yok sayılır
odendibooleanhayırİstek (27.10): hesap kapanışı; uç durumda da yazılır, GET odendi bunu döner
odeme_turustringhayırİstek (27.10): gerçek ödeme türü NAKIT|KAPIDA_KART|ONLINE_KART|YEMEK_KARTI (masa/kasa kapanışı)
successbooleanevetGeçersiz geçişte de true
data.siparis_nostringhayır
data.durumstringhayır
data.durum_textstringhayır
data.teslim_tahministring | nullhayırHH:mm (24.10)
data.degistibooleanhayırDurum gerçekten değişti mi (24.10)
data.reddedildibooleanhayırGeçersiz geçiş: uygulanmadı, message açıklar (24.10)
curl
curl -X PUT "$LEZZET35_URL/api/v1/firma/siparisler/1042/durum" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI" \
  -H "Content-Type: application/json" \
  -d '{"durum":"YOLDA"}'

Kaynak: §4.3 · SiparisController.php:773-828 · Entegrasyon.cs:8462-8476

post/api/v1/xqr/kayitHazır

xQR kaydı (Pro kasası → kod + alt alan)

Kimlik (Owner 26.10 gece: "kayıtta SiparişMatik ID kullanılsın"): X-Pool-Secret + istemci IP Pro paneli sunucusu (XQR_KAYIT_IZINLI_IP) + firmaid SiparişMatik yönetim listesinde var; telefon yalnız bilgi alanı (Firma/Şube telefonu). Firma Lezzet35'te yoksa Firma + ana marka + Merkez şube (pazaryeri dışı, açık) + sahip hesabı + tek seferlik api_key kurulur → 201. Firma zaten varsa yalnız xQR sitesi açılır → 200, api_key: null (mevcut Bearer geçerli). Aynı firmaid ile tekrar → aynı kod (idempotent). Hız sınırı firmaid başına 5/saat, IP başına 120/saat (kayıtlar Pro panelinden tek IP ile gelir).

Kimlik:
X-Pool-Secret

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
firmaidintegerevet
adstringevet
telefonstringevetİşletme telefonu (cep ya da sabit hat, 10–11 hane); yalnız bilgi — eşleşme aranmaz
cepstringhayırSahip cebi (isteğe bağlı): restoran paneli OTP girişi; yoksa telefon cepse o kullanılır
adresstringevet
ilstringevetİl adı ya da plaka kodu
ilcestringevet
konumnesnehayır
konum.enlemnumberhayır
konum.boylamnumberhayır
masa_siparisbooleanhayır
masa_sayisiintegerhayır
dillerdizi<enum(en | de | ar | ru)>hayır

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

201Yeni firma + xQR sitesi kuruldu; data.api_key tek sefer

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

403İstemci IP izinli listede değil ya da firmaid SiparişMatik listesinde yok

409Firma Lezzet35'te aktif değil / şubesi yok

422Doğrulama hatası (il/ilçe eşleşmedi, masa_sayisi, diller)

429IP başına 5/saat aşıldı

503SiparişMatik doğrulaması yapılandırılmamış ya da liste alınamadı

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
data.kodstringevet4 karakter; https://{kod}.xqr.com.tr
data.urlstringevetSitenin tam adresi (kapı etiketi QR'ı); masa QR'ı {url}/masa/{no}
data.api_keystring | nullevetYalnız yeni firmada (201), tek sefer; Pro Bearer olarak saklar
data.firma_idstringevetLezzet35 firma kimliği
data.lezzet35booleanevetFirma zaten Lezzet35'te miydi
data.online_urlstring | nullevetMüşteriye açık online sipariş adresi (markalı site / pazaryeri sayfası) ya da null
curl
curl -X POST "$LEZZET35_URL/api/v1/xqr/kayit" \
  -H "X-Pool-Secret: $POOL_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"firmaid":2456,"ad":"01 Lokman Usta","telefon":"05438676447","adres":"Saim Çıkrıkçı Cad. No 206","il":"İzmir","ilce":"Karabağlar","konum":{"enlem":38.38,"boylam":27.11},"masa_siparis":true,"masa_sayisi":20,"diller":["en"]}'

Kaynak: docs/api/xqr-sozlesme-taslagi.md §2

get/api/v1/xqrHazır

xQR ayarları

Kimlik:
Bearer (firma anahtarı)

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

404Firma xQR'a kayıtlı değil

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
data.kodstringevet
data.urlstringevet
data.masa_siparisbooleanevetMasadan sipariş açık mı (Faz 2)
data.masa_sayisiintegerevet1–200
data.dillerstring[]eveten|de|ar|ru
data.brosurobject | nullevet{surum, url, pdf_url} (Faz 4) ya da null
curl
curl -X GET "$LEZZET35_URL/api/v1/xqr" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: docs/api/xqr-sozlesme-taslagi.md §3

put/api/v1/xqrHazır

xQR ayarlarını güncelle (masadan sipariş anahtarı)

Kimlik:
Bearer (firma anahtarı)

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
masa_siparisbooleanhayır
masa_sayisiintegerhayır
dillerdizi<enum(en | de | ar | ru)>hayır

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

404Firma xQR'a kayıtlı değil

422Doğrulama hatası

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
masa_siparisbooleanhayırİstek
masa_sayisiintegerhayırİstek; 1–200
dillerstring[]hayırİstek
dataobjectevetGET ile aynı gövde
curl
curl -X PUT "$LEZZET35_URL/api/v1/xqr" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI" \
  -H "Content-Type: application/json" \
  -d '{"masa_siparis":false}'

Kaynak: docs/api/xqr-sozlesme-taslagi.md §3

put/api/v1/xqr/brosurHazır

Broşür PDF'ini barındır (Pro üretir, Lezzet35 sunar)

multipart: dosya (PDF, ≤ 10 MB, %PDF- imzası), surum (artan tam sayı; eski/aynı sürüm 409), tasarim (1–4, bilgi). Sonuç https://{kod}.xqr.com.tr/b (3 düğme + gömülü PDF) ve /b.pdf?v={surum}. Eski sürüm dosyası silinir. 10/dk.

Kimlik:
Bearer (firma anahtarı)

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

201Broşür kaydedildi

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

404Firma xQR'a kayıtlı değil

409surum mevcut sürümden büyük değil

422dosya/surum doğrulaması

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
data.surumintegerevet
data.boyutintegerevetbayt
data.urlstringevethttps://{kod}.xqr.com.tr/b
data.pdf_urlstringevethttps://{kod}.xqr.com.tr/b.pdf
curl
curl -X PUT "$LEZZET35_URL/api/v1/xqr/brosur" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: docs/api/xqr-sozlesme-taslagi.md §7

delete/api/v1/xqr/brosurHazır

Broşürü kaldır

Kimlik:
Bearer (firma anahtarı)

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

404Firma xQR'a kayıtlı değil

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
data.silindibooleanevetZaten yoksa false
curl
curl -X DELETE "$LEZZET35_URL/api/v1/xqr/brosur" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: docs/api/xqr-sozlesme-taslagi.md §7

get/api/v1/firma/masa-olaylariHazır

Masa olayları: garson çağır / hesap iste

Pro 10 sn sipariş döngüsüne eklenir (?durum=acik varsayılan). Müşteri masa sayfasındaki düğmeyle açar; aynı masada aynı türde açık olay tekrar açılmaz. sonSenkron damgalanır.

Kimlik:
Bearer (firma anahtarı)

Parametreler

AdKonumZorunluTipAçıklama
durumqueryhayırstring (acik | kapandi | tumu)acik (varsayılan) | kapandi | tumu

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

422Geçersiz durum

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
data[].idintegerevetOlay kimliği; kapatma ucunda kullanılır
data[].masa_nostringevetMasa (QR'daki numara ya da kısa ad)
data[].turstringevetGARSON | HESAP
data[].notstring | nullhayırMüşteri notu (≤ 200)
data[].durumstringevetACIK | KAPANDI
data[].olusturmastringevetISO 8601 (UTC)
data[].kapanisstring | nullevetISO 8601 (UTC) ya da null
toplamintegerevet
curl
curl -X GET "$LEZZET35_URL/api/v1/firma/masa-olaylari" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

Kaynak: docs/api/xqr-sozlesme-taslagi.md §6

put/api/v1/firma/masa-olaylari/{id}Hazır

Masa olayını kapat (garson gitti / hesap götürüldü)

Kimlik:
Bearer (firma anahtarı)

Parametreler

AdKonumZorunluTipAçıklama
idpathevetintegerMasa olayı kimliği (data[].id) Örnek: 17

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
durumenum(KAPANDI)evet

Yanıtlar

200v1 zarfı: success JSON boolean, message; veri anahtarları alan tablosunda

AlanTipZorunluAçıklama
successbooleanevet
messagestringhayır

401Kimlik başlığı eksik/yanlış: {success:false, message}

404Başka firmanın olayı ya da yok

422Geçersiz gövde

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
durumstringevetİstek; yalnız KAPANDI
data.idintegerevet
data.durumstringevetKAPANDI
data.kapanisstringevetISO 8601
data.degistibooleanevetZaten kapalıysa false (idempotent)
curl
curl -X PUT "$LEZZET35_URL/api/v1/firma/masa-olaylari/17" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI" \
  -H "Content-Type: application/json" \
  -d '{"durum":"KAPANDI"}'

Kaynak: docs/api/xqr-sozlesme-taslagi.md §6

Partner API v2 (Faz 6)

Diğer restoran yazılımları ve mobil uygulama için Partner API — taslak; Faz 6’da kontrat testleriyle sabitlenir

get/api/v2/restoranlarTaslak · Faz 6

Partnerin bağlı şubeleri

Anahtarın kapsamındaki şubeler (çoklu kiracı: bir anahtar birden çok şube yönetebilir). Kimlikler v2’de metin (cuid); v1’deki sayısal v1Id yalnız SiparişMatik için.

Kimlik:
X-Api-Key (partner)
Hız sınırı:
Partner başına 600 / dk (kota sözleşmeyle)

Yanıtlar

200{success, data} zarfı; şekil alan tablosunda

AlanTipZorunluAçıklama
success= trueevet
datanesneevet

401API anahtarı eksik/yanlış

429Partner kotası aşıldı

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
data[].idstringevetŞube kimliği
data[].adstringevet
data[].markastringevetVitrin adı
data[].ilcestringevet
data[].acikbooleanevet
data[].calismaSaatleri[]object[]hayır{gun, acilis, kapanis}
curl
curl -X GET "$LEZZET35_URL/api/v2/restoranlar" \
  -H "X-Api-Key: $PARTNER_API_ANAHTARI"
get/api/v2/restoranlar/{subeId}/menuTaslak · Faz 6

Şube menüsü

Kategoriler, ürünler, varyant/ekstra/menü grupları ve şube fiyatları. Fiyatlar kuruş (tam sayı).

Kimlik:
X-Api-Key (partner)
Hız sınırı:
Partner başına 600 / dk (kota sözleşmeyle)

Parametreler

AdKonumZorunluTipAçıklama
subeIdpathevetstringŞube kimliği (cuid) Örnek: cmfl3k9x40000abcd1234efgh

Yanıtlar

200{success, data} zarfı; şekil alan tablosunda

AlanTipZorunluAçıklama
success= trueevet
datanesneevet

401API anahtarı eksik/yanlış

404Şube anahtarın kapsamında değil

429Partner kotası aşıldı

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
data.kategoriler[]object[]evet{id, ad, sira, durum}
data.urunler[]object[]evet{id, kategoriId, ad, aciklama, fiyatKurus, indirimliFiyatKurus, durum, disKimlik}
data.urunler[].varyantGruplari[]object[]hayır
data.urunler[].ekstraGruplari[]object[]hayır
curl
curl -X GET "$LEZZET35_URL/api/v2/restoranlar/cmfl3k9x40000abcd1234efgh/menu" \
  -H "X-Api-Key: $PARTNER_API_ANAHTARI"
put/api/v2/restoranlar/{subeId}/menuTaslak · Faz 6

Menü senkronu (partner → Lezzet35)

Tam ya da kısmi menü gönderimi; disKimlik eşleme anahtarı. Yeni kayıt moderasyon kuyruğuna düşer (F4). İdempotent; Idempotency-Key zorunlu. Yanıt summary {created, updated, skipped}.

Kimlik:
X-Api-Key (partner)
Hız sınırı:
Partner başına 600 / dk (kota sözleşmeyle)

Parametreler

AdKonumZorunluTipAçıklama
subeIdpathevetstringŞube kimliği (cuid) Örnek: cmfl3k9x40000abcd1234efgh
Idempotency-KeyheaderevetstringPartnerin ürettiği tekil anahtar (UUID); aynı anahtarla tekrar → ilk yanıt, yan etki yok (24 sa) Örnek: 6f1c2a0e-3b8e-4c8f-9c1a-2d5f7a9b1c33

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
kategorilerdizi<nesne>hayır
urunlerdizi<nesne>evet

Yanıtlar

200{success, data} zarfı; şekil alan tablosunda

AlanTipZorunluAçıklama
success= trueevet
datanesneevet

400Doğrulama hatası (alan bazlı)

401API anahtarı eksik/yanlış

409Aynı Idempotency-Key farklı gövdeyle

429Partner kotası aşıldı

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
urunler[].disKimlikstringevetPartner ürün kimliği
urunler[].adstringevet
urunler[].fiyatKurusintegerevetKuruş
urunler[].kategoriDisKimlikstringhayır
urunler[].durumAKTIF | PASIFhayır
data.summaryobjectevet{created, updated, skipped}
curl
curl -X PUT "$LEZZET35_URL/api/v2/restoranlar/cmfl3k9x40000abcd1234efgh/menu" \
  -H "X-Api-Key: $PARTNER_API_ANAHTARI" \
  -H "Content-Type: application/json" \
  -d '{"kategoriler":[{"disKimlik":"12","ad":"Kumrular","sira":1}],"urunler":[{"disKimlik":"1001","kategoriDisKimlik":"12","ad":"Klasik Kumru","fiyatKurus":12000,"durum":"AKTIF"}]}'
put/api/v2/restoranlar/{subeId}/durumTaslak · Faz 6

Şubeyi aç/kapat

Kimlik:
X-Api-Key (partner)
Hız sınırı:
Partner başına 600 / dk (kota sözleşmeyle)

Parametreler

AdKonumZorunluTipAçıklama
subeIdpathevetstringŞube kimliği (cuid) Örnek: cmfl3k9x40000abcd1234efgh

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
acikbooleanevet
nedenstringhayır

Yanıtlar

200{success, data} zarfı; şekil alan tablosunda

AlanTipZorunluAçıklama
success= trueevet
datanesneevet

401API anahtarı eksik/yanlış

429Partner kotası aşıldı

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
acikbooleanevetİstek
nedenstringhayırVitrinde gösterilmez; panelde loglanır
data.acikbooleanevet
curl
curl -X PUT "$LEZZET35_URL/api/v2/restoranlar/cmfl3k9x40000abcd1234efgh/durum" \
  -H "X-Api-Key: $PARTNER_API_ANAHTARI" \
  -H "Content-Type: application/json" \
  -d '{"acik":false,"neden":"Yoğunluk"}'
get/api/v2/siparislerTaslak · Faz 6

Siparişleri listele

Webhook yerine ya da yanında çekme (polling) yolu. since ile artımlı; imleç tabanlı sayfalama (meta.sonraki).

Kimlik:
X-Api-Key (partner)
Hız sınırı:
Partner başına 600 / dk (kota sözleşmeyle)

Parametreler

AdKonumZorunluTipAçıklama
durumqueryhayırstring (ALINDI | ONAYLANDI | HAZIRLANIYOR | YOLDA | TESLIM_EDILDI | IPTAL | REDDEDILDI)
sincequeryhayırstringISO 8601; bu andan sonra güncellenenler
imlecqueryhayırstringÖnceki yanıtın meta.sonraki değeri

Yanıtlar

200{success, data} zarfı; şekil alan tablosunda

AlanTipZorunluAçıklama
success= trueevet
datanesneevet

401API anahtarı eksik/yanlış

429Partner kotası aşıldı

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
data[]object[]evetSipariş özeti: {id, no, subeId, durum, toplamKurus, olusturuldu, guncellendi}
meta.sonrakistring | nullevetSonraki sayfa imleci
curl
curl -X GET "$LEZZET35_URL/api/v2/siparisler" \
  -H "X-Api-Key: $PARTNER_API_ANAHTARI"
get/api/v2/siparisler/{id}Taslak · Faz 6

Sipariş detayı

Kalemler ve seçimler sipariş anındaki anlık görüntü; müşteri PII’si yalnız teslimat için gereken kadar (ad, telefon, adres).

Kimlik:
X-Api-Key (partner)
Hız sınırı:
Partner başına 600 / dk (kota sözleşmeyle)

Parametreler

AdKonumZorunluTipAçıklama
idpathevetstringSipariş kimliği (cuid) ya da numarası (L35-…) Örnek: L35-20260916-4F2A9C

Yanıtlar

200{success, data} zarfı; şekil alan tablosunda

AlanTipZorunluAçıklama
success= trueevet
datanesneevet

401API anahtarı eksik/yanlış

404Sipariş anahtarın kapsamında değil

429Partner kotası aşıldı

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
data.idstringevet
data.nostringevetL35-YYYYMMDD-XXXXXX
data.durumstringevetM06 iç durum
data.kalemler[]object[]evet{urunAdi, adet, birimFiyatKurus, toplamKurus, secimler[], not}
data.teslimatobjectevet{tip, adres, mahalle, not}
data.odemeobjectevet{tur, toplamKurus, tahsilatGerekli}
curl
curl -X GET "$LEZZET35_URL/api/v2/siparisler/L35-20260916-4F2A9C" \
  -H "X-Api-Key: $PARTNER_API_ANAHTARI"
put/api/v2/siparisler/{id}/durumTaslak · Faz 6

Sipariş durumunu güncelle

M06 durum makinesi kaynak: restoran kurallarıyla; geçersiz geçiş 400 döner (v1’den farklı: partnerin tekrar döngüsü yok). İdempotent.

Kimlik:
X-Api-Key (partner)
Hız sınırı:
Partner başına 600 / dk (kota sözleşmeyle)

Parametreler

AdKonumZorunluTipAçıklama
idpathevetstringSipariş kimliği (cuid) ya da numarası (L35-…) Örnek: L35-20260916-4F2A9C
Idempotency-KeyheaderevetstringPartnerin ürettiği tekil anahtar (UUID); aynı anahtarla tekrar → ilk yanıt, yan etki yok (24 sa) Örnek: 6f1c2a0e-3b8e-4c8f-9c1a-2d5f7a9b1c33

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
durumenum(ONAYLANDI | HAZIRLANIYOR | YOLDA | TESLIM_EDILDI | IPTAL | REDDEDILDI)evet
aciklamastringhayır
teslimTahminiDkintegerhayır

Yanıtlar

200{success, data} zarfı; şekil alan tablosunda

AlanTipZorunluAçıklama
success= trueevet
datanesneevet

400Geçersiz geçiş ya da doğrulama

401API anahtarı eksik/yanlış

404Sipariş yok

429Partner kotası aşıldı

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
durumstringevetİstek
aciklamastringhayırMüşteriye gösterilir (ret/iptal nedeni)
teslimTahminiDkintegerhayırOnayda tahmini süre
data.oncekistringevet
data.yenistringevet
curl
curl -X PUT "$LEZZET35_URL/api/v2/siparisler/L35-20260916-4F2A9C/durum" \
  -H "X-Api-Key: $PARTNER_API_ANAHTARI" \
  -H "Content-Type: application/json" \
  -d '{"durum":"ONAYLANDI","teslimTahminiDk":35}'
post/api/v2/webhooksTaslak · Faz 6

Webhook aboneliği

Olaylar: siparis.olusturuldu, siparis.durum, menu.degisti, sube.durum. Teslim: POST url, gövde {olay, kimlik, zaman, veri}; başlıklar X-Lezzet35-Olay, X-Lezzet35-Teslim-Id, X-Lezzet35-Imza: sha256=HMAC_SHA256(gizliAnahtar, hamGovde). 2xx dışı → üstel geri çekilme ile 5 deneme (1, 2, 5, 15, 60 dk), sonra dead-letter ve panelde uyarı. Sipariş oluştuğunda teslim hedefi ≤ 2 sn.

Kimlik:
X-Api-Key (partner)
Hız sınırı:
Partner başına 600 / dk (kota sözleşmeyle)

İstek gövdesi (application/json)

AlanTipZorunluAçıklama
urlstring (uri)evet
olaylardizi<enum(siparis.olusturuldu | siparis.durum | menu.degisti | sube.durum)>evet
gizliAnahtarstringhayırVerilmezse sunucu üretir ve yalnız bu yanıtta gösterir

Yanıtlar

200{success, data} zarfı; şekil alan tablosunda

AlanTipZorunluAçıklama
success= trueevet
datanesneevet

400URL https değil ya da olay bilinmiyor

401API anahtarı eksik/yanlış

429Partner kotası aşıldı

Sözleşme alanları (taslak)

AlanTipZorunluAçıklama
urluri (https)evetİstek
olaylar[]string[]evetİstek
gizliAnahtarstringhayırİstek; ≥ 32 karakter
data.idstringevetAbonelik kimliği
data.gizliAnahtarstringevetYalnız bu yanıtta düz metin
curl
curl -X POST "$LEZZET35_URL/api/v2/webhooks" \
  -H "X-Api-Key: $PARTNER_API_ANAHTARI" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://pos.ornek.com/lezzet35/webhook","olaylar":["siparis.olusturuldu","siparis.durum"]}'

Kimlik doğrulama

Herkese açık JSON uçları (sağlık, OTP, mahalle arama) kimlik istemez. Diğer bölgeler dört şemadan biriyle korunur; hepsinde sır sunucuda özet (sha256) olarak saklanır.

bearerFirma · HTTP bearer

Authorization: Bearer <api_token> — firma anahtarı; sunucuda sha256 özeti saklanır, düz metin yalnız üretim anında admin’e bir kez gösterilir. SiparişMatik exe GET /pool ile alır.

bash
curl "$LEZZET35_URL/api/v1/firma/siparisler" \
  -H "Authorization: Bearer $FIRMA_API_ANAHTARI"

poolSecret · Başlık X-Pool-Secret

Tüm SiparişMatik kurulumlarında ortak, exe’ye gömülü anahtar (yalnız /api/v1/pool ve /pool/sms/log). Değiştirilemez; HAZIR penceresiyle daraltılır (KARAR-9).

bash
curl "$LEZZET35_URL/api/v1/pool" \
  -H "X-Pool-Secret: $POOL_SECRET_KEY"

partnerAnahtar · Başlık X-Api-Key

Partner API v2 anahtarı; sha256 özet, çoklu kiracı, partner başına kota (Faz 6).

bash
curl "$LEZZET35_URL/api/v2/restoranlar" \
  -H "X-Api-Key: $PARTNER_API_ANAHTARI"

cerezOturum · Çerez l35_oturum

Tarayıcı oturumu: HttpOnly, SameSite=Lax, 30 gün; /giris Server Action açar. Dahili sayfa/eylem yetkisi bu çerezle; herkese açık JSON uçları çerez istemez.

bash
# Tarayıcı çerezi; /giris akışı açar. Çerezi elle taşıma önerilmez.

Hız sınırı

Sabit pencereli sayaç, Redis üzerinde. Aşımda 429, retry-after başlığı ve yenidenSn alanı döner. Üretimde Redis erişilemezse uç 503 verir (fail-closed); geliştirmede uyarıyla geçer.

UçSınırNot
POST /api/auth/otp/istekTelefon: 3 / 10 dk · IP: 21 / 10 dkArdışık istek 60 sn bekleme (OTP_BEKLEME_SN); e2e sunucusu gevşetir
POST /api/auth/otp/dogrulaTelefon: 10 / 10 dkKod başına 5 deneme (OTP_MAX_DENEME)
GET /api/bolge/mahalle-araIP: 60 / dkYanıt 60 sn önbellek
Restoran başvurusu (form)IP: 5 / günYalnız kayda giden gönderimler sayılır
/api/v1/pool*IP: 30 / dkX-Pool-Secret ortak anahtar
/api/v1/* firma uçlarıToken: 120 / dkExe 10 sn’de ≤ 4 çağrı yapar
/api/v2/* (Faz 6)Partner: 600 / dkKota sözleşmeyle; aşımda 429

Hata kodları

Hata zarfı: { success: false, message, errors? }. Mesajlar Türkçe ve kullanıcıya gösterilebilir; errors alan adı → mesaj listesi (yalnız 400). v1 katmanı WPSipariş zarfını korur.

KodAdAçıklama
400Doğrulama hatasıGövde/parametre şemaya uymuyor; errors alan bazlı mesajlar (Türkçe). Geçersiz JSON da 400.
401Kimlik gerekliOturum çerezi, Bearer ya da X-Pool-Secret eksik/yanlış.
403Yetki yokKimlik doğru ama kapsam dışı (başka firmanın şubesi, rol uymuyor).
404BulunamadıKayıt yok ya da kiracı sınırı dışında — ikisi aynı yanıt (varlık sızdırmaz).
409ÇakışmaAynı Idempotency-Key farklı gövdeyle (v2).
422İşlenemeyen içerikYalnız v1: WPSipariş doğrulama yanıtı biçimi (Doğrulama hatası: …).
429Hız sınırıretry-after başlığı ve yenidenSn alanı; sınırlar uç bazlı (bkz. Hız sınırı).
500Sunucu hatasıBeklenmeyen hata; ayrıntı yalnız sunucu logunda (PII maskeli).
503Hizmet dışıSağlık ucunda bağımlılık hatası; üretimde hız sınırı deposu (Redis) erişilemezse fail-closed.

Sürümleme

  • Belge sürümü 1.0.0 — anlamsal sürüm; kırıcı değişiklik büyük sürümü artırır ve yeni yol öneki açar.
  • /api/v1 SiparişMatik sözleşmesi dondurulmuştur: yol, başlık ve alan adları WPSipariş ile birebir; alan eklemek serbest, silmek/tip değiştirmek yasak (exe değişemez).
  • /api/v2 Partner API Faz 6’da yayınlanır; kırıcı değişiklik /api/v3 ile gelir, v2 en az 12 ay desteklenir.
  • Öneksiz uçlar (sağlık, OTP, bölge) dahili istemciler içindir; değişiklikler bu günlükte duyurulur.

Değişiklik günlüğü

  1. 1.0.0 2026-10-27

    • Sözleşme v2.0: iki sistem — WhatsApp/markalı site (akis: whatsapp, kanal MARKA_SITESI+XQR) ve Pazaryeri (akis: pazaryeri, kanal WEB); anahtar akış kapsamlı, sipariş uçları yalnız kendi akışını görür; sipariş gövdesine akis alanı
    • Webhook (Lezzet35 → SiparişMatik köprüsü, akış başına): siparis.olusturuldu / siparis.durum / siparis.iptal / test; JWT HS512 + X-Lezzet35-Signature; 10 deneme ≈ 24 sa (rehber: /docs/api/siparismatik)
    • Jeton otomasyonu: anahtar ve webhook sırrı SiparişMatik sunucusuna entegrasyon.anahtar olayıyla itilir (X-Pool-Secret + imza)
    • GET /iptal-nedenleri ve PUT …/durum iptal_nedeni (admin yönetir)
    • musteri_il teslimat mahallesinin ilinden (sabit İzmir kaldırıldı)
  2. 0.9.0 2026-10-27

    • xQR Faz 4: PUT|DELETE /xqr/brosur (PDF barındırma; /b sayfası ve /b.pdf)
    • POST /xqr/kayit: X-Xqr-Panel-Key canlıda zorunlu (27.10)
  3. 0.8.0 2026-10-27

    • xQR Faz 2: GET /firma/siparisler teslimat_tipi: MASA + masa_no (masa siparişi; YOLDA yok, hazır olunca servis, ödeme masada)
    • POST /pool/products/sync ve GET /menu: salon_fiyat, alerjenler[], etiketler[] (bilinmeyen kod 422)
    • POST /xqr/kayit: kimlik SiparişMatik ID + Pro paneli (telefon bilgi alanı), isteğe bağlı X-Xqr-Panel-Key
  4. 0.7.0 2026-10-26

    • xQR (QR menü, K-44) Faz 1: POST /xqr/kayit (X-Pool-Secret; firmaid + telefon doğrulaması, 201 tek seferlik api_key), GET|PUT /xqr (masa_siparis, masa_sayisi, diller)
    • GET /firma/masa-olaylari (garson çağır / hesap iste; Pro 10 sn çekimi) ve PUT /firma/masa-olaylari/{id} {durum:KAPANDI}
    • Sözleşme: docs/api/xqr-sozlesme-taslagi.md
  5. 0.6.0 2026-10-26

    • GET /firma/siparisler: urunler[].liste_fiyat, urunler[].indirim, urun_indirimi, para_ustu, musteri_enlem/musteri_boylam, musteri_adres_kisa, teslimat_tipi, odeme_turu, odendi, teslimat_ucreti belgeye eklendi
    • GET /firma/siparisler/{id} tek sipariş; süzgeçler (durum, tarih_baslangic, tarih_bitis)
    • PUT …/durum: tahmini_sure_dk; yanıtta teslim_tahmini, degisti, reddedildi
    • Ödeme kataloğu: odeme_turu+odendi öncelikli, odeme_yontemi görünen ad / yemek kartı markası
  6. 0.5.0 2026-10-23

    • SiparişMatik Pro çift yönlü menü senkronu: products/sync ek alanları (kdv, ekstralar, foto_url, silindi, guncellendi_at) ve conflicts[]
    • GET /menu?since= artımlı çekme; guncellendi_at, silindi, ekstralar, kdv, summary.sunucu_zamani
    • POST /pool/products/{sp_urun_id}/foto görsel yükleme
  7. 0.4.0 2026-10-23

    • SiparişMatik v1 uçları canlı (Faz 6): havuz/connect/disconnect, categories/products sync, sms/log, status, branches, menu, firma/siparisler + durum
    • Yeni ürün ONAY_BEKLIYOR; GET /firma/siparisler tek sayfa; ek alanlar teslimat_tipi, odeme_turu, odendi
    • entegrasyon_gunlugu ve admin “bağlantı koptu” uyarısı
  8. 0.3.0 2026-09-16

    • Belge ve /docs/api yayında (Faz 3)
    • GET /api/openapi.json
    • SiparişMatik v1 uçları sözleşmeden planlandı olarak eklendi
    • Partner API v2 taslağı
  9. 0.2.0 2026-09-15

    • GET /api/bolge/mahalle-ara — İzmir mahalle araması (Faz 2)
    • Servis alanı çekirdeği (M04)
  10. 0.1.0 2026-09-14

    • GET /api/health
    • POST /api/auth/otp/istek, POST /api/auth/otp/dogrula (Faz 1)
    • Yanıt zarfı {success, data | message, errors}