Public FA(3) API facade.
Klasy
ContactInfo
Import: from ksef2.fa3 import ContactInfo
class ContactInfo(KSeFBaseModel)Optional contact channels exposed on invoice parties.
Atrybuty
email:str | None— Email address.phone:str | None— Phone number.
FA3InvoiceBuilder
Import: from ksef2.fa3 import FA3InvoiceBuilder
class FA3InvoiceBuilder(StandardInvoiceBuilder)Canonical public FA(3) invoice builder.
Example
from datetime import date
from decimal import Decimal
from ksef2.fa3 import FA3InvoiceBuilder, VatRate
builder = (
FA3InvoiceBuilder()
.header(system_info="billing-service")
.seller(
name="ACME S.A.",
tax_id="1234567890",
country_code="PL",
address_line_1="ul. Przykladowa 123",
)
.buyer(
name="XYZ GmbH",
country_code="DE",
address_line_1="Unter den Linden 1",
)
.standard()
.issue_place("Warszawa")
.issue_date(date(2026, 3, 29))
.invoice_number("FV/2026/03/0001")
.rows()
.add_line(
name="Consulting service",
unit_of_measure="h",
quantity=Decimal("10"),
unit_price_net=Decimal("100.00"),
vat_rate=VatRate.VAT_23,
)
.done()
.done()
)
xml_bytes = builder.to_xml().encode("utf-8")InvoiceAddress
Import: from ksef2.fa3 import InvoiceAddress
class InvoiceAddress(KSeFBaseModel)Address shape aligned with FA(3) schemat.Tadres.
Atrybuty
country_code:str— Two-letter ISO 3166 country code.address_line_1:str— First address line, usually street and building number.address_line_2:str | None— Second address line, usually postal code and city.gln:str | None— Global Location Number of the address.
InvoiceEntity
Import: from ksef2.fa3 import InvoiceEntity
class InvoiceEntity(KSeFBaseModel)Seller or buyer domain entity used by the public FA(3) invoice API.
Atrybuty
tax_id:str | None— Polish NIP of the entity.eu_vat_id:str | None— EU VAT identifier of the entity, including the country prefix.other_id:str | None— Identifier of another kind, for entities without a NIP or EU VAT number.eori_number:str | None— EORI number of the entity.customer_number:str | None— Customer number assigned by the seller.buyer_id:str | None— Unique identifier of the buyer assigned by the seller.jst_subordinate_unit:bool— Whether the invoice is issued for a subordinate unit of a local government (JST).vat_group_member:bool— Whether the invoice is issued for a member of a VAT group.vat_prefix:str | None— Country prefix of the EU VAT identifier.name:str | None— Full name of the entity.address:InvoiceAddress | None— Address of the entity.contact:ContactInfo | None— Contact details of the entity.
InvoiceHeader
Import: from ksef2.fa3 import InvoiceHeader
class InvoiceHeader(KSeFBaseModel)FA(3) invoice header.
References
schemat.Tnaglowek
Maps
generation_timestamp - data_wytworzenia_fa system_info - system_info <absent> - wariant_formularza = KodFormularza.VALUE_3 <absent> - kod_systemowy = "FA (3)" <absent> - wersja_schemy = "1-0E"
Atrybuty
generation_timestamp:datetime— When the invoice was generated (DataWytworzeniaFa). Defaults to the current time.system_info:str | None— Name of the system that generated the invoice (SystemInfo, up to 256 characters).
InvoiceSummaryOverrides
Import: from ksef2.fa3 import InvoiceSummaryOverrides
class InvoiceSummaryOverrides(KSeFBaseModel)Imported FA(3) summary totals preserved when line-level data is incomplete.
Atrybuty
base_rate_net_total:Decimal | None— Total net amount at the basic VAT rate (P_13_1).base_rate_vat_total:Decimal | None— Total VAT at the basic rate (P_14_1).base_rate_vat_total_pln:Decimal | None— Total VAT at the basic rate converted to PLN (P_14_1W).first_reduced_rate_net_total:Decimal | None— Total net amount at the first reduced VAT rate (P_13_2).first_reduced_rate_vat_total:Decimal | None— Total VAT at the first reduced rate (P_14_2).first_reduced_rate_vat_total_pln:Decimal | None— Total VAT at the first reduced rate converted to PLN (P_14_2W).second_reduced_rate_net_total:Decimal | None— Total net amount at the second reduced VAT rate (P_13_3).second_reduced_rate_vat_total:Decimal | None— Total VAT at the second reduced rate (P_14_3).second_reduced_rate_vat_total_pln:Decimal | None— Total VAT at the second reduced rate converted to PLN (P_14_3W).taxi_flat_rate_net_total:Decimal | None— Total net amount under the taxi flat-rate scheme (P_13_4).taxi_flat_rate_vat_total:Decimal | None— Total VAT under the taxi flat-rate scheme (P_14_4).taxi_flat_rate_vat_total_pln:Decimal | None— Total VAT under the taxi flat-rate scheme converted to PLN (P_14_4W).special_procedure_xii_net_total:Decimal | None— Total net amount under the special procedure of Section XII (P_13_5).special_procedure_xii_vat_total:Decimal | None— Total VAT under the special procedure of Section XII (P_14_5).zero_rate_domestic_total:Decimal | None— Total net amount at the 0% rate for domestic supply, excluding intra-Community supply and export (P_13_6_1).zero_rate_wdt_total:Decimal | None— Total net amount at the 0% rate for intra-Community supply of goods (P_13_6_2).zero_rate_export_total:Decimal | None— Total net amount at the 0% rate for export of goods (P_13_6_3).exempt_total:Decimal | None— Total net amount of VAT-exempt supply (P_13_7).out_of_territory_total:Decimal | None— Total net amount of supply outside Poland, excluding the cases below and article 100 (P_13_8).article_100_services_total:Decimal | None— Total net amount of services under article 100(1)(4) of the VAT Act (P_13_9).reverse_charge_total:Decimal | None— Total net amount of supply subject to the domestic reverse charge (P_13_10).margin_total:Decimal | None— Total net amount under the margin scheme (P_13_11).total_gross:Decimal | None— Total amount due, gross (P_15).
Metody
InvoiceSummaryOverrides.round_optional_amount
@classmethod
def round_optional_amount(value: Decimal | None) -> Decimal | NoneRound a summary amount to PLN precision.
Parametry
value(Decimal | None) — Amount to round, orNone.
Zwraca
Decimal | None— The rounded amount, orNone.
InvoiceThirdParty
Import: from ksef2.fa3 import InvoiceThirdParty
class InvoiceThirdParty(KSeFBaseModel)Additional FA(3) subject stored in the repeated Faktura/Podmiot3 block.
Atrybuty
tax_id:str | None— Polish NIP of the third party.internal_id:str | None— Internal identifier of the third party within a VAT group (up to 20 characters).eu_vat_id:str | None— EU VAT identifier of the third party.country_code:str | None— Two-letter country code accompanyingother_idoreu_vat_id.other_id:str | None— Identifier of another kind (1–50 characters).no_id:bool— Marks a third party that has no identifier.name:str— Full name of the third party.address:InvoiceAddress | None— Address of the third party.correspondence_address:InvoiceAddress | None— Correspondence address, if different fromaddress.contact:list[ContactInfo] | ContactInfo | None— One or more contact entries.role:ThirdPartyRole | None— Role of the third party on the invoice.other_role:bool— Marks a role not covered byrole; describe it inrole_description.role_description:str | None— Free-text description of the role whenother_roleis set (1–256 characters).share_percentage:Decimal | None— Percentage share of the third party (0–100).customer_number:str | None— Customer number of the third party.eori_number:str | None— EORI number of the third party.buyer_id:str | None— Unique identifier of the buyer assigned by the seller.
KsefInvoice
Import: from ksef2.fa3 import KsefInvoice
class KsefInvoice(KSeFBaseModel)Root public aggregate for a FA(3) invoice.
Atrybuty
header:Annotated[InvoiceHeader, Field(description='Maps to Faktura.Naglowek')]— Invoice header (Faktura/Naglowek).seller:Annotated[InvoiceEntity, Field(description='Maps to Faktura.Podmiot1')]— Seller (Faktura/Podmiot1).buyer:Annotated[InvoiceEntity, Field(description='Maps to Faktura.Podmiot2')]— Buyer (Faktura/Podmiot2).third_parties:Annotated[Sequence[InvoiceThirdParty], Field(description='Maps to Faktura.Podmiot3')]— Additional subjects (Faktura/Podmiot3).body:Annotated[KsefInvoiceBody, Field(description='Maps to Faktura.Fa')]— Invoice body (Faktura/Fa).footer:Annotated[InvoiceFooter | None, Field(description='Maps to Faktura.Stopka')]— Footer (Faktura/Stopka), if any.attachment:Annotated[Attachment | None, Field(description='Maps to Faktura.FakturaZalacznik')]— Attachment (Faktura/Zalacznik), if any.
Metody
KsefInvoice.total_gross (właściwość)
total_gross: DecimalReturn the gross total computed by the invoice body.
Zwraca
Decimal— The gross total computed by the invoice body.
KsefInvoice.total_net (właściwość)
total_net: DecimalReturn the net total computed by the invoice body.
Zwraca
Decimal— The net total computed by the invoice body.
KsefInvoice.total_vat (właściwość)
total_vat: DecimalReturn the VAT total computed by the invoice body.
Zwraca
Decimal— The VAT total computed by the invoice body.
KsefInvoiceDraft
Import: from ksef2.fa3 import KsefInvoiceDraft
class KsefInvoiceDraft(KSeFPersistedModel)Serializable editable snapshot of FA(3) builder state.
Atrybuty
format_version:Literal[1]— Version of the serialized draft format; currently always1.header:Annotated[InvoiceHeader | None, Field(description='Draft header state.')]— Draft header state.seller:Annotated[InvoiceEntity | None, Field(description='Draft seller state.')]— Draft seller state.buyer:Annotated[InvoiceEntity | None, Field(description='Draft buyer state.')]— Draft buyer state.third_parties:Annotated[list[InvoiceThirdParty], Field(description='Draft third-party state.')]— Draft third-party state.body:Annotated[KsefInvoiceBody | None, Field(description='Draft invoice body state.')]— Draft invoice body state.footer:Annotated[InvoiceFooter | None, Field(description='Draft footer state.')]— Draft footer state.attachment:Annotated[Attachment | None, Field(description='Draft attachment state.')]— Draft attachment state.
Metody
KsefInvoiceDraft.from_invoice
@classmethod
def from_invoice(invoice: KsefInvoice) -> KsefInvoiceDraftCreate an editable draft from a finished invoice.
Parametry
invoice(KsefInvoice) — Invoice to snapshot.
Zwraca
KsefInvoiceDraft— A draft holding the invoice's state.
VatClassification
Import: from ksef2.fa3 import VatClassification
class VatClassification(KSeFBaseModel)Structured VAT treatment and numeric rate pair.
Atrybuty
treatment:VatTreatment— Legal VAT treatment used by the row.rate:Decimal | None— Numeric VAT rate in percent;Nonefor treatments without a rate.
Metody
VatClassification.validate_rate
def validate_rate() -> SelfCheck that the numeric rate agrees with the treatment.
Zwraca
Self— The validated classification.
Zgłasza
ValueError— If a taxable treatment has an unsupported rate, a zero-rated treatment has a non-zero rate, or another treatment carries a rate.
VatClassification.sale_category (właściwość)
sale_category: SaleCategoryReturn the strict sale category matching this classification.
Zwraca
SaleCategory— The strict sale category matching this classification.
VatClassification.vat_rate (właściwość)
vat_rate: VatRateReturn the FA(3) VAT rate marker for this classification.
Zwraca
VatRate— The FA(3) VAT rate marker for this classification.
VatClassification.numeric_rate (właściwość)
numeric_rate: Decimal | NoneReturn the numeric VAT rate when this treatment has one.
Zwraca
Decimal | None— The numeric VAT rate when this treatment has one.
VatClassification.is_zero_rated (właściwość)
is_zero_rated: boolReturn whether this classification is one of the zero-rate categories.
Zwraca
bool— Whether this classification is one of the zero-rate categories.
VatClassification.from_sale_category
@classmethod
def from_sale_category(category: SaleCategory) -> SelfBuild a classification from a strict sale category.
Parametry
category(SaleCategory) — Sale category to classify.
Zwraca
Self— The matching treatment and numeric rate.
VatClassification.from_vat_rate
@classmethod
def from_vat_rate(
vat_rate: VatRate | str,
*,
sale_category: SaleCategory | str | None = None,
) -> SelfBuild a classification from a VAT rate and optional sale category.
Parametry
vat_rate(VatRate | str) — VAT rate marker or its string form.sale_category(SaleCategory | str | None) — Sale category to disambiguate rates that map to several categories; inferred from the rate whenNone.
Zwraca
Self— The matching classification.
Zgłasza
ValueError— If the rate is not valid for the sale category.
VatClassification.from_schema_code
@classmethod
def from_schema_code(code: str) -> SelfBuild a classification from a raw FA(3) schema VAT code.
Parametry
code(str) — Schema VAT code, for example"23"or"zw".
Zwraca
Self— The matching classification.
Zgłasza
ValueError— If the code is not a supported FA(3) VAT code.
VatClassification.to_schema_code
def to_schema_code() -> strReturn the raw FA(3) schema VAT code for this classification.
Zwraca
str— The raw FA(3) schema VAT code for this classification.
Typy wyliczeniowe
SaleCategory
Import: from ksef2.fa3 import SaleCategory
class SaleCategory(StrEnum)Strict FA(3) sale category mapped to schema VAT codes.
Wartości
| Nazwa | Wartość |
|---|---|
RATE_23 | 'rate_23' |
RATE_22 | 'rate_22' |
RATE_8 | 'rate_8' |
RATE_7 | 'rate_7' |
RATE_5 | 'rate_5' |
RATE_4 | 'rate_4' |
RATE_3 | 'rate_3' |
ZERO_DOMESTIC | 'zero_domestic' |
ZERO_WDT | 'zero_wdt' |
ZERO_EXPORT | 'zero_export' |
EXEMPT | 'exempt' |
REVERSE_CHARGE | 'reverse_charge' |
OUT_OF_SCOPE_OUTSIDE_TERRITORY | 'out_of_scope_outside_territory' |
OUT_OF_SCOPE_ARTICLE_100 | 'out_of_scope_article_100' |
TaxRegime
Import: from ksef2.fa3 import TaxRegime
class TaxRegime(StrEnum)Additional tax regime context for non-standard line calculations.
Wartości
| Nazwa | Wartość |
|---|---|
STANDARD | 'standard' |
TAXI_FLAT_RATE | 'taxi_flat_rate' |
SPECIAL_XII | 'special_xii' |
MARGIN | 'margin' |
VatRate
Import: from ksef2.fa3 import VatRate
class VatRate(StrEnum)FA(3) schema VAT rate markers.
Wartości
| Nazwa | Wartość |
|---|---|
VAT_23 | '23' |
VAT_22 | '22' |
VAT_8 | '8' |
VAT_7 | '7' |
VAT_5 | '5' |
VAT_4 | '4' |
VAT_3 | '3' |
VAT_0 | '0' |
EXEMPT | 'zw' |
NOT_SUBJECT | 'np' |
REVERSE_CHARGE | 'oo' |
VatTreatment
Import: from ksef2.fa3 import VatTreatment
class VatTreatment(StrEnum)Legal VAT treatment categories used by the domain model.
Wartości
| Nazwa | Wartość |
|---|---|
TAXABLE | 'taxable' |
ZERO_DOMESTIC | 'zero_domestic' |
ZERO_WDT | 'zero_wdt' |
ZERO_EXPORT | 'zero_export' |
EXEMPT | 'exempt' |
REVERSE_CHARGE | 'reverse_charge' |
OUT_OF_SCOPE_OUTSIDE_TERRITORY | 'out_of_scope_outside_territory' |
OUT_OF_SCOPE_ARTICLE_100 | 'out_of_scope_article_100' |
Funkcje
parse_invoice_xml
Import: from ksef2.fa3 import parse_invoice_xml
def parse_invoice_xml(invoice_xml: bytes) -> KsefInvoiceParse FA(3) XML bytes without exposing generated schema types.
Parametry
invoice_xml(bytes) — Original XML bytes, including any encoding declaration.
Zwraca
KsefInvoice— The public invoice aggregate. Domain validation is applied; this isKsefInvoice— not full XSD validation or a lossless XML representation.
Zgłasza
ValueError— If XML is malformed, uses a DTD, is not FA(3), or cannot be mapped to a valid invoice. The original cause is preserved.
