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 + amountOfVatzawsze równa sięgrossValue. Po zsumowaniu w obrębie dokumentunetSum + 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.
FakturaVATto odpowiednik faktury podstawowej w KSeF.Fakturato dokument, który nie trafia do KSeF, dedykowany podmiotom zwolnionym z VAT — dostępny do końca 2026 roku. Od 1 stycznia 2027 typFakturaprzestanie być dostępny, aFakturaVATstanie się typemFakturaPodstawowa; przez pewien czas będzie można używać obu typów (tryb legacy). Obecnie używaj wyłącznieFakturaVATjako 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ąceZamowienie) orazadvancePaymentAmount. - Backend dzieli zaliczkę proporcjonalnie pomiędzy stawki VAT zamówienia i ten podział staje się pozycjami faktury.
- Dlatego
grossSum === advancePaymentAmount, przy czymnetSum/vatSumwynikają 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łneproducts. - Backend oblicza
settlementAmount = max(0, Σ products.gross − Σ advances.gross)(chyba że ustawiszisSettlementAmountManual: truei podaszsettlementAmount). grossSum === settlementAmount;netSum/vatSumpochodzą 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 zquantity: 0.FakturaKorygujacaZaliczkowakoryguje zaliczkę. Sumy to różnica kwoty zaliczki:grossSum = correctionAdvanceAmountAfter − advancePaymentAmountBefore, z VAT wynikającym z różnicy obu podziałów proporcjonalnych.FakturaKorygujacaRozliczeniowakoryguje 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
grossSumdla 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.