Paraşüt'te fatura, irsaliye, tahsilat ve ödeme kayıtlarının neredeyse hepsi bir cariye bağlanır. Cari, Paraşüt API'sinde contacts kaynağıdır ve hem müşterilerinizi hem de tedarikçilerinizi tek bir yapıda tutar. Entegrasyonun geri kalanı bu kayda dayandığı için cari tarafını baştan doğru kurmak, ileride mükerrer müşteri, yanlış vergi numarası ya da bakiyesi bölünmüş hesaplarla uğraşmamanın en kısa yoludur.
Bu yazıda Paraşüt API v4 ile cari oluşturmayı, şahıs ve şirket ayrımını, vergi numarası ve vergi dairesi alanlarını, yetkili kişi eklemeyi, aynı müşteriyi iki kez açmamak için arama yapmayı, güncellemeyi, arşivlemeyi ve salt okunur bakiye ile hesap ekstresini okumayı adım adım anlatıyoruz. OAuth, firma seçimi ve genel istek yapısı gibi temel konular için önce Paraşüt entegrasyonu genel rehberine göz atabilirsiniz.
Cari Uç Noktalarına Genel Bakış

Tüm yollar https://api.parasut.com/v4/{company_id} ile başlar. İsteklerde Authorization: Bearer başlığı ve Content-Type: application/vnd.api+json (veya application/json) gönderilir. Erişim belirtecini nasıl alacağınızı Paraşüt OAuth2 token alma rehberinde ayrıntılı anlattık.
| Metot ve yol | Ne işe yarar |
|---|---|
| GET /contacts | Carileri listeler; filtre, sıralama ve sayfalama alır |
| POST /contacts | Yeni müşteri ya da tedarikçi oluşturur (201) |
| GET /contacts/{id} | Tek cariyi döner |
| PUT /contacts/{id} | Cariyi günceller (200) |
| DELETE /contacts/{id} | Cariyi siler (204, gövdesiz) |
| GET /contacts/{contact_id}/transaction_history_items | Carinin hesap ekstresi |
| POST /contacts/{id}/contact_debit_transactions | Cariden faturasız tahsilat |
| POST /contacts/{id}/contact_credit_transactions | Cariye faturasız ödeme |
Son iki uç tahsilat ve ödeme konusuna girdiği için Paraşüt API ile tahsilat ve ödeme kaydı yazısında ele alınıyor. Burada cari kaydının kendisine odaklanıyoruz.
account_type ve contact_type: Müşteri mi, Tedarikçi mi, Şahıs mı, Şirket mi?
Cari oluştururken iki alan zorunludur: name ve account_type. account_type yalnızca customer (müşteri) ya da supplier (tedarikçi) değerini alır. Bundan bağımsız olarak contact_type alanı carinin hukuki niteliğini belirtir: person (şahıs) ya da company (şirket). Yani "tedarikçi olan bir şahıs" ya da "müşteri olan bir şirket" gibi dört kombinasyonun hepsi mümkündür.
Satış faturasında alıcı olarak seçeceğiniz kayıt genellikle customer, alış faturası ve fişlerde tedarikçi olarak bağlayacağınız kayıt ise supplier olur. Alış tarafını alış faturası ve gider kaydı yazısında işliyoruz.
| Alan | Açıklama |
|---|---|
| name | Zorunlu. Müşteri/tedarikçi adı veya unvanı |
| account_type | Zorunlu. customer veya supplier |
| contact_type | person veya company |
| short_name | Kısa ad |
| tax_number | Vergi numarası ya da TC kimlik no |
| tax_office | Vergi dairesi |
| email, phone, fax | İletişim bilgileri |
| address, district, city, postal_code, country | Adres alanları (ilçe, il, posta kodu, ülke) |
| is_abroad | Carinin yurt dışında olup olmadığı |
| iban | IBAN |
| archived | Arşiv durumu |
| untrackable | Listelenmemiş müşteri; sonradan listelenebilir hale getirilemez |
Vergi numarası alanı tek bir alandır: şirketler için vergi kimlik numarasını, şahıslar için TC kimlik numarasını tax_number içinde gönderirsiniz. Hangi belgeyi (e-Fatura, e-Arşiv) kesmeniz gerektiği bu alanla değil, alıcının e-Fatura mükellefiyeti sorgusuyla belirlenir; bu akışı e-Fatura ve e-Arşiv gönderme yazısında anlattık.
Cari Oluşturma: Şirket Örneği
Gövde JSON:API biçimindedir: data.type çoğul olarak contacts yazılır, data.id oluştururken gönderilmez. Aşağıdaki istek bir şirket müşterisi açar:
curl -X POST "https://api.parasut.com/v4/{company_id}/contacts" \
-H "Authorization: Bearer $PARASUT_TOKEN" \
-H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
"type": "contacts",
"attributes": {
"name": "Örnek Yazılım A.Ş.",
"account_type": "customer",
"contact_type": "company",
"tax_number": "1234567890",
"tax_office": "Kadıköy",
"email": "muhasebe@example.com",
"city": "İstanbul",
"district": "Kadıköy",
"address": "Örnek Mah. Deneme Sok. No:1"
}
}
}'Başarılı istekte 201 döner ve yanıtın data.id alanı yeni carinin kimliğidir. Bu değer bir string'dir; fatura oluştururken relationships.contact.data.id içine aynen string olarak yazılır. Bu kimliği kendi veritabanınızda müşteri kaydınızın yanına saklayın; sonraki siparişlerde aramaya bile gerek kalmaz.
{
"data": {
"id": "456",
"type": "contacts",
"attributes": {
"name": "Örnek Yazılım A.Ş.",
"account_type": "customer",
"contact_type": "company",
"tax_number": "1234567890",
"balance": 0,
"trl_balance": 0
}
}
}Şahıs müşteri ve yurt dışı müşteri
Bireysel bir e-ticaret müşterisi için contact_type değerini person yapın ve TC kimlik numarası biliniyorsa tax_number içine yazın. Yurt dışındaki bir alıcı için is_abroad: true ve country alanını doldurun. Yurt dışı satış faturası ve döviz konusu için Paraşüt API döviz kuru ve dövizli fatura yazısına bakabilirsiniz.
{
"data": {
"type": "contacts",
"attributes": {
"name": "Ayşe Demir",
"account_type": "customer",
"contact_type": "person",
"tax_number": "11111111111",
"email": "ayse@example.com",
"phone": "+90 555 000 00 00",
"city": "Ankara"
}
}
}Yetkili Kişi Ekleme (contact_people)
Şirket carilerinde muhasebe veya satın alma yetkilisini ayrı kişi olarak tutmak isteyebilirsiniz. Bunun için relationships.contact_people ilişkisi kullanılır. Diğer ilişkilerden farklı olarak bu ilişkinin elemanları attributes taşır: name, email, phone ve notes. Yeni kişide id gönderilmez, type değeri contact_people olur.
{
"data": {
"type": "contacts",
"attributes": {
"name": "Örnek Lojistik Ltd. Şti.",
"account_type": "supplier",
"contact_type": "company",
"tax_number": "9876543210",
"tax_office": "Çankaya"
},
"relationships": {
"contact_people": {
"data": [
{
"type": "contact_people",
"attributes": {
"name": "Mehmet Kaya",
"email": "mehmet@example.com",
"phone": "+90 312 000 00 00",
"notes": "Fatura ve ödeme yetkilisi"
}
}
]
}
}
}
}Kişileri okurken ?include=contact_people ekleyin; kayıtlar yanıtın included dizisinde gelir. Cari uçlarında geçerli include değerleri yalnızca category, contact_portal ve contact_people'dir. Listede olmayan bir değer uydurmayın.
Mükerrer Cari Açmamak: Önce Ara, Sonra Oluştur
![Mükerrer Cari Açmamak: Önce Ara, Sonra Oluştur: filter[tax_number], filter[email], filter[name], filter[tax_office] ve filter[city]](/assets/blog/parasut-api-cari-hesap-musteri-olusturma-b5.webp)
Entegrasyonlarda en sık görülen sorun, her siparişte aynı müşteri için yeni bir cari açılmasıdır. Bunun sonucu bölünmüş bakiyeler ve okunması zor ekstrelerdir. Paraşüt'ün kendi önerdiği akış basittir: önce vergi numarasıyla arayın, bulursanız o kaydın id'sini kullanın, bulamazsanız oluşturun.
GET /contacts ucunda belgelenen filtreler şunlardır:
filter[tax_number]: vergi numarası veya TC kimlik no ile arama (en güvenilir anahtar)filter[email]: e-posta ile arama (şahıs müşterilerde kullanışlı)filter[name]: ad veya unvan ile aramafilter[tax_office]vefilter[city]: vergi dairesi ve ilfilter[account_type]:customerveyasupplier
Sıralama için sort parametresi id, balance, name ve email değerlerini alır; varsayılan -balance'tır. Sayfa boyutu varsayılan 15, en fazla 25'tir. Filtre ve sayfalamanın genel kurallarını filtreleme, sayfalama ve include yazısında topladık.
curl -g "https://api.parasut.com/v4/{company_id}/contacts?filter[tax_number]=1234567890&filter[account_type]=customer&page[size]=25" \
-H "Authorization: Bearer $PARASUT_TOKEN" \
-H "Accept: application/json"Belge, filtrelerin tam eşleşme mi yoksa kısmi eşleşme mi yaptığını açıkça yazmaz. Bu yüzden dönen sonuçlardaki tax_number değerini kendi kodunuzda birebir karşılaştırmak en güvenli yoldur. Aşağıdaki Node.js örneği bu mantığı uygular:
// parasut.ts: tüm örneklerde kullanılan küçük istemci
const BASE = `https://api.parasut.com/v4/${process.env.PARASUT_COMPANY_ID}`;
export async function parasut(method: string, path: string, body?: unknown) {
const res = await fetch(BASE + path, {
method,
headers: {
Authorization: `Bearer ${process.env.PARASUT_TOKEN}`,
'Content-Type': 'application/vnd.api+json',
Accept: 'application/json',
},
body: body === undefined ? undefined : JSON.stringify(body),
});
if (res.status === 204 || res.status === 304) return null; // gövdesiz yanıtlar
const json = await res.json();
if (!res.ok) {
// Hata metnine değil, durum koduna ve errors[].source.pointer alanına bakın
throw Object.assign(new Error(`Paraşüt HTTP ${res.status}`), { status: res.status, errors: json.errors });
}
return json;
}import { parasut } from './parasut';
type Musteri = { ad: string; vergiNo?: string; vergiDairesi?: string; eposta?: string; sirket: boolean };
export async function cariBulVeyaOlustur(m: Musteri): Promise<string> {
// 1) Vergi numarası varsa onunla, yoksa e-posta ile ara
const q = new URLSearchParams({ 'filter[account_type]': 'customer', 'page[size]': '25' });
if (m.vergiNo) q.set('filter[tax_number]', m.vergiNo);
else if (m.eposta) q.set('filter[email]', m.eposta);
if (m.vergiNo || m.eposta) {
const sonuc = await parasut('GET', `/contacts?${q}`);
const eslesen = sonuc.data.find((c: any) =>
m.vergiNo ? c.attributes.tax_number === m.vergiNo : c.attributes.email === m.eposta);
if (eslesen) return eslesen.id; // string id
}
// 2) Bulunamadı: oluştur (salt okunur alanları göndermeyin)
const yeni = await parasut('POST', '/contacts', {
data: {
type: 'contacts',
attributes: {
name: m.ad,
account_type: 'customer',
contact_type: m.sirket ? 'company' : 'person',
tax_number: m.vergiNo,
tax_office: m.vergiDairesi,
email: m.eposta,
},
},
});
return yeni.data.id;
}Cariyi Güncelleme (PUT)
Cari güncellemesi PUT /{company_id}/contacts/{id} ile yapılır. Şemada name ve account_type güncelleme gövdesinde de zorunlu olarak işaretlidir; bu yüzden değişen alanların yanında bu ikisini de gönderin. Yol parametresindeki id integer, gövdedeki data.id ise string'dir.
curl -X PUT "https://api.parasut.com/v4/{company_id}/contacts/456" \
-H "Authorization: Bearer $PARASUT_TOKEN" \
-H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
"id": "456",
"type": "contacts",
"attributes": {
"name": "Örnek Yazılım A.Ş.",
"account_type": "customer",
"email": "finans@example.com",
"address": "Yeni Mah. Yeni Sok. No:5"
}
}
}'Doğrulama hatasında 422 döner. Hata metni değişebileceği için hangi alanın sorunlu olduğunu errors[].source.pointer (ör. /data/attributes/email) üzerinden okuyun. Hata kodlarının tamamı ve tekrar deneme kuralları için Paraşüt API hata kodları ve rate limit yazısına bakın.
Arşivleme ve Silme
Cariler için ayrı bir arşiv ucu belgelenmemiştir; arşiv durumu archived alanıyla tutulur ve bu alan yazılabilir. Bir müşteriyi listelerden kaldırmak ama geçmiş kayıtlarını korumak istiyorsanız güncellemede "archived": true gönderin. Geri almak için aynı alanı false yapın.
Kalıcı silme DELETE /{company_id}/contacts/{id} ile yapılır ve başarıda gövdesiz 204 döner. Üzerinde fatura veya işlem bulunan bir cari için silmenin ne sonuç verdiğini belge ayrıca açıklamaz; muhasebe geçmişi olan carilerde arşivlemeyi tercih etmek daha güvenlidir.
Bakiye ve Hesap Ekstresi (Salt Okunur)
![Bakiye ve Hesap Ekstresi (Salt Okunur): Filtreler filter[...] biçiminde değildir, Tarih filtreleri YYYY-MM-DD biçimindedir ve verilen günü dahil eder., Tür ya da tarih filtresi...](/assets/blog/parasut-api-cari-hesap-musteri-olusturma-b8.webp)
Cari yanıtında bakiye alanları gelir, ancak bunların hepsi salt okunurdur. Paraşüt bakiyeyi faturalar, tahsilatlar ve ödemelerden kendisi hesaplar; istek gövdesinde bu alanları göndermeyin.
| Alan | Anlamı |
|---|---|
| balance | Bakiye |
| trl_balance | TL bakiye |
| usd_balance | USD bakiye |
| eur_balance | EUR bakiye |
| gbp_balance | GBP bakiye |
| created_at, updated_at | Kayıt ve son güncelleme tarihi |
Hareket dökümü için GET /{company_id}/contacts/{contact_id}/transaction_history_items ucunu kullanın. Bu uç carinin borç ya da alacak tarafında yer aldığı işlemleri en yeniden en eskiye döner ve her satırda o işlemden sonraki yürüyen bakiyeyi (trl_balance, usd_balance, eur_balance, gbp_balance) verir.
- Filtreler
filter[...]biçiminde değildir:transaction_type_filter,transaction_from_date_filter,transaction_to_date_filtervetag_ids_filterdoğrudan sorgu parametresidir. - Tarih filtreleri
YYYY-MM-DDbiçimindedir ve verilen günü dahil eder. - Tür ya da tarih filtresi verildiğinde yürüyen bakiye yeniden hesaplanmaz; her satır güncel bakiyeyi tekrar eder.
- Sıralama sabittir,
sortkullanılmaz. Sayfa boyutu varsayılan 10, en fazla 25'tir. - İşlemin bağlı olduğu faturayı görmek için
include=transaction,transaction.sales_invoicegibi değerler kullanılabilir.
curl -g "https://api.parasut.com/v4/{company_id}/contacts/456/transaction_history_items?transaction_from_date_filter=2026-10-01&transaction_to_date_filter=2026-10-31&include=transaction" \
-H "Authorization: Bearer $PARASUT_TOKEN"Carileri Kategorilere Ayırma
Müşterilerinizi "Bayi", "Kurumsal" ya da "Pazaryeri" gibi gruplara ayırmak için Paraşüt kategorilerini kullanabilirsiniz. Kategoriler item_categories kaynağındadır ve cari kategorisinin category_type değeri Contact olmalıdır. Kategoriyi cari oluştururken relationships.category ile (type: item_categories) bağlayabilir ya da sonradan POST /item_categories/{id}/items/{categorizable_id} ucuyla ekleyebilirsiniz. Kategori uçlarının ayrıntıları ürün, stok ve depo yönetimi yazısında da yer alıyor.
Değişiklikleri Webhook ile İzlemek
Paraşüt arayüzünde muhasebeci bir cariyi düzenlediğinde bunu kendi sisteminize yansıtmak isterseniz contact modeli için create, update ve delete webhook event'leri tanımlıdır. Silme event'inde contact_people verisi yer almaz. Webhook teslimatı garanti edilmediği için düzenli aralıklarla API'den eşitleme yapmanız da önerilir. Kurulum için Paraşüt webhook kurulumu yazısına bakın.
Sık Yapılan Hatalar
account_typegöndermemek ya dacustomer/supplierdışında bir değer yazmak (422).data.typedeğerini tekilcontactyazmak; doğru değer çoğulcontacts'tır.balancegibi salt okunur alanları gövdeye koymak.- Fatura ilişkisinde cari kimliğini sayı olarak göndermek; ilişkilerdeki
iddeğeri string olmalıdır ("id": "456"). - Her siparişte yeni cari açmak; önce arayın ve bulunan kimliği saklayın.
page[size]değerini 25'in üzerine çıkarmak.
Sık Sorulan Sorular
Paraşüt API'de müşteri ile tedarikçi ayrı uçlarda mı?
Hayır. İkisi de /contacts ucundadır ve account_type alanıyla ayrılır: customer müşteri, supplier tedarikçidir. Listede yalnızca birini görmek için filter[account_type] kullanın.
TC kimlik numarasını hangi alana yazmalıyım?
tax_number alanına. Belgede bu alan "Vergi numarası/TC kimlik no" olarak tanımlıdır. Şahıs carilerde contact_type değerini person yapmanız yeterlidir.
Bir carinin borcunu API ile değiştirebilir miyim?
Bakiye alanları salt okunurdur ve doğrudan yazılamaz. Bakiye faturalar, tahsilatlar ve ödemeler sonucunda değişir. Tahsilat ve ödeme kaydı için tahsilat ve ödeme kaydı yazısına bakın.
Aynı vergi numarasıyla iki cari açılır mı?
Belge vergi numarası için bir tekillik kuralı tanımlamaz. Mükerrer kaydı önlemek sizin entegrasyonunuzun sorumluluğundadır: önce filter[tax_number] ile arayın, eşleşmeyi kodda doğrulayın ve paralel istekleri bir kilitle sıraya sokun.
Pazaryeri veya e-ticaret siparişlerinde hangi bilgiyle cari açmalıyım?
Faturalı kurumsal siparişlerde vergi numarası, bireysel siparişlerde e-posta ya da TC kimlik numarası iyi bir arama anahtarıdır. Siparişten faturaya uçtan uca akışı e-ticaret siparişini Paraşüt'e aktarma yazısında, WooCommerce tarafındaki vergi ve adres alanlarını WooCommerce Türkiye ayarları yazısında bulabilirsiniz.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Paraşüt entegrasyonu genel rehberi · Paraşüt API ile fatura kesme · Ürün, stok ve depo yönetimi · Tahsilat ve ödeme kaydı · Filtreleme, sayfalama ve include · E-ticaret siparişini Paraşüt'e aktarma · Pazaryeri entegrasyonu rehberi