Przejdź do treści

Dla programistów

API faktur: tworzenie szkiców, odczyt wystawionych faktur, odbiór zdarzeń

Ostatnia weryfikacja SUPPORTED WITH LIMITATIONS

Tłumaczenie wersji angielskiej, która jest aktualizowana jako pierwsza. Stwierdzenia regulacyjne odnoszą się do wymienionych źródeł i daty ich odczytu.

API faktur KRONENWERK pozwala Państwa oprogramowaniu rozpocząć szkic faktury dla klienta za pomocą POST /invoices/drafts, odczytać wystawione faktury przez GET /invoices i GET /invoices/{number} oraz dowiedzieć się o wystawieniu, zapłacie i anulowaniu dzięki webhookom invoice.issued, invoice.paid i invoice.cancelled. Samo wystawianie nie jest udostępnione: numer, werdykt podatkowy, weryfikacja VIES i zwalidowany plik ustrukturyzowany powstają wtedy, gdy osoba wystawia szkic w produkcie.

Co API faktur robi, a czego nie robi

Tworzy szkice i odczytuje archiwum. Szkic to dokument roboczy: można go poprawić, przecenić lub wyrzucić, a nikt spoza firmy go nie widział. Wystawiona faktura jest przeciwieństwem: numer został zużyty z ciągłej sekwencji, wiersz archiwum został zamrożony, wytworzono plik spełniający normę krajową, a w Polsce dokument mógł zostać przekazany systemowi państwowemu, który decyduje, czy prawnie istnieje. API daje Państwu to pierwsze, a to drugie tylko odczytuje.

OperacjaPrzez APIGdzie się odbywa
Utworzenie klientaPOST /customersAPI lub produkt
Rozpoczęcie szkicu fakturyPOST /invoices/draftsAPI lub produkt
Dodanie pozycji, ustalenie cen, wybór daty dostawynieudostępnioneProdukt
Wystawienie: numer, werdykt podatkowy, weryfikacja VIES, plik ustrukturyzowany, walidacjanieudostępnioneProdukt; raportowane przez invoice.issued
Zarejestrowanie płatnościnieudostępnioneProdukt (ręcznie, import bankowy); raportowane przez invoice.paid i payment.recorded
Anulowanie przez pełną korektęnieudostępnioneProdukt; raportowane przez invoice.cancelled
Odczyt wystawionych fakturGET /invoices, GET /invoices/{number}API
Odczyt bieżących należnościGET /reports/outstandingAPI

Pełna lista punktów końcowych, uwierzytelnianie i format błędów znajdują się na stronie API księgowego oraz w dokumentacji referencyjnej.

Tworzenie szkicu: POST /invoices/drafts

Żądanie wskazuje klienta i nic więcej. W odpowiedzi wraca szkic przygotowany tak, jak przygotowuje go produkt: propozycja numeracji sprzedawcy, termin płatności wynikający z uzgodnionych z klientem dni płatności oraz formuła płatności właściwa dla jurysdykcji sprzedawcy w języku, w którym ta jurysdykcja sporządza dokumenty. Każda z tych rzeczy to decyzja należąca do modułu krajowego; pole żądania pozwoliłoby wywołującemu po cichu nadpisać reguły kraju, których nie przeczytał.

Wymagane są trzy zakresy uprawnień — invoices:write, customers:read i companies:read — ponieważ szkic jest budowany na podstawie klienta i dla podmiotu prawnego, którego numeracja, dni płatności i jurysdykcja decydują o treści dokumentu. Nagłówek Idempotency-Key jest wymagany.

curl -X POST https://kronenwerk.org/api/extern/v1/invoices/drafts \
  -H "Authorization: Bearer greif_live_…" \
  -H "Idempotency-Key: contract-7731-invoice-1" \
  -H "Content-Type: application/json" \
  -d '{ "customerId": "3f2b…" }'
{
  "id": "e41a…",
  "number": "2026-0042",
  "documentType": "INVOICE",
  "customerId": "3f2b…",
  "customer": "Beispiel GmbH",
  "currency": "EUR",
  "issuedOn": "2026-09-03",
  "dueOn": "2026-09-17",
  "state": "DRAFT",
  "createdAt": "2026-09-03T08:16:05Z"
}

number to propozycja w formacie, który moduł krajowy sprzedawcy uznaje za zgodny z prawem, z prefiksem firmy, jeśli jest skonfigurowany; staje się ostateczny dopiero przy wystawieniu. state na tej powierzchni zawsze ma wartość DRAFT. customerId, który nie istnieje lub należy do innej firmy, otrzymuje odpowiedź 404 NICHT_GEFUNDEN — jedną dla obu przypadków, aby kodów statusu nie dało się użyć do enumerowania cudzych identyfikatorów. Powtórzenie z tym samym Idempotency-Key zwraca ten sam szkic; powtórzenie z innym ciałem żądania otrzymuje 409 IDEMPOTENZ_KONFLIKT. Zob. idempotentność.

Po wywołaniu szkic pojawia się na liście faktur w produkcie, gdzie osoba dodaje pozycje, sprawdza numer VAT klienta i wystawia fakturę. Państwa integracja dowiaduje się o wyniku przez webhook, a nie przez odpytywanie.

Dlaczego wystawianie pozostaje w produkcie

Ponieważ wystawienie to moment, w którym trzy decyzje stają się nieodwracalne, a każda z nich jest sprawdzana względem faktów, których wywołujący API nie posiada.

Walidacja pliku ustrukturyzowanego

Przy wystawieniu KRONENWERK generuje ustrukturyzowaną e-fakturę oczekiwaną w kraju sprzedawcy — XRechnung lub ZUGFeRD w Niemczech, Factur-X we Francji, Peppol BIS Billing 3.0 UBL w Belgii, XML FA(3) w Polsce — i waliduje ją, zanim numer zostanie zużyty. Dokument niemiecki jest sprawdzany regułami Schematron KoSIT i krzyżowo biblioteką Mustang. Szkic, który nie przechodzi walidacji, nie jest wystawiany; osoba widzi, która reguła zawiodła. API wystawiające bezpośrednio musiałoby albo pominąć tę kontrolę, albo wymyślić kanał błędów dla dokumentu, którego wywołujący nigdy nie widział. Zob. strona API e-fakturowania.

Werdykt podatkowy

Każda faktura otrzymuje werdykt podatkowy na podstawie faktów transakcji — kraj sprzedawcy i nabywcy, firma czy konsument, rodzaj świadczenia: stawka podstawowa, zerowa, zwolnienie, odwrotne obciążenie, poza zakresem albo „wymaga danych” / „wymaga potwierdzenia przez specjalistę”. Numer VAT nabywcy jest weryfikowany w VIES przy wystawieniu, a werdykt jest zapisywany z fakturą. Tam, gdzie fakty nie rozstrzygają, produkt mówi o tym i pyta osobę; nie zgaduje, a skrypt też nie powinien.

Numeracja

Numery faktur pochodzą z ciągłej sekwencji, a zużytego numeru nie można cofnąć; środkiem zaradczym na błędną fakturę jest dokument korygujący, a nie usunięcie. Pętla, która wykonała się dwa razy, nie może zużyć dwóch numerów — dlatego API zatrzymuje się na szkicu i dlatego każdy oferowany przez nie zapis jest idempotentny.

Odczyt wystawionych faktur: GET /invoices

GET /invoices zwraca wystawione faktury od najnowszej, po jednej stronie naraz, z kwotami zamrożonymi przy wystawieniu — klient, którego nazwę zmieniono w zeszłym tygodniu, nie zmienia nazwy na fakturze wystawionej w zeszłym roku. Filtry to status (OPEN lub PAID; wartość nieczytelna oznacza brak filtra), from i to (daty wystawienia w formacie ISO), page i size (domyślnie 25, maksymalnie 100). GET /invoices/{number} odczytuje jedną fakturę po numerze, pod którym znają ją zarówno firma, jak i jej klient.

curl "https://kronenwerk.org/api/extern/v1/invoices?status=OPEN&from=2026-01-01&size=50" \
  -H "Authorization: Bearer greif_live_…"
{
  "data": [
    {
      "id": "7a90…",
      "number": "2026-0041",
      "documentType": "INVOICE",
      "buyer": "Beispiel GmbH",
      "currency": "EUR",
      "issuedOn": "2026-08-28",
      "dueOn": "2026-09-11",
      "deliveredOn": "2026-08-28",
      "net": { "minor": 89000, "currency": "EUR" },
      "tax": { "minor": 16910, "currency": "EUR" },
      "gross": { "minor": 105910, "currency": "EUR" },
      "outstanding": { "minor": 105910, "currency": "EUR" },
      "paymentState": "OPEN",
      "overdue": false,
      "cancelled": false,
      "creditNote": false,
      "paidOn": null,
      "recordedAt": "2026-08-28T14:02:11Z"
    }
  ],
  "page": 0,
  "size": 50,
  "total": 1,
  "more": false
}

paymentState przyjmuje jedną z wartości OPEN, OVERDUE, PAID, CANCELLED lub CORRECTION; overdue jest obliczane względem dnia dzisiejszego. cancelled oznacza, że istnieje dokument korygujący, który w całości odwraca tę fakturę; creditNote oznacza, że ten dokument jest korektą. W archiwum nic nigdy nie jest usuwane ani edytowane.

Webhooki: invoice.issued, invoice.paid, invoice.cancelled

Każde zdarzenie jest dostarczane jako HTTPS POST z nagłówkiem podpisu (KRONENWERK-Signature: t=…,v1=…, HMAC-SHA256 nad znacznikiem czasu, kropką i surowym ciałem) oraz stabilnym identyfikatorem zdarzenia w KRONENWERK-Event-Id i Idempotency-Key. Dostarczanie jest typu at-least-once, więc należy zapisywać identyfikator zdarzenia i pomijać powtórzenia. Ciało to płaski obiekt JSON; każda wartość jest ciągiem znaków, a klucze są posortowane.

{
  "amountDueMinor": "105910",
  "buyerName": "Beispiel GmbH",
  "currency": "EUR",
  "documentType": "INVOICE",
  "dueDate": "2026-09-17",
  "event": "invoice.issued",
  "grossMinor": "105910",
  "id": "0d3c…",
  "invoiceId": "7a90…",
  "issueDate": "2026-09-03",
  "netMinor": "89000",
  "number": "2026-0042",
  "paymentState": "OPEN",
  "taxMinor": "16910"
}

invoice.paid niesie te same pola plus paidOn; jest wyzwalane tam, gdzie płatność faktycznie rozlicza należność, niezależnie od drogi, która do tego doprowadziła — ekran płatności, import bankowy, telefon. invoice.cancelled dodaje cancelledByInvoiceId, cancelledByNumber i reason, wskazując dokument korygujący, aby odbiorca mógł unieważnić właściwy rekord i uzgodnić notę kredytową. Odrębne zdarzenie payment.recorded raportuje przepływ pieniędzy w obu kierunkach, z polami direction, amountMinor, method, reference, targetKind i targetId. Kroki weryfikacji opisano na stronie webhooków.

Typowa sekwencja

  1. Państwa aplikacja tworzy klienta jednorazowo przez POST /customers (nazwa, ulica, kod pocztowy i miejscowość są wymagane; kraj, numer VAT i waluta są opcjonalne) i zapisuje zwrócone id.
  2. Gdy wystąpi zdarzenie podlegające fakturowaniu, aplikacja wywołuje POST /invoices/drafts z tym customerId i Idempotency-Key wyprowadzonym z własnego rekordu, na przykład numeru umowy lub zamówienia.
  3. Osoba w firmie uzupełnia i wystawia szkic. KRONENWERK oblicza werdykt podatkowy, weryfikuje numer VAT w VIES, waliduje plik ustrukturyzowany i zużywa numer.
  4. Państwa punkt końcowy webhooków odbiera invoice.issued, weryfikuje podpis, deduplikuje po id i zapisuje number oraz invoiceId przy własnym rekordzie.
  5. Gdy faktura zostanie rozliczona, przychodzi invoice.paid. Jeśli osoba ją anuluje, przychodzi invoice.cancelled z numerem korekty.
  6. Do uzgodnień GET /reports/outstanding zwraca należności i zobowiązania otwarte na dziś w walucie ksiąg, z tych samych kwot, które pokazuje pulpit właściciela.

Wzorzec ten jest przepracowany dla firmy subskrypcyjnej na stronie podłączanie produktu SaaS do księgowości.

Jak KRONENWERK to obsługuje

OBSŁUGIWANE Z OGRANICZENIAMI Tworzenie szkiców, odczyt faktur i trzy zdarzenia fakturowe działają jak opisano, w planie Enterprise (cennik). Ograniczenie jest celowe i trwałe w obecnym projekcie: API nie dodaje pozycji do szkicu, nie wystawia, nie rejestruje płatności i nie anuluje. Jeśli Państwa integracja potrzebuje w pełni zautomatyzowanego przepływu wystawiania bez udziału osoby, API KRONENWERK dziś tego nie oferuje — ta strona mówi to wprost, zamiast sugerować coś innego.

To, co produkt robi przy wystawieniu, opisano na stronach faktury i e-fakturowanie: XRechnung i ZUGFeRD dla Niemiec, Factur-X dla Francji, Peppol BIS UBL dla Belgii, FA(3) dla Polski oraz faktury PDF z krajowymi zasadami podatkowymi dla Kanady i Stanów Zjednoczonych. Wysyłka przez Peppol odbywa się przez akredytowanego dostawcę punktu dostępowego (Storecove) po podłączeniu firmy w Ustawienia → Doręczanie; polska transmisja do KSeF nie jest jeszcze gotowa produkcyjnie. Oba tematy omówiono na stronach integracja Peppol i integracja KSeF.

Najczęściej zadawane pytania

Czy mogę ustawić pozycje faktury lub kwotę łączną przez API?

Nie. POST /invoices/drafts przyjmuje wyłącznie customerId. Pozycje, ceny i data dostawy są wprowadzane w produkcie, zanim osoba wystawi szkic.

Czy API może wystawić fakturę?

Nie, w żadnym zakresie uprawnień. Wystawienie zużywa numer i wprowadza do obrotu dokument prawny; pozostaje w produkcie, a webhook invoice.issued o nim informuje.

Jak dowiedzieć się, że faktura została opłacona?

Subskrybując invoice.paid (oraz payment.recorded dla samej płatności) albo odpytując GET /invoices?status=PAID z datą from. Webhook jest zamierzoną drogą.

Dlaczego punkt końcowy szkiców wymaga companies:read?

Szkic jest budowany dla wystawiającego podmiotu prawnego: jego numeracja, dni płatności i jurysdykcja decydują o treści dokumentu. Odczyt tych ustawień jest częścią tworzenia szkicu, dlatego zakres jest deklarowany, a nie wymagany po cichu.

Czy numer faktury w szkicu jest ostateczny?

Nie. Jest propozycją modułu krajowego dotyczącą kolejnego zgodnego z prawem numeru i zostaje potwierdzony dopiero przy wystawieniu faktury.

Źródła

  1. KRONENWERK developer documentation odczytano
  2. Directive 2006/112/EC on the common system of value added tax, Title XI Chapter 3 (invoicing) odczytano
  3. European Commission — VIES VAT number validation odczytano

Czytaj dalej