Bir e-ticaret sitesinde her sipariş için Paraşüt'e elle fatura girmek, sipariş sayısı arttıkça hem zaman kaybına hem de hataya dönüşür. Çözüm, siparişi otomatik olarak Paraşüt'e aktaran küçük bir entegrasyon servisidir. Mağazanız WooCommerce, kendi yazdığınız bir uygulama ya da başka bir altyapı olabilir; Paraşüt tarafındaki işler hep aynıdır: cariyi bul ya da oluştur, ürünleri eşle, faturayı aç, resmileştir ve tahsilatı kaydet.

Bu yazı belirli bir eklentiyi değil, platformdan bağımsız sağlam bir mimariyi anlatıyor: siparişin iki kez faturalanmasını önleyen idempotans, yeniden denenebilir adımlar, kuyruk ve zamanlanmış görev tasarımı, loglama ve mutabakat. Paraşüt API'nin temel kavramları için Paraşüt entegrasyonu genel rehberine, mağaza tarafındaki vergi ve fatura alanları için WooCommerce Türkiye ayarları yazımıza bakabilirsiniz.

Mimariye Genel Bakış

Mimariye Genel Bakış: Tetikleyici, Kuyruk ve worker, Eşleme veritabanı, Token deposu

Entegrasyonu mağaza kodunun içine gömmek yerine ayrı bir servis olarak kurmak, Paraşüt'e yapılan isteklerin müşterinin ödeme ekranını yavaşlatmasını ve bir API hatasının siparişi bozmasını önler. Akış şöyledir:

text
Mağaza ("sipariş ödendi" olayı ya da periyodik çekme)
   |
   v
Kuyruk (order_id)  -->  Worker
                          1. Cari bul / oluştur        (contacts)
                          2. Ürünleri eşle             (products)
                          3. Faturayı idempotent aç    (sales_invoices + external_reference_key)
                          4. Resmileştir               (e_invoice_inboxes, e_archives / e_invoices)
                          5. İşi takip et              (trackable_jobs)
                          6. Tahsilatı kaydet          (sales_invoices/{id}/payments)
                          7. Durumu ve logu yaz        (kendi veritabanınız)
  • Tetikleyici: Mağazanın "sipariş ödendi" gibi bir olayı (webhook ya da kendi kodunuzdaki bir kanca) siparişi kuyruğa atar. Olay kaçarsa diye periyodik bir görev de ödenmiş ama aktarılmamış siparişleri tarar.
  • Kuyruk ve worker: Paraşüt istekleri arka planda, sırayla ve yeniden denenebilir biçimde yapılır.
  • Eşleme veritabanı: Hangi siparişin hangi faturaya, hangi müşterinin hangi cariye, hangi SKU'nun hangi ürüne karşılık geldiği burada tutulur.
  • Token deposu: OAuth token'ları tek bir yerde saklanır ve tek noktadan yenilenir. Ayrıntılar için Paraşüt OAuth2 token alma rehberine bakın.

Veri Modeli: Her Siparişin Durumunu Saklayın

İdempotent bir entegrasyonun temeli, her siparişin hangi adımda kaldığını bilen bir tablodur. Worker çökse, sunucu yeniden başlasa ya da Paraşüt geçici bir hata dönse bile iş kaldığı yerden devam eder.

sql
-- PostgreSQL örneği
CREATE TABLE parasut_order_sync (
  order_id          VARCHAR(64) PRIMARY KEY,
  external_key      UUID        NOT NULL UNIQUE,
  status            VARCHAR(32) NOT NULL DEFAULT 'pending',
  contact_id        VARCHAR(32),
  invoice_id        VARCHAR(32),
  e_doc_type        VARCHAR(16),
  trackable_job_id  VARCHAR(32),
  e_doc_id          VARCHAR(32),
  payment_recorded  BOOLEAN     NOT NULL DEFAULT FALSE,
  attempts          INT         NOT NULL DEFAULT 0,
  last_error        TEXT,
  updated_at        TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE parasut_contact_map (
  customer_key VARCHAR(128) PRIMARY KEY,   -- ör. vergi no ya da e-posta
  contact_id   VARCHAR(32)  NOT NULL
);

CREATE TABLE parasut_product_map (
  sku        VARCHAR(64) PRIMARY KEY,
  product_id VARCHAR(32) NOT NULL
);

external_key sütunu, Paraşüt'ün external_reference_key mekanizması için üretilen UUID'dir ve sipariş satırı oluşurken, yani fatura isteğinden önce yazılır. status sütunu için pending, invoiced, formalizing, formalized, done ve error gibi basit bir durum makinesi yeterlidir.

1. Siparişi Ne Zaman Aktarmalı?

Fatura genellikle ödemesi tamamlanmış siparişler için kesilir; hangi sipariş durumunda faturalayacağınız muhasebe sürecinize bağlıdır. Teknik tarafta iki yöntemi birlikte kullanmak en sağlamıdır:

  • Olay tabanlı: Mağaza siparişi ödendi olarak işaretlediğinde sipariş kimliğini kuyruğa atın ve hemen dönün. Uzun Paraşüt çağrılarını bu istek içinde yapmayın.
  • Zamanlanmış tarama: Birkaç dakikada bir çalışan bir görev, ödenmiş ama parasut_order_sync tablosunda done olmayan siparişleri yeniden kuyruğa atar. Kaçan olaylar ve yarıda kalan işler böyle toparlanır. Kurulum için cron job rehberine ve crontab rehberine bakabilirsiniz.

2. Cariyi Bul ya da Oluştur

Paraşüt'te her fatura bir cariye bağlanır. contacts liste ucu filter[name], filter[email], filter[tax_number], filter[tax_office], filter[city] ve filter[account_type] filtrelerini destekler. Kurumsal alıcıyı vergi numarasıyla, bireysel alıcıyı e-posta ya da TCKN ile aramak mantıklıdır. Yeni cari oluştururken zorunlu alanlar name ve account_type'dır; account_type yalnızca customer ya da supplier, contact_type ise person ya da company olabilir.

javascript
import { parasut } from './parasut.js';

export async function findOrCreateContact(order) {
  const key = order.billing.taxNumber || order.billing.email;
  const cached = await db.contactMap.get(key);
  if (cached) return cached;

  const filter = order.billing.taxNumber
    ? `filter[tax_number]=${encodeURIComponent(order.billing.taxNumber)}`
    : `filter[email]=${encodeURIComponent(order.billing.email)}`;
  const found = await parasut(`/contacts?${filter}&filter[account_type]=customer&page[size]=25`);
  if (found.status !== 200) throw new Error(`Cari arama: HTTP ${found.status}`);

  // Filtrenin tam eşleşme yapıp yapmadığı belgelenmez: sonucu kendiniz doğrulayın
  const match = found.body.data.find((c) =>
    order.billing.taxNumber
      ? c.attributes.tax_number === order.billing.taxNumber
      : c.attributes.email === order.billing.email);
  if (match) { await db.contactMap.set(key, match.id); return match.id; }

  const created = await parasut('/contacts', {
    method: 'POST',
    body: JSON.stringify({ data: { type: 'contacts', attributes: {
      name: order.billing.name,
      account_type: 'customer',
      contact_type: order.billing.isCompany ? 'company' : 'person',
      email: order.billing.email,
      tax_number: order.billing.taxNumber,
      tax_office: order.billing.taxOffice,
      address: order.billing.address,
      city: order.billing.city,
      district: order.billing.district,
      phone: order.billing.phone,
    } } }),
  });
  if (created.status !== 201) throw new Error(`Cari oluşturma: HTTP ${created.status}`);
  await db.contactMap.set(key, created.body.data.id);
  return created.body.data.id;
}

Filtrelerin tam eşleşme mi kısmi eşleşme mi yaptığı belgede yazmaz; bu yüzden örnek, dönen kaydın vergi numarasını ya da e-postasını ayrıca karşılaştırır. Bulunan kimliği eşleme tablosuna yazmak, sonraki siparişlerde aynı müşteri için API çağrısını tamamen ortadan kaldırır. Cari alanlarının tamamı için cari hesap oluşturma rehberine bakın.

3. Ürünleri Eşleyin

3. Ürünleri Eşleyin: Eşlemeyi parasut_product_map tablosunda tutun; her siparişte Paraşüt'te arama..., Birden fazla ürünü toplu doğrulamak için GET /products/by_ids?ids=1,2,3...

Her fatura kalemi bir Paraşüt ürününe bağlanır. Mağazadaki SKU'yu Paraşüt ürününün code alanına eşlemek en temiz yöntemdir: GET /products?filter[code]=SKU ile arayın, yoksa POST /products ile oluşturun. Ürün oluştururken zorunlu alan yalnızca name'dir; code, vat_rate, unit, list_price ve currency (TRL) alanlarını da doldurmak faydalıdır.

  • Eşlemeyi parasut_product_map tablosunda tutun; her siparişte Paraşüt'te arama yapmayın.
  • Birden fazla ürünü toplu doğrulamak için GET /products/by_ids?ids=1,2,3 en fazla 50 kimlik alır; bulunamayan kimlikler yanıtta yer almaz.
  • Kargo ücreti gibi ürün dışı bedelleri faturaya ayrı bir hizmet kalemi olarak eklemek isterseniz bunun için de bir ürün kaydı açmanız gerekir. Bu bedellerin vergisel durumu için mali müşavirinize danışın.

Stok takibi ve depo seçimi gibi konular için ürün, stok ve depo yönetimi rehberine bakın.

4. Faturayı İdempotent Oluşturun

Bu adım entegrasyonun en kritik parçasıdır. Siparişin anahtarı (external_key) istekten önce veritabanında olmalı ve her tekrar denemede aynı anahtar gönderilmelidir. Aynı anahtarla ikinci bir istek yeni fatura açmaz; Paraşüt 422 Bu key ile daha önce bir fatura oluşturulmuş. döner ve mevcut faturanın kimliğini hatanın meta.sales_invoice_id alanında verir. Bu mantığı içeren createInvoiceOnce fonksiyonunu Paraşüt API ile fatura kesme rehberinde adım adım yazdık; burada yalnızca siparişten fatura gövdesine dönüşümü gösteriyoruz.

javascript
export function buildInvoiceBody(order, contactId, productIds) {
  return {
    data: {
      type: 'sales_invoices',
      attributes: {
        item_type: 'invoice',
        issue_date: order.invoiceDate,        // YYYY-MM-DD
        currency: 'TRL',
        description: `Web siparişi #${order.number}`,
        order_no: String(order.number),       // order_no ve order_date birlikte
        order_date: order.createdDate,
        tax_number: order.billing.taxNumber,
        tax_office: order.billing.taxOffice,
        billing_address: order.billing.address,
        city: order.billing.city,
        district: order.billing.district,
      },
      relationships: {
        contact: { data: { type: 'contacts', id: String(contactId) } },
        details: {
          data: order.lines.map((line) => ({
            type: 'sales_invoice_details',
            attributes: {
              quantity: line.quantity,
              unit_price: line.unitPrice,     // KDV yorumunu staging'de doğrulayın
              vat_rate: line.vatRate,
              ...(line.discount > 0 ? { discount_type: 'amount', discount_value: line.discount } : {}),
            },
            relationships: {
              product: { data: { type: 'products', id: String(productIds[line.sku]) } },
            },
          })),
        },
      },
    },
  };
}
  • Sipariş numarası: order_no ve order_date alanları resmileştirmede birlikte zorunludur: biri doluysa diğeri de dolu olmalıdır. Sipariş numarasını faturada görmek, mutabakatta da işinizi kolaylaştırır.
  • Alıcı bilgileri: Paraşüt'ün örnek uygulaması, e-belgeye basılacak alıcı bilgilerini (tax_number, tax_office, billing_address, city, district) fatura alanlarına da yazar.
  • Kupon ve indirimler: Satır indirimi için discount_type + discount_value, sepet indirimi için faturadaki invoice_discount_type + invoice_discount kullanılabilir.
  • Sayılar: Resmî kurallar number alanlarının JSON sayısı olarak gönderilmesini ister; para birimi TRL'dir.

5. Faturayı Resmileştirin

Fatura açıldıktan sonra alıcının e-Fatura gelen kutusu GET /e_invoice_inboxes?filter[vkn]=... ile sorgulanır. Sonuç varsa POST /e_invoices, yoksa POST /e_archives çağrılır. İki istek de 202 ve bir trackable job döner; iş done olana kadar belge oluşmuş sayılmaz. Akışın tamamı, ilişki adlarındaki fark (invoice ve sales_invoice) ve iş takibi kodu e-Fatura ve e-Arşiv gönderme rehberinde anlatılıyor.

E-ticaret açısından önemli olan, e-Arşiv isteğindeki iki nesnedir. OpenAPI belgesine göre internet üzerinden satış yapıyorsanız internet_sale (url, payment_type, payment_platform, payment_date) doldurulmalıdır. Ürünü kargo ya da kuryeyle gönderiyorsanız shipment nesnesi de doldurulmalıdır (kargoda title ve vkn, kuryede name ve tckn, ayrıca date). payment_type şu değerleri alır: KREDIKARTI/BANKAKARTI, EFT/HAVALE, KAPIDAODEME, ODEMEARACISI. Bu değerleri siparişin ödeme yönteminden türeten küçük bir eşleme fonksiyonu yazın.

6. Tahsilatı Kaydedin

Mağazada ödemesi alınmış bir sipariş, Paraşüt'te de tahsil edilmiş görünmelidir. Tahsilat POST /sales_invoices/{id}/payments ile eklenir; gövdede account_id (kasa ya da banka hesabının kimliği, integer), date, amount ve isteğe bağlı description bulunur. account_id tahsilatın hangi para birimiyle yapılacağını da belirler. TRL hesaplarınızı GET /accounts?filter[currency]=TRL ile listeleyebilirsiniz.

javascript
export async function recordPaymentIfOpen(invoiceId, order) {
  // Tahsilat için idempotans anahtarı belgelenmez: önce açık tutara bakın
  const inv = await parasut(`/sales_invoices/${invoiceId}`);
  if (inv.status !== 200) throw new Error(`Fatura okuma: HTTP ${inv.status}`);
  if (Number(inv.body.data.attributes.remaining) <= 0) return;

  const res = await parasut(`/sales_invoices/${invoiceId}/payments`, {
    method: 'POST',
    body: JSON.stringify({ data: { type: 'payments', attributes: {
      account_id: Number(process.env.PARASUT_SALES_ACCOUNT_ID), // tahsilatın düştüğü kasa/banka
      date: order.paidDate,                                     // YYYY-MM-DD
      amount: Number(inv.body.data.attributes.remaining),
      description: `Web siparişi #${order.number} tahsilatı`,
    } } }),
  });
  if (res.status !== 201) throw new Error(`Tahsilat: HTTP ${res.status}`);
}

Fatura oluşturmanın aksine, tahsilat için belgelenmiş bir idempotans anahtarı yoktur. Bu yüzden örnek, tahsilattan önce faturanın salt okunur remaining (ödenmemiş tutar) alanına bakar ve yalnızca açık tutar varsa ödeme ekler. Kısmi tahsilat, tahsilatı geri alma ve cari bazında tahsilat için tahsilat ve ödeme kaydı rehberine bakın.

7. İade ve İptal: Belgenin Söyledikleri

7. İade ve İptal: Belgenin Söyledikleri: DELETE /sales_invoices/{id}/cancel faturayı iptal eder ve 200 döner; faturayı..., Satış faturası item_type değerleri arasında refund...

İade süreci e-ticarette kaçınılmazdır, ancak Paraşüt API belgesi bu konuda sınırlı bilgi verir. Belgelenen yapı taşları şunlardır:

  • DELETE /sales_invoices/{id}/cancel faturayı iptal eder ve 200 döner; faturayı silmez. PATCH /sales_invoices/{id}/recover iptali geri alır.
  • Satış faturası item_type değerleri arasında refund (iade) bulunur ve liste ucu filter[item_type]=refund ile süzülebilir.
  • Faturaya bağlı bir tahsilatı geri almak için tahsilatın işlemi bulunur (GET /sales_invoices/{id}/payments?include=transaction) ve DELETE /transactions/{id} ile silinir. DELETE /payments/{id} bu iş için kullanılmaz.

Resmileşmiş bir e-Arşiv ya da e-Fatura için iade faturasının nasıl düzenlenip orijinal faturaya bağlanacağı, fatura rehberinde adım adım anlatılmaz. Bu yüzden iadeleri otomatikleştirmeden önce süreci mali müşavirinizle tanımlayın, staging hesabında deneyin ve gerekirse ilk aşamada iadeleri elle işleyip yalnızca kaydını entegrasyon tablonuza düşün.

Kuyruk, Yeniden Deneme ve Rate Limit

Worker'ın tamamı yeniden çalıştırılabilir olmalıdır. Aşağıdaki iskelet her adımın sonucunu kaydeder ve bir sonraki çalıştırmada tamamlanmış adımları atlar:

javascript
export async function syncOrder(orderId) {
  const rec = await db.orderSync.lockForUpdate(orderId);   // aynı siparişi iki worker işlemesin
  const order = await store.getOrder(orderId);

  if (!rec.invoice_id) {
    const contactId = await findOrCreateContact(order);
    const productIds = await mapProducts(order.lines);
    const body = buildInvoiceBody(order, contactId, productIds);
    rec.invoice_id = await createInvoiceOnce(rec, body);   // external_reference_key ile
    rec.status = 'invoiced';
    await db.orderSync.save(rec);
  }

  if (!rec.e_doc_id) {
    if (!rec.trackable_job_id) {
      const { type, jobId } = await formalize(rec.invoice_id, order.billing.taxNumber, {
        scenario: process.env.PARASUT_E_INVOICE_SCENARIO,
        eArchiveAttrs: buildEArchiveAttrs(order),
      });
      Object.assign(rec, { e_doc_type: type, trackable_job_id: jobId, status: 'formalizing' });
      await db.orderSync.save(rec);
    }
    await waitForJob(rec.trackable_job_id);
    rec.e_doc_id = await readActiveEDocumentId(rec.invoice_id);
    rec.status = 'formalized';
    await db.orderSync.save(rec);
  }

  if (!rec.payment_recorded) {
    await recordPaymentIfOpen(rec.invoice_id, order);
    rec.payment_recorded = true;
    rec.status = 'done';
    await db.orderSync.save(rec);
  }
}
  • Rate limit: Paraşüt'e göre paketiniz 10 saniyede ve 1 ayda kaç istek yapabileceğinizi belirler; limit dolunca 429 döner ve yanıtta ne zaman tekrar deneyebileceğinize dair süre bilgisi bulunur. Bu sürenin hangi başlık ya da alanda geldiği belgede doğrulanmış değildir; Paraşüt'ün örnek uygulaması Retry-After başlığına bakar, yoksa sabit bir süre bekler. Siz de süre okunamazsa üstel geri çekilme ve rastgele gecikme kullanın.
  • 401: Token'ı bir kez yenileyip isteği bir kez tekrarlayın; yine 401 ise işi durdurun. Aynı refresh_token ile paralel iki yenileme başlatmayın.
  • 403 ve 402: Yetki, paket ya da kullanım süresi sorunudur; yeniden denemeyin, işi error durumuna alıp bildirim gönderin.
  • 5xx ve zaman aşımı: Yalnızca idempotent isteklerde ya da idempotans anahtarlı POST'ta sınırlı sayıda yeniden deneyin.
  • Eşzamanlılık: Rate limitinizi aşmamak için worker sayısını düşük tutun; tek firmaya yazan bir entegrasyonda tek worker çoğu zaman yeterlidir.

Kuyruk için Redis tabanlı bir çözüm ya da veritabanı tablosu kullanabilirsiniz; ayrıntılar için Redis rehberine ve API rate limiting stratejileri yazısına bakın. Paraşüt'e özgü hata kodları hata kodları ve rate limit rehberinde toplanmıştır.

Paraşüt Webhook'larıyla Geri Bildirim

Akış Paraşüt'e yazan tek yönlü bir iş gibi görünse de Paraşüt'ten gelen bildirimler de işe yarar. sales_invoice update event'i e-Fatura ya da e-Arşiv belgesi olan faturalar için gönderilir ve PDF oluştuğunda verisine 2 saat geçerli bir pdf_url eklenir; müşteriye PDF göndermeyi bu olaya bağlayabilirsiniz. Webhook teslimatı garanti edilmez; bu yüzden zamanlanmış taramanız ve trackable job sorgunuz yine birincil kaynak olmalıdır. Alıcı tarafında X-Client-Key doğrulaması, event_id ile tekrar ayıklama ve hemen 2xx dönme kuralları için Paraşüt webhook kurulum rehberine bakın.

Loglama, İzleme ve Mutabakat

Bir muhasebe entegrasyonunda "neden bu sipariş faturalanmadı?" sorusuna dakikalar içinde cevap verebilmelisiniz. Bunun için her Paraşüt isteğinde şunları loglayın:

AlanNeden
order_id ve external_keySipariş ile Paraşüt kaydını bağlamak için
Uç nokta, HTTP yöntemi ve durum koduHangi adımda takıldığını görmek için
invoice_id, trackable_job_id, e_doc_idParaşüt tarafında kaydı bulmak için
errors[].title, source.pointer, metaDoğrulama hatasını alana eşlemek için
Süre ve deneme sayısıRate limit ve yavaşlıkları fark etmek için

Günlük bir mutabakat görevi, o gün ödenen siparişleri parasut_order_sync tablosuyla karşılaştırıp done olmayanları raporlamalıdır. Paraşüt tarafında da GET /sales_invoices?filter[issue_date]=... ile günün faturalarını, filter[print_status] değerlerinden e_archive_sent ve e_invoice_sent ile resmileşmiş olanları listeleyebilirsiniz. Liste page[size] en fazla 25 kayıt döner; meta.total_pages değerine göre sayfalayın. Sayfalama ayrıntıları için filtreleme ve sayfalama rehberine bakın.

Servisi Nerede Çalıştırmalı?

Kuyruk worker'ı, zamanlanmış tarama ve Paraşüt'ten gelen webhook alıcısı 7/24 çalışması gereken parçalardır. Bunları paylaşımlı bir web hostingde değil, süreç yönetimi yapabildiğiniz bir sunucuda çalıştırmak daha güvenlidir. Linux üzerinde worker'ı bir systemd servisi olarak tanımlayıp gizli bilgileri ortam değişkenlerinde tutabilirsiniz; bunun için systemd servis dosyası rehberine, .env dosyası en iyi pratiklerine ve VDS rehberine bakabilirsiniz. Pazaryeri siparişlerini de aynı akışa almak isterseniz pazaryeri entegrasyonu rehberi iyi bir başlangıç noktasıdır.

Sık Sorulan Sorular

WooCommerce siparişlerini Paraşüt'e otomatik aktarmak için eklenti şart mı?

Hayır. Bu yazıdaki mimari platformdan bağımsızdır: mağazanızdan sipariş verisini okuyabildiğiniz ve bir olay ya da zamanlanmış görevle tetikleyebildiğiniz sürece kendi servisinizle aynı akışı kurabilirsiniz. Hazır bir eklenti kullanıyorsanız, onun da faturayı idempotent açıp açmadığını ve resmileştirme sonucunu takip edip etmediğini kontrol etmenizde fayda var.

Aynı sipariş iki kez faturalanırsa ne olur, nasıl önlerim?

Sipariş başına bir UUID üretip fatura isteğinden önce saklayın ve external_reference_key ilişkisiyle gönderin. Aynı anahtarla gelen ikinci istek fatura açmaz, 422 ile mevcut faturanın kimliğini döner. Bu tek kural, yeniden denemelerin ve çift tetiklemelerin yol açacağı mükerrer faturaların önüne geçer.

Her siparişte yeni cari ve ürün oluşturmalı mıyım?

Hayır. Cari ve ürünler bir kez oluşturulup tekrar kullanılır. Müşteriyi vergi numarası ya da e-postayla, ürünü SKU ile eşleyen tablolar tutun; böylece hem API çağrısı hem de Paraşüt'te mükerrer kayıt sayısı azalır.

Fatura açıldı ama resmileştirme hata verdi, ne yapmalıyım?

Trackable job error ile bittiyse attributes.errors dizisindeki metinleri loglayın, siparişi error durumuna alın ve sorunu (eksik sipariş tarihi, yanlış alıcı bilgisi gibi) düzelttikten sonra resmileştirme adımını yeniden çalıştırın. Fatura zaten açık olduğundan yeni fatura oluşturmaya gerek yoktur.

Tahsilatı ne zaman kaydetmeliyim?

Ödeme mağazada tahsil edildiyse fatura oluştuktan sonra payments ucuyla ekleyin. Kapıda ödeme gibi tahsilatın sonradan gerçekleştiği yöntemlerde bu adımı ödemenin onaylandığı ana bağlayın. Tahsilatın hangi kasa ya da banka hesabına yazılacağı muhasebe tercihinizdir.

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 · e-Fatura ve e-Arşiv gönderme · Cari hesap oluşturma · Tahsilat ve ödeme kaydı · Paraşüt webhook kurulumu · WooCommerce kurulumu · Entegrasyon nedir