Fakturnia Developers Szybki start Dokumentacja API English

Typy dokumentów i kwoty

To strona, którą warto przeczytać, zanim zaczniesz budować obsługę fakturowania. Wyjaśnia ona, jakie typy dokumentów istnieją, co przesyłasz oraz dokładnie jak obliczane są kwoty, co do grosza. Poprawne wyliczenia pieniężne to sedno sprawy, dlatego reguły są opisane precyzyjnie.

Złota zasada: ty przesyłasz ceny, my obliczamy wartości

Dla każdej pozycji przesyłasz cenę jednostkową oraz stawkę VAT. Resztę oblicza backend. Nigdy nie wyliczasz amountOfVat ani grossValue samodzielnie i nie powinieneś, ponieważ serwer jest jedynym źródłem prawdy, a Twoje liczby tylko by się rozjeżdżały.

Przesyłasz Znaczenie
quantity ilość w pozycji (wymagane)
netPrice lub grossPrice cena jednostkowa przed/po VAT (jedna z nich)
vatRate stawka VAT (liczba taka jak 23 lub kod specjalny)
discount opcjonalne, procent 0–100

Backend zwraca, dla każdej pozycji:

Pole Sposób obliczenia
netValue round2(quantity × netPrice × (1 − discount/100))
amountOfVat round2(netValue × rate / 100)
grossValue round2(netValue + amountOfVat)

Jeśli zamiast tego przesyłasz grossPrice, obliczenia przebiegają „w dół”: najpierw grossValue, następnie netValue = round2(gross / (1 + rate/100)) oraz amountOfVat = round2(gross − netValue).

Zaokrąglanie jest w górę (half-up), do grosza

Wszystkie kwoty są zaokrąglane do 2 miejsc po przecinku metodą zaokrąglania połówek w górę (round half-up):

round2(x) = Math.round((x + Number.EPSILON) * 100) / 100

Zatem 0.345 → 0.35 (a nie 0.34). Kolejność działań ma znaczenie na granicy zaokrąglenia: VAT to round2((net × rate) / 100), nigdy net × (rate/100). Dla niektórych wartości obie metody różnią się o grosz. Ten sam algorytm działa w naszej bibliotece fakturnia-shared, więc dokument utworzony przez API jest identyczny, co do grosza, z dokumentem utworzonym w aplikacji webowej.

W każdej pozycji netValue + amountOfVat zawsze równa się grossValue. Po zsumowaniu w obrębie dokumentu netSum + vatSum === grossSum. Jeśli kiedykolwiek zobaczysz rozbieżność o jeden grosz, jest to błąd. Zgłoś go.

Stawki VAT

vatRate przyjmuje procentową wartość liczbową ze słownika lub kod specjalny. Stawki liczbowe: 23, 22, 8, 7, 5, 4, 3. Kody specjalne (VAT = 0, netto = brutto):

Kod Znaczenie
zw zwolnione (zwolnione)
np I, np II nie podlega (nie podlega)
oo odwrotne obciążenie (odwrotne obciążenie)
0 WDT wewnątrzwspólnotowa dostawa towarów
0 EX eksport
0 KR krajowa 0%

Nie istnieje samo 0 ani samo np; używaj powyższych kodów. Nieznana stawka zwraca 400 VALIDATION_ERROR.

Typy dokumentów

Przez API dostępnych jest dziesięć typów dokumentów. Pięć typów dawnych (legacy) celowo nie zostało udostępnionych (zamiast nich używaj adnotacji, patrz niżej).

Typ Czym jest Wymagane dodatkowe pola
Faktura Faktura poza KSeF, dla podmiotów zwolnionych z VAT (dostępna do końca 2026) -
FakturaVAT Faktura VAT, odpowiednik faktury podstawowej w KSeF -
FakturaProforma Proforma -
FakturaProformaBezVAT Proforma bez VAT -
FakturaZaliczka Faktura zaliczkowa linkedOrderId, advancePaymentAmount
FakturaRozliczeniowa Faktura rozliczeniowa (końcowa) linkedAdvanceInvoiceIds
FakturaKorygujaca Faktura korygująca correctedInvoiceId
FakturaKorygujacaZaliczkowa Korekta faktury zaliczkowej correctedInvoiceId, correctionAdvanceAmountAfter
FakturaKorygujacaRozliczeniowa Korekta faktury rozliczeniowej correctedInvoiceId, correctionSettlementAmountAfter
Zamowienie Zamówienie -

KSeF i przyszłość typów faktur. FakturaVAT to odpowiednik faktury podstawowej w KSeF. Faktura to dokument, który nie trafia do KSeF, dedykowany podmiotom zwolnionym z VAT — dostępny do końca 2026 roku. Od 1 stycznia 2027 typ Faktura przestanie być dostępny, a FakturaVAT stanie się typem FakturaPodstawowa; przez pewien czas będzie można używać obu typów (tryb legacy). Obecnie używaj wyłącznie FakturaVAT jako odpowiednika faktury podstawowej.

Adnotacje

Szczególne tryby rozliczenia VAT nie są osobnymi typami dokumentów. Zgodnie z KSeF FA(3) ustawiasz je w obiekcie annotations na dokumencie, niezależnie od jego typu. Dostępne opcje:

Adnotacja Pole Znaczenie
Mechanizm podzielonej płatności (MPP) isSplitPayment Oznacza fakturę jako MPP. Wyklucza się z metodą kasową. Osobne konto VAT możesz podać w polach płatności (vatAccountNumber i pokrewne).
Odwrotne obciążenie isReverseCharge Podatek rozlicza nabywca.
Metoda kasowa isCashMethod Rozliczenie VAT w momencie zapłaty. Wyklucza się z MPP.
Samofakturowanie isSelfInvoicing Fakturę wystawia nabywca w imieniu sprzedawcy.
Procedura marży marginProcedure Obiekt { enabled, procedureId }. Identyfikatory procedur (biuro podróży, towary używane, dzieła sztuki, antyki) znajdziesz w słowniku marginProcedures.
Zwolnienie z VAT vatExemption Obiekt { enabled, exemptionType, legalBasis, showOnDocument }. Typy A/B/C opisuje słownik vatExemptionTypes.

Sprzeczne kombinacje (np. MPP razem z metodą kasową) zwracają 422 ANNOTATIONS_VALIDATION_ERROR (patrz Błędy). Pełny opis pól każdej adnotacji wraz z przykładami żądań znajdziesz w Tworzenie dokumentów → Adnotacje.

Informacje dodatkowe: faktura do paragonu

Obok adnotacji KSeF FA(3) przewiduje sekcję „Informacje dodatkowe" (additionalInfo). Obecnie API udostępnia w niej jedno pole:

Pole Znaczenie
additionalInfo.isInvoiceToReceipt Faktura do paragonu (art. 109 ust. 3d ustawy o VAT).

Ustawienie isInvoiceToReceipt: true na dokumencie FakturaVAT dodaje flagę <FP>1</FP> w dokumencie wysyłanym do KSeF oraz adnotację „Faktura do paragonu" na PDF. To nadal zwykła faktura VAT, a nie osobny typ dokumentu; kwoty liczone są tak samo. KSeF nie przewiduje pola na numer paragonu, więc API również go nie przyjmuje. Szczegóły znajdziesz w Tworzenie dokumentów → Informacje dodatkowe.

Faktury standardowe

Faktura, FakturaVAT, FakturaProforma, FakturaProformaBezVAT, Zamowienie są obliczane bezpośrednio z ich pozycji: grossSum = Σ grossValue i tak dalej. Nic zaskakującego.

Faktury zaliczkowe (FakturaZaliczka)

Faktura zaliczkowa księguje przedpłatę na poczet zamówienia (Zamowienie). Nie jest sumą pozycji zamówienia; jej wartością jest advancePaymentAmount.

  • Przekazujesz linkedOrderId (istniejące Zamowienie) oraz advancePaymentAmount.
  • Backend dzieli zaliczkę proporcjonalnie pomiędzy stawki VAT zamówienia i ten podział staje się pozycjami faktury.
  • Dlatego grossSum === advancePaymentAmount, przy czym netSum / vatSum wynikają z podziału proporcjonalnego.
{
  "documentType": "FakturaZaliczka",
  "issueDate": "2026-06-04",
  "buyerId": "681a…",
  "linkedOrderId": "6820…",
  "advancePaymentAmount": 615
}

Zaliczka nie może przekroczyć wartości brutto zamówienia (422 ADVANCE_EXCEEDS_ORDER_VALUE).

Faktury rozliczeniowe (FakturaRozliczeniowa)

Faktura rozliczeniowa (końcowa) zamyka zamówienie po jednej lub kilku zaliczkach. Jej wartość brutto to kwota pozostała do zapłaty, a nie pełna suma pozycji.

  • Przekazujesz linkedAdvanceInvoiceIds (rozliczane faktury zaliczkowe) oraz pełne products.
  • Backend oblicza settlementAmount = max(0, Σ products.gross − Σ advances.gross) (chyba że ustawisz isSettlementAmountManual: true i podasz settlementAmount).
  • grossSum === settlementAmount; netSum / vatSum pochodzą z proporcjonalnego podziału tej kwoty pomiędzy stawki VAT produktów.

Zatem jeśli Twoje pozycje sumują się do 6 150 brutto, a powiązane zaliczki do 2 460, to grossSum faktury rozliczeniowej wynosi 3 690, a nie 6 150.

Korekty

Pełna instrukcja wystawiania korekt przez API znajduje się w artykule Korygowanie dokumentów — trzy typy korekt, wyzerowanie faktury i reguły proporcjonalnego VAT.

Korekta przedstawia dokument na nowo. products to pełny stan „po” korekcie, cały dokument w postaci, jaką powinien mieć po korekcie. Backend oblicza różnicę; nie przesyłasz pozycji „+/−”.

  • FakturaKorygujaca: sumy to różnica pozycji: Σ after − Σ corrected. Aby anulować dokument, prześlij te same pozycje z quantity: 0.
  • FakturaKorygujacaZaliczkowa koryguje zaliczkę. Sumy to różnica kwoty zaliczki: grossSum = correctionAdvanceAmountAfter − advancePaymentAmountBefore, z VAT wynikającym z różnicy obu podziałów proporcjonalnych.
  • FakturaKorygujacaRozliczeniowa koryguje rozliczenie. grossSum = correctionSettlementAmountAfter − settlementAmountBefore, VAT proporcjonalnie.
{
  "documentType": "FakturaKorygujaca",
  "issueDate": "2026-06-04",
  "correctedInvoiceId": "681a…",
  "correctionReason": "Zmiana ilości",
  "products": [
    { "name": "Usługa", "unitOfMeasure": "szt.", "quantity": 2, "netPrice": 100, "vatRate": 23 }
  ]
}

Dlaczego ma to znaczenie dla integratorów. Wartości grossSum dla faktur zaliczkowych, rozliczeniowych i korekt nie są równe Σ products. Jeśli odwzorowujesz sumy faktur we własnym systemie, pobieraj je z odpowiedzi API, nie wyliczaj ich ponownie z pozycji.

Płatność i daty

Pole Uwagi
paymentMethodId 1 Gotówka · 2 Karta · 3 Bon · 4 Czek · 5 Kredyt · 6 Przelew · 7 Płatność mobilna
paymentStatusId 0 Opłacone (wymaga additionalPaymentDate) · 1 Do zapłaty (wymaga paymentDeadlineDate)
bankAccounts[] dla przelewu; pierwsze staje się rachunkiem głównym, pozostałe są wyświetlane jako dodatkowe
issueDate, subDate, subDateTo data wystawienia / data albo okres sprzedaży (ISO YYYY-MM-DD)
paymentInstallments, paymentDeadlineTerm raty i termin opisowy faktury do zapłaty, patrz Tworzenie dokumentów
exchangeRate, exchangeRateDate, exchangeRateTable kurs NBP z dnia roboczego przed obowiązkiem podatkowym, jego dzień i tabela

Zapłatę, która wpłynęła po wystawieniu, oznaczasz przez PATCH /documents/{id}/payment-status z receivedPayment: RECEIVED i opcjonalnym paymentDate (dzień wpłaty, YYYY-MM-DD; domyślnie dzisiejszy dzień w Polsce, nie może być z przyszłości). Przy metodzie kasowej to dzień powstania obowiązku podatkowego (art. 21 ust. 1 ustawy o VAT). GET /documents/{id} zwraca go w payment.receivedPaymentDate.

Usuwanie i edycja dokumentów

To, czy dokument można jeszcze zmienić lub usunąć, zależy od jego statusu w KSeF. DELETE /documents/{id} oraz aktualizacje dokumentu działają według tej samej reguły:

  • Gdy dokument ma już numer KSeF (został zatwierdzony w KSeF), jest ostateczny. Usunięcie lub edycja zwraca 400 KSEF_CONFIRMED.
  • Gdy dokument jest wysłany do KSeF i oczekuje na potwierdzenie, jest zablokowany. Usunięcie lub edycja zwraca 400 KSEF_SENT.
  • Jeśli wysyłka do KSeF się nie powiodła (dokument niesie błąd KSeF), blokada znika. Możesz usunąć dokument albo poprawić go i wysłać ponownie.

Dokumenty, które nigdy nie zostały wysłane do KSeF, zawsze można usunąć lub edytować. Stan dokumentu sprawdzisz przez GET /documents/{id}/ksef-status zanim spróbujesz go zmienić.

Zweryfikuj przed zatwierdzeniem

POST /documents/validate uruchamia pełny proces (numerację, sumy, ustalenie stron) i zwraca podgląd bez zapisywania. Użyj go, aby pokazać użytkownikom ekran potwierdzenia lub przeprowadzić próbne uruchomienie integracji.

Zobacz dokumentację API, aby poznać pełny schemat żądania i wszystkie pola.