ZATCA Faz 2 faturayı neden reddeder, nasıl önlenir
Reddedilen bir payload hata kaydı değildir. Yasal olarak kapanamayan bir satıştır — siz logu okurken satıcı kasanın başında bekliyordur.
29 Ağustos 202611 dk okuma
ZATCA Faz 2’de — entegrasyon fazı — standart bir vergi faturasının geçerli sayılması için idareye ulaşıp onaylanmış (cleared) olarak geri dönmesi gerekiyor. Ekiplerin hafife aldığı kısım burası. Faz 1’de geçersiz bir fatura sonradan düzeltilecek bir uyum sorunuydu. Faz 2’de tamamlanamayan bir işlem.
Bunu ticari WooCommerce ürünlerimizin içinde kurup sürdürüyoruz; yani canlıya alıp çekilmiyor, idarenin yayımladığı her revizyonla birlikte yaşıyoruz. Aşağıdakiler gerçekten tekrar eden hatalar.
ZATCA teknik kılavuzunu ve doğrulama kurallarını düzenli olarak revize ediyor. Bunu problemin şekli olarak okuyun, yürürlükteki kılavuzun yerine koymayın — kendi dalganız için geçerli sürümü her zaman kontrol edin.
Sıfırıncı hata: faturayı yanlış yola sokmak
Faz 2’de iki akış var ve birbirinin yerine geçmiyor. Standart faturalar — işletmeden işletmeye ve işletmeden kamuya — clearance’tan geçiyor: gerçek zamanlı gönderiliyor, ZATCA kriptografik damga ve QR ile geri döndürüyor, ancak ondan sonra alıcıya verilebiliyor. Basitleştirilmiş faturalar — işletmeden tüketiciye — raporlanıyor ve raporlama penceresi içinde sonradan gönderilebiliyor.
Basitleştirilmiş bir faturayı clearance’a, standart bir faturayı raporlamaya yollarsanız sonrasındaki her şey veri hatası gibi görünen biçimlerde patlar. Yolu fatura tipi ve alt tipi belirler; bu karar akışın en başına ait, bir hata yakalayıcının içine değil.
1. Hash zinciri kırılmış
Her fatura bir öncekinin özetini taşır. Zinciri kurcalamaya karşı korunaklı yapan şey budur ve en sık yanlış yapılan alan da budur — çünkü doğruluğu mevcut faturanın dışındaki bir şeye bağlı olan tek alan odur.
- Önceki fatura gönderilemedi ama yerelde yine de yazıldı; zincir sizin tarafınızda ilerledi, idarede ilerlemedi.
- İki sipariş aynı anda tamamlandı ve ikisi de aynı önceki özeti okudu. Artık biri yanlış, ve hata o iki faturada değil bir sonrakinde görünüyor.
- Üretim kimlik bilgileriyle bir test faturası kesildi ve sessizce zincire girdi.
- Zincir bir deploy, bir veritabanı geri yükleme ya da birinin tabloyu temizlemesiyle sıfırlandı.
Çözüm payload’da değil. Önceki özet ile sayaç tek bir sıralı adımda üretilmeli — satır kilidi, cihaz başına tek işçili bir kuyruk, eşzamanlı kesimi olası değil imkânsız kılan bir şey. İki checkout aynı önceki özeti okuyabiliyorsa zincir kırılacaktır; bu şans meselesi değil, trafik meselesidir.
2. Fatura sayacı atlamış
Sayaç cihaz başına, fatura başına bir artar. Sipariş başına değil, müşteri başına değil — kesen cihaz başına. Boşluk da tekrar da reddedilir.
Olağan sebep, sayacı türetilmiş bir değer sanmak: satır saymak, sipariş numarasını kullanmak ya da hatadan sonra yeniden başlatmak. Sayaç saklanmalı, özeti üreten kilidin altında artmalı ve gönderim başarısız olduğunda geri alınmamalı. Başarısız bir gönderim, kesilmiş faturayı kesilmemiş yapmaz.
3. Özet, imzaladığınız baytlarla uyuşmuyor
En kafa karıştırıcı destek taleplerini bu üretir, çünkü fatura her görüntüleyicide doğru görünür. Özet, kanonikleştirilmiş XML üzerinden alınır ve kanonikleştirme affetmez: nitelik sırası, ad alanı tanımları, öğeler arasındaki boşluklar, kodlama, satır sonları. Belgeyi bir kez serileştirin, tam olarak o baytları özetleyip imzalayın ve tam olarak o baytları gönderin.
Ekipler bunu özetleme ile gönderme arasında yeniden serileştirerek bozuyor: XML’i biçimlendirici bir loglayıcıdan geçirmek, ad alanlarını normalleştiren bir kütüphaneye vermek ya da belgeyi ayrıştırılmış nesneden yeniden kurmak. Sisteminizden çıkan belge, özetlediğinizle bayt bayt aynı olmalı.
4. İmza ve sertifika sorunları
Onboarding, belirli bir mükellefe ve cihaza bağlı bir sertifika üretir. Buradaki retler kriptografiden çok kayıt tutmayla ilgilidir.
- Onboarding’den gelen uyum (compliance) kimlik bilgileri, üretim kimlik bilgilerinin olması gereken yerde hâlâ kullanılıyor.
- Sertifika süresi dolmuş ya da çok sunuculu bir kurulumda yalnızca bir düğümde yenilenmiş.
- Belgedeki satıcı vergi kaydı, sertifikanın kesildiği kayıtla uyuşmuyor.
- Bir sunucunun saati kaydığı için imza zaman damgası kabul penceresinin dışında kalıyor.
Saat kayması özellikle şüphe hak ediyor. Aralıklı hata verir, birkaç düğümden yalnızca birinde hata verir ve biri sunucu saatlerini karşılaştırana kadar tam olarak rastgele bir idare hatası gibi görünür.
5. QR kodu yapısal olarak yanlış
QR içeriği TLV’dir — etiket, uzunluk, değer — ve base64’e kodlanır; bir URL ya da serbest metin değildir. Basitleştirilmiş faturalar standart olanlardan daha fazla etiket taşır, damga ve açık anahtar dahil. Sıra önemlidir ve uzunluklar bayt uzunluğudur.
Arapça satıcı adları bunun sessizce kırıldığı yerdir: uzunluk karakter değil UTF-8 bayt saymalıdır. Dize uzunluğunu karakterle ölçen kod, Arapça adlı her satıcı için anlamsız çözümlenen bir QR üretir ve İngilizce yazılmış her testten geçer.
6. Tutarlar tutmuyor
Satır tutarları, vergi ara toplamları ve belge toplamları yuvarlama kurallarına göre iki hanede uyuşmalı; yuvarlama da kütüphanenin koyduğu yerde değil, doğru seviyede yapılmalı. Karma oranlı sepetler, satır indirimleri, kargonun satır mı yoksa masraf mı sayıldığı ve vergi dahil saklanan fiyatlar — uyuşmazlıkların çoğunu bu dört durum üretir.
Belirtisi, yer değiştiren bir rettir: bazı siparişlerde çıkar bazılarında çıkmaz, ve çıktıklarının kimsenin ilgili sanmadığı ortak bir özelliği vardır.
Bunları asıl ne önler
Yukarıdakilerin hiçbiri daha iyi alan eşlemesiyle çözülmez. İlk fatura kesilmeden önce alınan dört mimari kararla önlenir.
- Kesimi sıraya sokun. Sayacı ve önceki özeti tek bir yazıcı, kilit altında, birlikte üretsin. Buradaki eşzamanlılık bir optimizasyon problemi değil, bir doğruluk problemidir.
- Göndermeden önce doğrulayın. Şema ve iş kuralları önce yerelde çalışsın. Geçemeyecek bir fatura ne bir gönderim denemesini ne de bir sayaç değerini harcamalı.
- Yeniden denemeyi idempotent yapın. Ağ zaman aşımı ret değildir. Aynı UUID’yi tekrar göndermek güvenli olmalı ve bir zaman aşımı asla yeni sayaçla yeniden kesime yol açmamalı.
- Hataları sınırda tercüme edin. Satıcı bir doğrulama kodu değil, ne yapacağını görmeli. Her ret; okunabilir bir gerekçe, ait olduğu fatura ve geliştirici gerektirmeyen bir yeniden deneme yolu taşımalı.
Sonuncusu, çalışan bir uyum entegrasyonu ile destek kuyruğu üreten bir entegrasyon arasındaki farktır. İdare size hangi kuralın patladığını söyler. Bunun hangi sipariş olduğunu, kasanın başında hangi satıcının beklediğini ve sırada ne yapması gerektiğini yalnızca sizin sisteminiz bilir.
Bir şey daha: şartname değişecek
ZATCA revizyon yayımlıyor; BAE ve AB de öyle. Bir uyum entegrasyonu canlıya alışta biten bir proje sayılırsa, ilk revizyon acil duruma dönüşür. Sürdürülen bir yüzey sayılırsa planlı bir bakım kalemi olur. Fark bundan ibaret ve bu, kodun nasıl yazıldığından çok işin nasıl sözleşmeye bağlandığıyla belirleniyor.
ZATCA Faz 2, BAE EIS ve AB Dijital Ürün Pasaportu’nu, inceleyemediğimiz satıcı ortamlarında canlıda çalışan ürünlerin içinde işletiyoruz. Bunlardan birine entegre oluyorsanız ya da mevcut entegrasyonunuz kimsenin açıklayamadığı retler üretiyorsa, sistemi bize anlatın.
Benzer bir şey mi geliştiriyorsunuz?
Ne geliştirdiğinizi ve neye bağlanması gerektiğini anlatın.