Masa Aç — POST /plugin-api/tables/create ⏳ Yakında

Eklentinin dine-in bir masayı AÇTIĞI yazma ucudur — QR self-order, kiosk ve masadan sipariş akışlarının giriş noktası. Daha önce eklenti yalnızca personelin açtığı bir masayı güncelleyebiliyordu; bu uç o boşluğu kapatır. Masa mağazanın salon planında tanımlı olmalıdır (tableId uydurulamaz), açık masada 409 döner, kuver otomatik uygulanır ve kapatma yetkisi verilmez.

← API Uçları · ortak kurallar (base, auth, hata zarfı) orada · Paket karşılığı: packets/create.

Yayına hazırlanıyor. Uç, backend dağıtımı tamamlandığında etkinleşir — sözleşme (gövde, yanıt, hata durumları) aşağıdaki gibidir. Yeni manifest alanı veya yeni scope gerekmez: mevcut orders:write bu ucu da kapsar.

Genel

Method / yolPOST /plugin-api/tables/create
Authinstall API key — Authorization: Bearer serverId.pluginId.secret
Scopeorders:writeartı orders:read (tableId'yi tables/layout'tan almak için; aşağı bkz.)
Rate limitAyrı write kovası (20/dk) — Limitler
Content-Typeapplication/json
Yan etkitable.created event'i tetiklenir (abone eklentilere)

İstek

POST {RESTOMENUM_BASE}/plugin-api/tables/create
Authorization: Bearer {serverId}.{pluginId}.{secret}     // install API key (token exchange)
Content-Type: application/json
  • Base: Sandbox https://sandbox.plugins.restomenum.app, Production https://plugins.restomenum.app (API Uçları).
  • Auth: Authorization: Bearer <apiKey>token exchange'teki install API key.
İstek gövdesi
{
  "tableId": "masa-5",                 // ZORUNLU — tables/layout'taki masa id'si
  "personCount": 4,                    // ops (0..999) — kuver hesabında kullanılır
  "cart": [                            // ops (<=200) — boş/yok olabilir: masa siparişsiz açılır
    { "product": "urun-abc123", "quantity": 2 },
    { "product": "urun-def456", "quantity": 1, "note": "az şekerli" }
  ],
  "idempotencyKey": "self-order-9f2c"  // ops AMA ÖNERİLİR (retry'da çift masa/adisyon engeller)
}

Gövde alanları

AlanTipZorunluKural
tableIdstringevet≤200 karakter; / içeremez; ., .. ve __ayrılmış__ biçimi kabul edilmez. tables/layout yanıtındaki masa id'si olmalı (aşağı bkz.).
personCountintegerhayır0–999 (varsayılan 0). Kuver hesabında kullanılır.
cart[]arrayhayır≤200 kalem. Boş/gönderilmemiş olabilir → masa sipariş olmadan açılır (rezervasyon / müşteri oturtma).
cart[].productstringevetÜrün id'si (products/list).
cart[].quantitynumberevet0.001–9999.
cart[].optionsstring[]hayır≤50 seçenek başlığı (ad; fiyatı backend belirler).
cart[].discountnumberhayır≥0 — satır indirimi.
cart[].notestringhayır≤500 karakter.
idempotencyKeystringönerilir≤128 karakter. Aynı anahtarla retry → yeni masa açılmaz, ilk sonuç döner (24sa pencere).

Yanıt

{ "success": true, "data": { "tableId": "masa-5", "docNo": 42, "total": 99 } }
  • data.tableId — açılan masanın id'si (gönderdiğinizle aynı); sonraki çağrılarda bunu kullanın.
  • data.docNo — tenant'ın işletme-günü fiş numarası (adisyon/belge no).
  • data.totalkuver ve satır indirimleri dahil, platformun hesapladığı otoriter tutar. Kendi hesabınızla farklıysa platformun değeri geçerlidir.

Masanın tam detayını (adisyon satırları, totaller) tables/get?id= ile çekebilirsiniz.

Hatalar

HTTPNe zamanNot
400tableId floor plan'da yok ya da masa pasif · cart'ta olmayan ürün · şema ihlali (geçersiz tableId biçimi, quantity aralık dışı vb.)Doküman hatası; istek düzeltilip tekrar denenebilir.
401Geçersiz/askıya alınmış install key
403orders:write scope'u yokTenant kurulumda onaylamadı → yeniden consent gerekir.
404Tenant bulunamadı
409Masa zaten açık · ya da aynı idempotencyKey ile eşzamanlı bir istek işleniyorAçık masaya sipariş eklemek için tables/update-orders.
429write bucket limiti (20 req/dk)Retry-After başlığına uyun — Limitler.

tableId uydurulamaz — layout'tan gelir

Masa, tenant'ın salon planında (floor plan) tanımlı ve aktif olmalıdır. Serbest metin masa adı kabul edilmez; tanımsız veya pasif masa 400 döner. Bu, panelde görünmeyen "hayalet masa" oluşmasını engeller.

Akış: GET /plugin-api/tables/layout → bölümler ve masalar → kullanacağınız masanın id alanı → tableId.

tables/create kullanan eklenti orders:read scope'una da ihtiyaç duyar — layout ucu orders:read ile korunuyor. Kurulum ekranında iki scope birlikte istenmeli (manifest requestedScopes: ["orders:read", "orders:write"]).

Masanın görünen adı, bulunduğu salon ve konumu platform tarafından layout'tan türetilir — istekte gönderilmez, gönderilse de yok sayılır.

Fiyat, kuver ve toplam otoritesi platformdadır

Fiyat göndermezsiniz. cart kaleminde fiyat alanı yoktur; fiyat tenant'ın ürün kaydından okunur (client fiyat iddiası kabul edilmez). Yalnız product (id) + quantity + options (ad) + discount verirsiniz.
  • Kuver tenant ayarından otomatik uygulanır ve masaya sabitlenir (personCount dikkate alınır). Eklenti kuver oranı gönderemez. cart boşsa kuver uygulanmaz.
  • total yanıtta döner; eklentinin kendi hesabıyla farklıysa platformun değeri geçerlidir (kendi tutarınızı kullanıcıya kesin tutar diye göstermeyin).

Açık masaya ikinci kez açma yok

Masa zaten açıksa 409 döner ve mevcut adisyona dokunulmaz. Personel ile eşzamanlı açılışta yalnızca bir taraf kazanır — çift adisyon oluşmaz.

Idempotency

idempotencyKey gönderirseniz, aynı anahtarla yapılan tekrar istekler yeni masa açmaz — ilk isteğin sonucu (tableId, docNo, total) aynen döner. Ağ hatası / timeout sonrası güvenle retry edebilirsiniz.

İstek bir iş hatasıyla (400/404/409) sonuçlanırsa anahtar serbest bırakılır: isteği düzeltip aynı anahtarla tekrar deneyebilirsiniz. Anahtar saklama süresi 24 saattir.

En iyi pratik: anahtarı kendi oturum/sepet kimliğinizden türetin (ör. self-order-<sessionId>) — kullanıcı "Gönder"e iki kez bastığında da tek masa açılır.

Timer (süre-bazlı) ürünler — dikkat

Süre-bazlı ürün (dakika ücretlendirmeli) içeren bir masa açabilirsiniz; ancak o masada daha sonra tables/update-orders çağıramazsınız (mevcut kısıt: kalem değişikliği geçen süreyi sıfırlayacağından reddedilir). Masayı sonradan güncellemeyi planlıyorsanız süre-bazlı ürünle açmayın.

table.created webhook'u — kendi eyleminizin echo'su

Bu uç, personelin masa açmasıyla aynı table.created event'ini üretir. table.created'a abone olan eklenti, kendi açtığı masa için de event alır.

Döngü riski. Event'i işleyip yeni masa açan bir mantık yazarsanız döngü oluşur. table.created handler'ınızda kendi oluşturduğunuz masaları elemeniz gerekir — açtığınız tableId/docNo'yu kendi kaydınıza yazın ve event geldiğinde eşleştirip atlayın (envelope id ile dedup ayrıca zorunludur, at-least-once teslim).

Kapatma yetkisi yok

Eklenti masayı kapatamaz, silemez, adisyonu sonlandıramaz. Kapanış (finansal kapanış, adisyon kapatma) yalnızca çekirdek/personel akışındadır. Kapanış anında haberdar olmak için table.closed event'ine abone olun; kapanışı engelleyip onaylamak için table.close gate hook'unu kullanın.

Uçtan uca örnek — QR self-order

Akış
1) GET  /plugin-api/tables/layout           → masaların id'leri
2) GET  /plugin-api/products/list           → ürün id'leri ve fiyatlar
3) POST /plugin-api/tables/create            { tableId, personCount, cart, idempotencyKey }
   → 200 { data: { tableId, docNo, total } }        (masa açıldı, adisyon oluştu)
   → 409                                            (masa zaten açık)
4) POST /plugin-api/tables/update-orders     { tableId, cart }   (aynı oturumda yeni sipariş)
5) POST /plugin-api/tables/update-payments   { tableId, payments }
   (kapanış personelde — eklenti kapatmaz)