# KSeF API Integration
Java integration for the Polish **Krajowy System e-Faktur (KSeF)** - the national e-invoicing system for Poland.
## Overview
This integration provides secure communication with the KSeF API to upload electronic invoices. It handles the complex multi-step authentication flow and encryption requirements mandated by the Polish tax authorities.
## Components
### 1. KSeFAuthManager
Manages authentication and session lifecycle for the KSeF API.
**Key Responsibilities:**
- Multi-step authentication flow
- RSA certificate management
- Session key generation and encryption
- Access token lifecycle management
- Session reuse and validation
### 2. KSeFAPIService
Provides business-level methods for invoice operations.
**Key Responsibilities:**
- Invoice encryption (AES-256-CBC)
- Invoice upload to KSeF
- Hash calculation and validation
- Error handling and reporting
## Authentication Flow
The KSeF API requires a sophisticated multi-step authentication process:
```
1. Load Public Keys
└─> GET /security/public-key-certificates
2. Challenge Request
└─> POST /auth/challenge
└─> Returns: challenge + timestamp
3. Token Authentication
└─> POST /auth/ksef-token
└─> Encrypts: token|timestamp with RSA-OAEP SHA-256
└─> Returns: authToken + referenceNumber
4. Token Redemption
└─> POST /auth/token/redeem
└─> Returns: accessToken
5. Open Interactive Session
└─> POST /sessions/online
└─> Generates AES-256 key + IV
└─> Encrypts session key with RSA
└─> Returns: sessionRefNumber + validUntil
```
## Invoice Upload Flow
Once authenticated, invoices can be uploaded:
```
1. Reuse or Create Session
└─> Validates existing session or creates new one
2. Encrypt Invoice
└─> AES-256-CBC encryption using session key
3. Calculate Hashes
└─> SHA-256 of original XML
└─> SHA-256 of encrypted XML
4. Upload Invoice
└─> POST /sessions/online/{sessionRef}/invoices
└─> Returns: referenceNumber
```
## Security Features
### Multi-Layer Encryption
- **RSA-OAEP SHA-256**: Token encryption with timestamp binding
- **RSA-OAEP SHA-1**: Session key encryption
- **AES-256-CBC**: Invoice content encryption
### Security Mechanisms
- **Replay Attack Protection**: Timestamp-bound tokens
- **Session Management**: Automatic session reuse and validation
- **Certificate Validation**: Dynamic X.509 certificate loading
- **UTC Timezone Handling**: Prevents timezone-related vulnerabilities
## Usage Example
```java
// Initialize Auth Manager
KSeFAuthManager authManager = new KSeFAuthManager();
authManager.setKsefToken("your-ksef-token");
authManager.setKsefNip("1234567890");
authManager.setKsefEndpoint("https://ksef-test.mf.gov.pl/api/v2");
authManager.init();
// Initialize API Service
KSeFAPIService apiService = new KSeFAPIService();
apiService.kseFAuthManager = authManager;
// Upload Invoice
ItemCollection workitem = new ItemCollection();
FileData fileData = new FileData("invoice.xml", xmlBytes, null, null);
workitem.addFileData(fileData);
String referenceNumber = apiService.uploadInvoice(workitem, "invoice.xml");
System.out.println("Invoice uploaded: " + referenceNumber);
```
## Configuration
Required environment variables:
```properties
ksef.api.token=your-ksef-authentication-token
ksef.api.nip=your-company-nip-number
ksef.api.endpoint=https://ksef-test.mf.gov.pl/api/v2
ksef.api.debug=false
```
## Session Management
The `KSeFAuthManager` automatically handles session lifecycle:
- **Session Reuse**: Validates `sessionValidUntil` timestamp (UTC)
- **Auto-Renewal**: Opens new session if current one expired
- **Thread-Safe**: Uses `@Lock(LockType.WRITE)` for concurrent access
## Testing
Test environment endpoint:
```
https://ksef-test.mf.gov.pl/api/v2
```
Production endpoint:
```
https://ksef.mf.gov.pl/api/v2
```
See `KSeFAPIServiceTest.java` for complete test examples.
## Error Handling
The implementation uses `PluginException` for error handling with two error types:
- `CONFIG_ERROR`: Configuration or setup issues
- `API_ERROR`: API communication or response errors
## Dependencies
- Jakarta EE (EJB, JSON-B)
- Java 11+ (HttpClient, Crypto APIs)
- Imixs Workflow (for document management)
## References
- [KSeF Official Documentation](https://www.gov.pl/web/kas/ksef)
- [KSeF API Specification](https://ksef-test.mf.gov.pl/docs/v2/index.html)
- [Upload Invoice](https://ksef-test.mf.gov.pl/docs/v2/index.html#tag/Wysylka-interaktywna/paths/~1api~1v2~1sessions~1online~1%7BreferenceNumber%7D~1invoices/post)
- [Facture Details](https://github.com/CIRFMF/ksef-docs/blob/main/sesja-interaktywna.md#2-wys%C5%82anie-faktury)
- [XML Invoice Example](https://github.com/CIRFMF/ksef-docs/blob/main/faktury/weryfikacja-faktury.md)
- [QR Code](https://github.com/CIRFMF/ksef-docs/blob/main/kody-qr.md)
- [Github Discussions](https://github.com/CIRFMF/ksef-docs/issues/351#issuecomment-3538013805)
- [Github Discussions](https://github.com/CIRFMF/ksef-docs/issues/399)
# Validate XML
To validate XML results use xmllint. To install run:
```bash
$ sudo apt install libxml2-utils
```
With the bash script `src/test/resources/ksef/validate_xml.sh` you can test a xml file:
```bash
$ ./validate_xml.sh example-invoice-01.xml
```
or to manual test a xml run:
```bash
$ xmllint --noout --schema 'schemat-FA(3)-v1-0E.xsd' example-invoice-01.xml
example-invoice-01.xml validates
```
# KSeF FA(3) Invoice Types: VAT vs. KOR
This section explains the key differences between regular invoices (VAT) and correction invoices (KOR) in the Polish KSeF system using FA(3) structure.
## Invoice Types
### VAT - Regular Invoice
Standard invoice documenting a sale or service delivery.
### KOR - Correction Invoice
Invoice that corrects a previously issued invoice (VAT, ZAL, or ROZ).
---
## Key Differences
| Element | VAT Invoice | KOR Invoice |
| ------------------------- | -------------------------- | --------------------------------------------- |
| **RodzajFaktury** | `VAT` | `KOR` |
| **P_2 (Invoice Number)** | `216525` | `216525-KOR` (with suffix) |
| **P_1 (Invoice Date)** | Original date (2024-04-03) | Correction date (2024-04-15) |
| **Amount Fields** | Absolute values | **Difference values** (negative or positive) |
| **DaneFaKorygowanej** | ❌ Not present | ✅ **Required** - references original invoice |
| **FaWiersz (Line Items)** | Original values | **New/corrected values** |
---
## Critical: Amount Fields in KOR
**KOR invoices show DIFFERENCES, not absolute amounts!**
### Example: Correction from 4128.00 → 3500.00 EUR
```xml
4128.00
0.00
4128.00
```
```xml
-628.00
-628.00
```
## DaneFaKorygowanej Element
**Required in KOR invoices** - Must appear AFTER `KOR`
```xml
2024-04-03
216525
1
9552521552-20240403-ABCDEF-123456-AB
```
| Field | Description |
| ----------------------- | --------------------------------------------------------- |
| `DataWystFaKorygowanej` | Date of **original** invoice |
| `NrFaKorygowanej` | Number of **original** invoice |
| `NrKSeF` | Flag: `1` = original was in KSeF |
| `NrKSeFFaKorygowanej` | KSeF number of original invoice (mandatory if `NrKSeF=1`) |
⚠️ **Critical:** The KSeF number must be saved when uploading the original VAT invoice!
---
## FaWiersz in KOR
**Line items show the NEW/CORRECTED values**, not differences:
```xml
4128.00
4128.00
```
```xml
3500.00
3500.00
0 KR
```
---
# Testdaten
Um Testdaten in die lokale Dev Umgebung zu importieren:
1. aus dem Produktiv Archiv System das XML eines Rechnungs-Snapshots unter /docker/transfer speichern
2. per api Call importieren:
http://localhost:8080/api/cargosoft/import?file=/opt/jboss/wildfly/transfer/f28bf914-04de-4843-9809-54c724bdc9bf-1764111735524.xml