KSeF Pro PSDocumentationSending Invoices to KSeF

Sending Invoices to KSeF

KSeF Pro generates FA(2) XML documents from your PrestaShop orders, signs them with XAdES-BES digital signatures, and submits them to the KSeF API through a managed session lifecycle. This page covers the full pipeline from order trigger to archived KSeF-ID.

FA(2) XML Structure Overview

Every invoice submitted to KSeF must conform to the FA(2) logical structure defined by the Ministry of Finance (schema version 2.0 mandatory from April 2026). KSeF Pro generates this XML automatically from order data.

Key FA(2) Blocks and Data Sources

| FA(2) Block | Element | Source in PrestaShop | |---|---|---| | <Naglowek> | <KodFormularza> | Fixed: FA, version 2 | | | <DataWystawienia> | Order confirmation date | | | <RodzajFaktury> | VAT (standard) or KOR (correction) | | | <NumerFaktury> | KSeF Pro sequential number or PrestaShop order reference | | <Podmiot1> (seller) | <NIP> | Seller NIP from KSeF Pro configuration | | | <NazwaPodmiotu> | Company name from KSeF Pro Seller Data | | | <Adres> | Seller address from KSeF Pro Seller Data | | <Podmiot2> (buyer) | <NIP> | Customer NIP from order (B2B) or BRAK (B2C) | | | <NazwaPodmiotu> | Customer billing company name or full name | | | <Adres> | Customer billing address | | <Fa> | <P_1> | Invoice date | | | <P_15> | Total gross amount (PLN) | | | <P_13_1> | Net amount at 23% VAT rate | | | <P_14_1> | VAT amount at 23% rate | | | <RodzajTransakcji> | krajowa (domestic) or UE (intra-EU) | | <FaWiersz> | Per-product rows | Order line items — one row per SKU | | | <P_7> | Product name | | | <P_8A> | Unit of measure (default: szt.) | | | <P_8B> | Quantity | | | <P_9A> | Unit net price | | | <P_12> | VAT rate code (23, 8, 5, 0, ZW, NP) |

Shipping Line Treatment

Shipping is included as a separate <FaWiersz> row using:

  • <P_7>: Shipping method name from the order
  • <P_12>: VAT rate mapped from your shipping tax rule
  • <P_8A>: usł. (services unit)

If your shipping is VAT-exempt or zero-rated, configure the shipping tax rule mapping accordingly in Invoice Settings → Tax Rate Mapping.

XML Preview

Before going live, review the XML output for a real order:

  1. Go to KSeF Pro → Audit Log
  2. Find any PENDING or ACCEPTED record
  3. Click the XML icon to view the signed FA(2) document
  4. Verify seller NIP, buyer data, line items, VAT rates, and total amounts

FA(2) XML preview screen in KSeF Pro

XAdES-BES Digital Signature

Before submission, every FA(2) XML document is signed with an XAdES-BES enveloped signature. KSeF requires this to confirm the document has not been tampered with in transit.

Signing Process

  1. The FA(2) XML is canonicalized (whitespace normalized, elements sorted per C14N spec)
  2. A SHA-256 digest is computed over the canonical XML
  3. The digest is signed using HMAC-SHA256 with the KSeF token as the key
  4. The resulting <ds:Signature> block is embedded in the FA(2) XML
  5. The entire signed document is Base64-encoded for API transport

No Qualified Certificate Required

You do not need a separate qualified electronic certificate (kwalifikowany podpis elektroniczny) for invoice-level signing. The KSeF portal token is sufficient for XAdES-BES. Qualified signatures are only required for token issuance at the KSeF portal — not for individual invoice submissions.

Signing Failure Diagnosis

If signing fails (audit log error 10100), the most common causes are:

| Cause | Diagnosis | Fix | |---|---|---| | OpenSSL extension missing | php -m \| grep openssl — not listed | Enable OpenSSL in PHP config | | Token has trailing whitespace | Copy token again from password manager | Re-paste token, save, verify | | OpenSSL 3.2+ deprecation | var/logs/ksefpl.log shows digest algorithm warning | Update to KSeF Pro 1.3.2+ |

Session Lifecycle

KSeF submissions happen within sessions — bounded API contexts. Each session has a lifecycle that must be completed for invoices to receive KSeF-IDs.

Stage 1: Open Session

POST /api/online/Session/InitSigned
→ Body: signed InitialisationSigned XML
← Response: {
    "sessionToken": "SESSION_TOKEN",
    "referenceNumber": "SESSION_REF_123"
  }

KSeF Pro opens a session automatically when the first invoice trigger fires. The referenceNumber is stored in the audit log — use it to cross-reference submissions in the KSeF portal if needed.

Stage 2: Submit Invoice(s)

POST /api/online/Session/Invoice/Send
→ Body: {
    "invoiceHash": {
      "hashSHA": { "algorithm": "SHA-256", "encoding": "Base64", "value": "HASH" },
      "fileSize": 12345
    },
    "invoicePayload": {
      "type": "plain",
      "invoiceBody": "BASE64_ENCODED_FA2_XML"
    }
  }
← Response: { "elementReferenceNumber": "ELEM_REF_456" }

Each invoice receives an elementReferenceNumber — a temporary reference within the session. KSeF Pro stores this in the audit record alongside the order until the UPO is downloaded and the permanent KSeF-ID is assigned.

Multiple invoices can be queued in a single session (up to 100 per session, MF-imposed limit). For stores processing fewer than 100 invoices per batch, all invoices go into one session.

Stage 3: Close Session

POST /api/online/Session/CloseSigned
← Response: { "processingCode": 200 }

Closing the session signals to KSeF that no more invoices will be submitted in this batch. The MF servers then begin asynchronous processing: validating every FA(2) document, assigning KSeF-IDs, and generating the UPO.

Sessions must be explicitly closed to receive KSeF-IDs. A session that is opened but never closed (e.g., the server process is killed) expires after 30 minutes without generating UPOs for any submitted invoices.

Stage 4: Poll for UPO

GET /api/common/Status/{referenceNumber}
← Response when ready: {
    "processingCode": 200,
    "upo": "BASE64_ENCODED_UPO_XML",
    "invoiceStatusList": [
      { "invoiceReferenceNumber": "ELEM_REF_456", "ksefReferenceNumber": "KSEF_ID_789" }
    ]
  }

UPO processing is asynchronous. KSeF Pro polls the status endpoint at a configurable interval (default: every 30 seconds) until processingCode: 200. Processing typically completes within 1–3 minutes during normal MF server load.

When the UPO is ready:

  • The UPO XML is downloaded and stored at modules/ksefpl/upo/{order-reference}-{timestamp}.xml
  • The KSeF-ID for each invoice is written to the PrestaShop order record
  • The audit log record status changes from SUBMITTED to ACCEPTED

Terminate Session (Error Recovery)

POST /api/online/Session/Terminate

If an unrecoverable error occurs before closing (e.g., the FA(2) XML for one invoice in the batch has a validation error that blocks the entire session), you can terminate the session to discard all submitted invoices. None receive KSeF-IDs.

After termination, fix the underlying issue (see Troubleshooting) and re-trigger submission from the audit log.

KSeF session management panel showing status and controls

UPO Content and Legal Standing

The UPO (Urzędowe Poświadczenie Odbioru — Official Proof of Receipt) is a signed XML document containing:

| UPO Field | Description | |---|---| | KSeF-ID | Permanent government-assigned invoice identifier | | Submission timestamp | When the FA(2) XML was received by KSeF | | Processing timestamp | When the invoice was validated and accepted | | Ministry of Finance seal | Cryptographic seal confirming authenticity | | FA(2) XML hash | SHA-256 hash of the original submitted document | | NIP | Your seller NIP |

The UPO is the legal proof that your invoice was submitted to and accepted by the Polish tax authority. It must be retained for the duration of your tax records — currently 5 years under Polish law (ustawa o rachunkowości). KSeF Pro does not auto-purge UPOs.

Batch Submission

For high-volume stores or when catching up after downtime (e.g., KSeF portal maintenance):

  1. Go to KSeF Pro → Audit Log
  2. Filter by status: PENDING or FAILED
  3. Select records using the checkbox column
  4. Click "Submit selected to KSeF"

KSeF Pro batches up to 100 invoices per session. If you select more than 100 orders, the module opens sequential sessions automatically — it does not prompt for confirmation between sessions.

Batch submission and compliance dashboard

Batch Rate Limits

The KSeF API does not publish explicit rate limits, but the Ministry of Finance recommends no more than 1 session open at a time per NIP. KSeF Pro enforces this — it does not open parallel sessions. If two processes attempt to open a session simultaneously (e.g., a cron job and a manual batch), the second is queued until the first session closes.

Correction Invoices (Faktura Korygująca)

When a correction is needed (price change, return, address error on a previously submitted invoice):

  1. KSeF Pro generates an FA(2) XML with <RodzajFaktury>KOR</RodzajFaktury>
  2. The <DaneFaKorygowanej> block references the original KSeF-ID
  3. The correction is submitted as a new session — it receives its own KSeF-ID
  4. Both the original and the correction appear in your KSeF ledger

Corrections are triggered from the KSeF Pro panel on the order detail page — click "Issue correction" and select the correction type (full reversal or partial).

Next Steps

Edit this page on GitHub
Was this page helpful?

Documentation associée

Ce sujet est également disponible pour d'autres plateformes :