receiptExtras ✓ CanlıKapanış 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
receiptExtras uygulamanın kendi hesap fişine alan ekler ve kullanıcı fiş bastığında çalışır — eklenti ekranının açık olması gerekmez. print ise kendi başına duran bir belge bastırır (kupon, çek, rapor) ve yalnız eklenti sayfan panelde açıkken çalışır.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 + fiscal.de bağlı sağlayıcısı | 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.tse.* yazdırırdı. Artık eklentinin o tenant'ta fiscal.de'nin bağlı sağlayıcısı olduğu da doğrulanır; değilse öğe sessizce düşer. Tenant'ta tek aday varsa davranış değişmez.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.receiptExtras yalnız kapanış gate'inde değil, fiscal.de capability yanıtında da dönebilir (fişi kendi basan kiosk eklentisi POS kapanış gate'ini tetiklemez). Her iki yolda da platform öğeleri satış belgesine yazar → aynı blok packets/get ile okunup yeniden basılabilir (yeni imza YOK). Sınırlar, namespace sahipliği ve verified kuralı ikisinde de aynıdır.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" }