POST /plugin-api/tables/update-payments ✓ CanlıDine-in masanın ödeme satırlarını yazar (packets/update-payments'ın masa karşılığı). İki mod: mode:'replace' (VARSAYILAN — TÜM ödemeleri değiştirir) ve mode:'append' (mevcutlara dokunmadan ekler; lineId zorunlu — 🧪 YALNIZ sandbox; production'da yok ve planlanmıyor). Ödeme kuralları paket ucuyla birebir aynı: id'ler tenant'ın gerçek ödeme yöntemlerine karşı doğrulanır. Hiçbir uç masayı KAPATMAZ.
← API Uçları · Masa kalemleri: tables/update-orders · Paket karşılığı: packets/update-payments.
POST {RESTOMENUM_BASE}/plugin-api/tables/update-payments
Authorization: Bearer <apiKey>
{
"tableId": "tbl-7a3f...", // ZORUNLU — açık masanın doc id'si
"expectedUuid": "9f3ab27c-...", // ops AMA verilirse ZORUNLU eşleşir — oturum kapısı (409 session_changed)
"mode": "replace", // ops — "replace" (VARSAYILAN) | "append" 🧪 append yalnız SANDBOX (prod'da YOK, planlanmıyor)
"payments": [ // ZORUNLU — replace: masanın YENİ ödeme listesi (FULL REPLACE)
{ "price": 268, "id": "cash", "title": "Nakit", "isDiscount": false,
"lineId": "pay-7c31", // ops (replace) / ZORUNLU (append) — ödeme SATIRININ kimliği (id = YÖNTEM id'si!)
"metadata": [ { "key": "terminal", "value": "kiosk-1" } ] } // ops — DİZİ (map değil)
]
}orders:write · write rate-limit.mode opsiyonel, varsayılan "replace" — göndermezsen davranış eskisiyle bit-bit aynı."replace": payments masanın tüm ödemelerini değiştirir. Satır: { price, id, title?, isDiscount?, lineId?, metadata? }."append": gönderilen satırlar mevcutların üzerine eklenir — aşağıdaki bölüm.tableId: açık masa doc id'si — tables/open'dan al.expectedUuid: opsiyonel oturum kapısı — gönderirsen masanın o anki oturum uuid'si ile eşleşmek zorundadır; eşleşmezse 409 session_changed ve hiçbir şey yazılmaz. Aşağıdaki bölüme bak — gecikmeli yazan her entegrasyon için pratikte zorunludur.expectedUuid — oturum kapısıuuid alır. Kapı olmadan, geç gelen onay yeni müşterinin hesabına düşer.session_changed alır ve yazma hiç yapılmaz.write.expectedUuid olarak gelir — satır yazarken onu geri ver. Kendi akışını kuruyorsan masanın okuma yanıtındaki oturum uuid'sini taşı.mode: "append"sandbox.plugins.restomenum.app üzerinden gerçek çağrılarla doğrulandı (9/9): masadaki nakit satırı korundu (100 + 150 = 250), tekrar gönderimde ikinci satır oluşmadı, replayed:true döndü. Paket ucuyla sözleşme paylaşımı artık varsayım değil, ölçüm. Prod'da mode göndermek isteği komple 400'e düşürür ("mode" is not allowed), eski davranışa düşmez → production entegrasyonunda gönderme. Durum değişirse değişiklik günlüğünden duyurulur.Sözleşme packets/update-payments ile birebir aynıdır — yalnız kimlik alanı değişir (tableId). Gerekçe, lineId zorunluluğu, replayed ve hata kodlarının tamamı için o sayfayı oku; burada özet:
POST {RESTOMENUM_BASE}/plugin-api/tables/update-payments
Authorization: Bearer <apiKey>
{
"tableId": "tbl-7a3f...",
"mode": "append", // mevcut satırlara DOKUNMAZ — üzerine ekler
"payments": [
{ "price": 268, "id": "m-card", "lineId": "pay-term-01H9..." } // lineId ZORUNLU (tekrar gönderim kalkanı)
]
}lineId ZORUNLU — tekrar gönderim kalkanı: kimliksiz satıra platform her çağrıda farklı kimlik üretir, ağ hatasındaki retry ikinci satır olur = çift tahsilat.lineId GÜÇLÜ olmalı — en az 8 karakter, saf rakam değil ("00000001" reddedilir). Grandfather affı ekleme modunda İŞLEMEZ: af yalnız dokümanda zaten var olan kimlikleri bağışlar. Kalıp: pay-01H9XYZ… (önek + uuid).paid birleşim üzerinden yeniden hesaplanır; paid ≤ total kapısı geçerli. Kapatma yok.replayed: true = aynı lineId ile tekrar gönderim, yazma yapılmadı, event yayılmadı.append_requires_line_id · append_requires_payment_line · append_partial_duplicate · append_replay_amount_mismatch · append_replay_method_mismatch · too_many_payment_lines (birleşim > 100 satır).table.updated'ı data.changed: "payment_added" ile yayar; replace modu eskisi gibi "payment_updated". Tekrar gönderimde (replayed) hiçbir event yayılmaz.// ekleme başarılı (masadaki 100₺ nakit KORUNDU, 150₺ eklendi → 250)
{ "success": true, "data": { "tableId": "e2e-table-A2", "paid": 250, "replayed": false } }
// aynı lineId ikinci kez → yazma YOK, ikinci satır oluşmadı
{ "success": true, "data": { "tableId": "e2e-table-A2", "paid": 250, "replayed": true } }Kurallar packets/update-payments ile aynı. Önce payment-methods/list (payment_methods:read).
| Satır | Kural |
|---|---|
Normal (isDiscount yok/false) | id tenant'ın yöntemi OLMALI. title/cash/noreport yöntem kaydından türetilir (gönderilen title yok sayılır). |
İndirim (isDiscount:true) | Doğrulamadan muaf (serbest id); title zorunlu. |
| Durum | message |
|---|---|
| Normal satır id'si tenant'ın yöntemi değil | unknown_payment_method (400) |
| Tenant'ta hiç ödeme yöntemi yok | no_payment_methods_configured (400) |
Yeni paid total'ı aşıyor | Paid (X) exceeds total (Y). (400) |
lineId biçim ihlali / rezerve / istekte tekrar | Invalid lineId: <id> · Duplicate lineId: <id> (400) |
| İptal edilmiş (void) satırın kimliği yeniden beyan edildi | lineId belongs to a cancelled line (409) |
metadata düz map gönderildi (dizi bekleniyor) | metadata must be an array of {key, value} (400) |
| Geçersiz key/değer, aynı yazarın tekrar eden anahtarı ya da yazar bütçesi (10 öğe / 256 karakter) aşımı | Invalid metadata: payments[i]: <sebep> (400) |
| İstek başına 20 KB ya da belge geneli 100 KB bütçe aşımı | Total metadata size after merge … (yours: X, other plugins: Y) (400) |
| Geçersiz gövde | joi doğrulama mesajı (400) |
| Masa yok / kapanmış | Table not found (404) |
| ⏳ Ekleme moduna özgü (yukarıdaki bölüm) | append_requires_line_id · append_requires_payment_line · append_partial_duplicate · append_replay_amount_mismatch · append_replay_method_mismatch · too_many_payment_lines (400) |
İki alan da opsiyoneldir; hiçbiri gönderilmezse davranış bugünküyle aynıdır (mevcut eklentiler etkilenmez). Tam kurallar: Satır Kimliği & metadata.
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| payments[].lineId | string | – | Kararlı satır kimliği — çağıran taşır, platform korur. 8–64 karakter (⏳ alt sınır 1 → 8'e çıktı), alfanümerik başlar, A-Z a-z 0-9 . _ : - içerir — ⚠️ noktalama yalnız İÇERİDE (pay_01H9ABCD geçer; _pay01H9ABCD ve -pay01H9ABCD 400); saf rakamdan oluşan kimlik reddedilir ("1", "42" → 400). kuver ve new rezervedir (büyük/küçük harf farketmez) → 400 Invalid lineId: kuver. Aynı istekteki liste içinde tekrar edemez → 400 Duplicate lineId: <id>; iptal edilmiş (void) bir satırın kimliğini yeniden beyan etmek → 409 lineId belongs to a cancelled line. Gönderilmeyen satıra platform üretir ve üretilen kimlikler beyan edilenlerle çakışmaz. Göndermesen bile her ödeme satırı kalıcı bir lineId alır (platform üretir, pay- önekli — önceden ödeme kaydının kimliği hiç yoktu). ⚠️ Kimlik korunması koşulludur: her istekte yeniden beyan edilmelidir (aşağı bkz.). |
| payments[].metadata | array | – | Opak korelasyon alanı — { key, value } dizisi (düz map değil; map gönderen istek 400 metadata must be an array of {key, value} alır). Platform yorumlamaz: saklar ve okuma yanıtında yazar damgasıyla (by) döner. key alfanümerik başlar, A-Za-z0-9_-, ≤64; value string | number | boolean (iç içe obje / dizi / null → 400). Bütçeler: yazar başına ≤10 öğe / satır ve value ≤256 karakter, istek başına ≤20 KB (sepet ve ödeme ayrı), belge geneli birleşme sonrası ≤100 KB. |
(uuid, lineId) çiftini anahtar yapmaktır. uuid (kalıcı satış kimliği) artık her olayda geliyor ve satış bazında kesin ayrık — çift, bu hata sınıfını kuralın da ötesinde kapatır.payments[].id satır kimliği DEĞİLDİR. O alan ödeme yönteminin kimliğidir (nakit/kart tanımı — bkz. payment-methods/list) ve yerli akışlarda satır uuid'si de taşıyabilir; polimorfiktir, satır silme her yerde onu hedefler. Bu yüzden kalıcı kimlik ayrı lineId alanına yazıldı; id'nin anlamı değişmedi. Okuma yanıtında ödeme satırı lineId (kimlik) ve methodId (yöntem) alanlarını ayrı ayrı döner.metadata (başka eklentilerin yazdıkları dahil) onunla birlikte gider. İstek reddedilmez (meşru satır silme de bu yola düşer) ama platform kaybı loglar. Kimliği kendi kaydından türet ve kendi tarafında sakla — doğru/yanlış örneği.metadata'ya PII yazmayın (ad, telefon, e-posta, adres, kart): sözleşme gereği yasaktır. Platform bu alanda desen taraması yapmaz — yanlış pozitif meşru bir mali kaydı reddedip satışı durdururdu; kural sözleşme düzeyindedir, ihlal eklentinin sorumluluğundadır. Müşteri verisi customers:read + rıza üzerinden alınır.orders:read yeterlidir, müşteri-PII rızası gerekmez ve alan push gövdelerinden silinmez. note, paymentNote ve iptal reason bu kapsamda değildir — onlar gerçek kullanıcı girdisi taşır ve rıza kapısına tabi olmaya devam eder.{ id, title, price, isDiscount?, lineId?, metadata? } gönderirsiniz; tables/get ise payments[] dizisini { lineId, methodId, title, amount, cash, isDiscount, metadata } olarak döner (price→amount, yazmadaki id = YÖNTEM id'si → methodId, artı yöntemin cash bayrağı — nakit/nakit-dışı ayrımı buradan okunur). Satır kimliği ayrı alandır (lineId; eski satırlarda null).