Paraşüt’ten geçiş

Aynı işi yapan iki API’nin farkları, entegrasyonu yazarken değil okurken görülsün diye.

Ad eşlemesi — önce buraya bakın

En pahalı yanlış anlama adlardadır, çünkü kod derlenir ve yanlış tabloyu okur.

Aradığınız şeyYouSoft kaynağı
Müşteri / tedarikçi kartı (cari)/v1/contacts
Carinin hareket dökümü (ekstre)/v1/contacts/{id}/ledger
Carinin iletişim kişileri/v1/contacts/{id}/people (ya da ?include=people)
Kasa / banka hesabı/v1/accounts — cari DEĞİL
Kasa / banka hareketleri/v1/accounts/{id}/transactions
Satış faturası ve taslakları/v1/invoices (taslağı status: draft ayırır)
Satış faturasına tahsilat (ödeme) işleme/v1/invoices/{id}/payments
Gelen (alış) e-faturalar/v1/inbox-invoices
e-SMM / e-Müstahsil/v1/receipts
e-İrsaliye/v1/despatches
Alıcının e-fatura posta kutusu sorgusu/v1/e-invoice-inboxes/{tax_number}

contacts ile accounts ayrımı burada keskindir: “hesap” sözcüğü YouSoft’ta kasa ve banka demektir, carinin bakiyesi demek değildir. Cari kartında bakiye alanı yoktur: bakiye ledger satırlarının balance alanındadır (satırın yazıldığı anda saklanan, para birimi başına yürüyen bakiye).

Cari adresi bir nesnedir

Cari kartının adresi tek bir address nesnesinde durur: line, neighborhood, district, city, postal_code ve country (ISO 3166-1 alpha-2, boşsa Türkiye). Adresi hiç girilmemiş kartta anahtar gelmez. PATCH adresi alan alan birleştirir: göndermediğiniz alan korunur, boş dize o alanı siler.

e-Fatura ve e-Arşiv gönderimi alıcının il ve ilçesini ister. Kartı aktarırken adresi de yazın; ikisi boş karta kesilen fatura gönderimde 400 (details.field: contact_id) alır.

İlişkiler satır içi gelir — included[] yok

JSON:API alışkanlığıyla yanıtın kökünde bir included[] dizisi arayıp tip+id ile birleştirme yapmayın: burada genişletme satır içidir. ?include=contact istediğinizde cari, faturanın kendi contact alanına yazılır. Derinlik 1’dir; noktalı ad 400 alır.

Cari kartı çözülemeyen belgede contact anahtarı hiç gelmez (null da değil) — dönen kart, belge düzenlenirken seçilenkarttır (cari hareketinin yazıldığı kartın ta kendisi) ve kart seçilmemiş alıcıya da fatura kesilir. Ayrıntısı sorgu sözleşmesinde.

Sayfalama: numara değil imleç, tavan 25 değil 100

page= yoktur; sayfa meta.next_cursor ile ilerler ve page_size tavanı 100’dür (varsayılan 25). Toplam kayıt sayısı (total) yayımlanmaz — ilerleme çubuğu kuran istemciler bunu baştan bilsin.

Kimlik: OAuth token değil, istek imzası

Jeton uç noktası, yenileme jetonu ve süre yönetimi yoktur. Her istek anahtar + zaman damgası + HMAC-SHA256 imzasıyla gider; imza gövdeyi ve ham sorgu dizesini kapsar. Geçişte en sık kaybedilen yer burasıdır: test vektörünü ilk gün koşturun.

password grant’ının karşılığı yoktur ve olmayacaktır: kullanıcının panel parolasını üçüncü tarafa verdiren bir akış, parolayı üçüncü tarafın log ve yedeklerine taşır. Yetki, kullanıcının parolasından değil, firma sahibinin ürettiği anahtarın kapsamlarından gelir. client_credentials de v1’de yoktur — gerekçesi başlangıç rehberinde.

Gönderim asenkrondur

POST /v1/invoices/{id}/send 202 döner ve bu, belgenin GİB’e ulaştığı anlamına gelmez: uç, taslağı gönderilebilir olduğunu doğrular ve kuyruğa alır. İlerlemeyi GET /v1/invoices/{id} ile status alanından izleyin (draft → sending → sent, ya da failed; sonrasında accepted, rejected ya da cancelled); daraltılmamış ham durum status_detail’dedir. Yanıtı senkron sanan bir istemci, faturayı gönderilmemiş sayıp yeniden dener.