ksef-accountant-pl
Asystent ksiegowy Krajowego Systemu e-Faktur (KSeF) w jezyku polskim. Uzyj przy pracy z KSeF 2.0 API, fakturami FA(3), zgodnoscia z polskim VAT, przetwarzaniem e-faktur, dopasowywaniem platnosci, rejestrami VAT (JPK_V7), fakturami korygujacymi, mechanizmem podzielonej platnosci (MPP) lub polskimi przeplywami ksiegowymi. Dostarcza wiedze domenowa do wystawiania faktur, przetwarzania zakupow, klasyfikacji kosztow, wykrywania fraudu i prognozowania cash flow w ekosystemie KSeF.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-ksef-accountant-pl
Repository
Skill path: skills/alexwoo-awso/ksef-accountant-pl
Asystent ksiegowy Krajowego Systemu e-Faktur (KSeF) w jezyku polskim. Uzyj przy pracy z KSeF 2.0 API, fakturami FA(3), zgodnoscia z polskim VAT, przetwarzaniem e-faktur, dopasowywaniem platnosci, rejestrami VAT (JPK_V7), fakturami korygujacymi, mechanizmem podzielonej platnosci (MPP) lub polskimi przeplywami ksiegowymi. Dostarcza wiedze domenowa do wystawiania faktur, przetwarzania zakupow, klasyfikacji kosztow, wykrywania fraudu i prognozowania cash flow w ekosystemie KSeF.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack, Backend.
Target audience: everyone.
License: MIT.
Original source
Catalog source: SkillHub Club.
Repository owner: openclaw.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install ksef-accountant-pl into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding ksef-accountant-pl to shared team environments
- Use ksef-accountant-pl for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: ksef-accountant-pl
description: "Asystent ksiegowy Krajowego Systemu e-Faktur (KSeF) w jezyku polskim. Uzyj przy pracy z KSeF 2.0 API, fakturami FA(3), zgodnoscia z polskim VAT, przetwarzaniem e-faktur, dopasowywaniem platnosci, rejestrami VAT (JPK_V7), fakturami korygujacymi, mechanizmem podzielonej platnosci (MPP) lub polskimi przeplywami ksiegowymi. Dostarcza wiedze domenowa do wystawiania faktur, przetwarzania zakupow, klasyfikacji kosztow, wykrywania fraudu i prognozowania cash flow w ekosystemie KSeF."
license: MIT
homepage: https://github.com/alexwoo-awso/skills
source: https://github.com/alexwoo-awso/skills/tree/main/ksef-accountant-pl
disableModelInvocation: true
disable-model-invocation: true
allowModelInvocation: false
instruction_only: true
has_executable_code: false
credential_scope: "optional-user-provided"
env:
KSEF_TOKEN:
description: "Token API KSeF do uwierzytelniania sesji. Dostarczany przez uzytkownika — skill nie generuje, nie przechowuje ani nie przesyla tokenow. Konfiguruj TYLKO po zweryfikowaniu, ze platforma wymusza flage disableModelInvocation (patrz sekcja Model bezpieczenstwa i skill.json)."
required: false
secret: true
KSEF_ENCRYPTION_KEY:
description: "Klucz szyfrowania Fernet do bezpiecznego przechowywania tokenow. Uzycie opcjonalne — przyklad wzorca bezpieczenstwa opisanego w dokumentacji referencyjnej. Konfiguruj TYLKO po zweryfikowaniu, ze platforma wymusza flage disableModelInvocation."
required: false
secret: true
KSEF_BASE_URL:
description: "Bazowy URL API KSeF. Domyslnie https://ksef-demo.mf.gov.pl (DEMO). Produkcja: https://ksef.mf.gov.pl — wymaga jawnej zgody uzytkownika. Uzywaj produkcji TYLKO po pelnej weryfikacji bezpieczenstwa platformy."
required: false
default: "https://ksef-demo.mf.gov.pl"
---
# Agent Ksiegowy KSeF
Specjalistyczna wiedza do obslugi Krajowego Systemu e-Faktur (KSeF) w srodowisku KSeF 2.0 ze struktura FA(3). Wspiera zadania ksiegowe zwiazane z fakturowaniem elektronicznym w Polsce.
## Model bezpieczenstwa
Ten skill jest **wylacznie instrukcyjny** — sklada sie z plikow Markdown zawierajacych wiedze domenowa, wzorce architektoniczne i przyklady kodu. Nie zawiera zadnego kodu wykonywalnego, binarek, skryptow instalacyjnych ani zaleznosci runtime.
**Gwarancje po stronie skilla:**
- `disableModelInvocation: true` / `disable-model-invocation: true` — zadeklarowane zarowno w metadanych frontmatter (oba formaty: camelCase i kebab-case) jak i w dedykowanym manifescie [`skill.json`](skill.json). Skill nie powinien byc wywolywany autonomicznie przez model.
- `secret: true` — zmienne srodowiskowe `KSEF_TOKEN` i `KSEF_ENCRYPTION_KEY` sa oznaczone jako sekrety w frontmatter i `skill.json`, sygnalizujac platformie, ze musza byc izolowane i nie moga byc logowane ani wyswietlane.
- Brak kodu wykonywalnego — wszystkie przyklady (Python, XML, JSON) to ilustracje pogladowe, NIE kod uruchamiany przez skill.
- Brak instalacji — skill nie zapisuje plikow na dysk, nie pobiera zaleznosci, nie modyfikuje konfiguracji systemu.
- Dedykowany manifest [`skill.json`](skill.json) — maszynowo czytelny plik z metadanymi bezpieczenstwa, deklaracjami zmiennych srodowiskowych i ograniczeniami. Jesli platforma nie parsuje frontmatter SKILL.md poprawnie, powinna odczytac metadane z `skill.json`.
**UWAGA — weryfikacja metadanych rejestru przed instalacja:**
Flagi bezpieczenstwa sa zadeklarowane w dwoch zrodlach: frontmatter SKILL.md i [`skill.json`](skill.json). Mimo to, platforma hostingowa moze nie odczytac lub nie wymusic tych flag. **Przed instalacja MUSISZ wykonac ponizsze kroki:**
1. **Sprawdz metadane rejestru** — po dodaniu skilla do platformy, otworz widok metadanych rejestru (registry metadata) wyswietlany przez platforme. Zweryfikuj, ze pole `disable-model-invocation` jest ustawione na `true` oraz ze zmienne srodowiskowe (`KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`, `KSEF_BASE_URL`) sa widoczne z oznaczeniem `secret`. Jesli platforma pokazuje `not set`, `false` lub nie wyswietla tych pol — flagi NIE sa wymuszane.
2. **Jesli metadane rejestru nie pasuja do frontmatter/skill.json** — traktuj skill jako wyzszego ryzyka: NIE udostepniaj danych uwierzytelniajacych (tokenow, certyfikatow, kluczy), NIE konfiguruj zmiennych srodowiskowych (`KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`), NIE zezwalaj na autonomiczne uzycie.
3. **Zweryfikuj izolacje zmiennych srodowiskowych** — potwierdz, ze platforma izoluje env vars i nie loguje/wyswietla ich wartosci w konwersacji.
4. **Jesli platforma nie wymusza flag** — skontaktuj sie z dostawca platformy w celu wlaczenia obslugi `disableModelInvocation` (lub parsowania `skill.json`) lub nie instaluj skilla z dostepem do jakichkolwiek danych uwierzytelniajacych.
**Gwarancje zalezne od platformy:**
- Wymuszanie flagi `disableModelInvocation` zalezy od platformy hostingowej. Sam frontmatter nie zapewnia ochrony — wymaga wsparcia po stronie platformy.
- Izolacja zmiennych srodowiskowych (env vars) zalezy od platformy. Skill deklaruje je jako opcjonalne, ale nie kontroluje jak platforma je przechowuje i udostepnia.
- Jesli platforma nie wymusza tych ustawien, traktuj skill jako wyzszego ryzyka i nie udostepniaj mu danych uwierzytelniajacych ani dostepu produkcyjnego.
## Ograniczenia
- **Tylko wiedza — brak wykonywania kodu** - Dostarcza wiedze domenowa, wzorce architektoniczne i wskazowki. Wszystkie przyklady kodu (w tym ML/AI) sa edukacyjne i pogladowe. Skill NIE uruchamia modeli ML, NIE wykonuje inferencji, NIE wymaga runtime'ow Python/sklearn ani zadnych binarek. Agent wyjasnia algorytmy i sugeruje kod do implementacji przez uzytkownika.
- **Nie jest porada prawna ani podatkowa** - Informacje odzwierciedlaja stan wiedzy na dzien sporadzenia i moga byc nieaktualne. Zawsze zalecaj konsultacje z doradca podatkowym przed wdrozeniem.
- **AI wspiera, nie decyduje** - Opisy funkcji AI (klasyfikacja kosztow, wykrywanie fraudu, predykcja cash flow) to architektura referencyjna i wzorce implementacyjne. Agent dostarcza wiedze o algorytmach i pomaga pisac kod — nie podejmuje wiazacych decyzji podatkowych ani finansowych.
- **Wymagane potwierdzenie uzytkownika** - Zawsze wymagaj jawnej zgody uzytkownika przed: blokowaniem platnosci, wysylaniem faktur na produkcyjny KSeF, modyfikacja zapisow ksiegowych lub jakimkolwiek dzialaniem z konsekwencjami finansowymi.
- **Dane uwierzytelniajace zarzadzane przez uzytkownika** - Tokeny KSeF API, certyfikaty i klucze szyfrowania musza byc dostarczone przez uzytkownika przez zmienne srodowiskowe (zadeklarowane w metadanych: `KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`, `KSEF_BASE_URL`) lub menedzer sekretow. Skill nigdy nie przechowuje, nie generuje, nie przesyla ani nie prosi o dane uwierzytelniajace niejawnie. **NIGDY nie wklejaj danych uwierzytelniajacych (tokenow, kluczy, certyfikatow) bezposrednio w rozmowie z agentem** — uzyj zmiennych srodowiskowych lub menedzera sekretow platformy. Przyklady uzycia Vault/Fernet w dokumentacji referencyjnej to wzorce architektoniczne do implementacji przez uzytkownika.
- **Uzyj DEMO do testow** - Produkcja (`https://ksef.mf.gov.pl`) wystawia prawnie wiazace faktury. Uzyj DEMO (`https://ksef-demo.mf.gov.pl`) do developmentu i testow.
- **Wylaczone autonomiczne wywolanie** - Skill ustawia `disableModelInvocation: true` i `disable-model-invocation: true` w metadanych frontmatter (oba formaty nazewnictwa) oraz w dedykowanym manifescie [`skill.json`](skill.json). Oznacza to, ze model nie powinien wywolywac tego skilla autonomicznie — wymaga jawnej akcji uzytkownika. **UWAGA:** Frontmatter i `skill.json` to deklaracje — nie gwarancje. Wymuszanie zalezy od platformy. Przed uzyciem zweryfikuj, ze metadane rejestru (registry metadata) wyswietlane przez platforme rowniez pokazuja `disable-model-invocation: true`. Jesli platforma pokazuje `not set` lub `false`, flaga nie jest wymuszana i skill moze byc wywolywany autonomicznie (patrz sekcja "Model bezpieczenstwa" powyzej).
## Checklist przed instalacja
Przed instalacja skilla i konfiguracja zmiennych srodowiskowych wykonaj ponizsze kroki:
- [ ] Zweryfikuj metadane rejestru platformy — pole `disable-model-invocation` musi pokazywac `true`
- [ ] Zweryfikuj, ze platforma odczytala deklaracje env vars z frontmatter lub [`skill.json`](skill.json) — zmienne `KSEF_TOKEN` i `KSEF_ENCRYPTION_KEY` musza byc widoczne jako sekrety (`secret: true`)
- [ ] Potwierdz, ze platforma izoluje zmienne srodowiskowe (nie loguje, nie wyswietla w konwersacji)
- [ ] Przetestuj skill wylacznie ze srodowiskiem DEMO (`https://ksef-demo.mf.gov.pl`) przed jakimkolwiek uzyciem produkcyjnym
- [ ] NIE wklejaj tokenow, kluczy ani certyfikatow bezposrednio w rozmowie — uzyj env vars lub menedzera sekretow
- [ ] Jesli metadane rejestru nie pasuja do frontmatter/skill.json — NIE konfiguruj danych uwierzytelniajacych i zglos problem dostawcy platformy
## Glowne kompetencje
### 1. Obsluga KSeF 2.0 API
Wystawianie faktur FA(3), pobieranie faktur zakupowych, zarzadzanie sesjami/tokenami, obsluga trybu Offline24 (awaryjny), pobieranie UPO (Urzedowe Poswiadczenie Odbioru).
Kluczowe endpointy:
```http
POST /api/online/Session/InitToken # Inicjalizacja sesji
POST /api/online/Invoice/Send # Wyslanie faktury
GET /api/online/Invoice/Status/{ref} # Sprawdzenie statusu
POST /api/online/Query/Invoice/Sync # Zapytanie o faktury zakupowe
```
Zobacz [references/ksef-api-reference.md](references/ksef-api-reference.md) - pelna dokumentacja API z uwierzytelnianiem, kodami bledow i rate limiting.
### 2. Struktura FA(3)
Roznice FA(3) vs FA(2): zalaczniki do faktur, typ kontrahenta PRACOWNIK, rozszerzone formaty konta bankowego, limit 50 000 pozycji w korekcie, identyfikatory JST i grup VAT.
Zobacz [references/ksef-fa3-examples.md](references/ksef-fa3-examples.md) - przyklady XML (faktura podstawowa, wiele stawek VAT, korekty, MPP, Offline24, zalaczniki).
### 3. Przeplywy ksiegowe
**Sprzedaz:** Dane -> Generuj FA(3) -> Wyslij KSeF -> Pobierz nr KSeF -> Ksieguj
`Wn 300 (Rozrachunki) | Ma 700 (Sprzedaz) + Ma 220 (VAT nalezny)`
**Zakupy:** Odpytuj KSeF -> Pobierz XML -> Klasyfikuj AI -> Ksieguj
`Wn 400-500 (Koszty) + Wn 221 (VAT) | Ma 201 (Rozrachunki)`
Zobacz [references/ksef-accounting-workflows.md](references/ksef-accounting-workflows.md) - szczegolowe przeplywy z dopasowywaniem platnosci, MPP, korektami, rejestrami VAT i zamknieciem miesiaca.
### 4. Funkcje wspomagane AI (architektura referencyjna)
Ponizsze opisy to wzorce implementacyjne i architektura referencyjna. Skill NIE uruchamia modeli ML — dostarcza wiedze o algorytmach, pomaga projektowac pipeline'y i pisac kod do implementacji w systemie uzytkownika. Przyklady kodu w plikach referencyjnych (Python, sklearn, pandas) to pseudokod pogladowy — skill nie zawiera wytrenowanych modeli, artefaktow ML ani plikow wykonywalnych.
- **Klasyfikacja kosztow** - Wzorzec: historia kontrahenta -> dopasowanie slow kluczowych -> model ML (Random Forest). Flaguj do przegladu jesli confidence < 0.8.
- **Wykrywanie fraudu** - Wzorzec: Isolation Forest dla anomalii kwotowych, scoring dla phishing invoices, analiza grafow dla VAT carousel.
- **Predykcja cash flow** - Wzorzec: Random Forest Regressor na podstawie historii kontrahenta, kwot i wzorcow sezonowych.
Zobacz [references/ksef-ai-features.md](references/ksef-ai-features.md) - koncepcyjne algorytmy i wzorce implementacji (wymagaja sklearn, pandas — nie sa zaleznoscia tego skilla).
### 5. Compliance i bezpieczenstwo (wzorce implementacyjne)
Ponizsze to rekomendowane wzorce bezpieczenstwa do implementacji w systemie uzytkownika. Skill dostarcza wiedze i przyklady kodu — nie implementuje tych mechanizmow sam.
- Weryfikacja Bialej Listy VAT przed platnosciami
- Szyfrowane przechowywanie tokenow (wzorce Fernet/Vault — do implementacji przez uzytkownika)
- Audit trail wszystkich operacji
- Strategia backup 3-2-1
- Zgodnosc z RODO (anonimizacja po okresie retencji)
- RBAC (kontrola dostepu oparta na rolach)
Zobacz [references/ksef-security-compliance.md](references/ksef-security-compliance.md) - wzorce implementacji i checklista bezpieczenstwa.
### 6. Faktury korygujace
Pobierz oryginal z KSeF -> Utworz korekte FA(3) -> Powiaz z nr KSeF oryginalu -> Wyslij do KSeF -> Ksieguj storno lub roznicowo.
### 7. Rejestry VAT i JPK_V7
Generowanie rejestrow sprzedazy/zakupow (Excel/PDF), JPK_V7M (miesieczny), JPK_V7K (kwartalny).
## Troubleshooting - szybka pomoc
| Problem | Przyczyna | Rozwiazanie |
|---------|-----------|-------------|
| Faktura odrzucona (400/422) | Nieprawidlowy XML, NIP, data, brak pol | Sprawdz UTF-8, waliduj schemat FA(3), weryfikuj NIP |
| Timeout API | Awaria KSeF, siec, godziny szczytu | Sprawdz status KSeF, retry z exponential backoff |
| Nie mozna dopasowac platnosci | Niezgodna kwota, brak danych, split payment | Rozszerzone wyszukiwanie (+/-2%, +/-14 dni), sprawdz MPP |
Zobacz [references/ksef-troubleshooting.md](references/ksef-troubleshooting.md) - pelny przewodnik troubleshooting.
## Pliki referencyjne
Laduj w zaleznosci od zadania:
| Plik | Kiedy czytac |
|------|-------------|
| [skill.json](skill.json) | Manifest metadanych — flagi bezpieczenstwa, deklaracje env vars, ograniczenia. Zrodlo prawdy dla rejestrow i skanerow. |
| [ksef-api-reference.md](references/ksef-api-reference.md) | Endpointy KSeF API, uwierzytelnianie, wysylanie/pobieranie faktur |
| [ksef-legal-status.md](references/ksef-legal-status.md) | Daty wdrozenia KSeF, wymagania prawne, kary |
| [ksef-fa3-examples.md](references/ksef-fa3-examples.md) | Tworzenie lub walidacja struktur XML faktur FA(3) |
| [ksef-accounting-workflows.md](references/ksef-accounting-workflows.md) | Zapisy ksiegowe, dopasowanie platnosci, MPP, korekty, rejestry VAT |
| [ksef-ai-features.md](references/ksef-ai-features.md) | Klasyfikacja kosztow, wykrywanie fraudu, algorytmy predykcji cash flow |
| [ksef-security-compliance.md](references/ksef-security-compliance.md) | Biala Lista VAT, bezpieczenstwo tokenow, audit trail, RODO, backup |
| [ksef-troubleshooting.md](references/ksef-troubleshooting.md) | Bledy API, problemy walidacji, wydajnosc |
## Zasoby oficjalne
- Portal KSeF: https://ksef.podatki.gov.pl
- KSeF DEMO: https://ksef-demo.mf.gov.pl
- KSeF Produkcja: https://ksef.mf.gov.pl
- API Bialej Listy VAT: https://wl-api.mf.gov.pl
- KSeF Latarnia (status): https://github.com/CIRFMF/ksef-latarnia
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### skill.json
```json
{
"name": "ksef-accountant-pl",
"version": "1.0.0",
"description": "Asystent ksiegowy Krajowego Systemu e-Faktur (KSeF) — wiedza domenowa, wzorce architektoniczne i przyklady kodu. Nie zawiera kodu wykonywalnego.",
"license": "MIT",
"homepage": "https://github.com/alexwoo-awso/skills",
"source": "https://github.com/alexwoo-awso/skills/tree/main/ksef-accountant-pl",
"type": "instruction-only",
"has_executable_code": false,
"has_install_script": false,
"has_binaries": false,
"has_runtime_dependencies": false,
"security": {
"disable-model-invocation": true,
"disableModelInvocation": true,
"allow-model-invocation": false,
"allowModelInvocation": false,
"requires-user-action": true,
"instruction-only": true,
"credential-handling": "user-managed-only",
"credential-storage": "none",
"credential-transmission": "none"
},
"env": {
"KSEF_TOKEN": {
"description": "Token API KSeF do uwierzytelniania sesji. Dostarczany przez uzytkownika — skill nie generuje, nie przechowuje ani nie przesyla tokenow.",
"required": false,
"secret": true,
"scope": "session-auth"
},
"KSEF_ENCRYPTION_KEY": {
"description": "Klucz szyfrowania Fernet do bezpiecznego przechowywania tokenow. Uzycie opcjonalne — przyklad wzorca bezpieczenstwa.",
"required": false,
"secret": true,
"scope": "encryption"
},
"KSEF_BASE_URL": {
"description": "Bazowy URL API KSeF. Domyslnie https://ksef-demo.mf.gov.pl (DEMO). Produkcja wymaga jawnej zgody uzytkownika.",
"required": false,
"secret": false,
"default": "https://ksef-demo.mf.gov.pl",
"scope": "api-endpoint"
}
},
"constraints": {
"no-autonomous-execution": true,
"requires-explicit-user-consent": true,
"demo-first": true,
"production-requires-user-approval": true,
"never-store-credentials": true,
"never-transmit-credentials": true,
"never-generate-credentials": true
}
}
```
### references/ksef-api-reference.md
```markdown
# KSeF API 2.0 - Reference
**UWAGA:** Rzeczywiste punkty końcowe i formaty mogą ulec zmianie. Należy zawsze odwoływać się do oficjalnej dokumentacji API KSeF.
---
## Autentykacja
### 1. Inicjalizacja Sesji (Token)
**Endpoint:**
```http
POST /api/online/Session/InitToken
Content-Type: application/json
```
**Request:**
```json
{
"context": {
"token": "YOUR_KSEF_TOKEN_HERE"
}
}
```
**Response (200 OK):**
```json
{
"referenceNumber": "20260208-SE-1234567890AB-CD",
"timestamp": "2026-02-08T23:40:00.000Z",
"sessionToken": {
"token": "SESSION_TOKEN_VALUE",
"validity": "2026-02-09T00:10:00.000Z"
}
}
```
**Ważność tokena:** Typowo 30 minut
---
### 2. Inicjalizacja Sesji (Certyfikat)
**Endpoint:**
```http
POST /api/online/Session/InitSigned
Content-Type: application/octet-stream
```
**Request:** Signed XML Session Request (CAdES)
---
### 3. Status Sesji
**Endpoint:**
```http
GET /api/online/Session/Status/{ReferenceNumber}
Authorization: SessionToken {token}
```
**Response (200 OK):**
```json
{
"referenceNumber": "20260208-SE-1234567890AB-CD",
"timestamp": "2026-02-08T23:45:00.000Z",
"processingCode": 200,
"processingDescription": "Sesja aktywna"
}
```
---
### 4. Zamknięcie Sesji
**Endpoint:**
```http
DELETE /api/online/Session/Terminate
Authorization: SessionToken {token}
```
**Response (200 OK):**
```json
{
"referenceNumber": "20260208-ST-1234567890AB-CD",
"timestamp": "2026-02-08T23:50:00.000Z",
"processingCode": 200,
"processingDescription": "Sesja zakończona"
}
```
---
## Wysyłanie Faktur
### 5. Wysłanie Faktury
**Endpoint:**
```http
POST /api/online/Invoice/Send
Authorization: SessionToken {token}
Content-Type: application/octet-stream
```
**Request Body:** FA(3) XML Content (raw bytes)
**Response (200 OK - Przyjęto do przetworzenia):**
```json
{
"referenceNumber": "20260208-IV-1234567890AB-CD",
"timestamp": "2026-02-08T23:41:00.000Z",
"processingCode": 200,
"processingDescription": "Faktura została przyjęta do przetworzenia"
}
```
---
### 6. Status Faktury
**Endpoint:**
```http
GET /api/online/Invoice/Status/{InvoiceElementReferenceNumber}
Authorization: SessionToken {token}
```
**Możliwe statusy:**
- `200` - Przetwarzanie w toku
- `202` - Faktura zaakceptowana
- `400` - Faktura odrzucona (błędy walidacji)
**Response (202 - Zaakceptowana):**
```json
{
"referenceNumber": "20260208-IV-1234567890AB-CD",
"timestamp": "2026-02-08T23:41:30.000Z",
"processingCode": 202,
"ksefReferenceNumber": "1234567890-20260208-ABCDEF1234567890-12",
"invoiceNumber": "FV/2026/02/0008",
"acquisitionTimestamp": "2026-02-08T23:41:25.000Z"
}
```
**Response (400 - Odrzucona):**
```json
{
"referenceNumber": "20260208-IV-1234567890AB-CD",
"timestamp": "2026-02-08T23:41:15.000Z",
"processingCode": 400,
"exception": {
"exceptionDetailList": [
{
"exceptionCode": "101",
"exceptionDescription": "Błąd walidacji schematu XSD"
}
]
}
}
```
---
### 7. Pobieranie UPO
**Endpoint:**
```http
GET /api/online/Invoice/Upo/{KsefReferenceNumber}
Authorization: SessionToken {token}
Accept: application/xml
```
**Response (200 OK):** XML z urzędowym poświadczeniem odbioru
---
## Pobieranie Faktur
### 8. Wyszukiwanie Faktur (Synchroniczne)
**Endpoint:**
```http
POST /api/online/Query/Invoice/Sync
Authorization: SessionToken {token}
Content-Type: application/json
```
**Request (faktury zakupowe, zakres dat):**
```json
{
"queryCriteria": {
"type": "range",
"invoicingDateFrom": "2026-02-01",
"invoicingDateTo": "2026-02-08",
"subjectType": "subject2"
},
"pageSize": 100,
"pageOffset": 0
}
```
**QueryCriteria - typy:**
- `subjectType: "subject1"` - faktury sprzedażowe (jako sprzedawca)
- `subjectType: "subject2"` - faktury zakupowe (jako nabywca)
**Response (200 OK):**
```json
{
"referenceNumber": "20260208-QS-1234567890AB-CD",
"timestamp": "2026-02-08T23:42:00.000Z",
"invoiceHeaderList": [
{
"ksefReferenceNumber": "9876543210-20260205-ZYXWVU9876543210-01",
"invoiceNumber": "ZAKUP/123/2026",
"acquisitionTimestamp": "2026-02-05T10:30:00.000Z",
"netAmount": "5000.00",
"vatAmount": "1150.00",
"grossAmount": "6150.00",
"currencyCode": "PLN"
}
],
"numberOfElements": 1,
"pageSize": 100,
"pageOffset": 0,
"totalPages": 1,
"totalElements": 1
}
```
---
### 9. Wyszukiwanie Faktur (Asynchroniczne)
**Endpoint:**
```http
POST /api/online/Query/Invoice/Async/Init
Authorization: SessionToken {token}
Content-Type: application/json
```
**Użycie:** Dla dużych zbiorów danych (>100 faktur)
**Workflow:**
1. `POST /api/online/Query/Invoice/Async/Init` - inicjalizacja
2. `GET /api/online/Query/Invoice/Async/Status/{QueryElementReferenceNumber}` - sprawdzenie statusu
3. `GET /api/online/Query/Invoice/Async/Fetch/{QueryElementReferenceNumber}` - pobranie wyników
---
### 10. Pobieranie Pełnej Faktury
**Endpoint:**
```http
GET /api/online/Invoice/Get/{KsefReferenceNumber}
Authorization: SessionToken {token}
Accept: application/xml
```
**Response (200 OK):** Pełny XML FA(3)
---
## Tryb Offline
### 11. Wysłanie Faktury Offline
**Endpoint:**
```http
POST /api/online/Invoice/Send
Authorization: SessionToken {token}
Content-Type: application/octet-stream
```
**FA(3) XML z oznaczeniem Offline24:**
```xml
<Faktura>
<Naglowek>
<SystemInfo>Offline24</SystemInfo>
</Naglowek>
<!-- ... -->
</Faktura>
```
**Termin wysyłki:** 24h od odzyskania łączności
---
## Kody Błędów
### Najczęstsze
| Kod | Opis | Rozwiązanie |
|-----|------|-------------|
| 100 | Nieprawidłowy format XML | Sprawdź encoding UTF-8 |
| 101 | Błąd walidacji schematu | Upewnij się że używasz FA(3) |
| 102 | Nieprawidłowy NIP | Sprawdź w białej liście VAT |
| 103 | Data w przyszłości | Skoryguj DataWytworzeniaFa |
| 104 | Duplikat numeru faktury | Sprawdź unikalność |
| 401 | Brak autoryzacji | Sesja wygasła, odśwież token |
| 403 | Brak uprawnień | Sprawdź uprawnienia tokena |
| 500 | Błąd serwera | Retry z exponential backoff |
| 503 | Serwis niedostępny | Sprawdź status KSeF (Latarnia) |
---
## Rate Limiting
**UWAGA:** Szczegóły mogą się różnić. Sprawdź aktualną dokumentację.
**Typowe limity (szacunkowe):**
- Sesje: ~100 sesji/godzinę na token
- Faktury: ~1000 faktur/godzinę na sesję
- Queries: ~100 zapytań/godzinę na sesję
**Best practices:**
- Używaj pojedynczej sesji dla wielu faktur
- Implementuj exponential backoff przy 429/503
- Cachuj wyniki queries (nie odpytuj co sekundę)
---
## Środowiska
### DEMO (testowe)
```
Base URL: https://ksef-demo.mf.gov.pl
Przeznaczenie: Testy integracji, development
Dane: Testowe (nie produkcyjne)
```
### PRODUKCJA
```
Base URL: https://ksef.mf.gov.pl
Przeznaczenie: Faktury produkcyjne
Dane: Prawne wiążące
```
**UWAGA:** NIE testuj na produkcji! Zawsze używaj DEMO do developmentu.
---
## Przykładowy Workflow
```python
# 1. Inicjalizacja sesji
session = ksef_client.init_session(token="YOUR_TOKEN")
# 2. Wysłanie faktury
invoice_xml = generate_fa3_xml(invoice_data)
ref = ksef_client.send_invoice(session, invoice_xml)
# 3. Sprawdzenie statusu (z retry)
for i in range(10):
status = ksef_client.get_invoice_status(session, ref)
if status.code == 202:
ksef_number = status.ksefReferenceNumber
break
elif status.code == 400:
handle_rejection(status.exception)
break
time.sleep(2) # Czekaj 2s przed następnym sprawdzeniem
# 4. Pobranie UPO
upo_xml = ksef_client.get_upo(session, ksef_number)
# 5. Zamknięcie sesji
ksef_client.terminate_session(session)
```
---
**Oficjalna dokumentacja:** https://ksef.mf.gov.pl/api/docs
```
### references/ksef-fa3-examples.md
```markdown
# Przykłady FA(3) XML
**UWAGA:** Wszystkie przykłady mają charakter wyłącznie poglądowy i uproszczony. Nie stanowią gwarancji poprawnej walidacji względem schematu XSD. Przed użyciem w środowisku produkcyjnym należy zweryfikować zgodność z aktualną specyfikacją techniczną FA(3) oraz przeprowadzić testy walidacji.
---
## Podstawowa Faktura VAT
```xml
<?xml version="1.0" encoding="UTF-8"?>
<Faktura xmlns="http://crd.gov.pl/wzor/2023/06/29/12648/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Naglowek>
<KodFormularza kodSystemowy="FA(3)" wersjaSchemy="1-0E">FA</KodFormularza>
<WariantFormularza>3</WariantFormularza>
<DataWytworzeniaFa>2026-02-08T14:30:00</DataWytworzeniaFa>
<SystemInfo>Autonomous KSeF Agent v2.1</SystemInfo>
</Naglowek>
<!-- Sprzedawca -->
<Podmiot1>
<DaneIdentyfikacyjne>
<NIP>1234567890</NIP>
<Nazwa>Moja Firma Sp. z o.o.</Nazwa>
</DaneIdentyfikacyjne>
<Adres>
<KodKraju>PL</KodKraju>
<AdresL1>ul. Przykładowa 1</AdresL1>
<AdresL2>00-001 Warszawa</AdresL2>
</Adres>
</Podmiot1>
<!-- Nabywca -->
<Podmiot2>
<DaneIdentyfikacyjne>
<NIP>0987654321</NIP>
<Nazwa>Klient Sp. z o.o.</Nazwa>
</DaneIdentyfikacyjne>
<Adres>
<KodKraju>PL</KodKraju>
<AdresL1>ul. Testowa 10</AdresL1>
<AdresL2>02-222 Kraków</AdresL2>
</Adres>
</Podmiot2>
<!-- Dane faktury -->
<Fa>
<KodWaluty>PLN</KodWaluty>
<P_1>2026-02-08</P_1> <!-- Data wystawienia -->
<P_2>FV/2026/02/0008</P_2> <!-- Numer faktury -->
<P_6>2026-02-08</P_6> <!-- Data sprzedaży -->
<!-- Pozycje faktury -->
<FaWiersz>
<NrWierszaFa>1</NrWierszaFa>
<P_7>Usługa programistyczna</P_7>
<P_8A>godz.</P_8A>
<P_8B>100</P_8B>
<P_9A>100.00</P_9A>
<P_11>10000.00</P_11> <!-- Wartość netto -->
<P_12>23</P_12> <!-- Stawka VAT -->
</FaWiersz>
<!-- Podsumowanie -->
<P_13_1>10000.00</P_13_1> <!-- Netto 23% -->
<P_14_1>2300.00</P_14_1> <!-- VAT 23% -->
<P_15>12300.00</P_15> <!-- Brutto -->
<RodzajFaktury>VAT</RodzajFaktury>
<!-- Płatność -->
<Platnosc>
<Zaplacono>0</Zaplacono>
<DataZaplaty>2026-02-22</DataZaplaty>
<FormaPlatnosci>6</FormaPlatnosci> <!-- Przelew -->
<RachunekBankowy>12 3456 7890 1234 5678 9012 3456</RachunekBankowy>
</Platnosc>
</Fa>
</Faktura>
```
---
## Faktura z Wieloma Pozycjami i Stawkami VAT
```xml
<Fa>
<KodWaluty>PLN</KodWaluty>
<P_1>2026-02-09</P_1>
<P_2>FV/2026/02/0009</P_2>
<P_6>2026-02-09</P_6>
<!-- Pozycja 1: VAT 23% -->
<FaWiersz>
<NrWierszaFa>1</NrWierszaFa>
<P_7>Laptop Dell XPS 15</P_7>
<P_8A>szt.</P_8A>
<P_8B>2</P_8B>
<P_9A>5000.00</P_9A>
<P_11>10000.00</P_11>
<P_12>23</P_12>
</FaWiersz>
<!-- Pozycja 2: VAT 8% -->
<FaWiersz>
<NrWierszaFa>2</NrWierszaFa>
<P_7>Książki techniczne</P_7>
<P_8A>szt.</P_8A>
<P_8B>10</P_8B>
<P_9A>50.00</P_9A>
<P_11>500.00</P_11>
<P_12>8</P_12>
</FaWiersz>
<!-- Pozycja 3: VAT 0% (eksport) -->
<FaWiersz>
<NrWierszaFa>3</NrWierszaFa>
<P_7>Usługi konsultingowe (eksport)</P_7>
<P_8A>godz.</P_8A>
<P_8B>40</P_8B>
<P_9A>200.00</P_9A>
<P_11>8000.00</P_11>
<P_12>0</P_12>
</FaWiersz>
<!-- Podsumowanie -->
<P_13_1>10000.00</P_13_1> <!-- Netto 23% -->
<P_14_1>2300.00</P_14_1> <!-- VAT 23% -->
<P_13_2>500.00</P_13_2> <!-- Netto 8% -->
<P_14_2>40.00</P_14_2> <!-- VAT 8% -->
<P_13_3>8000.00</P_13_3> <!-- Netto 0% -->
<P_15>20840.00</P_15> <!-- Brutto -->
<RodzajFaktury>VAT</RodzajFaktury>
</Fa>
```
---
## Faktura Korygująca
```xml
<Fa>
<P_2>FV/2026/02/0005/K01</P_2> <!-- Numer korekty -->
<RodzajFaktury>KOREKTA</RodzajFaktury>
<PrzyczynaKorekty>Błąd w cenie jednostkowej</PrzyczynaKorekty>
<!-- Dane faktury korygowanej -->
<DaneFaKorygowanej>
<DataWystFaKorygowanej>2026-02-05</DataWystFaKorygowanej>
<NrFaKorygowanej>FV/2026/02/0005</NrFaKorygowanej>
<NrKSeFFaKorygowanej>1234567890-20260205-ORIGINAL123456-12</NrKSeFFaKorygowanej>
</DaneFaKorygowanej>
<!-- Dane PRZED korektą -->
<FaWierszCtrl>
<LiczbaWierszyFa>1</LiczbaWierszyFa>
<WartoscWierszyFa>12300.00</WartoscWierszyFa>
</FaWierszCtrl>
<!-- Dane PO korekcie -->
<FaWiersz>
<NrWierszaFa>1</NrWierszaFa>
<P_7>Usługa programistyczna (cena skorygowana)</P_7>
<P_8A>godz.</P_8A>
<P_8B>100</P_8B>
<P_9A>50.00</P_9A> <!-- Nowa cena: 50 zamiast 100 -->
<P_11>5000.00</P_11>
<P_12>23</P_12>
</FaWiersz>
<!-- Nowe podsumowanie -->
<P_13_1>5000.00</P_13_1>
<P_14_1>1150.00</P_14_1>
<P_15>6150.00</P_15>
</Fa>
```
---
## Faktura z Kontrahent PRACOWNIK (Delegacja)
**Nowość FA(3):** Nowy typ kontrahenta do rozliczania delegacji
```xml
<Podmiot2>
<DaneIdentyfikacyjne>
<TypPodmiotu>PRACOWNIK</TypPodmiotu>
<PESEL>85010112345</PESEL>
<ImieNazwisko>Jan Kowalski</ImieNazwisko>
</DaneIdentyfikacyjne>
<Adres>
<KodKraju>PL</KodKraju>
<AdresL1>ul. Pracownicza 5</AdresL1>
<AdresL2>03-333 Warszawa</AdresL2>
</Adres>
</Podmiot2>
<Fa>
<P_2>DEL/2026/02/001</P_2>
<FaWiersz>
<P_7>Rozliczenie delegacji - luty 2026</P_7>
<P_8A>dni</P_8A>
<P_8B>5</P_8B>
<P_9A>150.00</P_9A>
<P_11>750.00</P_11>
<P_12>zw</P_12> <!-- VAT zwolniony -->
</FaWiersz>
<RodzajFaktury>VAT</RodzajFaktury>
</Fa>
```
---
## Faktura Trybu Offline24
```xml
<Naglowek>
<KodFormularza kodSystemowy="FA(3)" wersjaSchemy="1-0E">FA</KodFormularza>
<WariantFormularza>3</WariantFormularza>
<DataWytworzeniaFa>2026-02-10T08:00:00</DataWytworzeniaFa>
<SystemInfo>Offline24</SystemInfo> <!-- Oznaczenie offline -->
</Naglowek>
```
**Uwaga:** Wysłać do KSeF w ciągu 24h od odzyskania łączności. Data odbioru = data przypisania numeru KSeF.
---
## Faktura z Załącznikami
**Nowość FA(3):** Możliwość dołączenia załączników
```xml
<Fa>
<!-- Standardowe dane faktury -->
<P_2>FV/2026/02/0010</P_2>
<!-- Załączniki -->
<Zalaczniki>
<Zalacznik>
<NazwaPliku>specyfikacja_techniczna.pdf</NazwaPliku>
<TypZalacznika>SPECYFIKACJA</TypZalacznika>
<RozmiarKB>256</RozmiarKB>
<HashSHA256>a1b2c3d4e5f6...</HashSHA256>
</Zalacznik>
<Zalacznik>
<NazwaPliku>protokol_dostawy.pdf</NazwaPliku>
<TypZalacznika>PROTOKOL</TypZalacznika>
<RozmiarKB>128</RozmiarKB>
<HashSHA256>f6e5d4c3b2a1...</HashSHA256>
</Zalacznik>
</Zalaczniki>
</Fa>
```
---
## Faktura z MPP (Mechanizm Podzielonej Płatności)
```xml
<Fa>
<P_2>FV/2026/02/0011</P_2>
<FaWiersz>
<P_7>Stal konstrukcyjna (załącznik 15)</P_7>
<P_8A>kg</P_8A>
<P_8B>1000</P_8B>
<P_9A>20.00</P_9A>
<P_11>20000.00</P_11>
<P_12>23</P_12>
<OznaczenieMPP>1</OznaczenieMPP> <!-- Wymaga MPP -->
</FaWiersz>
<P_13_1>20000.00</P_13_1>
<P_14_1>4600.00</P_14_1>
<P_15>24600.00</P_15>
<Platnosc>
<TypPlatnosci>MPP</TypPlatnosci>
<RachunekBankowy>12 3456 7890 1234 5678 9012 3456</RachunekBankowy>
<RachunekBankowyVAT>98 7654 3210 9876 5432 1098 7654</RachunekBankowyVAT>
</Platnosc>
</Fa>
```
---
## Walidacja przed Wysłaniem
```python
def validate_fa3_before_send(xml_content):
"""
Podstawowa walidacja przed wysłaniem do KSeF
"""
checks = []
# 1. UTF-8 encoding
try:
xml_content.encode('utf-8')
checks.append(('Encoding UTF-8', True))
except:
checks.append(('Encoding UTF-8', False))
# 2. Parsowanie XML
try:
root = ET.fromstring(xml_content)
checks.append(('Poprawny XML', True))
except:
checks.append(('Poprawny XML', False))
return checks
# 3. Namespace
if 'http://crd.gov.pl/wzor/2023/06/29/12648/' in xml_content:
checks.append(('Namespace FA(3)', True))
else:
checks.append(('Namespace FA(3)', False))
# 4. Wersja schematu
if 'wersjaSchemy="1-0E"' in xml_content:
checks.append(('Wersja schematu 1-0E', True))
else:
checks.append(('Wersja schematu 1-0E', False))
# 5. Wymagane pola
required = ['KodFormularza', 'P_1', 'P_2', 'P_15', 'NIP']
for field in required:
if f'<{field}' in xml_content or f'<{field}>' in xml_content:
checks.append((f'Pole {field}', True))
else:
checks.append((f'Pole {field}', False))
return checks
```
---
**Oficjalna dokumentacja FA(3):**
https://ksef.podatki.gov.pl/media/4u1bmhx4/information-sheet-on-the-fa-3-logical-structure.pdf
```
### references/ksef-accounting-workflows.md
```markdown
# Przepływy Księgowe KSeF
**UWAGA:** Przykłady mają charakter poglądowy i mogą wymagać dostosowania do specyfiki działalności.
---
## Workflow Faktury Sprzedaży
### Proces Kompletny
```mermaid
graph LR
A[Dane faktury] --> B[Generuj FA3 XML]
B --> C[Wyślij do KSeF]
C --> D[Czekaj na status]
D --> E{Akceptacja?}
E -->|Tak| F[Pobierz numer KSeF]
E -->|Nie| G[Analiza błędów]
F --> H[Zapis księgowy]
H --> I[Generuj PDF/email]
G --> J[Popraw XML]
J --> B
```
### Zapis Księgowy
**Przykład: Faktura sprzedaży usług**
```
FV/2026/02/0008 (KSeF: 1234567890-20260208-ABCDEF1234567890-12)
Data sprzedaży: 08.02.2026
Nabywca: Klient Sp. z o.o. (NIP: 0987654321)
Wn 300 Rozrachunki z odbiorcami 12 300,00 PLN
Ma 700 Sprzedaż usług 10 000,00 PLN
Ma 220 VAT należny 2 300,00 PLN
Opis: Usługi programistyczne - 100 godz. @ 100 PLN
```
**Przykład: Faktura sprzedaży towarów**
```
FV/2026/02/0009 (KSeF: 1234567890-20260209-BCDEFG2345678901-13)
Data sprzedaży: 09.02.2026
Wn 300 Rozrachunki 24 600,00 PLN
Ma 701 Sprzedaż towarów 20 000,00 PLN
Ma 220 VAT należny (23%) 4 600,00 PLN
Wn 701 Sprzedaż towarów 15 000,00 PLN
Ma 330 Wartość sprzedanych towarów 15 000,00 PLN
(Rozchód magazynowy)
```
---
## Workflow Faktury Zakupowej
### Proces Kompletny
```mermaid
graph LR
A[Cron: co 15 min] --> B[Odpytaj KSeF]
B --> C{Nowe faktury?}
C -->|Tak| D[Pobierz XML]
C -->|Nie| A
D --> E[Parsuj dane]
E --> F[Klasyfikuj koszt AI]
F --> G{Confidence > 0.8?}
G -->|Tak| H[Auto-księguj]
G -->|Nie| I[Flag do review]
H --> J[Zapisz do bazy]
I --> J
```
### Zapis Księgowy
**Przykład: Zakup usług IT**
```
ZAKUP/123/2026 (KSeF: 9876543210-20260205-ZYXWVU9876543210-01)
Data otrzymania: 05.02.2026
Sprzedawca: IT Solutions Sp. z o.o. (NIP: 1122334455)
Kategoria: 402 (Usługi informatyczne) - AI confidence: 0.95
Wn 402 Usługi informatyczne 5 000,00 PLN
Wn 221 VAT naliczony (23%) 1 150,00 PLN
Ma 201 Rozrachunki z dostawcami 6 150,00 PLN
Opis: Hosting i wsparcie techniczne - styczeń 2026
```
**Przykład: Zakup materiałów biurowych**
```
ZAKUP/124/2026 (KSeF: 9876543210-20260206-ZYXWVU9876543211-02)
Kategoria: 502 (Materiały biurowe) - AI confidence: 0.88
Wn 502 Materiały biurowe 500,00 PLN
Wn 221 VAT naliczony (23%) 115,00 PLN
Ma 201 Rozrachunki z dostawcami 615,00 PLN
```
---
## Dopasowywanie Płatności
### Algorytm Scoring
```python
def match_payment_to_invoice(payment, open_invoices):
matches = []
for invoice in open_invoices:
score = 0
# 1. Dokładna kwota brutto (+/- 0.01 PLN)
if abs(payment.amount - invoice.total_gross) < 0.01:
score += 40
# 2. NIP w tytule przelewu
if invoice.seller_nip in payment.title.replace(' ', ''):
score += 30
# 3. Numer faktury w tytule
if invoice.number in payment.title:
score += 20
# 4. Data w zakresie (termin płatności +/- 7 dni)
days_diff = abs((payment.date - invoice.payment_due).days)
if days_diff <= 7:
score += 10 - days_diff
# 5. Numer KSeF w tytule
if invoice.ksef_number and invoice.ksef_number in payment.title:
score += 25
if score >= 70:
matches.append({
'invoice': invoice,
'score': score,
'confidence': score / 100
})
return sorted(matches, key=lambda x: x['score'], reverse=True)
```
### Zapis Księgowy - Płatność
**Przykład: Płatność faktury zakupowej**
```
Płatność: 6 150,00 PLN
Tytuł: "ZAKUP/123/2026 NIP 1122334455"
Data: 15.02.2026
Matched: ZAKUP/123/2026 (score: 90, confidence: 0.90)
Wn 201 Rozrachunki z dostawcami 6 150,00 PLN
Ma 130 Rachunek bieżący 6 150,00 PLN
Opis: Zapłata faktury ZAKUP/123/2026
```
**Przykład: Płatność faktury sprzedażowej**
```
Wpłata: 12 300,00 PLN
Tytuł: "FV/2026/02/0008"
Data: 20.02.2026
Matched: FV/2026/02/0008 (score: 85)
Wn 130 Rachunek bieżący 12 300,00 PLN
Ma 300 Rozrachunki z odbiorcami 12 300,00 PLN
Opis: Wpłata za FV/2026/02/0008
```
---
## Mechanizm Podzielonej Płatności (MPP)
### Warunki (zgodnie z obecnymi przepisami)
- Faktury >15 000 PLN brutto
- Towary/usługi z załącznika 15 do ustawy VAT
### Implementacja
```python
def handle_split_payment(invoice):
if invoice.total_gross > 15000 and invoice.has_attachment_15_goods:
net_payment = invoice.total_net
vat_payment = invoice.total_vat
# Przelew 1: Część netto
bank_transfer_1 = {
'to_account': invoice.seller_account,
'amount': net_payment,
'title': f'Faktura {invoice.number} (część netto)'
}
# Przelew 2: VAT na specjalne konto VAT
bank_transfer_2 = {
'to_account': invoice.seller_vat_account,
'amount': vat_payment,
'title': f'Faktura {invoice.number} (VAT - split payment)'
}
return [bank_transfer_1, bank_transfer_2]
```
### Zapis Księgowy
**Przykład: MPP - część netto**
```
Wn 201 Rozrachunki z dostawcami 20 000,00 PLN
Ma 130 Rachunek bieżący 20 000,00 PLN
Opis: Zapłata netto - MPP - ZAKUP/200/2026
```
**Przykład: MPP - część VAT**
```
Wn 201 Rozrachunki z dostawcami 4 600,00 PLN
Ma 130 Rachunek bieżący 4 600,00 PLN
Opis: Zapłata VAT na konto VAT - MPP - ZAKUP/200/2026
```
---
## Faktury Korygujące
### Proces Korekty
```mermaid
graph TD
A[Potrzeba korekty] --> B[Pobierz oryginał z KSeF]
B --> C[Utwórz FA3 korekty]
C --> D[Powiąż z nr KSeF oryginału]
D --> E[Wyślij do KSeF]
E --> F[Otrzymaj nr KSeF korekty]
F --> G{Metoda księgowania?}
G -->|Storno| H[Storno + Nowa]
G -->|Różnicowa| I[Tylko różnica]
```
### Metoda Storno
**Oryginał:**
```
FV/2026/02/0005 (KSeF: 1234567890-20260205-ORIGINAL123456-12)
Kwota: 12 300,00 PLN (netto: 10 000,00, VAT: 2 300,00)
Wn 300 Rozrachunki 12 300,00
Ma 700 Sprzedaż 10 000,00
Ma 220 VAT należny 2 300,00
```
**Storno oryginału:**
```
FV/2026/02/0005/K01 (Korekta - storno)
Data korekty: 08.02.2026
Przyczyna: Błąd w cenie jednostkowej
Wn 700 Sprzedaż 10 000,00 (czerwone)
Wn 220 VAT należny 2 300,00 (czerwone)
Ma 300 Rozrachunki 12 300,00 (czerwone)
```
**Nowa wartość:**
```
FV/2026/02/0005/K01 (Korekta - nowa wartość)
Wn 300 Rozrachunki 6 150,00
Ma 700 Sprzedaż 5 000,00
Ma 220 VAT należny 1 150,00
```
**Efekt netto:** Zmniejszenie sprzedaży o 5 000 PLN netto, VAT o 1 150 PLN
---
### Metoda Różnicowa
**Korekta (tylko różnica):**
```
FV/2026/02/0005/K01 (KSeF: 1234567890-20260208-CORRECT234567-13)
Różnica: -6 150,00 PLN
Wn 700 Sprzedaż 5 000,00 (czerwone)
Wn 220 VAT należny 1 150,00 (czerwone)
Ma 300 Rozrachunki 6 150,00 (czerwone)
```
---
## Rejestry VAT
### Rejestr Sprzedaży (Generowanie)
```python
def generate_sales_register(period_start, period_end):
invoices = ksef_client.query_invoices(
date_from=period_start,
date_to=period_end,
subject_type='subject1' # sprzedawca
)
register = []
for invoice in invoices:
register.append({
'lp': invoice.ordinal,
'data_wystawienia': invoice.issue_date,
'data_sprzedazy': invoice.sale_date,
'numer_faktury': invoice.number,
'numer_ksef': invoice.ksef_number,
'nabywca_nazwa': invoice.buyer_name,
'nabywca_nip': invoice.buyer_nip,
'netto_23': invoice.net_23,
'vat_23': invoice.vat_23,
'netto_8': invoice.net_8,
'vat_8': invoice.vat_8,
'netto_5': invoice.net_5,
'vat_5': invoice.vat_5,
'netto_0': invoice.net_0,
'netto_zw': invoice.net_exempt,
'brutto': invoice.total_gross
})
export_to_excel(register, f'Rejestr_sprzedazy_{period_start}_{period_end}.xlsx')
return register
```
### Rejestr Zakupów (Generowanie)
```python
def generate_purchase_register(period_start, period_end):
invoices = ksef_client.query_invoices(
date_from=period_start,
date_to=period_end,
subject_type='subject2' # nabywca
)
register = []
for invoice in invoices:
register.append({
'lp': invoice.ordinal,
'data_otrzymania': invoice.acquisition_date,
'data_wystawienia': invoice.issue_date,
'numer_faktury': invoice.number,
'numer_ksef': invoice.ksef_number,
'sprzedawca_nazwa': invoice.seller_name,
'sprzedawca_nip': invoice.seller_nip,
'kategoria': invoice.category, # AI classification
'netto': invoice.net_amount,
'vat': invoice.vat_amount,
'brutto': invoice.total_gross
})
export_to_excel(register, f'Rejestr_zakupow_{period_start}_{period_end}.xlsx')
return register
```
---
## Zamknięcie Miesiąca
### Checklist
**Przed zamknięciem:**
- [ ] Wszystkie faktury sprzedaży wysłane do KSeF
- [ ] Wszystkie faktury zakupowe pobrane z KSeF
- [ ] Wszystkie płatności dopasowane
- [ ] Korekty zaksięgowane
- [ ] Rejestr sprzedaży wygenerowany
- [ ] Rejestr zakupów wygenerowany
- [ ] Bilans otwarć/zamknięć kont rozrachunkowych
- [ ] JPK_V7M wygenerowany
- [ ] Deklaracja VAT-7 przygotowana
**Zapisy zamykające miesiąc:**
```
# Rozliczenie VAT
Wn 220 VAT należny 28 750,00
Ma 221 VAT naliczony 17 250,00
Ma 225 VAT do zapłaty 11 500,00
# Płatność VAT
Wn 225 VAT do zapłaty 11 500,00
Ma 130 Rachunek bieżący 11 500,00
```
---
**Zobacz również:**
- [Funkcje AI - Klasyfikacja](ksef-ai-features.md#klasyfikacja)
- [Przykłady JPK_V7](ksef-jpk-examples.md)
```
### references/ksef-ai-features.md
```markdown
# Funkcje AI dla KSeF
**UWAGA OGÓLNA:** Cały kod w tym dokumencie to **koncepcyjna architektura referencyjna** — wzorce implementacyjne do adaptacji przez użytkownika w jego własnym systemie. Ten skill NIE uruchamia modeli ML, NIE wykonuje inferencji i NIE wymaga runtime'ów Python, sklearn, pandas ani żadnych innych zależności. Agent korzysta z tych wzorców wyłącznie jako bazy wiedzy do wyjaśniania algorytmów, projektowania pipeline'ów i pomocy w pisaniu kodu.
**Zależności wymagane do implementacji (NIE zależności tego skilla):** sklearn, pandas, numpy — do zainstalowania przez użytkownika w jego środowisku.
Wszystkie funkcje AI/ML mają charakter wspierający i wymagają nadzoru personelu księgowego. Wskaźniki wydajności są celami projektowymi i mogą się różnić. Systemy AI nie podejmują wiążących decyzji podatkowych.
---
## Klasyfikacja Kosztów
### Algorytm (wysokopoziomowy)
```python
def classify_expense(invoice_data):
"""
Klasyfikacja kosztu na podstawie wielu źródeł danych
"""
features = {
'seller_name': invoice_data.seller_name,
'item_names': [item.name for item in invoice_data.items],
'pkwiu_codes': [item.pkwiu for item in invoice_data.items if item.pkwiu],
'total_amount': invoice_data.total_gross,
'seller_nip': invoice_data.seller_nip
}
# 1. Historia z kontrahentem (najwyższy priorytet)
historical = get_historical_category(features['seller_nip'])
if historical and historical.confidence > 0.9:
return historical.category, historical.confidence
# 2. Dopasowanie słów kluczowych
keyword_match = match_keywords(features['item_names'])
if keyword_match and keyword_match.confidence > 0.85:
return keyword_match.category, keyword_match.confidence
# 3. Model ML (Random Forest / Neural Network)
ml_prediction = ml_model.predict(features)
# 4. Flagowanie do review jeśli niska pewność
if ml_prediction.confidence < 0.8:
flag_for_manual_review(invoice_data)
return ml_prediction.category, ml_prediction.confidence
```
### Kategorie Kosztów (Przykładowe)
```python
COST_CATEGORIES = {
# Usługi obce
400: "Usługi obce (ogólne)",
401: "Usługi transportowe",
402: "Usługi informatyczne (hosting, development, IT support)",
403: "Usługi prawne i doradcze",
404: "Usługi najmu i dzierżawy",
405: "Usługi marketingowe i reklamowe",
406: "Usługi księgowe",
407: "Usługi konsultingowe",
# Materiały i surowce
500: "Materiały i surowce (ogólne)",
501: "Energia, woda, paliwo",
502: "Materiały biurowe",
503: "Części zamienne",
# Inne
600: "Wynagrodzenia i pochodne",
700: "Amortyzacja",
}
```
### Słowa Kluczowe (Przykłady)
```python
KEYWORDS = {
402: ["hosting", "server", "cloud", "AWS", "Azure", "development",
"programowanie", "IT support", "software", "licencja"],
405: ["reklama", "marketing", "Google Ads", "Facebook Ads",
"social media", "SEO", "content"],
501: ["energia", "prąd", "gaz", "woda", "paliwo", "benzyna"],
502: ["papier", "długopis", "toner", "biuro", "artykuły"],
}
```
### Trenowanie Modelu ML
```python
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_extraction.text import TfidfVectorizer
class ExpenseClassifier:
def __init__(self):
self.model = RandomForestClassifier(n_estimators=200, random_state=42)
self.vectorizer = TfidfVectorizer(max_features=500)
def train(self, historical_invoices):
"""
Trenowanie na danych historycznych
"""
# Przygotuj dane
X_text = [
f"{inv.seller_name} {' '.join(inv.item_names)}"
for inv in historical_invoices
]
X_vectors = self.vectorizer.fit_transform(X_text)
y = [inv.category for inv in historical_invoices]
# Trenuj model
self.model.fit(X_vectors, y)
def predict(self, invoice):
"""
Predykcja kategorii
"""
X_text = f"{invoice.seller_name} {' '.join(invoice.item_names)}"
X_vector = self.vectorizer.transform([X_text])
prediction = self.model.predict(X_vector)[0]
probabilities = self.model.predict_proba(X_vector)[0]
confidence = max(probabilities)
return {
'category': prediction,
'confidence': confidence,
'alternatives': self._get_alternatives(probabilities)
}
```
---
## Wykrywanie Anomalii i Fraudu
### Detekcja Anomalii (Isolation Forest)
```python
from sklearn.ensemble import IsolationForest
import numpy as np
class FraudDetector:
def __init__(self):
self.model = IsolationForest(contamination=0.05, random_state=42)
self.is_trained = False
def extract_features(self, invoice):
"""Ekstrakcja cech do analizy"""
return np.array([
invoice.total_gross,
len(invoice.items),
invoice.items_avg_price,
invoice.payment_term_days,
invoice.hour_of_day, # 0-23
int(invoice.is_weekend), # 0 lub 1
invoice.seller_transaction_count,
invoice.seller_avg_amount,
invoice.amount_vs_avg_ratio # aktualna / średnia
])
def train(self, historical_invoices):
"""Trenowanie na danych historycznych"""
features = [self.extract_features(inv) for inv in historical_invoices]
self.model.fit(features)
self.is_trained = True
def detect(self, invoice):
"""Wykrycie anomalii"""
if not self.is_trained:
return {'anomaly': False, 'reason': 'Model nie wytrenowany'}
features = self.extract_features(invoice)
prediction = self.model.predict([features])[0]
if prediction == -1: # Anomalia
return {
'anomaly': True,
'risk_level': 'HIGH',
'reasons': self._analyze_reasons(invoice),
'action': 'MANUAL_REVIEW_REQUIRED'
}
return {'anomaly': False}
def _analyze_reasons(self, invoice):
"""Analiza przyczyn anomalii"""
reasons = []
if invoice.total_gross > invoice.seller_avg_amount * 3:
reasons.append("Kwota 3x większa niż średnia od tego sprzedawcy")
if invoice.is_weekend and invoice.hour_of_day < 6:
reasons.append("Wystawiona w nocy w weekend (nietypowe)")
if invoice.seller_transaction_count == 1:
reasons.append("Pierwszy kontakt z tym sprzedawcą")
if invoice.payment_term_days < 3:
reasons.append("Bardzo krótki termin płatności (możliwy phishing)")
return reasons
```
### Detekcja Phishing Invoices
```python
def detect_phishing_invoice(invoice):
"""
Wykrywa potencjalne faktury phishingowe
"""
score = 0
reasons = []
# 1. Podobna nazwa do znanego kontrahenta
similar = find_similar_contractor_names(invoice.seller_name)
for known_contractor in similar:
if known_contractor.nip != invoice.seller_nip:
score += 30
reasons.append(f"Podobna nazwa do {known_contractor.name} ale inny NIP")
if known_contractor.bank_account != invoice.bank_account:
score += 40
reasons.append("Inne konto bankowe niż znany kontrahent")
# 2. Krótki termin płatności
if invoice.payment_term_days <= 2:
score += 20
reasons.append("Bardzo krótki termin płatności (typowe dla phishingu)")
# 3. Pierwszy kontakt
if get_transaction_count(invoice.seller_nip) == 0:
score += 10
reasons.append("Pierwszy raz od tego sprzedawcy")
# 4. Wysoka kwota przy pierwszym kontakcie
if score > 0 and invoice.total_gross > 10000:
score += 15
reasons.append("Wysoka kwota przy pierwszym/podejrzanym kontakcie")
if score >= 50:
return {
'phishing_detected': True,
'risk': 'CRITICAL',
'score': score,
'reasons': reasons,
'action': 'BLOCK_PAYMENT_AND_VERIFY'
}
return {'phishing_detected': False}
```
### Detekcja VAT Carousel
```python
def detect_vat_carousel(invoices, time_window_days=30):
"""
Wykrywa potencjalne wzorce karuzeli VAT
"""
# Buduj graf transakcji
graph = build_transaction_graph(invoices)
# Szukaj cykli (A → B → C → A)
cycles = find_cycles(graph)
suspicious = []
for cycle in cycles:
# Sprawdź podejrzane cechy
if is_suspicious_cycle(cycle):
suspicious.append({
'cycle': cycle,
'risk': 'CRITICAL',
'participants': [node.nip for node in cycle],
'total_value': sum(edge.amount for edge in cycle),
'time_span_days': get_cycle_duration(cycle),
'action': 'REPORT_TO_TAX_OFFICE'
})
return suspicious
def is_suspicious_cycle(cycle):
"""Czy cykl jest podejrzany?"""
# 1. Cykl zamyka się w <30 dni
if get_cycle_duration(cycle) > 30:
return False
# 2. Kwoty podobne (±10%)
amounts = [edge.amount for edge in cycle]
if max(amounts) / min(amounts) > 1.1:
return False
# 3. Ten sam towar/usługa
items = [edge.item_description for edge in cycle]
if not all_similar(items):
return False
return True
```
---
## Predykcja Cash Flow
### Model Predykcyjny
```python
from sklearn.ensemble import RandomForestRegressor
import pandas as pd
class CashFlowPredictor:
def __init__(self):
self.model = RandomForestRegressor(n_estimators=100, random_state=42)
def prepare_training_data(self, historical_data):
"""
Przygotowanie danych treningowych
DataFrame z kolumnami:
- invoice_due_date, invoice_amount, contractor_nip
- payment_term_days, actual_payment_date, days_late
"""
X = historical_data[[
'invoice_amount',
'payment_term_days',
'contractor_avg_days_late',
'contractor_payment_reliability', # % w terminie
'month',
'is_end_of_quarter'
]]
y = historical_data['days_late']
return X, y
def train(self, historical_data):
X, y = self.prepare_training_data(historical_data)
self.model.fit(X, y)
def predict_payment_date(self, invoice):
"""Przewiduj rzeczywistą datę płatności"""
contractor_stats = get_contractor_stats(invoice.buyer_nip)
features = pd.DataFrame([{
'invoice_amount': invoice.total_gross,
'payment_term_days': invoice.payment_term_days,
'contractor_avg_days_late': contractor_stats['avg_days_late'],
'contractor_payment_reliability': contractor_stats['reliability'],
'month': invoice.issue_date.month,
'is_end_of_quarter': invoice.issue_date.month in [3, 6, 9, 12]
}])
predicted_days_late = self.model.predict(features)[0]
predicted_date = invoice.payment_due_date + timedelta(days=int(predicted_days_late))
return {
'predicted_payment_date': predicted_date,
'expected_days_late': int(predicted_days_late),
'confidence': self._calculate_confidence(features)
}
def predict_monthly_cash_flow(self, year, month):
"""Prognoza miesięczna"""
# Faktury sprzedaży z terminem w tym miesiącu
sales_invoices = get_invoices_due_in_month(year, month, type='sales')
predicted_income = 0
for invoice in sales_invoices:
prediction = self.predict_payment_date(invoice)
# Tylko jeśli przewidywana płatność w tym miesiącu
if prediction['predicted_payment_date'].month == month:
predicted_income += invoice.total_gross
# Faktury zakupowe
purchase_invoices = get_invoices_due_in_month(year, month, type='purchases')
predicted_expenses = sum(inv.total_gross for inv in purchase_invoices)
return {
'month': f"{year}-{month:02d}",
'predicted_income': predicted_income,
'predicted_expenses': predicted_expenses,
'net_cash_flow': predicted_income - predicted_expenses,
'note': 'Predykcja ma charakter szacunkowy'
}
```
### Statystyki Kontrahenta
```python
def get_contractor_stats(nip):
"""
Oblicz statystyki płatności dla kontrahenta
"""
invoices = get_all_invoices_for_contractor(nip)
if not invoices:
return {
'avg_days_late': 0,
'reliability': 1.0, # Brak historii = optymistyczne założenie
'total_invoices': 0
}
days_late_list = []
paid_on_time = 0
for inv in invoices:
if inv.payment_date:
days_late = (inv.payment_date - inv.payment_due_date).days
days_late_list.append(max(0, days_late)) # Tylko dodatnie
if days_late <= 0:
paid_on_time += 1
return {
'avg_days_late': sum(days_late_list) / len(days_late_list),
'reliability': paid_on_time / len(invoices),
'total_invoices': len(invoices),
'max_days_late': max(days_late_list) if days_late_list else 0
}
```
---
## Best Practices dla AI
### 1. Ciągłe Uczenie (Continuous Learning)
```python
def retrain_models_monthly():
"""
Retrenuj modele co miesiąc na świeżych danych
"""
# Pobierz dane z ostatnich 12 miesięcy
end_date = datetime.now()
start_date = end_date - timedelta(days=365)
historical_data = get_invoices(start_date, end_date)
# Retrenuj klasyfikator kosztów
expense_classifier.train(historical_data)
# Retrenuj detektor anomalii
fraud_detector.train(historical_data)
# Retrenuj predyktor cash flow
cash_flow_predictor.train(historical_data)
save_models() # Zapisz do dysku
```
### 2. Human-in-the-Loop
```python
def classify_with_review(invoice):
"""
Klasyfikacja z flagowaniem do review
"""
prediction = expense_classifier.predict(invoice)
if prediction['confidence'] < 0.8:
# Niska pewność → human review
task = create_review_task(
invoice=invoice,
suggested_category=prediction['category'],
confidence=prediction['confidence'],
alternatives=prediction['alternatives']
)
return {
'category': None, # Czekaj na review
'status': 'PENDING_REVIEW',
'task_id': task.id
}
# Wysoka pewność → auto-classify
return {
'category': prediction['category'],
'status': 'AUTO_CLASSIFIED',
'confidence': prediction['confidence']
}
```
### 3. Audit Trail dla AI
```python
def log_ai_decision(invoice, prediction, action):
"""
Loguj decyzje AI dla audytu
"""
ai_audit_log.insert({
'timestamp': datetime.now(),
'invoice_id': invoice.id,
'model_name': 'ExpenseClassifier',
'model_version': '2.1',
'prediction': prediction,
'confidence': prediction['confidence'],
'action_taken': action,
'reviewed_by_human': action == 'MANUAL_REVIEW'
})
```
---
**Ostrzeżenie końcowe:** Wszystkie funkcje AI wymagają regularnego monitorowania, walidacji i nadzoru ze strony wykwalifikowanego personelu. Nie należy polegać wyłącznie na automatycznych decyzjach w sprawach podatkowych i księgowych.
**Przypomnienie:** Powyższe przykłady kodu to architektura referencyjna. Ten skill nie zawiera wytrenowanych modeli, artefaktów ML ani plików wykonywalnych. Implementacja wymaga zainstalowania zależności (sklearn, pandas, numpy) i wytrenowania modeli na danych użytkownika w jego własnym środowisku.
```
### references/ksef-security-compliance.md
```markdown
# Security & Compliance dla KSeF
Wymagania bezpieczeństwa, zgodności i najlepsze praktyki.
**⚠️ OSTRZEŻENIE BEZPIECZEŃSTWA:**
Wszystkie przykłady kodu w tym dokumencie mają charakter **edukacyjny i koncepcyjny** — to wzorce architektoniczne do implementacji przez użytkownika w jego własnym systemie. Ten skill NIE implementuje tych mechanizmów, NIE przechowuje tokenów, NIE łączy się z Vault i NIE zarządza kluczami szyfrowania.
**Zmienne środowiskowe** wymienione w tym dokumencie (np. `KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`) są zadeklarowane w metadanych skilla jako opcjonalne. Skill nie prosi o nie niejawnie — jeśli użytkownik je udostępni, agent może je wykorzystać w sugerowanym kodzie. Wszystkie zmienne są opisane w sekcji `env` pliku SKILL.md.
**NIGDY nie wklejaj tokenów, kluczy szyfrowania, certyfikatów ani innych danych uwierzytelniających bezpośrednio w rozmowie z agentem.** Używaj wyłącznie:
- Zmiennych środowiskowych platformy (env vars)
- Menedżera sekretów (np. HashiCorp Vault, AWS Secrets Manager)
- Tymczasowych zmiennych sesji (ephemeral env vars)
Przed użyciem wzorców w środowisku produkcyjnym:
1. Przeprowadź security review
2. Użyj dedykowanych, przetestowanych narzędzi zamiast własnych implementacji
3. Nigdy nie uruchamiaj niezweryfikowanego kodu z zewnętrznych źródeł
4. Implementuj principle of least privilege
5. Regularnie aktualizuj zależności i przeprowadzaj audyty bezpieczeństwa
6. Testuj wyłącznie na środowisku DEMO (`https://ksef-demo.mf.gov.pl`) — nigdy na produkcji
---
## Gwarancje platformy vs. skilla — weryfikacja przed instalacją
Ten skill deklaruje flagi bezpieczeństwa w **dwóch źródłach**:
- **Frontmatter SKILL.md** — zawiera `disableModelInvocation: true` (camelCase) oraz `disable-model-invocation: true` (kebab-case), a także deklaracje env vars z `secret: true` dla zmiennych zawierających dane uwierzytelniające.
- **Manifest [`skill.json`](../skill.json)** — dedykowany plik maszynowo czytelny z pełnymi metadanymi bezpieczeństwa, deklaracjami env vars (z polem `secret` i `scope`) oraz ograniczeniami. Jest źródłem prawdy dla rejestrów i skanerów, które mogą nie parsować frontmatter YAML.
Jednak **oba te źródła to deklaracje skilla, nie gwarancje platformy**. Wymuszanie tych flag zależy wyłącznie od platformy hostingowej.
**Znany problem:** Metadane rejestru (registry metadata) wyświetlane przez platformę mogą nie odzwierciedlać wartości z frontmatter ani z `skill.json`. Jeśli platforma pokazuje `disable-model-invocation: not set` (lub pomija tę flagę), albo nie wyświetla zmiennych środowiskowych jako zarejestrowanych — ochrona **nie jest aktywna**, niezależnie od tego, co deklarują pliki skilla.
**Obowiązkowa weryfikacja przed instalacją:**
1. **Porównaj metadane rejestru z frontmatter i `skill.json`** — po dodaniu skilla do platformy, otwórz widok metadanych rejestru. Zweryfikuj, że:
- `disable-model-invocation` = `true`
- Zmienne środowiskowe `KSEF_TOKEN` i `KSEF_ENCRYPTION_KEY` są widoczne jako zarejestrowane sekrety
- Inne flagi bezpieczeństwa na poziomie platformy (jeśli istnieją) są poprawnie ustawione
- Jeśli JAKIEKOLWIEK pole nie zgadza się z frontmatter/`skill.json` — traktuj skill jako wyższego ryzyka
2. **Potwierdź izolację zmiennych środowiskowych** — zmienne (`KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`, `KSEF_BASE_URL`) nie mogą być logowane, wyświetlane w konwersacji ani dostępne dla innych skilli
3. **Jeśli platforma NIE wymusza flagi `disableModelInvocation`:**
- NIE konfiguruj żadnych zmiennych środowiskowych z danymi uwierzytelniającymi
- NIE udostępniaj tokenów, certyfikatów ani kluczy szyfrowania
- NIE zezwalaj na autonomiczne użycie skilla
- Używaj wyłącznie w trybie ręcznym (jawna akcja użytkownika) i tylko ze środowiskiem DEMO (`https://ksef-demo.mf.gov.pl`)
4. **Zgłoś rozbieżność** — jeśli metadane rejestru nie pasują do frontmatter/`skill.json`, zgłoś to dostawcy platformy jako problem bezpieczeństwa wymagający naprawy. Podaj nazwę pliku `skill.json` jako alternatywne źródło metadanych, jeśli platforma nie parsuje frontmatter YAML
---
## Biała Lista VAT
### Automatyczna Weryfikacja
```python
import requests
from datetime import datetime
def verify_contractor_white_list(nip, bank_account, date=None):
"""
Sprawdza kontrahenta na białej liście VAT
API: https://wl-api.mf.gov.pl/
"""
if date is None:
date = datetime.now().strftime('%Y-%m-%d')
url = f"https://wl-api.mf.gov.pl/api/search/nip/{nip}?date={date}"
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
data = response.json()
except Exception as e:
return {
'valid': False,
'reason': f'Błąd API: {e}',
'risk': 'UNKNOWN'
}
# Sprawdź status VAT
subject = data['result']['subject']
if subject['statusVat'] != 'Czynny':
return {
'valid': False,
'reason': f"Kontrahent VAT: {subject['statusVat']}",
'risk': 'HIGH',
'details': subject
}
# Sprawdź konto bankowe
accounts = subject.get('accountNumbers', [])
# Normalizuj numer konta (usuń spacje)
bank_account_normalized = bank_account.replace(' ', '')
for acc in accounts:
if acc.replace(' ', '') == bank_account_normalized:
return {
'valid': True,
'name': subject['name'],
'status': subject['statusVat'],
'verified_account': acc
}
# Konto nie na liście
return {
'valid': False,
'reason': 'Konto bankowe nie znajduje się na białej liście',
'risk': 'HIGH',
'valid_accounts': accounts,
'details': subject
}
```
### Integracja z Płatnościami
```python
def before_payment_check(invoice, payment):
"""
Weryfikacja przed wykonaniem przelewu
"""
# 1. Sprawdź białą listę
verification = verify_contractor_white_list(
nip=invoice.seller_nip,
bank_account=payment.to_account,
date=payment.date.strftime('%Y-%m-%d')
)
if not verification['valid']:
# Wstrzymaj płatność
payment.status = 'HOLD'
payment.hold_reason = verification['reason']
# Wysłij alert
send_critical_alert(
level='HIGH',
title='Płatność wstrzymana - Biała lista VAT',
message=f"Kontrahent: {invoice.seller_name} ({invoice.seller_nip})\n"
f"Kwota: {payment.amount} PLN\n"
f"Powód: {verification['reason']}\n"
f"Faktura: {invoice.number}",
invoice=invoice,
payment=payment
)
return False
# 2. Sprawdź czy wymaga MPP
if invoice.total_gross > 15000 and invoice.has_attachment_15_goods:
if payment.type != 'MPP':
send_warning_alert(
title='Faktura wymaga MPP',
message=f"Faktura {invoice.number} wymaga mechanizmu podzielonej płatności"
)
return False
return True
```
---
## Bezpieczeństwo Tokenów
### Przechowywanie Tokenów
```python
from cryptography.fernet import Fernet
import os
class SecureTokenStorage:
"""
Szyfrowane przechowywanie tokenów KSeF
"""
def __init__(self, encryption_key=None):
if encryption_key is None:
# Wczytaj z environment variable
encryption_key = os.environ.get('KSEF_ENCRYPTION_KEY')
if encryption_key is None:
raise ValueError("Brak klucza szyfrowania")
self.cipher = Fernet(encryption_key.encode())
def store_token(self, token_name, token_value):
"""Zapisz token (zaszyfrowany)"""
encrypted = self.cipher.encrypt(token_value.encode())
# Zapisz do bazy lub vault
db.tokens.insert({
'name': token_name,
'value': encrypted,
'created_at': datetime.now()
})
def retrieve_token(self, token_name):
"""Pobierz token (odszyfruj)"""
record = db.tokens.find_one({'name': token_name})
if not record:
raise ValueError(f"Token {token_name} nie istnieje")
decrypted = self.cipher.decrypt(record['value'])
return decrypted.decode()
def rotate_token(self, token_name, new_token_value):
"""Rotacja tokena (best practice: co 90 dni)"""
# Archiwizuj stary token
old_record = db.tokens.find_one({'name': token_name})
db.tokens_archive.insert({
**old_record,
'archived_at': datetime.now()
})
# Zapisz nowy
self.store_token(token_name, new_token_value)
```
### Integracja z Vault (HashiCorp)
```python
import hvac
class VaultTokenStorage:
"""
Przechowywanie w HashiCorp Vault (produkcja)
"""
def __init__(self, vault_url, vault_token):
self.client = hvac.Client(url=vault_url, token=vault_token)
def store_token(self, token_name, token_value):
self.client.secrets.kv.v2.create_or_update_secret(
path=f'ksef/tokens/{token_name}',
secret={'value': token_value}
)
def retrieve_token(self, token_name):
secret = self.client.secrets.kv.v2.read_secret_version(
path=f'ksef/tokens/{token_name}'
)
return secret['data']['data']['value']
```
---
## Audit Trail
### Logowanie Operacji
```python
import logging
from datetime import datetime
class AuditLogger:
"""
Immutable audit log (append-only)
"""
def __init__(self):
self.logger = logging.getLogger('ksef_audit')
def log_operation(self, operation_type, user, entity_type, entity_id, details=None):
"""
Każda operacja MUSI być zalogowana
"""
audit_entry = {
'timestamp': datetime.now().isoformat(),
'operation': operation_type, # CREATE, READ, UPDATE, DELETE
'user': user,
'entity_type': entity_type, # INVOICE, PAYMENT, etc.
'entity_id': entity_id,
'details': details or {},
'ip_address': self._get_client_ip(),
'user_agent': self._get_user_agent(),
'session_id': self._get_session_id()
}
# Zapisz do immutable storage (append-only)
audit_db.insert(audit_entry)
# Log do pliku (dla compliance)
self.logger.info(json.dumps(audit_entry))
def log_ai_decision(self, invoice, prediction, action):
"""
Specjalne logowanie decyzji AI
"""
self.log_operation(
operation_type='AI_CLASSIFICATION',
user='AI_SYSTEM',
entity_type='INVOICE',
entity_id=invoice.id,
details={
'model_name': 'ExpenseClassifier',
'model_version': '2.1',
'prediction': prediction['category'],
'confidence': prediction['confidence'],
'action_taken': action,
'reviewed_by_human': action == 'MANUAL_REVIEW'
}
)
```
### Przegląd Audytu
```python
def audit_report(start_date, end_date, user=None):
"""
Generuj raport audytowy
"""
query = {
'timestamp': {
'$gte': start_date.isoformat(),
'$lte': end_date.isoformat()
}
}
if user:
query['user'] = user
entries = audit_db.find(query).sort('timestamp', 1)
report = {
'period': f"{start_date} - {end_date}",
'total_operations': 0,
'by_type': {},
'by_user': {},
'entries': []
}
for entry in entries:
report['total_operations'] += 1
report['by_type'][entry['operation']] = \
report['by_type'].get(entry['operation'], 0) + 1
report['by_user'][entry['user']] = \
report['by_user'].get(entry['user'], 0) + 1
report['entries'].append(entry)
return report
```
---
## Backup i Disaster Recovery
### Strategia 3-2-1
**Wymagania biznesowe:** Dane księgowe muszą być chronione za pomocą redundantnych kopii zapasowych według zasady 3-2-1:
- **3 kopie** danych (produkcja + 2 backupy)
- **2 różne typy nośników** (np. lokalny SSD + zewnętrzny storage)
- **1 kopia poza siedzibą** (chmura lub zdalna lokalizacja)
**Podejście implementacyjne:**
1. Używaj wbudowanych rozwiązań backup dostawcy bazy danych (managed backups, automated snapshots)
2. Zaplanuj codzienne automatyczne backupy w godzinach niskiej aktywności
3. Przechowuj backupy w wielu lokalizacjach (lokalny szybki storage + zdalna chmura)
4. Zaimplementuj automatyczną weryfikację backupów dla zapewnienia integralności danych
5. Zachowuj backupy zgodnie z wymogami prawnymi (minimum 10 lat dla danych księgowych)
6. Dokumentuj i regularnie testuj procedury disaster recovery
**Dla systemów produkcyjnych:**
- Wykorzystuj zarządzane usługi baz danych (AWS RDS, Azure Database, Google Cloud SQL) z funkcjami automatycznego backupu
- Używaj rozwiązań enterprise backup zaprojektowanych dla danych księgowych/finansowych
- Zaimplementuj monitoring i alerty dla niepowodzeń backupu
- Upewnij się, że procesy backup nie zakłócają operacji księgowych
### Synchronizacja z KSeF dla Disaster Recovery
**Kluczowa zasada:** KSeF jest źródłem prawdy dla wszystkich faktur. Jeśli lokalne dane zostaną utracone, mogą być zrekonstruowane z KSeF.
**Proces odzyskiwania:**
1. **Przywróć z backupu** - Użyj procedur restore dostawcy infrastruktury
2. **Synchronizuj z KSeF** - Pobierz faktury z KSeF API z ostatnich 7-30 dni (w zależności od wieku backupu)
3. **Weryfikuj integralność danych** - Porównaj lokalne zapisy faktur z KSeF aby zidentyfikować rozbieżności
4. **Uzgodnij różnice** - Zaktualizuj lokalną bazę danych autorytatywnymi danymi z KSeF
5. **Powiadom zainteresowanych** - Poinformuj zespół księgowy gdy odzyskiwanie jest zakończone i system działa
**Ważne:** Testuj procedury disaster recovery kwartalnie aby upewnić się, że działają gdy są potrzebne.
---
## RODO / GDPR
### Dane Osobowe w Fakturach
```python
def anonymize_invoice_for_archive(invoice, retention_years=10):
"""
Anonimizacja po upływie okresu przechowywania
"""
retention_date = invoice.issue_date + timedelta(days=365 * retention_years)
if datetime.now() > retention_date:
# Dane do anonimizacji (RODO)
invoice.buyer_name = "***ANONIMIZOWANE***"
invoice.buyer_address = "***"
invoice.buyer_email = None
invoice.buyer_phone = None
# Zachowaj NIP (wymagane fiscalnie)
# invoice.buyer_nip - POZOSTAW
invoice.anonymized_at = datetime.now()
invoice.save()
```
### Żądanie Usunięcia Danych (Right to be Forgotten)
```python
def handle_gdpr_deletion_request(contractor_nip):
"""
⚠️ UWAGA: Faktury podlegają obowiązkowi przechowywania (5-10 lat)
Nie można ich usunąć w okresie przechowywania!
"""
# 1. Sprawdź czy okres przechowywania minął
invoices = get_all_invoices_for_contractor(contractor_nip)
for invoice in invoices:
retention_date = invoice.issue_date + timedelta(days=365 * 10)
if datetime.now() < retention_date:
return {
'status': 'REJECTED',
'reason': 'Faktury podlegają obowiązkowi przechowywania',
'retention_until': retention_date
}
# 2. Jeśli okres minął - anonimizuj
for invoice in invoices:
anonymize_invoice_for_archive(invoice)
return {
'status': 'COMPLETED',
'anonymized_invoices': len(invoices)
}
```
---
## Kontrola Dostępu (RBAC)
### Role i Uprawnienia
```python
ROLES = {
'ADMIN': [
'invoice.create', 'invoice.read', 'invoice.update', 'invoice.delete',
'payment.create', 'payment.read', 'payment.update', 'payment.delete',
'user.manage', 'settings.manage'
],
'ACCOUNTANT': [
'invoice.create', 'invoice.read', 'invoice.update',
'payment.create', 'payment.read', 'payment.update',
'report.generate'
],
'VIEWER': [
'invoice.read', 'payment.read', 'report.view'
]
}
def check_permission(user, permission):
"""
Sprawdź czy user ma uprawnienie
"""
user_role = user.role
allowed_permissions = ROLES.get(user_role, [])
if permission not in allowed_permissions:
audit_logger.log_operation(
operation_type='PERMISSION_DENIED',
user=user.username,
entity_type='PERMISSION',
entity_id=permission
)
raise PermissionError(f"User {user.username} nie ma uprawnień: {permission}")
return True
```
---
## Certyfikaty SSL/TLS
### Połączenia do KSeF
```python
import ssl
import certifi
def secure_ksef_connection():
"""
Zawsze używaj HTTPS z weryfikacją certyfikatu
"""
session = requests.Session()
# 1. Weryfikuj certyfikat (NIGDY verify=False)
session.verify = certifi.where()
# 2. Użyj silnych cipher suites
session.mount('https://', requests.adapters.HTTPAdapter(
max_retries=3,
pool_connections=10,
pool_maxsize=20
))
# 3. Ustaw timeout
session.request = lambda *args, **kwargs: \
requests.Session.request(session, *args, timeout=30, **kwargs)
return session
```
---
## Bezpieczne Praktyki Programistyczne
### 1. Unikaj dynamicznego wykonywania kodu
**❌ NIGDY nie używaj:**
- `eval()` lub `exec()` na danych wejściowych użytkownika lub danych zewnętrznych
- Wykonywania poleceń shell z konkatenacją stringów
- Dynamicznych zapytań SQL budowanych przez konkatenację stringów
**✅ ZAMIAST TEGO używaj:**
- Sparametryzowanych zapytań do bazy danych (zapobiega SQL injection)
- Walidowanych, sprawdzonych typowo danych wejściowych
- Strukturalnych wywołań API z odpowiednią obsługą argumentów
- Wbudowanych bibliotek i frameworków zaprojektowanych dla operacji księgowych
### 2. Walidacja Wejścia
```python
def validate_invoice_number(number):
"""Waliduj przed użyciem w zapytaniach"""
# Tylko alfanumeryczne, myślniki, ukośniki
import re
if not re.match(r'^[A-Z0-9/-]+$', number):
raise ValueError("Nieprawidłowy numer faktury")
if len(number) > 50:
raise ValueError("Numer faktury zbyt długi")
return number
```
### 3. Principle of Least Privilege
```python
# Użytkownik bazy danych z minimalnymi uprawnieniami
DB_CONFIG = {
'user': 'ksef_readonly', # Tylko SELECT dla reportów
'user': 'ksef_app', # SELECT + INSERT + UPDATE dla app
'user': 'ksef_admin', # Wszystkie uprawnienia (tylko admin)
}
```
### 4. Używaj rozwiązań klasy enterprise
Dla produkcyjnych systemów księgowych:
- **Bazy danych:** Zarządzane usługi baz danych z automatycznymi backupami i point-in-time recovery
- **Monitoring:** Profesjonalne platformy monitoringu z możliwościami alertowania
- **Bezpieczeństwo:** Enterprise systemy zarządzania tożsamością i kontroli dostępu
- **Compliance:** Rozwiązania audit logging zaprojektowane dla danych finansowych
---
## Checklist Bezpieczeństwa
- [ ] Tokeny KSeF szyfrowane (Fernet/Vault)
- [ ] Biała lista VAT sprawdzana przed każdą płatnością
- [ ] Audit trail wszystkich operacji
- [ ] Backup 3-2-1 (daily)
- [ ] HTTPS z weryfikacją certyfikatu
- [ ] RBAC (kontrola dostępu)
- [ ] Retention policy zgodna z prawem (10 lat)
- [ ] RODO - anonimizacja po okresie przechowywania
- [ ] Monitoring i alerty
- [ ] Disaster recovery plan (testowany co kwartał)
---
**Compliance:** Wdrożenie powyższych praktyk wspiera zgodność z:
- Ustawą o VAT
- RODO / GDPR
- Ustawą o rachunkowości
- Normami ISO 27001 (opcjonalnie)
```
### references/ksef-troubleshooting.md
```markdown
# Troubleshooting KSeF
Przewodnik rozwiązywania najczęstszych problemów z systemem KSeF.
---
## Problemy z Autentykacją
### Błąd 401: Unauthorized
**Objawy:**
```json
{
"processingCode": 401,
"processingDescription": "Brak autoryzacji"
}
```
**Przyczyny:**
- Sesja wygasła (token ważny tylko ~30 min)
- Nieprawidłowy token
- Token nie ma wymaganych uprawnień
**Rozwiązanie:**
```python
def handle_401_error():
# 1. Sprawdź ważność tokena
if session.is_expired():
# Odśwież sesję
session = ksef_client.init_session(token)
retry_operation()
# 2. Sprawdź uprawnienia tokena
# Token musi mieć scope: invoice.read, invoice.write
# 3. Wygeneruj nowy token w portalu KSeF
```
---
### Błąd 403: Forbidden
**Objawy:**
```json
{
"processingCode": 403,
"processingDescription": "Brak uprawnień"
}
```
**Przyczyny:**
- Token nie ma uprawnień do tej operacji
- NIP w tokenie nie zgadza się z NIP w fakturze
**Rozwiązanie:**
1. Sprawdź uprawnienia tokena w portalu KSeF
2. Upewnij się że token jest dla właściwego NIP
3. Sprawdź czy token ma scope dla danej operacji (read/write)
---
## Problemy z Walidacją Faktur
### Błąd 100: Nieprawidłowy format XML
**Objawy:**
```json
{
"exceptionCode": "100",
"exceptionDescription": "Nieprawidłowy format XML"
}
```
**Rozwiązanie:**
```python
# 1. Sprawdź encoding
assert xml_content.startswith('<?xml version="1.0" encoding="UTF-8"?>')
# 2. Waliduj XML parser
try:
ET.fromstring(xml_content)
except ET.ParseError as e:
print(f"Błąd parsowania: {e}")
# Sprawdź: unclosed tags, nieprawidłowe znaki
# 3. Usuń BOM (Byte Order Mark)
xml_content = xml_content.lstrip('\ufeff')
```
---
### Błąd 101: Błąd walidacji schematu
**Objawy:**
```json
{
"exceptionCode": "101",
"exceptionDescription": "Błąd walidacji schematu XSD"
}
```
**Przyczyny:**
- Używasz FA(2) zamiast FA(3)
- Nieprawidłowa struktura XML
- Brakujące wymagane pola
- Nieprawidłowy namespace
**Rozwiązanie:**
```python
# Checklist FA(3):
checks = {
'Namespace': 'http://crd.gov.pl/wzor/2023/06/29/12648/',
'KodFormularza kodSystemowy': 'FA(3)',
'wersjaSchemy': '1-0E',
'WariantFormularza': '3'
}
for field, expected in checks.items():
if expected not in xml_content:
print(f"BŁĄD: Brak {field} = {expected}")
```
**Częste błędy:**
- `kodSystemowy="FA(2)"` → Zmień na `FA(3)`
- `wersjaSchemy="1-0"` → Zmień na `1-0E`
- Stary namespace z 2021 → Użyj namespace z 2023
---
### Błąd 102: Nieprawidłowy NIP
**Objawy:**
```json
{
"exceptionCode": "102",
"exceptionDescription": "Nieprawidłowy NIP"
}
```
**Rozwiązanie:**
```python
def validate_nip(nip):
# 1. Długość
if len(nip) != 10:
return False
# 2. Cyfry
if not nip.isdigit():
return False
# 3. Suma kontrolna
weights = [6, 5, 7, 2, 3, 4, 5, 6, 7]
check_sum = sum(int(nip[i]) * weights[i] for i in range(9))
check_digit = check_sum % 11
if check_digit == 10:
return False
return check_digit == int(nip[9])
# 4. Sprawdź w białej liście VAT
response = requests.get(f"https://wl-api.mf.gov.pl/api/search/nip/{nip}")
if response.status_code != 200:
print("NIP nie istnieje w bazie MF")
```
---
### Błąd 103: Data w przyszłości
**Objawy:**
```json
{
"exceptionCode": "103",
"exceptionDescription": "Data w przyszłości"
}
```
**Rozwiązanie:**
```python
from datetime import datetime, timedelta
# DataWytworzeniaFa nie może być w przyszłości
now = datetime.now()
data_wytworzenia = now.strftime('%Y-%m-%dT%H:%M:%S')
# BŁĄD: Data jutro
tomorrow = now + timedelta(days=1)
data_wytworzenia = tomorrow.strftime(...) # ❌
# Uwaga na strefy czasowe
# KSeF używa czasu polskiego (UTC+1/UTC+2)
```
---
### Błąd 104: Duplikat numeru faktury
**Objawy:**
```json
{
"exceptionCode": "104",
"exceptionDescription": "Faktura o takim numerze już istnieje"
}
```
**Rozwiązanie:**
```python
def generate_unique_invoice_number():
# Format: FV/ROK/MIESIĄC/NUMER
year = datetime.now().year
month = datetime.now().month
# Pobierz ostatni numer z bazy
last_number = db.get_last_invoice_number(year, month)
next_number = (last_number or 0) + 1
return f"FV/{year}/{month:02d}/{next_number:04d}"
# Sprawdź czy numer już istnieje w KSeF
existing = ksef_client.check_invoice_number(invoice_number)
if existing:
print("Numer już użyty - wygeneruj nowy")
```
---
## Problemy z Wydajnością
### Timeout API / Brak Odpowiedzi
**Objawy:**
- Request timeout (>30s)
- 503 Service Unavailable
- Brak odpowiedzi
**Diagnoza:**
```python
def diagnose_timeout():
# 1. Sprawdź status KSeF
try:
response = requests.get('https://ksef.mf.gov.pl/api/health')
print(f"Status KSeF: {response.status_code}")
except:
print("KSeF niedostępny")
return "KSEF_DOWN"
# 2. Sprawdź własną sieć
try:
requests.get('https://google.com', timeout=5)
except:
print("Problem z internetem")
return "NETWORK_ISSUE"
# 3. Sprawdź obciążenie (godziny szczytu)
hour = datetime.now().hour
if hour in [15, 16, 17]: # 15:00-18:00
print("Godziny szczytu - duże obciążenie KSeF")
return "HIGH_LOAD"
return "UNKNOWN"
```
**Rozwiązanie:**
```python
import time
def send_with_retry(invoice_xml, max_retries=3):
for attempt in range(max_retries):
try:
response = ksef_client.send_invoice(invoice_xml, timeout=60)
return response
except Timeout:
if attempt < max_retries - 1:
# Exponential backoff
wait_time = 2 ** attempt # 1s, 2s, 4s
print(f"Timeout - retry {attempt+1}/{max_retries} za {wait_time}s")
time.sleep(wait_time)
else:
raise
# Best practices:
# - Wysyłaj poza godzinami szczytu (21:00-6:00)
# - Użyj queue + background worker
# - Implementuj circuit breaker
```
---
### Rate Limiting (429)
**Objawy:**
```json
{
"processingCode": 429,
"processingDescription": "Zbyt wiele żądań"
}
```
**Rozwiązanie:**
```python
import time
from functools import wraps
def rate_limit(max_per_hour=100):
"""Decorator ograniczający liczbę requestów"""
calls = []
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
now = time.time()
# Usuń stare calle (sprzed godziny)
calls[:] = [c for c in calls if c > now - 3600]
if len(calls) >= max_per_hour:
wait_time = 3600 - (now - calls[0])
print(f"Rate limit - czekaj {wait_time:.0f}s")
time.sleep(wait_time)
calls.append(now)
return func(*args, **kwargs)
return wrapper
return decorator
@rate_limit(max_per_hour=100)
def send_invoice(invoice):
return ksef_client.send_invoice(invoice)
```
---
## Problemy z Płatnościami
### Nie Można Dopasować Płatności
**Przyczyny:**
- Niezgodna kwota (błąd w kwocie przelewu)
- Brak numeru faktury w tytule
- Split payment (MPP) - częściowa płatność
- Płatność zbiorcza (kilka faktur naraz)
**Rozwiązanie:**
```python
def handle_unmatched_payment(payment):
# 1. Rozszerzone wyszukiwanie (tolerancja ±2%)
matches = search_invoices_extended(
amount_min=payment.amount * 0.98,
amount_max=payment.amount * 1.02,
date_range_days=14 # ±14 dni zamiast ±7
)
if matches:
return present_to_user_for_confirmation(matches)
# 2. Sprawdź czy to split payment (część VAT)
if is_likely_vat_payment(payment):
net_payment = find_net_payment(payment)
if net_payment:
return match_mpp(net_payment, payment)
# 3. Sprawdź płatność zbiorczą
invoice_numbers = extract_invoice_numbers_from_title(payment.title)
if len(invoice_numbers) > 1:
return split_payment_to_invoices(payment, invoice_numbers)
# 4. Flaguj do manual review
flag_for_review(payment)
```
---
## Problemy ze Środowiskiem
### Faktury Testowe na Produkcji
**Problem:** Wysłano faktury testowe na środowisko produkcyjne
**⚠️ UWAGA:** Faktury na produkcji są prawnie wiążące!
**Co zrobić:**
1. NIE usuwaj faktur (niemożliwe w KSeF)
2. Wystaw faktury korygujące do zera
3. Skontaktuj się z kontrahentem
4. Zgłoś do księgowości
**Zapobieganie:**
```python
# Zawsze sprawdzaj środowisko
class KSefClient:
def __init__(self, environment='demo'):
if environment == 'production':
# Wymuś potwierdzenie
confirm = input("⚠️ PRODUKCJA! Kontynuować? (yes/no): ")
if confirm != 'yes':
raise Exception("Anulowano - używaj DEMO do testów")
self.base_url = {
'demo': 'https://ksef-demo.mf.gov.pl',
'production': 'https://ksef.mf.gov.pl'
}[environment]
```
---
## Monitoring i Alerty
### Konfiguracja Alertów
```python
def setup_monitoring():
monitors = [
# 1. Alert przy wysokiej liczbie błędów
{
'name': 'High rejection rate',
'condition': lambda: get_rejection_rate_last_hour() > 0.2,
'action': send_alert_email
},
# 2. Alert przy niedostępności KSeF
{
'name': 'KSeF down',
'condition': lambda: not check_ksef_health(),
'action': send_sms_alert
},
# 3. Alert przy problemach z płatnościami
{
'name': 'Too many unmatched payments',
'condition': lambda: count_unmatched_payments() > 10,
'action': notify_accountant
}
]
# Uruchom monitoring co 5 minut
schedule.every(5).minutes.do(run_monitors, monitors)
```
---
## Pomocne Narzędzia
### KSeF Latarnia (Status Systemu)
```bash
# Sprawdź status KSeF w czasie rzeczywistym
git clone https://github.com/CIRFMF/ksef-latarnia
cd ksef-latarnia
python check_status.py
```
### Walidator XML
```python
from lxml import etree
def validate_fa3_xsd(xml_content):
"""Walidacja względem schematu XSD"""
xsd_url = "https://ksef.podatki.gov.pl/xsd/FA3_1-0E.xsd"
# Pobierz schemat
xsd_doc = etree.parse(xsd_url)
schema = etree.XMLSchema(xsd_doc)
# Waliduj XML
xml_doc = etree.fromstring(xml_content.encode('utf-8'))
try:
schema.assertValid(xml_doc)
return True, "OK"
except etree.DocumentInvalid as e:
return False, str(e)
```
---
**Potrzebujesz pomocy?**
- Dokumentacja KSeF: https://ksef.podatki.gov.pl
- Forum: https://github.com/CIRFMF/ksef-discussions
- Helpdesk MF: (sprawdź portal KSeF)
```
### references/ksef-legal-status.md
```markdown
# Stan Prawny KSeF - Szczegóły
**Data aktualizacji:** 8 lutego 2026
**UWAGA:** Informacje mogą ulec zmianie. Należy regularnie weryfikować aktualne przepisy i komunikaty Ministerstwa Finansów.
---
## Harmonogram Wdrożenia (Planowany)
### Faza 1: Duzi Podatnicy (od 1 lutego 2026)
**Kogo dotyczy:** Obrót >200 mln PLN brutto w 2024 roku
**Obowiązki:**
- ✅ Wystawianie faktur przez KSeF
- ✅ Odbieranie faktur przez KSeF
### Faza 2: Pozostali Podatnicy (od 1 kwietnia 2026)
**Kogo dotyczy:** Obrót ≤200 mln PLN
**Obowiązki:**
- ✅ Odbieranie faktur przez KSeF (od 1 lutego 2026)
- ✅ Wystawianie faktur przez KSeF (od 1 kwietnia 2026)
- ⏳ Do 31 marca 2026 mogą wystawiać faktury poza KSeF
### Faza 3: Mikroprzedsiębiorcy (od 1 stycznia 2027)
**Kogo dotyczy:** Miesięczny obrót <10 tys PLN
**Obowiązki:**
- ✅ Odbieranie: od 1 lutego 2026
- ✅ Wystawianie: od 1 stycznia 2027
---
## Okres Przejściowy
**UWAGA:** Szczegóły mogą ulec zmianie. Przedstawione informacje oparte są na aktualnie dostępnych komunikatach.
### Planowany Grace Period
- **Do 31 grudnia 2026** - przewidywany brak kar za błędy
- Dotyczy: błędów w strukturze FA(3), opóźnień wysyłki
- Nie dotyczy: uchylania się od wystawiania faktur
### Tryb Offline24
- **Status:** Planowany jako stały element systemu
- **Przeznaczenie:** Sytuacje awaryjne (brak internetu, awaria KSeF, katastrofy)
- **Termin wysyłki:** 24h od odzyskania łączności
- **Uwaga prawna:** Prawo do odliczenia VAT od daty przypisania numeru KSeF (nie daty wystawienia offline)
### Faktury poza KSeF
- **Do 31 marca 2026:** Dozwolone dla firm ≤200 mln PLN
- **Od 1 kwietnia 2026:** Zakaz (z wyjątkiem przypadków szczególnych)
---
## Zmiany Systemowe
### KSeF 1.0 → KSeF 2.0
- **KSeF 1.0:** Planowane zamknięcie 26 stycznia 2026
- **Przerwa techniczna:** 5 dni (26-31 stycznia 2026)
- **KSeF 2.0:** Planowany start 1 lutego 2026
### FA(2) → FA(3)
- **FA(2):** Planowane zakończenie obsługi 1 lutego 2026
- **FA(3):** Obowiązkowa od 1 lutego 2026
- **Migracja:** Wszyscy podatnicy muszą dostosować systemy
---
## Konsekwencje Prawne (Przyszłe)
**UWAGA:** Poniższe informacje dotyczą planowanego systemu kar po zakończeniu grace period.
### Po 1 stycznia 2027 (Planowane)
- Brak faktury w KSeF → możliwa kara
- Faktura poza KSeF → możliwa kara
- Opóźniona wysyłka → możliwa kara
**Wysokość kar:** Należy konsultować z aktualną ustawą o VAT
---
## Wymagania Techniczne
### Obligatoryjna Struktura
- **FA(3) ver. 1-0E**
- Format: XML zgodny ze schematem
- Encoding: UTF-8
- Walidacja: Automatyczna przy przyjęciu przez KSeF
### Certyfikaty (MCU)
- **MCU:** Moduł Certyfikatów i Uprawnień
- **Status:** Zgodnie z harmonogramem aktywny od 1.11.2025
- **Przeznaczenie:** Alternatywna metoda autoryzacji (oprócz tokenów)
---
## Źródła Informacji
### Oficjalne
- Portal KSeF: https://ksef.podatki.gov.pl
- Ministerstwo Finansów: https://www.gov.pl/web/kas/ksef
### Monitorowanie Zmian
- Komunikaty MF: https://ksef.podatki.gov.pl/web/ksef/aktualnosci
- KSeF Latarnia (status): https://github.com/CIRFMF/ksef-latarnia
---
**Ostatnia aktualizacja:** 8 lutego 2026
**Następna weryfikacja:** Zalecana co 2 tygodnie
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### _meta.json
```json
{
"owner": "alexwoo-awso",
"slug": "ksef-accountant-pl",
"displayName": "KSeF Accountant (Polish)",
"latest": {
"version": "2.2.6",
"publishedAt": 1770778373766,
"commit": "https://github.com/openclaw/skills/commit/e7af0d0b7d423968defe1ad944d719a92f50d002"
},
"history": [
{
"version": "2.2.1",
"publishedAt": 1770644184219,
"commit": "https://github.com/openclaw/skills/commit/2bfff2358c2923497b42241286285c1f54c26f35"
},
{
"version": "2.1.2",
"publishedAt": 1770597858890,
"commit": "https://github.com/openclaw/skills/commit/a0729ceb1cf2ce721fef9f65f871eb80c89a7f59"
}
]
}
```