Ana içeriğe geç

Örnek Senaryolar

Her senaryo uçtan uca: satış → fatura. Akışın kendisi hep aynı (İki adım); değişen, belgenin hangi alanları taşıdığı.

İstekler kısaltılmıştır — provider, order_number, alıcı adresi gibi alanlar her senaryoda aynı ve referansta duruyor.

İki ucun KDV'si zıt

Satış ucunda fiyatlar KDV dahil ve vat_rate yüzde (20). Fatura ucunda KDV hariç ve vat_rate oran (0.2). En sık yapılan hata budur.

1. Yurt içi normal satış​

En yaygın hâl: TL, tek KDV oranı, nihai tüketici.

POST /v1/integrations/orders
{
"external_id": "ORD-1001",
"buyer": { "title": "Ahmet Yılmaz", "tckn": "11111111111", "email": "[email protected]" },
"lines": [
{ "title": "Kablosuz kulaklık", "sku": "SKU-42", "quantity": 1,
"unit_price": 1200, "total_price": 1200, "vat_rate": 20 }
]
}
POST /v1/invoicing/invoices/ · Idempotency-Key: ORD-1001
{
"document_type": "EARSIV",
"transaction_header_id": "<satıştan dönen transaction_id>",
"canonical": {
"Recipient": { "VKNorTCKN": "11111111111", "Title": "Ahmet Yılmaz" },
"Lines": [
{ "Title": "Kablosuz kulaklık", "ProductCode": "SKU-42", "Quantity": 1,
"UnitPrice": 1000, "LineTotal": 1000, "UnitCode": "C62", "VatRate": 0.2 }
],
"Totals": { "SubtotalExclVAT": 1000, "VatTotal": 200, "DiscountTotal": 0, "GrandTotal": 1200 }
}
}

document_type olarak EARSIV göndermek güvenli varsayılandır: alıcı kayıtlı bir e-Fatura mükellefi çıkarsa belgeyi biz e-Faturaya yükseltiriz.

2. Dövizli satış — kuru biz dolduralım​

currency TRY değilse belge TL karşılığının türetildiği kuru taşımak zorunda. Kur göndermeniz gerekmiyor:

POST /v1/integrations/orders
{
"external_id": "ORD-1002",
"currency": "USD",
"buyer": { "title": "Acme LLC", "tax_number": "1234567890", "tax_office": "Kadıköy" },
"lines": [
{ "title": "Danışmanlık", "quantity": 1, "unit_price": 1200,
"total_price": 1200, "vat_rate": 20 }
]
}
201 Created
{
"transaction_id": "9f1c…",
"currency": "USD",
"exchange_rate": 41.37,
"exchange_rate_source": "TCMB",
"exchange_rate_date": "27.09.2026"
}

Yanıt hangi kuru kullandığımızı söyler. Kendi kurunuzu kullanmak istiyorsanız exchange_rate gönderin: aynen kullanılır, MANUAL işaretlenir ve TCMB ile karşılaştırılmaz.

Faturada canonical.Currency göndermeyin — para biriminin ve kurun tek kaynağı satıştır. Satır tutarları sipariş para biriminde kalır; çevrilmez.

Bülten her gün yayımlanmıyor

TCMB hafta içi ~15:30'da yayımlar, hafta sonu yayımlamaz. Pazartesi sabahı kesilen belge cumanın bültenini taşır — döndüğümüz exchange_rate_date bunu açık eder. Bülten o para birimini hiç taşımıyorsa kur uydurulmaz: ERROR_EXCHANGE_RATE_REQUIRED döner ve kuru sizden ister.

3. KDV istisnalı satış (ihracat, %0 KDV)​

%0 KDV'li satır istisna sebebi olmadan faturalanamaz — GİB reddediyor. Sebep belge genelinde tek koddur:

POST /v1/integrations/orders
{
"external_id": "ORD-1003",
"currency": "USD",
"invoice_exemption_code": "301",
"invoice_exemption_reason": "11/1-a Mal ihracatı",
"buyer": { "title": "Acme LLC", "tax_number": "1234567890" },
"lines": [
{ "title": "Tekstil ürünü", "quantity": 100, "unit_price": 50,
"total_price": 5000, "vat_rate": 0 }
]
}

Faturada kod yalnız %0 satırlara iner; KDV'li satıra dokunulmaz:

canonical.Lines
[
{ "Title": "Tekstil ürünü", "Quantity": 100, "UnitPrice": 50, "LineTotal": 5000,
"VatRate": 0,
"TaxExemptionReasonCode": "301", "TaxExemptionReason": "11/1-a Mal ihracatı" },
{ "Title": "Kargo", "Quantity": 1, "UnitPrice": 100, "LineTotal": 100, "VatRate": 0.2 }
]

InvoiceTypeCode göndermeyin: sunucu satırlardan türetir, bu belge ISTISNA olur.

Kodu gönderemiyorsanız (kanalınız GİB istisna kodunu tutmuyor olabilir) istek yine kabul edilir ve satış oluşur; yalnız faturası ERROR_INVOICE_ZERO_VAT_ NEEDS_EXEMPTION ile bekler ve mükellef kodu panelden seçerek keser.

4. Tevkifatlı hizmet faturası​

Tevkifat, KDV'nin bir kısmının satıcı yerine alıcı tarafından beyan edilmesidir. Satır bazındadır ve yalnız fatura ucunda gönderilir:

canonical.Lines
[
{ "Title": "Temizlik hizmeti", "Quantity": 1, "UnitPrice": 10000,
"LineTotal": 10000, "VatRate": 0.2,
"WithholdingCode": "612", "WithholdingName": "Temizlik hizmeti" }
]

Oranı göndermiyorsunuz. 612 kodunun yasal oranı 9/10'dur ve bunu sunucu koddan belirler. Fatura KDV'nin tamamını (2.000 TL) gösterir; alıcı tevkifat dışı kalan 200 TL'yi satıcıya öder, 1.800 TL'yi doğrudan devlete beyan eder.

Belge tipi otomatik TEVKIFAT olur.

5. Özel matrahlı satış (ikinci el araç)​

Özel matrah, KDV'nin satış bedelinin tamamı üzerinden değil beyan edilen bir taban üzerinden hesaplanmasıdır (KDVK md. 23): ikinci el araç/taşınmaz kâr marjı, kuyumcuda külçe bedeli düşülmüş kısım, telefon kartı bayi satışı.

canonical.Lines
[
{ "Title": "2019 model binek araç", "Quantity": 1, "UnitPrice": 550000,
"LineTotal": 550000, "VatRate": 0.2,
"TaxBaseAmount": 50000, "TaxBaseCode": "812",
"TaxBaseReason": "İkinci el araç kâr marjı" }
]

KDV 550.000 değil 50.000 üzerinden hesaplanır. İstisnayla karıştırmayın: istisnada KDV yoktur, burada vardır — yalnız tabanı farklıdır.

8xx kodları iki listede birden var

Tevkifat 801-825 ile özel matrah 801-812 sayısal olarak çakışır ama farklı UBL elemanlarıdır ve farklı alanlardır (WithholdingCode ↔ TaxBaseCode). Kodu yanlış alana yazmak farklı bir belge üretir; biçim kontrolü bunu ERROR_INVOICE_TAX_BASE_INVALID_CODE ile yakalar.

6. Kısmi iade​

İade kendi belgesidir ve satışa bağlanmaz — bağlanırsa aynı satış iki kez sayılır. Satırlar pozitif tutar taşır:

POST /v1/integrations/refunds
{
"external_id": "REF-2001",
"order_external_id": "ORD-1001",
"buyer": { "title": "Ahmet Yılmaz", "tckn": "11111111111" },
"lines": [
{ "title": "Kablosuz kulaklık", "quantity": 1, "unit_price": 1200,
"total_price": 1200, "vat_rate": 20 }
]
}

external_id iadenin kendi kimliğidir, siparişin değil: bir siparişin birden çok kısmi iadesi olabilir ve sipariş kimliğine bakılsaydı ikinci iade sessizce düşerdi.

Dövizli bir satışın iadesinde exchange_rate göndermezseniz asıl satışın kurunu kendimiz buluruz — bugünün kurunu değil. Aylar önce 41,37'den kesilen satışı bugün 43,10'dan iade etmek yanlış beyandır.

İade belgesini kendiniz kesiyorsanız​

Satış zorunluluğunun tek istisnası iade tipleridir (IADE, TEVKIFATIADE, YTBIADE) — ama iade asıl fatura atfı olmadan kesilemez:

POST /v1/invoicing/invoices/
{
"document_type": "EARSIV",
"canonical": {
"InvoiceTypeCode": "IADE",
"return_info": {
"Originals": [
{ "Number": "FF32026000000123", "IssueDate": "2026-09-27T00:00:00Z" }
]
}
}
}

Anahtar return_info (snake_case) — canonical içindeki diğer alanlar PascalCase'dir ama bu blok farklı etiketlenmiştir ve ReturnInfo yazımı sessizce düşer. IssueDate RFC 3339 olmalıdır. Resmî kütüphanelerimiz ikisini de sizin için doğru yazar.

7. e-Fatura mükellefine TEMELFATURA​

Alıcı kayıtlı bir e-Fatura mükellefiyse belge e-Fatura olarak gider. Senaryo seçimi yalnız burada vardır:

POST /v1/invoicing/invoices/
{
"document_type": "EFATURA",
"transaction_header_id": "9f1c…",
"canonical": {
"Scenario": "TEMELFATURA",
"RecipientAlias": "",
"Recipient": { "VKNorTCKN": "1234567890", "Title": "Örnek Ticaret A.Ş." }
}
}

TEMELFATURA'da alıcı yanıt veremez, belge kesindir. Varsayılan TICARIFATURA'da alıcı 8 gün içinde KABUL/RED gönderebilir. Fark hukukidir, görünüm değil.

RecipientAlias'ı boş bırakın: posta kutusu etiketini VKN'den biz çözeriz.

Sırada ne var​