Krajowy system e-Faktur

Z6
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 8
0

Próbuję pobrać nagłówki poprzez /api/online/Query/Invoice/Sync. Sesja zainicjowana bez szyfrowania, faktury też. Wysyłam takie zapytanie:

{
    "queryCriteria": {
        "invoicingDateFrom": "2025-06-10T00:00:00.000Z",
        "invoicingDateTo": "2025-06-20T23:59:59.999Z",
        "subjectType": "subject1",
        "type": "range"
    }
}

Ciągle zwraca błąd 415.

KU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 23
0

Miał ktoś moze podobny problem, proboje dla 2 spółek sprawdzic faktury: i dla tej drugiej nie moge juz sie zautoryzować, po terminate tej pierwszej sesji jest 10s sleep: 2025-06-25 10:25:22.4482|0|INFO|0|GetInvoicesWithoutContext STARTED for all companies
2025-06-25 10:25:22.4482|0|INFO|0|Processing invoices for company NIP: 1111111111
2025-06-25 10:25:22.4584|0|INFO||ConfigureServiceAsync STARTED for NIP: 1111111111
2025-06-25 10:25:22.4584|0|INFO|0|Calling AuthenticateAsync for NIP: 1111111111
2025-06-25 10:25:24.4821|0|INFO|0|Authentication successful for NIP: 1111111111, SessionToken: 53c3611674...
2025-06-25 10:25:24.4821|0|INFO|0|Setting session tokens for NIP: 1111111111
2025-06-25 10:25:24.4821|0|INFO|0|Session tokens set - InvoiceService: True, SessionService: True for NIP: 1111111111
2025-06-25 10:25:24.4821|0|INFO|0|Starting session status check loop for NIP: 1111111111, ReferenceNumber: 20250625-SE-CA0CDCD2ED-A190C4931F-65
2025-06-25 10:25:29.4885|0|INFO|0|Session status check attempt 1/60 for NIP: 1111111111
2025-06-25 10:25:29.5824|0|INFO|0|Session status for NIP 1111111111: ProcessingCode=100, Description=Sesja interaktywna rozpoczęta. Komunikacja otwarta.
2025-06-25 10:25:34.5830|0|INFO|0|Session status check attempt 2/60 for NIP: 1111111111
2025-06-25 10:25:34.6053|0|INFO|0|Session status for NIP 1111111111: ProcessingCode=310, Description=Zakończenie etapu autoryzacji procesu
2025-06-25 10:25:39.6153|0|INFO|0|Session status check attempt 3/60 for NIP: 1111111111
2025-06-25 10:25:39.6357|0|INFO|0|Session status for NIP 1111111111: ProcessingCode=315, Description=Sesja interaktywna aktywna. Komunikacja otwarta.
2025-06-25 10:25:39.6357|0|INFO|0|Session successfully configured for NIP: 1111111111
2025-06-25 10:25:39.6717|0|INFO|0|Natural progression based on interval (01:00:00). Next date: 17.04.2025 17:00:00
2025-06-25 10:25:39.6717|0|INFO|0|GetInvoicesSync from KSEF STARTED
2025-06-25 10:25:39.8632|0|INFO|0|Numbers of KSEF invoices in system: 0
2025-06-25 10:25:39.8632|0|INFO|0|GetInvoicesSync from KSEF END
2025-06-25 10:25:39.8632|0|INFO|0|GetInvoiceAsync STARTED
2025-06-25 10:25:39.8632|0|INFO|0|GetInvoiceAsync END number of invoices:0
2025-06-25 10:26:01.4793|0|INFO|0|Invoices Filtration: Total=0, Unique=0, Duplicates=0
2025-06-25 10:26:01.5195|0|INFO|0|Webcon Process Information: Total Invoices: 0, Successfully Processed: 0, Failed: 0
2025-06-25 10:26:01.5195|0|INFO|0|NIP: 1111111111 - Invoicing Date Range: 2025-04-17T16:00:00.000Z to 2025-04-17T17:00:00.000Z
2025-06-25 10:26:01.5195|0|INFO|0|GetInvoicesWithoutContext END - Success: True NIP: 1111111111
2025-06-25 10:26:01.5195|0|INFO|0|Processing invoices for company NIP: 2222222222
2025-06-25 10:26:01.5195|0|INFO|0|ConfigureServiceAsync STARTED for NIP: 2222222222
2025-06-25 10:26:01.5195|0|INFO|0|Calling AuthenticateAsync for NIP: 2222222222
2025-06-25 10:26:03.0413|0|INFO|0|Authentication successful for NIP: 2222222222, SessionToken: ba2ac27da5...
2025-06-25 10:26:03.0413|0|INFO|0|Setting session tokens for NIP: 2222222222
2025-06-25 10:26:03.0413|0|INFO|0|Session tokens set - InvoiceService: True, SessionService: True for NIP: 2222222222
2025-06-25 10:26:03.0413|0|INFO|0|Starting session status check loop for NIP: 2222222222, ReferenceNumber: 20250625-SE-E304A1BA4B-25FB1AABC8-65
2025-06-25 10:26:08.0550|0|INFO|0|Session status check attempt 1/60 for NIP: 2222222222
2025-06-25 10:26:08.0871|0|INFO|0|Session status for NIP 2222222222: ProcessingCode=0, Description=
2025-06-25 10:26:13.0984|0|INFO|0|Session status check attempt 2/60 for NIP: 2222222222
2025-06-25 10:26:13.1161|0|INFO|0|Session status for NIP 2222222222: ProcessingCode=0, Description=
2025-06-25 10:26:18.1169|0|INFO|0|Session status check attempt 3/60 for NIP: 2222222222
2025-06-25 10:26:18.1390|0|INFO|0|Session status for NIP 2222222222: ProcessingCode=0, Description=
2025-06-25 10:26:23.1483|0|INFO|0|Session status check attempt 4/60 for NIP: 2222222222
2025-06-25 10:26:23.1696|0|INFO|0|Session status for NIP 2222222222: ProcessingCode=0, Description=

SI
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 24
0

Witam, Próbuję zbudować Init Request do wysyłki wsadowej, środowisko testowe. I nie bardzo potrafię zrozumieć struktury tego dokumentu. Mam przygotowany klucz AES, IV, Wrzucam to w requesta w Node "Value" odpowiednio w Nodach "EncryptionKey" i ":EncryptionInitializationVector", wszystko jasne do tej pory, Później mam Node Package i tam w Value idzie nazwa .zipa który rozdzielam na chunki (w moim przypadku zip ma tylko 1 fakturę więc 1 chunk), wyliczam filesize oraz tworzą skrót SHA zipa. Dalej zrozumiałe, potem przechodzę do chunków i to samo, w OrdinalNumber jest 1, PartFileName zawiera nazwę chunku, potem PartFileHash zawiera HashSHA w którym wstawiam skrót paczki, a potem po HashSHA jest Filesize. W przykładzie na którym się wzorowałem wygląda to tak:

Kopiuj
<ns:PackagePartSignature>
  <ns2:OrdinalNumber>1</ns2:OrdinalNumber>
  <ns2:PartFileName>invoice.zip.part1</ns2:PartFileName>
    <ns2:PartFileHash>
      <ns1:HashSHA>
        <ns1:Algorithm>SHA-256</ns1:Algorithm>
        <ns1:Encoding>Base64</ns1:Encoding>
        <ns1:Value>xdrsY+FXuu77OXzG77uVvRZSqYWlTBgwR2/vF4w1508=</ns1:Value>
      </ns1:HashSHA>
      <ns1:FileSize>5520</ns1:FileSize>
    </ns2:PartFileHash>
</ns:PackagePartSignature>

I moje pytanie jest następujące. W którym miejscu mam wstawić zaszyfrowany AESem chunk? Spodziewałem się gdzieś Nodu "body" ale jest tylko hashSHA (zanim użyłem hashowania chunk został zaszyfrowany AESem)

Specyfikacja interfejsu sugeruje że potrzebne mi jest zaszyfrowane body chunka:

• Części archiwum zaszyfrowane za pomocą wcześniej wygenerowanego klucza symetrycznego
AES oraz wektora inicjalizacyjnego
• Skrót SHA-256 każdej zaszyfrowanej części archiwum

i teraz nie rozumiem czego rozumiem. Specyfikacja mówi że muszę mieć przygotowane zaszyfrowane częsci archiwum, a w requeście nie widzę gdzie mogę taką część wstawić.

ME
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 8
0

witam mam jeden problem z kSeF, niedawno to działało bez problemu a teraz dostaje komunikat: 21304 Brak uwierzytelnienia.
Chodzi o pobieranie listy faktur z zadanego okresu obojętnie czy podam subject1 czy subject2 dostaje ten komunikat

endpoint wywołania; https://ksef-test.mf.gov.pl/api/online/Query/Invoice/Sync?PageSize=30&PageOffset=0

Przy zwracanym curl_getinfo dla request_header - dostaje

"POST /api/online/Query/Invoice/Sync?PageSize=30&PageOffset=0 HTTP/2
Host: ksef-test.mf.gov.pl
Content-Type: application/json
accept: application/json
SessionToken: ****
Content-Length: 151

'queryCriteria' => [
'subjectType' => 'subject2',
'type' => 'range',
'invoicingDateFrom' => '2025-06-01T00:00:00.000Z',
'invoicingDateTo' => '2025-06-15T20:45:31.610Z'
]

Dodam że wszystkie pozostałe akcje typu wyślij fakturę, pobierz fakturę czy sprawdzenie statusu faktury pobranie UPO i generowanie sesji interaktwnej działa bez problemu. Rozwiązanie napisane w PHP czysty curl w czym jest problem ?

DJ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2
RA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 57
0

Hej
Najpierw kontekst: piszę apkę, żeby sobie można było ułatwić życie, bierzesz, konfigurujesz i pracujesz lokalnie, żadnych chmur itp
Mam kilka pytań odnośnie dokumentów co je dzisiaj opublikowali.
1 To tak tylko organizacyjnie (nie mam dostępu do produkcji obecnej) Na prodzie w aplikacji ksef generowanie tokenów ksef (tych co mają wylecieć) wygląda tak samo jak na testowym prawda? Klikasz, kopiujesz i ogień?
2. Odnośnie tych nowych certyfikatów ksef. Będzie można je wygenerować przez api ale tylko po uwierzytelnieniu podpisem. Do podpisania requestu uwierzytelniającego można użyć:

  • Certyfikat kwalifikowany osoby fizycznej
  • Certyfikat kwalifikowany organizacji (tzw. pieczęć firmowa)
  • Profil Zaufany (ePUAP)
  • TpSigning - dla instytucji publicznych
  • Certyfikat KSeF

Tego certyfikatu ksef pewnie nie będzie mozna wygenerować z aplikacji tak jak to obecnie jest z tokenami (tutaj prośba: jeśli ktoś wie, że będzie to możliwe to proszę mnie zwyzywać od debili co nie umieją czytać a ja podziękuję).
I teraz tak: pan Kowalski (sprzedawca doniczek, własiciel firmy POLDONIX z nipem 1129863154) certyfikatu kwalifikowanego nie będzie chciał kupować, certyfikatu ksef jeszcze nie ma (chcemy go wygenerować), instytucją publiczną nie jest, więc tpsigning odpada. Pozostaje profil zaufany? Może nie w temacie ksef ale ktoś to kiedyś robił? Jak to można zautomatyzować?
Ewentualnie jeśli pominąłem jakąś "darmową" drogę do uzyskania certyfikatu ksef to oczywiście poproszę o wskazówkę

K2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 16
0

No to weszło: https://ksef.podatki.gov.pl/ksef-na-okres-obligatoryjny/wsparcie-dla-integratorow/ .
(pierwsze wrażenie jest, wg mnie, dużo lepsze niż to co zobaczyłem dla KSeF 1.0)

RA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 57
0

Dokopał się ktoś do finalnego xsd dla faktur RR? Na epuapie nie mogę znaleźć. Dostępna jest tylko wersja przekazana do konsultacji z roboczą FA3

Dzyszla
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 184
0

Wyciąg ze zmian (co by pod ręką tu było dla ciekawych):

  • Uwierzytelnianie zostało wydzielone jako osobny proces, niezależny od inicjalizacji sesji.
  • Wprowadzono standardowe tokeny JWT, które są wykorzystywane do autoryzacji wszystkich operacji chronionych.
  • Obowiązkowe szyfrowanie wszystkich faktur
  • wprowadzono nową parę kluczy RSA o długości 4096 bit oraz padding OAEP z SHA-256 i MGF1-SHA256
  • zmiany w endpointach
  • wsadowa: każda faktura przetwarzana jest niezależnie [nareszcie!]
  • publiczne limity wywołań w dokumentacji
  • API do generowania danych testowych

Przy czym:
30 września 2025 r. zostanie udostępniony interfejs programistyczny API KSeF 2.0 do otwartych testów dla wszystkich integratorów i przedsiębiorstw. Udostępnione obecnie materiały umożliwiają już dziś zaplanowanie architektury integracji, przygotowanie zmian oraz opracowanie prototypów. Wszystkie dokumenty będą na bieżąco rozwijane i aktualizowane aż do momentu uruchomienia środowiska testowego.

To znaczy, że to nie jest wersja ostateczna? Że nawet czytanie teraz dokumentacji i robienie (bez możliwości testowania) i tak na próżno i w praktyce to dopiero po 30.09 będzie się można brać za robotę? Zatem mamy realnie 2 miesiące na zapoznanie się z dokumentacją, napisanie klienta i integracja z oprogramowaniem tak, żeby zostały 2 miesiące na szkolenia tysięcy ludzi w kraju (przynajmniej w naszym przypadku).

Dzyszla
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 184
0

Z ciekawości dałem Coilotowi przejrzenie biblioteki klienckiej Java. Niby wygląda nie najgorzej. Ciekaw jestem, jak się komuś tego będzie używać. Ja nie poużywam i tak żadnej. :(

Here are some potential bugs or problematic areas detected in the CIRFMF/ksef-client-java project based on the code and comments:

Random NIP Generation Logic:
    In TestUtils.generateRandomNIP(), the method uses random.nextInt(1,10), which generates numbers from 1 to 9, never 0. Polish NIP numbers can contain zeros, so this may not produce valid test NIPs.
    Example:
    Java

sb.append(random.nextInt(1,10)); // Generates digit 0-9

Should be random.nextInt(0,10) to allow zeros.

Hardcoded Sleep Delays in Integration Tests:

Many integration tests use Thread.sleep() with hardcoded values (e.g., 5000 ms). This can make tests slow and flaky, especially in CI environments, and may not always guarantee the required state is reached.
Example:
Java

Thread.sleep(5000);

TODO Comments Indicating Known Issues:

In OnlineSessionIntegrationTest, the comment //TODO FAKTURY SIE NIE PRZETWARZAJĄ suggests invoices are not being processed as expected—a likely bug or incomplete implementation.
In EntityPermissionIntegrationTest, the comment //TODO NIE ZWRACA Ról indicates that roles are not being returned—another possible bug.

Possible Inconsistency in Test Assertions:

In TokensIntegrationTest, after generating three tokens, the code asserts the filtered list size is exactly 3:
Java

    Assertions.assertEquals(3, filteredTokens.size());

    If previous tokens exist or are not cleaned up between test runs, this assertion may fail.

Potential Off-by-One Error in File Splitting:
    In BatchIntegrationTest, the code uses Arrays.copyOfRange(zipBytes, start, start + size); inside a loop for splitting files. If the calculations of start and size are not correct, this could result in missing or overlapping bytes.

Dependency Version Mix and Potential Instabilities:
    The project mixes JUnit 4.x and 5.x dependencies (junitVersion = "4.4", junitJupiterVersion = "5.10.3"). This can cause confusion, especially if both are used in the same test suite.
    Also, the dependency org.apache.commons:commons-collections4:4.5.0-M2 is a milestone (unstable) version. Production code should use release versions.

Resource Handling in Tests:
    In BatchIntegrationTest, the method reads a resource with BaseIntegrationTest.class.getResourceAsStream(...) but does not check for null. If the resource is missing, this will throw a NullPointerException.

General: Lack of Exception Handling in Some Test Utility Methods:
    Some test helper methods may not robustly handle IO or checked exceptions, which can lead to test instability.

Summary:
Most of the issues are in test code, but some (like random NIP generation and TODOs about unimplemented features) may point to deeper bugs or missing functionality. It is recommended to:

Fix the NIP generation logic.
Replace Thread.sleep() with more reliable synchronization.
Address all TODOs.
Ensure proper resource handling.
Review dependency versions for stability.

Let me know if you want to see more detailed code examples or further analysis of a specific area!

AL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6
0

Czy jest gdzieś dostępna broszura informacyjna dla FA(3)? Dla wersji roboczej jest dostępna ale nie widzę nic takiego dla wersji ostatecznej FA(3).
https://ksef.podatki.gov.pl/ksef-na-okres-obligatoryjny/struktura-logiczna-fa-3/

KU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 25
0

Nowa wersja API wymaga szyfrowania RSA-OAEP z funkcją skrótu SHA-256 (MGF1). W technologii w której piszę nie ma dostępnych bibliotek pod tego rodzaju szyfrowanie więc musi powstać coś własnego. Wiecie może czy jest jakaś możliwość sprawdzenia czy wynik szyfrowania jest prawidłowy?

P2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 9
0

Cześć) Może ktoś podpowie, czy jest możliwość pobrania PDF'a faktury przez API?

GS
  • Rejestracja: dni
  • Ostatnio: dni
0

Czyli, jak dobrze zrozumiałem, to póki co jest tylko opublikowana dokumentacja API v2 ale bez żadnej możliwości wykonania jakichkolwiek testów ??

GigaKatowice
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 26
1

Zadałem ostatnio pytanie KIS (Krajowa Informacja Skarbowa) czy poza środowiskiem testowym planują również uruchomić środowisko DEMO dla KSeF 2.0 (tak jak to jest teraz w KSeF 1.0).
Dostałem dziś od nich odpowiedź:

Kopiuj
Informujemy, że uruchomienie środowiska TR (środowisko przedprodukcyjne - DEMO), które integratorzy będą wykorzystywali do testów integracji w oparciu o rzeczywiste dane do autoryzacji i uwierzytelniania w systemie KSeF, planowane jest na druga połowę października 2025 r.
AW
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 8
0

Jakiś czas temu była w tym miejscu dostępna robocza wersja struktury FA(3). Był też plik z projektowanymi zmianami w FA(3) w porównaniu do FA(2). Obecnie nie mogę znaleźć ani tego ani tego.

Czy wiecie coś na temat zmian między FA(3) roboczą a FA(3) oficjalną? Może ktoś posiada zapisany plik schemat.xsd wersji roboczej FA(3)?

Dzyszla
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 184
0
awyduba napisał(a):

Jakiś czas temu była w tym miejscu dostępna robocza wersja struktury FA(3). Był też plik z projektowanymi zmianami w FA(3) w porównaniu do FA(2). Obecnie nie mogę znaleźć ani tego ani tego.

Czy wiecie coś na temat zmian między FA(3) roboczą a FA(3) oficjalną? Może ktoś posiada zapisany plik schemat.xsd wersji roboczej FA(3)?

A jednak znalazłem starszy FA(3).
zmiany są raczej kosmetyczne:

Kopiuj
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:etd="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2022/01/05/eD/DefinicjeTypy/" xmlns:tns="http://crd.gov.pl/wzor/2025/04/03/04031/" targetNamespace="http://crd.gov.pl/wzor/2025/04/03/04031/" elementFormDefault="qualified" attributeFormDefault="unqualified" xml:lang="pl">
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:etd="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2022/01/05/eD/DefinicjeTypy/" xmlns:tns="http://crd.gov.pl/wzor/2025/06/25/13775/" targetNamespace="http://crd.gov.pl/wzor/2025/06/25/13775/" elementFormDefault="qualified" attributeFormDefault="unqualified" xml:lang="pl">
 	<xsd:import namespace="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2022/01/05/eD/DefinicjeTypy/" schemaLocation="http://crd.gov.pl/xml/schematy/dziedzinowe/mf/2022/01/05/eD/DefinicjeTypy/StrukturyDanych_v10-0E.xsd"/>
 	<xsd:simpleType name="TKodyKrajowUE">
 		<xsd:annotation>
@@ -1101,7 +1101,7 @@
 				</xsd:annotation>
 				<xsd:simpleType>
 					<xsd:restriction base="etd:TDataCzas">
-					<xsd:minInclusive value="2022-01-01T00:00:00Z"/>
+					<xsd:minInclusive value="2025-09-01T00:00:00Z"/>
 						<xsd:maxInclusive value="2050-01-01T23:59:59Z"/>
 					</xsd:restriction>
 				</xsd:simpleType>

Czyli zmiany w adresach schemy i zmiana minimalnej daty dla DataWytworzeniaFa.

TO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 22
0

Sprawdzał ktoś, czy dałoby się tę ich DLL przerobić na obsługę aktualnej wersji KSEF?
Czy różnice są raczej za duże?
Da się jakoś prosto porównać interfejsy (endpointy, struktury body, resulty itp)?

Trochę bez sensu, że nie będzie możliwości by poużywać tej ich DLL produkcyjnie PRZED obowiązkowym KSEF.
Nagle 1 lutego trzeba będzie się przełączyć z "własnych DLL" na ich DLL i nie będzie miało prawa nie działać, bo obowiązek...

RA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 57
0

Czy ktoś patrzył na to openapi.json?
W kilku miejscach gdzie jest mowa o uprawnieniach (np AuthenticationToken, GenerateTokenRequest i kilka innych np InvoicesQueryRequest, InvoicesAsynqQueryRequest ) są struktury z listą enumów. Dla AuthenticationToken jest np:

Kopiuj
"AuthenticationToken": {
        "type": "object",
        "properties": {
   ...      
          "requestedPermissions": {
            "enum": [
              "InvoiceRead",
              "InvoiceWrite",
              "CredentialsRead",
              "CredentialsManage"
            ],
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TokenPermissionType"
            },
            "description": "Uprawnienia przypisane tokenowi.",
            "nullable": true
          },
   ...
        },
        "additionalProperties": false
      }

gdzie TokenPermissionType:

Kopiuj
 "TokenPermissionType": {
        "enum": [
          "InvoiceRead",
          "InvoiceWrite",
          "CredentialsRead",
          "CredentialsManage"
        ],
        "type": "string"
      },

Czy mi się wydaje czy definiowanie "enum" w AuthenticationToken.requestedPermissions jest co najmniej no... ekhm? Niby wartości się zgadzają ale przez tą duplikację próba wygenarowania klienta będzie problematyczna mówiąc najgrzeczniej.
W ich libce do javy nie widzę openapi.json ale jest ksefApi.yaml a w nim AuthenticationToken wygląda już tak:

Kopiuj
"AuthenticationToken": {
        "type": "object",
        "properties": {
    ...      
          "requestedPermissions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TokenPermissionType"
            },
            "description": "Uprawnienia przypisane tokenowi.",
            "nullable": true
          },
    ...
        },
        "additionalProperties": false
      },
WJ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 47
1

Uwagi do biblioteki .NET dla KSeF MF (mogą się przydać tym, którzy zaglądają do niej po raz pierwszy):

Struktura projektu:
W folderze głównym projektu nie ma niczego istotnego, Najważniejszy jest folder Http. Zawiera pliki:

KSeFClient.cs:
implementacja podstawowego interfejsu biblioteki (udostępnia metodę dla każdego enpointu API)

RestClient.cs:
pomocniczy (wyspecjalizowany klient HTTP), wykorzystywany przez KSeFClient.

JsonUtil:
pomocniczy (prosty "wrapper" wokół JsonSerializer, aby co chwila nie odwoływać się do opcji przyjętych dla tej biblioteki API)

Kod KSeFClient i JsonUtil jest przejrzysty. W zasadzie każde wywołanie API w KSeFClient to wstawienie parametrów wejściowych do odpowiedniej struktury i wywołanie RestClienta, aby ją wysłał. Otrzymany wynik jest deserializown przez JSON do odpowiedniej strukturki rezultatu.

Drugim ważnym folderem jest Api/Services. To takie opcjonalne dodatki ("procedury wyższego rzędu") z których można korzystać. Zawiera:

AuthCoordinator.cs:
Zarządzanie parą tokenów dostępowych (access tokens). Dwie metody na ich uzyskanie: 1. za pomocą certyfikatu; 2. za pomocą tokena autoryzacji. Oprócz tego metoda na odświeżenie tokena i na jego wyłączenie.

CryptographyService.cs:
Grupa przydatnych funkcji pomocniczych (wykorzystywanych m.in. w projekcie MF testującym API)

SignatureService.cs:
Grupa przydatnych funkcji pomocniczych (wykorzystywanych m.in. w projekcie MF testującym API)

Ocena
Ogólnie rzecz biorąc, struktura projektu tej biblioteki jest czytelna, szczególnie gdy już się znajdzie początek (czyli KSeFClient.cs). Kod jest zrozumiały.

WJ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 47
1

Zauważone niedociągnięcia w bibliotece .NET API KSeF (i "po sąsiedzku" - Javy)
To nie błędy, ale - parafrazując pozytywną nowomowę - "obszary do poprawy". Do każdego z nich proponuję poprawkę - czy możecie mi podpowiedzieć, czy się nie mylę, i czy warto to zgłaszać jako Issue w GitHub / helpdesku KSeF?

Więc po kolei:

#1 RestClient.cs
RestClient to bardzo ważna klasa biblioteki .NET (właściwie to ona obsługuje logikę każdego wywołania API). A wygląda jak coś zmienianego, na różnych etapach przez różnych autorów, którzy woleli szybko powielić jakiś kod zamiast się nad nim pochylić. Zawiera trzy metody o tej samej nazwie SendAsync, o coraz mniejszej liczbie parametrów. I każda z nich powstała chyba przez jakieś "copy/paste", bo zawierają (prawie) takie same bloki kodu.

*Wariant SendAsync() z największą liczbą parametrów jest podstawowym - wykorzystany w 47 miejscach. W IRestClient jest zdefiniowana tak:

Kopiuj
public Task<TResponse> SendAsync<TResponse, TRequest>(
HttpMethod method,
string url,
TRequest requestBody = default,
string bearerToken = null,
string contentType = "application/json",
CancellationToken cancellationToken = default,
Dictionary<string, string> additionalHeaders = null);

Aby logika jej implementacji pozwalała na obsługę pozostałych wariantów, wystarczyłoby zamienić wiersz 62 w obecnym pliku RestClient.cs
z takiego:

Kopiuj
var content = await response.Content.ReadAsStreamAsync(cancellationToken);

na taki:

Kopiuj
Stream content = null;
if (response.Content != null) content = await response.Content.ReadAsStreamAsync(cancellationToken);

*Pierwsze uproszczenie SendAsync(), używane w implementacji: CloseBatchSession, ClientRevokeCertificate, zwraca Task zamiast Task<TResponse> i nie ma opcjonalnego argumentu z dodatkowymi nagłówkami. Zamiast obecnego powielenia kodu, można byłoby potraktować jako szczególny przypadek metody poprzedniej:

Kopiuj
public Task SendAsync<TRequest>(
HttpMethod method,
string url,
TRequest requestBody = default,
string bearerToken = null,
string contentType = "application/json",
CancellationToken cancellationToken = default)
{
	return SendAsync<object?, TRequest>(method,url,requestBody,bearerToken,contentType,cancellationToken);
}

*Drugie uproszczenie SendAsync(), użyte w implementacji: RevokeAccessToken, CloseOnlineSession, RevokeKsefToken, nie ma opcjonalnego TRequest, a contentType jest "na zicher" wpisany otwartym tekstem zamiast stałą (inna sprawa, że tak zdefiniowali go we wzorcowym interfejsie). Podobnie jak poprzednio, można to wyrazić jako szczególny przypadek poprzedniej metody:

Kopiuj
public Task SendAsync(
HttpMethod method,
string url,
string bearerToken = null,
string contentType = "application/json",
CancellationToken cancellationToken = default)
{	
	return SendAsync<object?>(method, url, null, bearerToken, contentType, cancellationToken);
}

(Na marginesie: argument bearerToken to accessToken. Tak się autorom interefejsu skojarzyło, bo nagłówek HTTP z tokenem JWT wygląda tak: "Authorization: Bearer eyJhbGciOiJIUzI1NiIXVCJ9TJV...r7E20RMHrHDcEfxjoYZgeFONFh7HgQ")

W IRestClient jest jeszcze metoda GetPemAsync(), która jest zwykłym pobraniem pliku publicznego certyfikatu (*.pem). Użyta tylko raz, w konstruktorze pomocniczej klasy CryptographyServices(.cs), wygląda na jakąś rozpaczliwą łatkę (por poniżej), która zniknie w docelowej implementacji. Nie warto jej optymalizować.

[Jak sądzicie - zgłosić taką optymalizację jako Issue do projektu .NET na GitHub?]

#2 CryptographyServices
W konstruktorze klasy umieszczono poprawny ("na oko") kod pobierający certyfikaty serwera za pomoca oficjalnej, dedykowanej metody API (kSeFClient.GetPublicCertificates(default) - czyli /api/v2/security/public-key-certificates). Ale ten kod jest skomentowany!
ZAMIAST tego plik certyfikatu jest "ściągany" zwykłym, statycznym HTTP:GET (por. metoda RestClient.GetPemAsync())
Żeby było ciekawiej: w równoległej bibliotece Java ekwiwalent tej funkcji też tak robi. Tylko tam jest to głębiej "zakopane" w DefaultKsefClient.getPublicKey() woła PublicKeyEnvironmentApi.apiV2PublicKeyGet(), a ta woła metodę o nazwie apiV2PublicKeyGetWithHttpInfo(), która ściąga plik *.pem.

[Tego bym na razie nie ruszał, bo wygląda że mają ze swoim API problem]. (Na marginesie: żeby taki "wrapper" jak v2/security/public-key-certificates, zwracający stałą odpowiedź, nie działał, to - moje uszanowanie :)).

#3 XadeSDummy(.cs):
po co do tych ogólnie użytecznych serwisów dodano coś takiego? Jedyna metoda tej klasy tworzy na lokalnym dysku plik xml do nazwie "ksefDummySign_{guid}.xml", i czeka przez 5 minut na pojawienie się nowego pliku z "ksefDummySign_{guid} (1).xml", który będzie z podpisem cyfrowym.
Ta klasa jest wykorzystywana przez środowisko (projekt) z przebiegami testowymi i przykładowy projekt portalu ASP .NET.
Gdyby chociaż gdzieś napisali jakiś komentarz, żeby ten dziwoląg ignorować! Coś takiego powinno się umieszczać w tych testach /
przykładzie, a nie w finalnej bibliotece. Tylko tworzy niepotrzebną zagadkę "po co to jest"? Zamiast takiego "kwiatka" mogliby ten plik wrzucić i do projektu testowego, i do przykładu. Tym bardziej, że jak pokazuje przypadek RestClient.cs, nie mają oporów z duplikowaniem o wiele ważniejszego kodu.

[Zgłosić to jako Issue do projektu .NET na GitHub?]

#4 Język komunikatów (błędów)
Język zwracanych tekstów nie jest ujednolicony. Programy z folderu Http "mówią" po angielsku, a te z Api/Services - w połowie po polsku. Przy czym moja ulubiona klasa XadeSDummy w jednej metodzie potrafi się odezwać raz tak, raz siak. Podobnie jest z biblioteką Java.
Uważam, że powinni to wszystko przestawić na angielski. (Dlaczego? Bo ten kod nie ma wersji językowych, a zakładam, że wszyscy polscy programiści, którzy się mogą nim zajmować, są obyci z komunikatami po angielsku. W drugą stronę to nie działa :)).

[Zgłosić to jako Issue do projektu .NET na GitHub?]

Dzyszla
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 184
0

Próbował ktoś wysyłać zgłoszenia przez formularz? Ja próbuję i...
screenshot-20250715115901.png

Edit: Udało się w końcu.

KU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 25
0

Myślicie, że certyfikaty które będą jedynym sposobem uwierzytelnienia w 2027 roku to są dokładnie te same co teraz? Czyli wymagające podpisu XADES

KU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 23
0

Czesc, jest ktos moze w stanie wychwycic bład, doslownie wczoraj działalo, dzisiaj generuje challange ale cos sie nie podoba jak wrzucam podpisany xml:
"https://ksef-test.mf.gov.pl/api/online/Session/InitSigned"

blad
"{"exception":{"serviceCtx":"srvTEMFE","serviceCode":"20250718-EX-D895DA4729-5091438A27-2B","serviceName":"online.session.session.signed.init","timestamp":"2025-07-18T08:47:26.901Z","referenceNumber":"20250718-SE-B790ED7D2D-3CF507CF22-BB","exceptionDetailList":[{"exceptionCode":31000,"exceptionDescription":"Nieprawidłowe wywołanie."}]}}"

xml podpisany

<?xml version="1.0" encoding="utf-8"?> <initsessionsignedrequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ksef.mf.gov.pl/schema/gtw/svc/online/auth/request/2021/10/01/0001"> <context> <challenge xmlns="http://ksef.mf.gov.pl/schema/gtw/svc/online/types/2021/10/01/0001">20250718-CR-17DB7E7CA8-FCDFE892A8-B4</challenge> <identifier xmlns:q1="http://ksef.mf.gov.pl/schema/gtw/svc/types/2021/10/01/0001" xmlns="http://ksef.mf.gov.pl/schema/gtw/svc/online/types/2021/10/01/0001" xsi:type="q1:SubjectIdentifierByCompanyType"> <q1:identifier>5555555555</q1:identifier> </identifier> <documenttype xmlns="http://ksef.mf.gov.pl/schema/gtw/svc/online/types/2021/10/01/0001"> <service xmlns="http://ksef.mf.gov.pl/schema/gtw/svc/types/2021/10/01/0001">KSeF</service> <formcode xmlns="http://ksef.mf.gov.pl/schema/gtw/svc/types/2021/10/01/0001"> <systemcode>FA (2)</systemcode> <schemaversion>1-0E</schemaversion> <targetnamespace>http://crd.gov.pl/wzor/2023/06/29/12648/</targetnamespace> <value>FA</value> </formcode> </documenttype> <type xmlns="http://ksef.mf.gov.pl/schema/gtw/svc/online/types/2021/10/01/0001">SerialNumber</type> </context> <signature xmlns="http://www.w3.org/2000/09/xmldsig#" id="Signature"><signedinfo><canonicalizationmethod algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /><signaturemethod algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /><reference id="mainRefId" uri=""><transforms><transform algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /></transforms><digestmethod algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><digestvalue>WSkwFcdOppTiTeMhYtagjvF9aiXDpSo0C01jrqRSfNY=</digestvalue></reference><reference uri="#ObjectRef1" type="http://uri.etsi.org/01903#SignedProperties"><digestmethod algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /><digestvalue>oda+GxObGZNYuDpUFdAXcdl8s5LfZKQWjY3xHqxhBjM=</digestvalue></reference></signedinfo><signaturevalue>TNRltSVTvzrnvHesX8YVRbM5vfJAnf0OrQc6C36kgjMA/SjxHcxs2yzKXQDKg+Sd9t00/VZKSc/o+cLL+RM0Gv93Lh+sanmOKvMQyi3JAKCurmAoLOM3ePjZbEcHA019zZhKN+NGTqS8D/9wAqbsVwrNstwwze0BbmQKP4s3q976oDCUjlPLdZzHApVXETpgxm0neR7pg8d3EVpBNmRrpPxoTZ3pCeegwDEBP2P+sGrZKls8ohxiJxudHWnff2yrpbGtYGt2F2pvbwNoHM02DuuCDGDobgq1vTQ8LZYEVk0DpzkSQu8thQvBJ3rqf3SGPhTDVPXaLixtHt1Ge5FYBg==</signaturevalue><keyinfo><x509data><x509certificate>MIIEIzCCAwugAwIBAgIUdj1NpYycKw+DWHNI+E/We88Zy18wDQYJKoZIhvcNAQELBQAwgbkxGDAWBgNVBAMMD01hcmVrIE1vc3Rvd2lhazESMBAGA1UEBAwJTW9zdG93aWFrMQwwCgYDVQQqDANKYW4xFjAUBgNVBAoMDVRlc3Rvd2EgZmlybWExCzAJBgNVBAYTAlBMMRQwEgYDVQQHDAtNYXpvd2llY2tpZTEXMBUGA1UEBRMOTklQLTExMTExMTExMTExJzAlBgNVBA0MHk1hcmVrIE1vc3Rvd2lhayBOSVAtMTExMTExMTExMTAeFw0yNDA3MTcxMzUzMThaFw0yNTA3MTcxMzUzMThaMIG5MRgwFgYDVQQDDA9NYXJlayBNb3N0b3dpYWsxEjAQBgNVBAQMCU1vc3Rvd2lhazEMMAoGA1UEKgwDSmFuMRYwFAYDVQQKDA1UZXN0b3dhIGZpcm1hMQswCQYDVQQGEwJQTDEUMBIGA1UEBwwLTWF6b3dpZWNraWUxFzAVBgNVBAUTDk5JUC0xMTExMTExMTExMScwJQYDVQQNDB5NYXJlayBNb3N0b3dpYWsgTklQLTExMTExMTExMTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz1wKwjv4TIadxT/gHfFH9PK7lCOyKhqYZeKxdRIXiWLji0gdz+h4AZnQwqal1Qwvn72icqEMfjJPLxXrjlMOxt3K3dC+675m21ElbSCcu9yBjh/GzsZNcaRDexTPJxF4MuuFAbqO58/w86pu83af6uiG1P0IwpSixg3MpPtjJD6HC3db4wL/J8RJ5nP+aX9xRlUiK5JLl7BOjuOFEUyiN9HvOql1dum3q8Xw+iVSrx/i45qYiWZw4ZkiRCFee7Wb8eirUhJFLEFGRH2WHYnVz4iYJlFaTl02Byw29nWn7jh9NTiMe+UVVjC1qq6SJI7xEkNApCsYB+lJgAu2jhkDbAgMBAAGjITAfMB0GA1UdDgQWBBTCkt9G8jNGgCPxM9+0OajPREUSGjANBgkqhkiG9w0BAQsFAAOCAQEAfkYCPbiYW/aJqaLcsqob1eSmdt2Pz3/iHPtgcoCeRxzL2MF+kUqSwSSisstgM3TJsoRVzqdM6g0tTqaSqJT8z6HQQQb8MoHpRr6k+adHL8ee7TZg3vFKXfvMlPQEeVIZ/S/UyM0blrZ49t6JtVwx6q7lv9L/K3HCRAS12AEjeAUU8uHc2xb8dNypaG7h21INKzAQqq4dXaYncl9nMKrX1Fso3GrtN7UWUFFb6YGpEXG0B9cb6aBeM8Pj+V0A5fmI2FnSCwk+fcVUzS5e/a4B0dAMy9nxGDwRr1AD62grcTvKYCBTl/pg51m3TUkBj+L9Gjv24LT+9r0YEDPQZubQ8Q==</x509certificate></x509data></keyinfo><object id="ObjectRef1"><xades:qualifyingproperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" target="#Signature"><xades:signedproperties id="SignedProperties2"><xades:signedsignatureproperties><xades:signingtime>2025-07-18T08:47:13Z</xades:signingtime><xades:signingcertificate><xades:cert><xades:certdigest><digestmethod algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /><digestvalue>/KzJxqlgM0LZIw8BzWPefQOsM2g=</digestvalue></xades:certdigest><xades:issuerserial><x509issuername>Description=Marek Mostowiak NIP-1111111111, SERIALNUMBER=NIP-1111111111, L=Mazowieckie, C=PL, O=Testowa firma, G=Jan, SN=Mostowiak, CN=Marek Mostowiak</x509issuername><x509serialnumber>675028020393833510457487434121168365541249370975</x509serialnumber></xades:issuerserial></xades:cert></xades:signingcertificate></xades:signedsignatureproperties><xades:signeddataobjectproperties><xades:dataobjectformat objectreference="#mainRefId"><xades:mimetype>text/xml</xades:mimetype></xades:dataobjectformat></xades:signeddataobjectproperties></xades:signedproperties></xades:qualifyingproperties></object></signature></initsessionsignedrequest>
Dzyszla
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 184
0

Na Githubie padło bardzo ważne stwierdzenie od autorów:

Tokeny będą obsługiwane do końca 2026 r., po czym ich funkcjonalność przejmą certyfikaty KSeF

QL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1
0

hej, czy komuś już udało się zalogować przez API do wersji DEMO z wykorzystaniem metody InitSigned przy użyciu pieczęci firmowej?
Za każdym razem dostaję "21305: Brak uwierzytelnienia certyfikatu". Sprawdziłem publicKey, strzelam na pewno na demo.
Jakieś sugestie?

ZK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10
0

Czy ktoś orientował się jak będzie wyglądała integracja poprzez Delphi? Załóżmy że użyję bilblioteki .NET, wspomniano o szyfrowaniu faktury, czy wiecie czy są jakieś komponenty do szyfrowania pod Delphi?

M4
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 58
0

mam problem z inicjalizacją sesji, mam błąd
Błąd inicjowania sesji: HTTP 415 -

<?xml version="1.0" encoding="UTF-8"?>

<ns3:InitSessionTokenRequest xmlns:ns2="http://ksef.mf.gov.pl/schema/gtw/svc/types/2021/10/01/0001" xmlns:ns3="http://ksef.mf.gov.pl/schema/gtw/svc/online/auth/request/2021/10/01/0001" xmlns:ns4="http://ksef.mf.gov.pl/schema/gtw/svc/online/types/2021/10/01/0001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> ◀
ns3:Context
ns4:Challenge20250721-CR-F23144184B-C2EFD65384-81</ns4:Challenge>
<ns4:Identifier xsi:type="ns2:SubjectIdentifierByCompanyType">
ns2:Identifier7343170998</ns2:Identifier>
</ns4:Identifier>
ns4:DocumentType
ns2:ServiceServiceKSeF</ns2:Service>
ns2:FormCode
ns2:SystemCodeFA</ns2:SystemCode>
ns2:SchemaVersion1-0E</ns2:SchemaVersion>
ns2:TargetNamespacehttp://crd.gov.pl/wzor/2023/06/29/12648/</ns2:TargetNamespace>
ns2:ValueFA(2)</ns2:Value>
</ns2:FormCode>
</ns4:DocumentType>
ns4:TokenQG/h6wn4xGSHTKDFbQMUejk6Krfk5+pIYtTeSGn4tTNCL6USgEY42QoAKNZeSj/dlgGugPiSmpAFjqmlHvQlisfDlLFNujTuImBhhwqOAZvz6V/1ZcGb8Ct9MiWwJnvARhZeifJwPvV4J9oJ1 ▶
</ns3:Context>
</ns3:InitSessionTokenRequest>
"""

funkcja wygląda jak poniżej
public function initSession(string $initSessionTokenXml)
{
// ✅ Poprawiony endpoint dla autoryzacji tokenem:
$url = "{$this->apiUrl}/online/Session/InitToken";

    $headers = [
        'Content-Type: application/xml',
        'Accept: application/json'
    ];

    dump($initSessionTokenXml);


    $url = "https://ksef-test.mf.gov.pl/api/online/Session/InitToken";
    $headers = [
        'Accept: application/json',
        'Content-Type: application/xml',
    ];
    $response = $this->sendRequest($url, $initSessionTokenXml, $headers, 'POST');

    if ($response['httpCode'] === 200) {
        echo "Sesja zainicjowana.\n";
        print_r(json_decode($response['response'], true));
    } else {
        echo "Błąd inicjowania sesji: HTTP {$response['httpCode']} - {$response['response']}\n";
    }
}
M4
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 58
0

Zmieniłem Content-Type ale nie pomogło, token mam wygenerowany ze strony mf i publicKey.pem z linku do serwera testowego mf dla ksef

M4
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 58
0

Tak robie ale jest ten błąd 415

public function encryptToken($token, $challengeTimeMillis) {
    $dataToEncrypt = "$token|$challengeTimeMillis";
    $publicKey = file_get_contents($this->publicKeyPath);
    if (!$publicKey) {
        echo "Nie można odczytać klucza publicznego.\n";
        return false;
    }

    if (openssl_public_encrypt($dataToEncrypt, $encrypted, $publicKey, OPENSSL_PKCS1_PADDING)) {
        return base64_encode($encrypted);
    } else {
        echo "Nie udało się zaszyfrować tokenu.\n";
        return false;
    }

    return $dataToEncrypt;
}

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.