receiptExtras ⏳ YakındaKapanış gate'i (table.close / packet.close) allow yanıtında receiptExtras dizisi dönerse, öğeler kapanış yazılmadan ÖNCE adisyon dokümanına işlenir ve fişe basılabilir hale gelir. Karar ile veri aynı yanıtta gelir — belgeyi bağlamak için ikinci bir API çağrısı gerekmez. Tipik kullanım: Almanya KassenSichV / TSE mali bloğu, e-arşiv belge numarası, sadakat/kampanya satırı.
← Hook'lar (Akış Kontrolü) · table.close · packet.close
Gate isteği değişmedi (bkz. Action Hook referansı). Yanıta yalnız receiptExtras eklendi:
{
"decision": "allow",
"receiptExtras": [
{ "key": "tse.qr", "type": "qr", "value": "V0;…" },
{ "key": "tse.txNumber", "type": "text", "label": "Beleg-Nr", "value": "366" },
{ "key": "tse.signatureCounter", "type": "text", "label": "Sig-Zähler", "value": "774" },
{ "key": "tse.timeStart", "type": "text", "label": "TSE-Start", "value": "1785438065" },
{ "key": "tse.status", "type": "text", "value": "signed" }
]
}{ "data": { … } } sarmalı da kabul edilir (mevcut hook davranışı).
| Alan | Tip | Zorunlu | Kural |
|---|---|---|---|
| key | string | evet | ≤64; a-zA-Z0-9_- segmentleri, nokta ile ayrılır (tse.qr). Namespace sahipliğine tabidir. |
| type | 'text' | 'qr' | hayır | Bilinmeyen değer öğeyi DÜŞÜRMEZ — güvenli default text uygulanır. |
| value | string | evet | DAİMA metin, 1–2000 karakter. Sayı göndermeyin, string gönderin. |
| label | string | hayır | ≤64 — fişte değerin başına basılacak etiket (Beleg-Nr). |
| verified | boolean | platform üretir | Sahiplenilmiş namespace + yetki doğrulandıysa platform ekler. Eklenti gönderemez (gönderilirse yok sayılır). |
type değerleri:
text — Metin — fişe düz satır olarak basılır (label varsa başına eklenir)qr — QR — fişe QR kodu olarak basılır (ör. TSE doğrulama verisi)value neden hep metin? Bu veri fişe basılan gösterim verisidir, hesaplama verisi değil. Beleg-Nr, Sig-Zähler ve epoch değerleri metin taşındığı için int32/precision taşması diye bir sorun doğmaz — TSE'den ne geldiyse fişe o basılır. Sayı göndermeyin, string gönderin.Gate yanıtındaki diğer alanlar (decision, message, level, display) protokol alanlarıdır: akışı yönetir ve kasiyere bildirim gösterir. Adisyon dokümanına yazılan tek alan receiptExtras'tır.
key yalnız dizi öğesinin içinde yaşar — doküman kökünde alan açamaz. {"key":"total"} göndermek adisyon tutarını değiştirmez, yalnızca total adlı bir gösterim öğesi üretir (ve verified işareti almaz).Adisyon tutarını/kalemlerini gerçekten değiştirmeniz gerekiyorsa tables/update-orders · packets/update-orders ve update-payments uçlarını kullanın — onlar recompute + paid ≤ total doğrulamasından geçer.
Bazı namespace'ler sahiplenilmiştir; onları yalnız o alanın yetkilisi yazabilir:
| Namespace | Gereken yetki | Anlamı |
|---|---|---|
| tse.* | hook scope'u + capability:fiscal.de:provide | Mali blok (KassenSichV / TSE) |
diğer (loyalty.*, kampanya…) | hook scope'u yeterli | Serbest gösterim öğesi |
tse.qr döndürüp fişe sahte mali blok bastırabilirdi. Yetkisiz eklentinin sahiplenilmiş key'i sessizce düşürülür (dizide yer almaz) — hata dönmez, bu yüzden yetkinizi kurulumda doğrulayın.provides: [{ capability: "fiscal.de" }] beyan edersiniz (portal editöründe "Eklentiler-Arası Yetenekler" kartı); türetilmiş capability:fiscal.de:provide scope'u otomatik eklenir — elle scope seçmezsiniz. Aynı scope, fişi imzalamak için platformdan gelen type:"capability" isteğini almanızı da sağlar: Mali Fişleme (fiscal.de). E-fatura/e-arşiv belgesi ayrı bir yetenektir (invoice.issue) — mali cihaz imzasıyla karıştırmayın; invoice.issue sağlayıcısı tse.* yazamaz.verified işaretiSahiplenilmiş namespace'te ve yetki doğrulandıysa platform öğeye verified: true ekler:
{ "key":"tse.txNumber", "type":"text", "label":"Beleg-Nr", "value":"366", "verified":true }verified öğelere basar.verified'ı kendisi gönderemez; platform üretir (gönderilirse yok sayılır).allow'da yazılır. deny dönerseniz hiçbir şey yazılmaz — ödeme eşlenemediği için deny döndüyseniz fiş de kesilmemiştir, o key'lerin belgeye girmemesi gerekir. pending'de karar henüz yoktur.key bir kez yazıldıysa üzerine yazılmaz. Aynı key'i tekrar göndermek sessizce yok sayılır (platformda frozen olarak loglanır). Düzeltme gerekiyorsa fiscal doğru yol iptal/düzeltme belgesidir — yeni bir key ile gönderin.allow dediyseniz kapanış devam eder.Kapanış gate'i tenant-genel fan-out yapar (packet.close tüm kayıtlı eklentilere paralel sorulur), bu yüzden eşzamanlı yazım normaldir:
| Durum | Sonuç |
|---|---|
Farklı key'ler (TSE eklentisi tse.*, sadakat eklentisi loyalty.*) | İkisi de yazılır, dizi birleşir |
| Aynı key | İlk yazan kazanır; ikincinin değeri yok sayılır (değiştirilemezlik) |
Yani başka bir eklentinin varlığı sizin öğelerinizi ezmez; siz de onunkini ezemezsiniz. 10 eşzamanlı yazımda kayıp gözlenmedi.
| Sınır | Değer |
|---|---|
| Dizi öğe sayısı | 30 (adisyon başına toplam) |
key uzunluğu | 64 |
value uzunluğu | 2000 |
label uzunluğu | 64 |
type | text | qr |
tse.qr için özel not: TSE QR verisi ölçümde 341–363 karakter. Sınır bilinçli olarak yüksek tutuldu; 255 karakterlik bir alan bu veriyi taşırdı ve kırpılan QR doğrulanamaz hale gelirdi. Platform uzun değeri kırpmaz — reddeder: bozuk QR üretmektense öğeyi düşürmeyi tercih eder.receiptExtras şu an tables/get / packets/get yanıtlarında dönmez. Yazdığınız belge verisini kendi tarafınızda saklayın. Yeniden basım/denetim sorgusu bu mekanizmanın dışındadır: POS bilgisiyle (kasa, belge no, iş günü) sizden çekilir — platform tarafında ek izin gerekmez.table.close, packet.close). Kapanış olmayan bir hook'ta gönderirseniz fişle ilişkilendirilecek bir belge yoktur.tse.qr varsa QR basar, tse.status uyarı durumundaysa uyarı gösterir. Öğe sırası fişteki sırayı garanti etmez — label göndererek anlamı öğenin kendisinde taşıyın.timeoutMs'tir (manifest'ten; table.close varsayılanı 10 sn, paket gate'lerinde 5 sn). Mali belge kesimi bu süreye sığmıyorsa failMode politikanızı gözden geçirin; süre aşımında yanıtınız değerlendirilmez.allow dönmek kapanışa izin vermektir, kapanışı sizin yapmanız değil.// Gate isteği (platform → eklenti)
{ "type":"hook", "event":"table.close", "target":{ "type":"table", "id":"masa-5" }, "timeoutMs":5000 }
// Yanıt (eklenti → platform) — belge kesildi, fişe basılacak alanlar döndü
{ "decision":"allow",
"receiptExtras":[
{ "key":"tse.qr", "type":"qr", "value":"V0;KassenSN;Kassenbeleg-V1;…" },
{ "key":"tse.txNumber", "type":"text", "label":"Beleg-Nr", "value":"366" },
{ "key":"tse.signatureCounter", "type":"text", "label":"Sig-Zähler", "value":"774" },
{ "key":"tse.timeStart", "type":"text", "label":"TSE-Start", "value":"1785438065" },
{ "key":"tse.status", "type":"text", "value":"signed" }
] }
// Ödeme eşlenemedi → belge KESİLMEDİ → hiçbir key yazılmamalı
{ "decision":"deny", "message":"Ödeme TSE ile eşlenemedi" }