Hata Kodları

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 zarfı

// 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ı.

Statü, mesajın SON EKİNDEN türetilir

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.

AlanTipZorunluAçıklama
*.notFound404–Kayıt yok.
*.missingParams400–Zorunlu parametre eksik.
plugin.scope.denied403–Kurulumun bu izni yok.
*.suspended · *.consumerBlocked403–Askıya alınmış / engellenmiş.
*.duplicateInProgress · *.idempotencyKeyReused409–Çakışma.
*.noProvider424–Tenant sağlayıcı bağlamamış (önkoşul eksik).
*.providerUnavailable503–Sağlayıcı erişilemez / devre kesici açık.
*.timeout504–Sağlayıcı yanıt penceresini aştı.
diğer iş hataları400–Doğrulama.
internal500–Beklenmeyen — bize bildir.

Veri API (GET /plugin-api/*)

messageHTTPAnlam / çözüm
plugin.scope.denied403Ucun istediği scope onaylı değil → manifest'e ekle, tenant yeniden onaylasın.
unauthorized401Geçersiz/eksik install apiKey → token exchange'teki anahtarı kullan.
plugin.rateLimited429Rate limit aşıldı → Retry-After'a uy. Limitler (DEV 5/dk, write 20/dk).
plugin.<kaynak>.notFound404Kayıt yok (packets/tables/products/categories/customers) → id'yi doğrula.
plugin.<kaynak>.missingParams400Zorunlu parametre eksik/yanlış adlı (örn. packets/get → packetId, customers/get → customerId).

Yazma — POST /plugin-api/* (packets/tables/katalog)

messageHTTPAnlam / çözüm
joi doğrulama mesajı400Geçersiz gövde (eksik/yanlış alan) → gövde şeması.
Product not found: <id>400cart'taki bir ürün yok — TÜM ürünler var olmalı (yarım sipariş yazılmaz).
Invalid taxRate (0-100 expected): <id>400Satırın taxRate'i aralık dışı/geçersiz — sessizce ürünün oranına düşülmez.
Invalid lineId: <id>400Biç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>400Aynı 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}400metadata 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>400Sö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)400Belge 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_method400Ödeme satırı id'si tenant'ın yöntemi değil → önce payment-methods/list.
no_payment_methods_configured400Tenant'ta hiç ödeme yöntemi tanımlı değil.
Paid (X) exceeds total (Y).400payments toplamı sipariş tutarını aşıyor.
categoryNotEmpty409Boş olmayan kategori silinemez (önce ürünleri taşı/sil).
Duplicate request already in progress409Aynı idempotencyKey ile eşzamanlı 2. istek.
plugin.<kaynak>.notOwner403Yalnız kendi oluşturduğun katalog kaydını düzenler/silersin (sahiplik).
Table/Server not found404Masa kapanmış (tables yalnız açık masaları tutar) / geçersiz tenant.
callbackUrl must be under the same domain…400callbackUrl manifest webhookUrl'üyle aynı registered domain değil.
callbackUrl rejected: <sebep>400Güvenlik kontrolünden geçemedi (private IP / DNS).
Masa açma (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.

Hook'lar (gate çağrısı)

messageAnlam / çözüm
plugin.hook.notOwnerPaket sizin değil (yalnız packet.status.update'te — sahiplik damgası eşleşmedi).
plugin.hook.targetNotFoundHedef (paket/masa) bulunamadı.
plugin.hook.missingTransitionGeçiş bağlamı eksik/geçersiz (panel hatası).
plugin.hook.notRegisteredManifest'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.gateRequiredGate yanıtı bekleniyor — iframe gate'i resolve/close ile sonuçlandırmadınız.
plugin.hook.inactiveKurulum pasif (kill-switch / billing / connect).
plugin.scope.deniedİlgili hooks:<action> scope'u onaylı değil.

Aksiyon / senkron timeout

messageAnlam / çözüm
plugin.action.timeoutSenkron aksiyon/hook cevabı süresinde gelmedi (timeoutMs). Hook'ta failMode uygulanır.
plugin.rateLimitedSenkron çağrı kovası aşıldı (Limitler).

Eklentiler-arası yetenekler (capability)

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)HTTPAnlam / çözüm
…noProvider424Tenant sağlayıcı bağlamamış — önkoşul eksik → özelliği gizle, retry etme.
…providerUnavailable503Sağlayıcı inaktif/askıda/breaker-open/ulaşılamaz → aynı key ile sonra dene.
…timeout504Sağlayıcı ≈10s içinde yanıtlamadı → AYNI idempotencyKey ile retry (belirsiz sonuç).
…providerChanged409Belirsiz sonuç + tenant sağlayıcı değişimi → çift-işlem koruması; retry engellendi, manuel uzlaştır.
…duplicateInProgress · …idempotencyKeyReused · …selfTarget409Sırasıyla: eşzamanlı çift çağrı · aynı key farklı içerik · tüketici=sağlayıcı.
…suspended · …consumerBlocked403Eklenti kill-switch'te · tenant tüketiciyi panelden engellemiş.
…idempotencyKeyRequired · …rawPiiForbidden · …invalidPayload400Key eksik · to'da ham PII · payload doğrulaması başarısız.
plugin.capability.notFound404Bilinmeyen capability (jenerik /capabilities/{cap}/* ucunda).

Ayrıntı + sağlayıcı rehberi: Yetenekler — Genel Bakış.

HTTP eşlemesi (Veri API): not-found 404 · doğrulama/eksik param 400 · scope/sahiplik 403 · çakışma 409 · rate limit 429 · auth 401 · yetenek önkoşulu 424 · sağlayıcı 503/504. message her zaman makine-okur koddur. İlgili: Veri API · Hook'lar · Yetenekler · Limitler · İmza (401).