Tüm yüzeylerdeki (Veri API, yazma ucu, hook'lar, aksiyon, webhook) dokümante hata mesajları tek yerde. Veri API hataları artık REST-uyumlu HTTP status döner (not-found 404, doğrulama 400, scope/sahiplik 403, çakışma 409, rate limit 429, auth 401); gövde { success:false, message } korunur (message = makine-okur kod). Her kodun anlamı ve çözümü aşağıda.
// Hata — REST-uyumlu HTTP status + zarf (message makine-okur koddur)
HTTP 404
{ "success": false, "message": "plugin.packets.notFound" }
// Başarı
HTTP 200
{ "success": true, "data": … }SDK/istemci: 4xx'i hata olarak işle; message'a göre dallan (i18n anahtarı değil, sabit koddur). Eski davranış (her şey HTTP 200) kaldırıldı — gövde uyumlu kaldı.
HTTP statüsü tek tek eşlenmez — message'ın son ekine bakan bir kuraldan türer. Bu yüzden yeni yetenekler bu tabloyu güncellemeden doğru statüyü alır; sen de tanımadığın bir kodu son ekine göre sınıflandırabilirsin.
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| *.notFound | 404 | – | Kayıt yok. |
| *.missingParams | 400 | – | Zorunlu parametre eksik. |
| plugin.scope.denied | 403 | – | Kurulumun bu izni yok. |
| *.suspended · *.consumerBlocked | 403 | – | Askıya alınmış / engellenmiş. |
| *.duplicateInProgress · *.idempotencyKeyReused | 409 | – | Çakışma. |
| *.noProvider | 424 | – | Tenant sağlayıcı bağlamamış (önkoşul eksik). |
| *.providerUnavailable | 503 | – | Sağlayıcı erişilemez / devre kesici açık. |
| *.timeout | 504 | – | Sağlayıcı yanıt penceresini aştı. |
| diğer iş hataları | 400 | – | Doğrulama. |
| internal | 500 | – | Beklenmeyen — bize bildir. |
| message | HTTP | Anlam / çözüm |
|---|---|---|
| plugin.scope.denied | 403 | Ucun istediği scope onaylı değil → manifest'e ekle, tenant yeniden onaylasın. |
| unauthorized | 401 | Geçersiz/eksik install apiKey → token exchange'teki anahtarı kullan. |
| plugin.rateLimited | 429 | Rate limit aşıldı → Retry-After'a uy. Limitler (DEV 5/dk, write 20/dk). |
| plugin.<kaynak>.notFound | 404 | Kayıt yok (packets/tables/products/categories/customers) → id'yi doğrula. |
| plugin.<kaynak>.missingParams | 400 | Zorunlu parametre eksik/yanlış adlı (örn. packets/get → packetId, customers/get → customerId). |
| message | HTTP | Anlam / çözüm |
|---|---|---|
| joi doğrulama mesajı | 400 | Geçersiz gövde (eksik/yanlış alan) → gövde şeması. |
| Product not found: <id> | 400 | cart'taki bir ürün yok — TÜM ürünler var olmalı (yarım sipariş yazılmaz). |
| Invalid taxRate (0-100 expected): <id> | 400 | Satırın taxRate'i aralık dışı/geçersiz — sessizce ürünün oranına düşülmez. |
| Invalid lineId: <id> | 400 | Biçim ihlali (⏳ 8–64, alfanümerik başlar, A-Z a-z 0-9 . _ : -, saf rakam reddedilir) ya da rezerve kimlik (kuver/new) → Satır kimliği. |
| Duplicate lineId: <id> | 400 | Aynı istekteki listede lineId tekrar ediyor (benzersizlik istek içidir). |
| lineId belongs to a cancelled line: <id> | 409 | İptal edilmiş (void) bir satırın kimliği yeniden beyan edildi — aynı adisyonda aktif ve void satır aynı kimliği taşıyamaz. |
| metadata must be an array of {key, value} | 400 | metadata düz map olarak gönderildi. Nihai şekil { key, value } dizisidir; geriye uyum yoktur → Satır kimliği & metadata. |
| Invalid metadata: <ürün|payments[i]>: <sebep> | 400 | Sözleşme dışı öğe: geçersiz key biçimi, iç içe obje / dizi / null değer, aynı yazarın tekrarlanan anahtarı ya da yazar bütçesi aşımı (≤10 öğe, value ≤256). Sepette hangi ürün satırı, ödemede hangi indeks olduğu mesajda gelir. |
| cart|payments: total metadata size … | 400 | İstek başına bütçe aşımı — bir istekteki tüm cart satırları ≤20 KB; aynı sınır payments için ayrıca geçerli. |
| Total metadata size after merge … (yours: X, other plugins: Y) | 400 | Belge geneli bütçe aşımı (birleşme sonrası ≤100 KB; orders + payments + iptaller). Kırılım aşımın kimden geldiğini söyler — other plugins baskınsa kendi payload'ını küçültmek çözmez. |
| unknown_payment_method | 400 | Ödeme satırı id'si tenant'ın yöntemi değil → önce payment-methods/list. |
| no_payment_methods_configured | 400 | Tenant'ta hiç ödeme yöntemi tanımlı değil. |
| Paid (X) exceeds total (Y). | 400 | payments toplamı sipariş tutarını aşıyor. |
| categoryNotEmpty | 409 | Boş olmayan kategori silinemez (önce ürünleri taşı/sil). |
| Duplicate request already in progress | 409 | Aynı idempotencyKey ile eşzamanlı 2. istek. |
| plugin.<kaynak>.notOwner | 403 | Yalnız kendi oluşturduğun katalog kaydını düzenler/silersin (sahiplik). |
| Table/Server not found | 404 | Masa kapanmış (tables yalnız açık masaları tutar) / geçersiz tenant. |
| callbackUrl must be under the same domain… | 400 | callbackUrl manifest webhookUrl'üyle aynı registered domain değil. |
| callbackUrl rejected: <sebep> | 400 | Güvenlik kontrolünden geçemedi (private IP / DNS). |
tables/create) durum kodları: 400 — tableId salon planında yok ya da masa pasif (masa layout'tan gelmeli; uydurulamaz) · 409 — masa zaten açık (mevcut adisyona dokunulmaz → kalem eklemek için tables/update-orders) ya da aynı idempotencyKey ile eşzamanlı istek. İş hatasında (400/404/409) idempotency anahtarı serbest bırakılır: isteği düzeltip aynı anahtarla tekrar denenebilir.| message | Anlam / çözüm |
|---|---|
| plugin.hook.notOwner | Paket sizin değil (yalnız packet.status.update'te — sahiplik damgası eşleşmedi). |
| plugin.hook.targetNotFound | Hedef (paket/masa) bulunamadı. |
| plugin.hook.missingTransition | Geçiş bağlamı eksik/geçersiz (panel hatası). |
| plugin.hook.notRegistered | Manifest'inizde bu hook yok. |
| plugin.hook.preconditionFailed | ⏳ Hesap kapanamaz durumda (borç/fazla tahsilat/kalemsiz ödeme) → kapanış gate'i hiç çalıştırılmadı. İmzalanmış ama karşılığı olmayan fiş üretimini baştan engeller; ayrıntı: kapanış düştü. |
| plugin.hook.gateRequired | Gate yanıtı bekleniyor — iframe gate'i resolve/close ile sonuçlandırmadınız. |
| plugin.hook.inactive | Kurulum pasif (kill-switch / billing / connect). |
| plugin.scope.denied | İlgili hooks:<action> scope'u onaylı değil. |
| message | Anlam / çözüm |
|---|---|
| plugin.action.timeout | Senkron aksiyon/hook cevabı süresinde gelmedi (timeoutMs). Hook'ta failMode uygulanır. |
| plugin.rateLimited | Senkron çağrı kovası aşıldı (Limitler). |
Tam kod plugin.<errorPrefix>.<suffix>; <errorPrefix> = capability id'nin İLK segmenti (plugin.messaging / plugin.notify / plugin.invoice). Ör. notify.staff için plugin.notify.noProvider (plugin.notify.staff.* DEĞİL).
| message (suffix) | HTTP | Anlam / çözüm |
|---|---|---|
| …noProvider | 424 | Tenant sağlayıcı bağlamamış — önkoşul eksik → özelliği gizle, retry etme. |
| …providerUnavailable | 503 | Sağlayıcı inaktif/askıda/breaker-open/ulaşılamaz → aynı key ile sonra dene. |
| …timeout | 504 | Sağlayıcı ≈10s içinde yanıtlamadı → AYNI idempotencyKey ile retry (belirsiz sonuç). |
| …providerChanged | 409 | Belirsiz sonuç + tenant sağlayıcı değişimi → çift-işlem koruması; retry engellendi, manuel uzlaştır. |
| …duplicateInProgress · …idempotencyKeyReused · …selfTarget | 409 | Sırasıyla: eşzamanlı çift çağrı · aynı key farklı içerik · tüketici=sağlayıcı. |
| …suspended · …consumerBlocked | 403 | Eklenti kill-switch'te · tenant tüketiciyi panelden engellemiş. |
| …idempotencyKeyRequired · …rawPiiForbidden · …invalidPayload | 400 | Key eksik · to'da ham PII · payload doğrulaması başarısız. |
| plugin.capability.notFound | 404 | Bilinmeyen capability (jenerik /capabilities/{cap}/* ucunda). |
Ayrıntı + sağlayıcı rehberi: Yetenekler — Genel Bakış.
message her zaman makine-okur koddur. İlgili: Veri API · Hook'lar · Yetenekler · Limitler · İmza (401).