e-Fatura XML dosyası nasıl okunur? UBL-TR yapısı adım adım

"Bana gelen faturanın XML'inde satıcı, alıcı ve vergi toplamı hangi etikette?"

2 5 dk. 30 Eylül 2026 00:09 / Çözümce / Web Araçları
e-Fatura XML dosyasındaki etiketlerin ağaç yapısını gösteren çizim
Kurgusal bir e-Fatura XML'ini XML Biçimlendirici'de açtık: 13 ana öğe, satıcı, alıcı ve vergi toplamı. İyi biçimli ile geçerli farkı da yazıda.

Muhasebe ve yazılım tarafında e-Fatura dosyasına bakanlar için: hangi bilgi hangi etikette ve hatalı bir etiket nasıl bulunur.

Muhasebeciniz e-Fatura dosyasını gönderdi, ama açınca tek satırlık, anlaşılmaz bir metin duruyor. Tutar nerede, KDV nerede, satıcı kim? Cevap dosyanın içinde; yalnızca etiketleri okumayı bilmek gerekiyor.

Bu yazıda kurgusal bir e-Fatura XML'ini XML Biçimlendirici'ye yapıştırdık. Ağaç görünümünde hangi bilginin hangi etikette durduğuna baktık, bir kapanış etiketini bozup aracın hatayı nasıl gösterdiğini yazdık. Şirket adları ve vergi numaraları kurgusaldır.

Kısaca

Bir e-Fatura, UBL-TR biçiminde yazılmış bir XML dosyasıdır. Araç dosyanın sözdizimini denetler ve şema (XSD) verilirse yapıyı da denetler. Bizim denememizde şema vermedik; bu yüzden yalnız sözdizimi kontrol edildi.

e-Fatura aslında bir XML dosyası

XML, veriyi etiketlerle sarmalayan bir metin biçimidir. Bir arşiv dolabındaki klasörler gibi: en dışta Invoice klasörü, içinde satıcı, alıcı ve satırlar için alt klasörler var. e-Fatura'da bu klasörlerin adları UBL-TR kılavuzunda tek tek belirlenmiş.

Etiketlerin önündeki cbc ve cac, ad alanı önekleridir. cbc temel bilgileri (numara, tarih, tutar), cac ise iç içe grupları (satıcı, alıcı, satır) taşır.

Kurgusal faturamız

Kamu e-Fatura teknik kılavuzundaki etiket adlarını temel alarak 50 satırlık bir fatura hazırladık. Satıcı "Örnek Ticaret Ltd. Şti.", alıcı "Deneme Market"; vergi numaraları açıkça sahte (1111111111 ve 2222222222). Fatura tek satırlık: iki adet ürün, 50,00 TRY birim fiyat, 100,00 TRY tutar, 20,00 TRY vergi, 120,00 TRY ödenecek toplam. Tam vergi kırılımı gibi ayrıntıları bilerek kısalttık; bu bir örnek dosyadır, göndermeye hazır bir fatura değildir.

<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
  <cbc:UBLVersionID>2.1</cbc:UBLVersionID>
  <cbc:CustomizationID>TR1.2</cbc:CustomizationID>
  <cbc:ProfileID>TEMELFATURA</cbc:ProfileID>
  <cbc:ID>ORN2026000000001</cbc:ID>
  <cbc:UUID>11111111-2222-3333-4444-555555555555</cbc:UUID>
  <cbc:IssueDate>2026-09-29</cbc:IssueDate>
  <cbc:InvoiceTypeCode>SATIS</cbc:InvoiceTypeCode>
  <cbc:DocumentCurrencyCode>TRY</cbc:DocumentCurrencyCode>
  <cac:AccountingSupplierParty>
    <cac:Party>
      <cac:PartyIdentification>
        <cbc:ID schemeID="VKN">1111111111</cbc:ID>
      </cac:PartyIdentification>
      <cac:PartyName>
        <cbc:Name>Örnek Ticaret Ltd. Şti.</cbc:Name>
      </cac:PartyName>
    </cac:Party>
  </cac:AccountingSupplierParty>
  <cac:AccountingCustomerParty>
    <cac:Party>
      <cac:PartyIdentification>
        <cbc:ID schemeID="VKN">2222222222</cbc:ID>
      </cac:PartyIdentification>
      <cac:PartyName>
        <cbc:Name>Deneme Market</cbc:Name>
      </cac:PartyName>
    </cac:Party>
  </cac:AccountingCustomerParty>
  <cac:TaxTotal>
    <cbc:TaxAmount currencyID="TRY">20.00</cbc:TaxAmount>
  </cac:TaxTotal>
  <cac:LegalMonetaryTotal>
    <cbc:LineExtensionAmount currencyID="TRY">100.00</cbc:LineExtensionAmount>
    <cbc:TaxInclusiveAmount currencyID="TRY">120.00</cbc:TaxInclusiveAmount>
    <cbc:PayableAmount currencyID="TRY">120.00</cbc:PayableAmount>
  </cac:LegalMonetaryTotal>
  <cac:InvoiceLine>
    <cbc:ID>1</cbc:ID>
    <cbc:InvoicedQuantity unitCode="C62">2</cbc:InvoicedQuantity>
    <cbc:LineExtensionAmount currencyID="TRY">100.00</cbc:LineExtensionAmount>
    <cac:Item>
      <cbc:Name>Deneme ürünü</cbc:Name>
    </cac:Item>
    <cac:Price>
      <cbc:PriceAmount currencyID="TRY">50.00</cbc:PriceAmount>
    </cac:Price>
  </cac:InvoiceLine>
</Invoice>

Aracı Biçimlendir'de çalıştırdık. Sonuç: "Sözdizimi doğru, belge iyi biçimli". Araç iki uyarı verdi. Birincisi şema denetiminin yapılmadığıydı. İkincisi, belgenin varsayılan ad alanı kullandığına dair bir hatırlatmaydı: XPath sorgularında çıplak öğe adı eşleşmez. Özet satırı: 36 öğe, 15 öznitelik, 6 seviye derinlik.

Girdi 1.851 karakter, çıktı 2.040 karakterdi; fark girintiden geliyor. Küçült seçeneği bu farkı tersine çevirir, ama biz bu yazıda onu denemedik. Araç çıktıyı yeniden okuyup girdiyle düğüm düğüm karşılaştırdı ve "yorumlar, CDATA, ad alanları ve öznitelikler değişmedi" dedi.

XML Biçimlendirici ağaç görünümü: Invoice öğesi ve 13 alt öğesi, sözdizimi doğru, şema denetimi yapılmadı
XML Biçimlendirici ağaç görünümü: Invoice öğesi ve 13 alt öğesi, sözdizimi doğru, şema denetimi yapılmadı

Hangi bilgi hangi etikette?

Ağaç görünümünde kök öğe Invoice ve 13 alt öğesi göründü. Bu alt öğelerin başında yaptığımız faturanın üst bilgileri duruyor, sonra satıcı, alıcı, vergi toplamı, yasal tutarlar ve fatura satırı geliyor.

flowchart LR I["Invoice"] --> K["Üst bilgiler: sürüm, profil, no, tarih, para birimi"] I --> S["AccountingSupplierParty: satıcı"] I --> M["AccountingCustomerParty: alıcı"] I --> V["TaxTotal: vergi toplamı"] I --> T["LegalMonetaryTotal: tutarlar"] I --> L["InvoiceLine: fatura satırı"]
Invoice öğesinin ana dalları
Etiket Anlamı Bizim faturada
cbc:UBLVersionID UBL sürümü 2.1
cbc:CustomizationID Özelleştirme kimliği TR1.2
cbc:ProfileID Profil kimliği TEMELFATURA
cbc:ID Fatura numarası ORN2026000000001
cbc:UUID Evrensel benzersiz kimlik 11111111-2222-3333-4444-555555555555
cbc:IssueDate Düzenleme tarihi 2026-09-29
cbc:InvoiceTypeCode Fatura türü kodu SATIS
cbc:DocumentCurrencyCode Para birimi TRY
cac:AccountingSupplierParty Satıcı (faturayı düzenleyen) Örnek Ticaret Ltd. Şti.
cac:AccountingCustomerParty Alıcı Deneme Market
cac:TaxTotal Toplam vergi tutarı 20.00 TRY
cac:LegalMonetaryTotal Yasal parasal toplam 100.00 / 120.00 / 120.00 TRY
cac:InvoiceLine Fatura satırı 1 satır, 2 adet

Etiket adlarının ve anlamlarının çoğunu Kamu Harcama Süreçlerinde UBL-TR e-Fatura Uygulaması kılavuzundaki listeyle karşılaştırdık. Fatura türü kodu için kılavuzda belirli bir kod değeri yazıyordu; biz kurgusal dosyada SATIS yazdık, kendi faturanız için geçerli kod listesini kılavuzdan kontrol edin.

İyi biçimli ile geçerli arasındaki fark

XML'de iki ayrı soru var. Birincisi, dosya XML kurallarına uyuyor mu? Yani her açılan etiket kapanıyor mu, öznitelikler tırnaklı mı? Buna iyi biçimli denir. İkincisi, dosya beklenen yapıda mı? Yani doğru etiketler, doğru sırada, doğru veri türüyle mi yazılmış? Buna geçerli denir ve bunu ölçmek için bir şema (XSD) gerekir.

Dikkat

Araç ekranında iki ayrı satır var: biri sözdizimi (iyi biçimli), biri şema. Biz şema vermediğimiz için ikinci satır "Şema denetimi yapılmadı" dedi. "Sözdizimi doğru" yazması, faturanın geçerli ya da resmi olarak kabul edilebilir olduğu anlamına gelmez.

İyi biçimli bir dosya yanlış etiketlerle de yazılmış olabilir. Araç bu durumda ancak şema verirseniz öğe sırasını, zorunlu öznitelikleri ve veri türlerini denetleyebilir. Biz resmi XSD paketine sahip olmadığımız için şema doğrulamasını denemedik.

Hatalı bir etiketi bulmak

Faturadan bir kapanış etiketini sildik: alıcının </cac:PartyName> etiketini. Araç kırmızı bir kutu açtı ve biçimlendirmeyi reddetti.

XML Biçimlendirici sözdizimi hatası: 28. satır 13. sütunda PartyName açıldı, Party ile kapandı
XML Biçimlendirici sözdizimi hatası: 28. satır 13. sütunda PartyName açıldı, Party ile kapandı

Kutuda "28. satır, 13. sütun: Belge iyi biçimli değil: Açılış ve kapanış etiketi uyuşmuyor: PartyName açıldı, Party ile kapandı" yazıyordu. Şema satırı da "belge önce iyi biçimli olmalı" dedi. Yani şema denetimi, sözdizimi düzelmeden yapılmıyor.

Bu mesaj satırı doğrudan gösteriyor: hatalı etiket alıcının PartyName öğesinin hemen altında. Elle düzenlenmiş ya da bir programdan yarım çıkmış bir faturada, hatanın satır ve sütunla verilmesi aramayı çok kısaltır; yoksa yüzlerce satırlık dosyayı gözle taramak gerekir.

Adım adım

  1. XML dosyasını Dosya aç ile yükleyin ya da metni sol kutuya yapıştırın.
  2. Biçimlendir'i seçin. "Sözdizimi doğru" mesajını bekleyin.
  3. Ağaç görünümünü açın; Invoice altındaki grupları tek tek açarak aradığınız bilgiyi bulun.
  4. Tutar için LegalMonetaryTotal, vergi için TaxTotal, satırlar için InvoiceLine altına bakın.
  5. Hata çıkarsa mesajdaki satır ve sütuna gidin.

Çıktı biçimini JSON yaparsanız araç, tek çocuğu olan öğeleri nesne, birden fazla olanları dizi yazıyor. Bunu denedik: tek satırlı faturada InvoiceLine bir nesne olarak geldi. Aynı faturaya ikinci bir satır ekleyince InvoiceLine bir dizi oldu. Araç bunu da bildiriyor: "XML kardinalite bildirmez, JSON nesne ile diziyi ayırır". Yani JSON'a çevirip bir program yazacaksanız, tek satırlı ve çok satırlı faturaları ayrı ele almanız gerekir. Dönüşüm geri alınamıyor, ad alanı bildirimleri öznitelik olarak geçiyor, yorumlar hiç aktarılmıyor.

Sınırlar: araç faturayı imzalamaz, göndermez, e-imzayı doğrulamaz

  • Faturayı imzalamıyor ve göndermiyor. Yalnız metnin biçimini ve yapısını denetliyor.
  • e-imzayı doğrulamıyor. İmzalı bir faturanın imzasının geçerli olup olmadığını bu araçla anlayamazsınız.
  • Biz şema doğrulamasını denemedik. Resmi XSD paketi elimizde olmadığı için bunu anlattık ama yapmadık.
  • Örnek dosyamız kısaltılmıştı. Gerçek bir e-Fatura daha fazla alan, vergi kırılımı ve imza içerir.

Kaynak olarak GİB e-Belge sitesindeki kılavuza ulaşmayı denedik; sayfa otomatik erişime kapalıydı. Bu yüzden etiketleri, GİB ve Hazine ve Maliye Bakanlığı'nın kamu e-Fatura uygulama kılavuzundan doğruladık.

Kendi dosyanızla XML Biçimlendirici'yi ücretsiz deneyebilirsiniz.

Bu denemeyi 29 Eylül 2026'da Chrome'da yaptık. Fatura kurgusaldır, gerçek bilgi içermez.

Kaynaklar

Alıntı
Bahsedilen
  • Belirtilmemiş
Temel Alınan Çalışma
  • Belirtilmemiş

Puanla

Yazar Hakkında


Hüseyin Battal Fotoğraf

Meslek Lisesi Bilişim Teknolojileri Web Tasarımı bölümü mezunuyum. Balıkesir Üniversitesi Bilgisayar Programcılığı Ön Lisans programının son senesinde İzmir'e yatay geçiş yaptım. Dokuz Eylül Üniversitesi'nde yarım dönem eğitim aldıktan sonra çalışmaya karar verdim. Yarattığım ve/veya yamaladığım yazılım, eklenti, web uygulamaları ve modları yayınlamak için bir platform oluşturmaya karar verdim ve bu amaç doğrultusunda Çözümce projesini hayata geçirdim.