Profil dokumentu: Faktura (Invoice) — KSeF i przepisy prawa
Profil Faktura definiuje użycie zasobu DocumentReference dla faktur w kontekście polskiego prawa (ustawa o VAT, art. 106e) oraz Krajowego Systemu e-Faktur (KSeF) ze strukturą logiczną FA(2)/FA(3). Struktura pozostaje spójna z modelem DocumentReference (nagłówek + position[] + attribute[]), przy czym pola wynikające z przepisów prawa są wprost odzwierciedlone w profilu (nazewnictwo i lokalizacja).
Profil jest konwencją mapowania (unifikacja, archiwum, obieg). API udostępnia faktury jako dedykowany zasób Invoice (GET /v1/invoices); dekretacja faktury odbywa się przez Invoice + PostingInstruction — DocumentReference w tym procesie nie uczestniczy.
Profil jest zbieżny z podejściem Common Data Model (Microsoft CDM) dla faktur (Invoice, FreeTextInvoiceHeader, CustInvoiceTrans): nagłówek + wiersze + sumy.
1. DocumentReference jako faktura
Faktura to DocumentReference z:
- type =
invoice(systemfinance/document-type). - identifier (0..; w profilu co najmniej jeden) — numer faktury, opcjonalnie id faktury (przestrzeń
Invoice.Id, klucz referencyjny) i numer KSeF (system=https://ksef.podatki.gov.pl). Rodzaj identyfikatora niesie Identifier.system*; przestrzenie wewnętrzneurn:oid:1.2.616.1.113769.4.<instalacja>.<klucz>publikuje NamingSystem. - issueDate (0..1; w profilu wymagana) — data wystawienia (obligatoryjna wg art. 106e).
- participant (0..; w profilu wystawca i nabywca) — referencje do PartyRole (rola
supplier— wystawca,customer— nabywca,payer— płatnik; słownikparty-role). Strona (nazwa, adres, NIP) wynika z PartyRole.party* → Party. - position (0..; w profilu co najmniej jeden wiersz) — wiersze faktury oraz opcjonalnie linie podsumowania VAT; rodzaj w code*.
- attribute (0..*; w profilu co najmniej kwota brutto) — podsumowanie dokumentu i pola profilu (sekcja 3).
Kardynalności schematu DocumentReference są luźne (0..*); wymagania „co najmniej" pochodzą z profilu i przepisów, nie z walidacji API.
Pola referencyjne a wartości wbudowane: participant to tablica referencji do PartyRole; w PartyRole pole party to referencja do Party. Dane wystawcy i nabywcy (nazwa, adres, NIP) znajdują się w zasobie Party — w payloadzie faktury mogą być dostarczone w contained lub pobrane osobnym wywołaniem. Rachunek bankowy to referencja do BankAccount; produkt w wierszu to referencja do ProductDefinition w elemencie value[] (valueReference). Pola niebędące referencjami (issueDate, identifier, kwoty) niosą wartości bezpośrednio.
2. Mapowanie wymogów prawnych (art. 106e ustawy o VAT) na DocumentReference
| Wymóg prawny (art. 106e / KSeF) | Pole w modelu | Lokalizacja w DocumentReference / profilu |
|---|---|---|
| Data wystawienia | issueDate | DocumentReference.issueDate |
| Kolejny numer identyfikujący fakturę | invoiceNumber | DocumentReference.identifier — element w przestrzeni numeru faktury |
| Imiona, nazwiska/nazwy i adresy wystawcy | seller | DocumentReference.participant[] = Reference(PartyRole) (rola supplier); dane w Party wskazanym przez PartyRole.party |
| Imiona, nazwiska/nazwy i adresy nabywcy | buyer | DocumentReference.participant[] = Reference(PartyRole) (rola customer); dane w PartyRole.party |
| NIP podatnika (wystawcy) | sellerTaxId | W zasobie Party wystawcy: Identifier z system = https://gov.pl/nip |
| NIP nabywcy (z wyjątkami) | buyerTaxId | W zasobie Party nabywcy: Identifier z system = https://gov.pl/nip |
| Opis towaru/usługi | lineDescription | DocumentPosition.value[] — element valueString |
| Ilość | quantity | DocumentPosition.value[] — element valueQuantity |
| Cena jednostkowa netto | unitPriceNet | DocumentPosition.value[] — element valueMoney z type ceny jednostkowej |
| Rabaty i opusty | discount | DocumentPosition.value[] — element valueMoney z type rabatu |
| Wartość sprzedaży netto (wiersz) | netAmount | DocumentPosition.value[] — type = net-amount (finance/value-item-type), valueMoney |
| Stawka VAT (wiersz) | vatRate | DocumentPosition.value[] — valueCodeableConcept ze słownika vat-rate: 23, 8, 5, 0, zw, np |
| Kwota VAT (wiersz) | vatAmount | DocumentPosition.value[] — type = vat-amount, valueMoney |
| Akcyza (wiersz) | exciseAmount | DocumentPosition.value[] — valueMoney z type akcyzy |
| Suma wartości netto z podziałem na stawki | totalNetByRate | position z linią podsumowania VAT (value[]: stawka + net-amount) |
| Kwota VAT z podziałem na stawki | totalVatByRate | position z linią podsumowania VAT (value[]: stawka + vat-amount) |
| Kwota należności ogółem | totalGross | DocumentReference.attribute — code = gross-amount (finance/document-attribute-type), value[].valueMoney |
| Numer identyfikacyjny KSeF | – | DocumentReference.identifier — system = https://ksef.podatki.gov.pl, value = numer nadany przez KSeF |
| Data sprzedaży (gdy inna niż wystawienia) | saleDate | Profil FK: attribute sale-date |
| Termin płatności / data płatności | dueDate | Profil FK: attribute due-date |
| Sposób zapłaty / podział płatności | paymentMethod, splitPayment | Profil FK: attribute payment-method, split-payment |
| Rachunek bankowy do płatności | paymentAccount | Profil FK: attribute z valueReference → BankAccount (kod atrybutu nadaje wdrożenie) |
Kody type elementów value[] poza net-amount / vat-amount (ilość, cena jednostkowa, rabat, akcyza) oraz kod position.code (wiersz faktury / podsumowanie VAT) nadaje wdrożenie.
3. Pola profilu FK (rozszerzenie DocumentReference dla faktury)
Pola poniżej nie są w rdzeniu DocumentReference; należą do profilu Faktura (FK) i są realizowane przez attribute[] (Attribute: code + value[]) w systemie finance/document-attribute-type.
| Pole profilu FK | Kod atrybutu | Wariant value[] |
Odpowiednik prawny / KSeF |
|---|---|---|---|
| saleDate | sale-date |
valueString (ISO 8601) |
Data sprzedaży (gdy inna niż data wystawienia); KSeF Fa.P_1 |
| dueDate | due-date |
valueString (ISO 8601) |
Termin płatności |
| paymentMethod | payment-method |
valueCodeableConcept |
Sposób zapłaty (kody nadaje wdrożenie) |
| splitPayment | split-payment |
valueBoolean |
Mechanizm podzielonej płatności (MPP) |
| ksefAcquisitionDate | ksef-acquisition-date |
valueString (ISO 8601) |
Data otrzymania w KSeF (rejestracji) |
| totalNet | net-amount |
valueMoney |
Suma netto dokumentu |
| totalVat | vat-amount |
valueMoney |
Suma VAT dokumentu |
| totalGross | gross-amount |
valueMoney |
Kwota należności ogółem |
| paymentAccount | (wdrożenie) | valueReference → BankAccount |
Rachunek bankowy do wpłaty |
| register | register-symbol |
valueString |
Rejestr księgowy dokumentu |
4. Mapowanie struktury logicznej KSeF (FA) na DocumentReference
| Element FA (KSeF) | Odpowiednik w DocumentReference |
|---|---|
| Naglowek (numer, daty, identyfikatory) | identifier (w tym numer KSeF), issueDate, type, status; profil: sale-date, due-date, ksef-acquisition-date |
| Podmiot1 (wystawca) | participant[] = Reference(PartyRole) (rola supplier); dane strony w Party (PartyRole.party) |
| Podmiot2 (nabywca) | participant[] = Reference(PartyRole) (rola customer); dane w Party |
| Podmiot3 (inne, np. płatnik) | participant[] = Reference(PartyRole) (rola payer) |
| Fa (część faktury: wiersze, rozliczenia, płatności) | position[] (wiersze + opcjonalnie linie podsumowania VAT), attribute[] (sumy), profil: payment-method, split-payment, rachunek |
| FaWiersz (pojedynczy wiersz) | DocumentPosition: code (wiersz), positionNo, value[] (ilość, cena jedn., net-amount, vat-amount, akcyza, stawka VAT jako valueCodeableConcept, produkt jako valueReference, opis jako valueString) |
| Stopka (podsumowanie) | attribute (net-amount, vat-amount, gross-amount) oraz opcjonalnie position z linią podsumowania per stawka |
5. Wiersz faktury (DocumentPosition)
DocumentPosition ma pola positionNo, code, value[], status, attachment[]. Profil Faktura ustala użycie value[] (ValueItem: opcjonalny type + jeden wariant wartości). W wierszu: code (rodzaj pozycji), positionNo (od 1) i element net-amount; pozostałe elementy wg potrzeb.
| Element prawny / biznesowy | Element value[] |
|---|---|
| Opis towaru/usługi | valueString |
| Ilość i jednostka miary | valueQuantity (value, unit) |
| Cena jedn. netto | valueMoney z type ceny jednostkowej (kod nadaje wdrożenie) |
| Wartość netto pozycji | type = net-amount (finance/value-item-type), valueMoney |
| Stawka VAT | valueCodeableConcept — słownik vat-rate: 23, 8, 5, 0, zw, np |
| Kwota VAT pozycji | type = vat-amount, valueMoney |
| Akcyza (wiersz) | valueMoney z type akcyzy (kod nadaje wdrożenie) |
| Towar/usługa | valueReference → ProductDefinition (referencja, nie pełny obiekt) |
| Rabat | valueMoney z type rabatu (kod nadaje wdrożenie) |
Numeracja wierszy: positionNo (1, 2, 3, …) — spójna dla referencji pozycji źródłowych.
6. Zgodność z Common Data Model (CDM)
Profil Faktura jest zbieżny z podejściem Microsoft Common Data Model:
- Invoice (CRM): nagłówek (daty, kontrahent, kwoty) + powiązane szczegóły — u nas DocumentReference (participant → PartyRole, issueDate, attribute
gross-amount) + position. - FreeTextInvoiceHeaderEntity (Finance): InvoiceNumber, InvoiceDate, DueDate, CustomerAccount, CurrencyCode, PaymentTerms — u nas: identifier (numer faktury), issueDate, profil
due-date, participant → PartyRole (nabywca), waluta w Money, profilpayment-method. - CustInvoiceTrans (wiersze): ilość, kwoty, VAT — u nas DocumentPosition.value[] (
valueQuantity,net-amount,vat-amount, stawka jakovalueCodeableConcept).
Różnica: w CDM często osobne encje dla nagłówka i wierszy; u nas jeden zasób DocumentReference z position[] i attribute[], co upraszcza wymianę i walidację jednym dokumentem.
7. Odniesienia
- DocumentReference — rdzeń dokumentu (identifier, issueDate, participant, position, attribute)
- DocumentPosition — wiersz faktury i linia podsumowania VAT (
value[]) - Attribute, ValueItem — atrybuty dokumentu i elementy wartości
- PartyRole (participant → supplier, customer), Party (PartyRole.party — dane wystawcy i nabywcy)
- BankAccount — rachunek do płatności
- Invoice — model kanoniczny — zasób udostępniany przez API (
GET /v1/invoices) - KSeF – struktura FA(3) — struktura logiczna e-faktury
- Art. 106e ustawy z 11.03.2004 r. o podatku od towarów i usług — obowiązkowe elementy faktury
- Przykłady JSON: Invoice-Examples §1 (DocumentReference + profil FK) i §2 (Invoice)