Integracja Stripe z KSeF: jak faktura ze Stripe staje się FA(3)
Żeby faktury ze Stripe trafiały do KSeF, potrzebujesz trzech rzeczy: czegoś, co nasłuchuje webhooka invoice.finalized, czegoś, co zamienia payload faktury na XML w schemacie FA(3), i czegoś, co uwierzytelnia się w KSeF, otwiera sesję, szyfruje dokument i odbiera numer KSeF wraz z UPO. Możesz to napisać sam, bo protokół jest otwarty i nasza biblioteka też (gem ksef, licencja Apache-2.0), albo podłączyć gotowe: w KSeF Kit łączysz Stripe, podajesz NIP, wklejasz token lub certyfikat i pierwsza faktura idzie do środowiska TEST w kilka minut.
Dalej jest cała mechanika: co dokładnie się dzieje między finalizacją faktury a numerem KSeF, gdzie ta droga najczęściej pęka i ile pracy zostaje po Twojej stronie w każdym z dwóch wariantów. Programista może przejechać po nagłówkach i kodzie, właściciel firmy przeczytać od góry do dołu.
Zanim jednak przejdziemy dalej: obowiązuje schemat FA(3). Jeśli trafiłeś na poradnik, dokumentację albo bibliotekę, która mówi o FA(2), czytasz opis formatu, którego KSeF już nie przyjmuje. To nie jest kosmetyczna zmiana numeru wersji i ma osobną sekcję niżej.
Co musi się wydarzyć, żeby faktura ze Stripe znalazła się w KSeF
Cała droga ma sześć etapów. Żaden z nich nie jest trudny sam w sobie, ale każdy ma miejsce, w którym łatwo zrobić błąd.
- Stripe finalizuje fakturę. Do tego momentu faktura jest szkicem i można ją zmieniać.
Finalizacja to zdarzenie
invoice.finalized, i to ono jest wyzwalaczem. Warto zapisać payload w niezmienionej postaci: to Twój dokument źródłowy i za pół roku będziesz chciał wiedzieć, z czego dokładnie zbudowałeś XML. - Powstaje XML w schemacie FA(3). Z pól faktury Stripe budujesz strukturę
Faktura: sprzedawcę (Podmiot1), nabywcę (Podmiot2), kubełki stawek VAT, pozycje, sumy i adnotacje. Kolejność elementów wynika ze schematu XSD i nie jest dowolna. - Uwierzytelniasz się w KSeF. Pobierasz challenge, podpisujesz go tokenem albo podpisem XAdES, odpytujesz o wynik i odbierasz token dostępowy.
- Otwierasz sesję i wysyłasz dokument. Sesja niesie klucz AES wygenerowany na tę jedną sesję i zaszyfrowany kluczem publicznym KSeF. Fakturę wysyłasz zaszyfrowaną, razem z jej rozmiarem i skrótem SHA-256.
- Zamykasz sesję i odpytujesz o status. Dopiero zamknięcie sesji uruchamia wystawienie UPO. Kiedy dokument zostanie przyjęty, dostajesz numer KSeF i UPO, czyli urzędowe poświadczenie odbioru.
- Zapisujesz numer z powrotem w Stripe. Numer KSeF trafia do metadanych faktury
(
ksef_number), więc widzisz go w panelu Stripe i możesz go odczytać z API. Przy eksporcie dokładamy teżksef_verification_url, czyli adres weryfikacyjny, z którego rysuje się kod QR.
To wszystko musi się zdarzyć dokładnie raz. Faktura wysłana dwa razy to dwa dokumenty w KSeF,
a dokumentu z numerem KSeF nie da się anulować. Dlatego rozdziel etap 4 i 5: najpierw
zapisz u siebie identyfikator sesji i identyfikator faktury, dopiero potem odpytuj o wynik.
Jeśli proces padnie w trakcie odpytywania, masz z czego wznowić i nie kusi Cię, żeby wysłać
dokument jeszcze raz. U nas tak właśnie działa Filing#submit: open_and_send zwraca referencje,
zapisujemy je w bazie, i dopiero wtedy leci await.
FA(3): co się zmieniło i dlaczego FA(2) już nie przejdzie
FA(3) obowiązuje od 1 lutego 2026 r. FA(2) był ważny od 1 września 2023 r. do 31 stycznia
2026 r. i to jest cała historia: nie ma okresu przejściowego, w którym KSeF przyjmuje oba formaty.
Podstawa to ustawa z 5 sierpnia 2025 r. (Dz.U. 2025 poz. 1203). Aktualny schemat to 1-0E,
w przestrzeni nazw z datą 2025/06/25.
Kod pisany pod stary schemat najszybciej poznasz po pozycjach faktury. W FA(2) wiersze siedziały
w opakowaniu <FaWiersze>. W FA(3) <FaWiersz> jest bezpośrednim, powtarzalnym dzieckiem
<Fa> i żadnego opakowania nie ma. Wyemitujesz <FaWiersze>, a KSeF odrzuci fakturę na walidacji
schematu, kodem 21401. Tego rodzaju różnic nie widać w opisach ofertowych, a kosztują popołudnie.
Druga rzecz: kolejność elementów w <Fa> jest sekwencją XSD, nie sugestią. Wygląda tak:
KodWaluty · P_1 · P_2 · kubełki P_13_n/P_14_n · P_15 · Adnotacje · RodzajFaktury
· (blok korekty: PrzyczynaKorekty? · TypKorekty · DaneFaKorygowanej)
· FaWiersz*
Wyemitujesz to w innej kolejności i sesja kończy się odrzuceniem, mimo że wszystkie dane są na miejscu i poprawne.
Trzecia rzecz, o której często się zapomina: korekty wystawiane dziś idą w FA(3), nawet jeśli oryginał był w FA(2) albo FA(1). Nie ma czegoś takiego jak korekta „w schemacie oryginału”.
I czwarta, ważna dla planowania pracy: kontrakt produkcyjnego API jest zamrożony od 22 grudnia 2025 r. To dobra wiadomość, bo znaczy, że integracja napisana raz nie rozjedzie się co miesiąc. Zła jest taka, że zamrożony kontrakt to również koniec wymówek: to, co dziś nie przechodzi, nie przejdzie samo z siebie za kwartał.
Praktyczny test na jakość źródła: jeśli tekst o integracji ze Stripe mówi „XML zgodny ze schematem FA(2)”, opisuje stan prawny sprzed 1 lutego 2026 r. Cała reszta takiego tekstu, łącznie z wyceną pracy i argumentem „zbuduj albo kup”, opiera się na nieaktualnym założeniu.
Jak wygląda faktura ustrukturyzowana od strony pojęć, opisujemy osobno w jak wystawić fakturę ustrukturyzowaną, a same terminy i progi obowiązku w KSeF obowiązkowy 2026.
Trudne miejsca, uczciwie
Poniżej lista rzeczy, które zajmują najwięcej czasu przy własnej integracji. Nie po to, żeby odstraszyć, tylko żeby nikt nie planował dwóch dni na coś, co ma sześć warstw.
Uwierzytelnienie
Są dwie drogi i obie sprowadzają się do podpisania challenge'a pobranego z API.
Token KSeF (maszyna do maszyny): pobierasz challenge, szyfrujesz łańcuch
"{token}|{timestampMs}" algorytmem RSA-OAEP z SHA-256, kluczem publicznym KSeF pobranym
z endpointu certyfikatów, wysyłasz do /auth/ksef-token, odpytujesz o wynik i wymieniasz go na
token dostępowy. Klasyczna pułapka: token szyfrowany jest dosłownie, więc jedna spacja albo
znak nowej linii z kopiowania rozwala uwierzytelnienie i dostajesz kod 450. Dlatego i gem, i sama
aplikacja przycinają wklejoną wartość, zanim cokolwiek z nią zrobią.
Podpis XAdES: budujesz AuthTokenRequest w przestrzeni nazw auth/token/2.1, podpisujesz go
w wariancie enveloped XAdES-BES (SHA-256 nad kluczem RSA albo EC) i wysyłasz jako application/xml.
Dochodzi jeszcze wybór, po czym KSeF ma dopasować certyfikat do podatnika: po polu subject
(certyfikat firmowy z NIP-em) albo po odcisku palca (osobisty certyfikat kwalifikowany, który NIP-u
nie niesie). Na produkcji łańcuch certyfikatów jest weryfikowany, w TEST i DEMO nie, bo tam używa
się certyfikatów samopodpisanych.
Co wybrać, rozkładamy na czynniki w token czy certyfikat KSeF. Skrótowo: opublikowana zasada mówi, że tokeny działają do 31 grudnia 2026 r., a od 1 stycznia 2027 r. zostają same certyfikaty. Ministerstwo Finansów po konsultacjach z 9 czerwca 2026 r. samo zarekomendowało, żeby tokeny jednak zostały, ale to nadal rekomendacja, a nie przepis. Jest przy tym twarde ograniczenie: sesja uwierzytelniona tokenem nie pozwala złożyć wniosku o certyfikat. Z tokena na certyfikat przechodzi więc człowiek, świadomie, a nie skrypt puszczony w nocy.
Szyfrowanie sesji
KSeF nie przyjmuje faktury otwartym tekstem. Na każdą sesję generujesz świeży klucz AES-256
(32 bajty) i wektor inicjujący (16 bajtów), klucz opakowujesz RSA-OAEP z SHA-256 i MGF1-SHA-256,
a fakturę szyfrujesz AES-256-CBC z dopełnieniem PKCS#7. Deklarujesz przy tym cztery wartości,
nie dwie: rozmiar i skrót SHA-256 jawnego XML-a (invoiceSize, invoiceHash) oraz rozmiar i skrót
zaszyfrowanych bajtów (encryptedInvoiceSize, encryptedInvoiceHash), wszystkie w Base64.
Miejsce, w którym prawie każdy się przewraca: w sesji interaktywnej wektor inicjujący idzie osobnym
polem initializationVector, a w sesji wsadowej jest doklejony na początek każdej paczki. Pomylisz
to i dostajesz 21403 (niezgodny skrót) albo 21402 (niezgodny rozmiar), czyli komunikaty, które nie
podpowiadają, gdzie naprawdę leży problem.
Rygor schematu
FA(3) waliduje się twardo i nie wybacza drobiazgów:
- Stawka VAT w
P_12to zamknięty słownik. Wartość spoza niego jest odrzucana, więc lepiej, żeby kod głośno odmówił zbudowania dokumentu, niż wysłał coś, co zostanie odbite. - Nabywca zidentyfikowany (mający NIP, numer VAT-UE albo zagraniczny numer podatkowy) musi
mieć adres. To wymóg art. 106e ust. 1 pkt 3, a pusty
AdresL1jest po prostu niezgodny ze schematem. Nabywca bez żadnego numeru, czyli konsument, adres mieć nie musi. - Sprzedawca i nabywca nie mogą być tym samym NIP-em. KSeF odrzuca
Podmiot1równyPodmiot2, a sesja kończy się statusem 445, czyli „przyjęto zero faktur”.
Waluty i kursy NBP
Kwota VAT w FA(3) zawsze musi być podana w złotych, w polach P_14_xW. Kurs, którego trzeba użyć, to
średni kurs NBP z ostatniego dnia roboczego poprzedzającego moment powstania obowiązku
podatkowego (art. 31a). Tabela A NBP publikowana jest tylko w dni robocze, więc odpytujesz krótkie
okno wstecz i bierzesz ostatni opublikowany kurs, zamiast zakładać, że wczoraj był dzień roboczy.
Najczęstszy błąd: użycie kursu rozliczeniowego Stripe. To kurs, po którym Stripe przewalutował Twoje pieniądze, i do faktury się nie nadaje. Cała mechanika, razem z przypadkami brzegowymi, jest w kursy walut NBP na fakturze.
Korekty
Nota kredytowa w Stripe (credit_note.created) odpowiada fakturze korygującej. W FA(3) to dokument
rodzaju KOR, który w bloku DaneFaKorygowanej wskazuje oryginał: jego numer KSeF, numer własny
i datę wystawienia, plus TypKorekty i opcjonalny powód. Korekta jest osobnym dokumentem
i przechodzi całą tę samą drogę, z własną sesją i własnym UPO.
Faktury z numerem KSeF nie da się anulować. Jedyną drogą wstecz jest korekta, więc zaprojektuj ścieżkę zwrotów tak, żeby nie zakładała cofnięcia dokumentu. Szerzej w korekta faktury w KSeF (KOR).
Kody odrzuceń
Odrzucenia nie są jednorodne i nie ma sensu obsługiwać ich jednym rescue. Dzielą się na rodziny,
a rodzina mówi Ci, po której stronie leży naprawa:
| Kod | Znaczenie | Gdzie naprawiasz |
|---|---|---|
| 21401 | Dokument nie przeszedł walidacji FA(3) | dane albo generator XML |
| 21402 / 21403 | Niezgodny rozmiar albo skrót | transmisja, zwykle wystarczy powtórzyć |
| 21301 / 21304 / 21478 | NIP błędny, brakujący albo nieaktywny | dane nabywcy |
| 21408 | Duplikat, faktura już jest w KSeF | nic nie rób, sprawdź swoje ślady |
| 450 / 401 / 403 / 415 / 425 / 460 | Uwierzytelnienie albo uprawnienia | połączenie z KSeF |
| 21470 | Klucz publiczny się zmienił | pobierz klucz ponownie i powtórz |
| 429 | Za dużo zapytań | odczekaj i ponów, honorując Retry-After |
| 440 / 445 / 21440 | Sesja anulowana, pusta albo zamknięta | otwórz nową sesję |
| 500 / 550 | Błąd po stronie KSeF | ponów później |
Przy pisaniu logiki ponawiania rozstrzyga jedno: 429 i 5xx wolno ponawiać, ale tylko dopóki nie masz jeszcze referencji wysłanego dokumentu. Jeśli wysyłka się udała, a dopiero potem coś padło, faktura jest już w KSeF i ponowna wysyłka zrobi z niej duplikat.
Czego nie ma w danych Stripe
Stripe wygląda na system, który „ma wszystko”. Do zbudowania FA(3) brakuje w nim sześciu rzeczy.
- NIP nabywcy. Stripe trzyma go w
customer_tax_idstylko wtedy, gdy go zebrałeś. Brak numeru to nie drobiazg formalny: bez niego transakcja jest B2C, a więc poza obowiązkiem KSeF. Faktura B2B po cichu zamienia się w konsumencką. - Adres nabywcy.
customer_address.line1bywa puste, a dla nabywcy z numerem podatkowym adres jest obowiązkowy. - Kod GTU i inne oznaczenia. Stripe nie ma pojęcia o polskich oznaczeniach towarów i usług. Jeśli Twoja sprzedaż ich wymaga, muszą pochodzić z Twojej strony.
- Adnotacja o odwrotnym obciążeniu.
P_18to decyzja podatkowa, nie pole ze Stripe. - Eksport usług. Stripe Tax potrafi policzyć podatek, ale nie rozstrzyga, czy to eksport poza polskim VAT, czy odwrotne obciążenie w UE. To dwie różne rzeczy i mylenie ich jest jednym z najczęstszych błędów w polskich poradnikach.
- Pełna lista pozycji. W payloadzie webhooka
linesjest stronicowane po 10 pozycji, z flagąhas_more. Faktura na piętnaście pozycji zbudowana z samego payloadu będzie po prostu niekompletna, a KSeF ją przyjmie, bo formalnie jest poprawna.
Co dokładnie zbierać w Stripe i jak wymusić to w Checkoucie, rozpisujemy w dane klienta w Stripe do faktury KSeF.
Sprzedaż zagraniczna, czyli najczęściej mylona część
Faktura eksportowa B2B też jest objęta KSeF. Obowiązek wynika z art. 106ga ust. 1 i przywiązany jest do wystawcy, a nie do nabywcy. Polska jednoosobowa działalność, która fakturuje spółkę z Delaware, składa tę fakturę do KSeF tak samo jak fakturę dla firmy z Katowic. Do tego art. 106gb ust. 4 mówi, że dokument przekazywany poza systemem musi nieść numer KSeF i kod QR, bo zagraniczny kontrahent do KSeF się nie zaloguje.
Trzy przypadki, trzy różne dokumenty:
- Firma z UE z ważnym numerem VAT-UE. Odwrotne obciążenie przy usługach, samo netto, bez VAT,
P_18=1, kubełeknp II(art. 100 ust. 1 pkt 4). - Firma spoza UE z zagranicznym numerem. Eksport usług poza zakresem polskiego VAT, samo netto,
P_18=2, kubełeknp I. To nie jest odwrotne obciążenie, choć połowa poradników tak to nazywa. - Konsument. W KSeF dobrowolnie, nie obowiązkowo. Procedury OSS i IOSS są poza systemem.
Rozwinięcie z przykładami jest w faktura eksportowa w KSeF, a sam kod QR w kod QR na fakturze KSeF. KSeF tego kodu nie zwraca: liczysz go sam z adresu weryfikacyjnego, NIP-u sprzedawcy, daty wystawienia i skrótu SHA-256 dokładnie tych bajtów XML, które wysłałeś.
Zbudować samemu czy wziąć gotowe
Napiszemy to wprost, choć sprzedajemy narzędzie: samodzielna integracja jest sensowna i wcale nie rzadka. Protokół jest publiczny, Ministerstwo Finansów udostępnia klienty referencyjne, a nasza własna biblioteka protokołu jest otwarta na licencji Apache-2.0, więc nie musisz zaczynać od zera ani prosić nas o zgodę.
Uczciwa ocena pracy, jeśli piszesz w Ruby i korzystasz z gemu: kilka dni na pierwszą fakturę w TEST, a potem od kilku do kilkunastu dni na rzeczy, które decydują o tym, czy to przeżyje kontakt z produkcją. Te rzeczy to:
- kolejka i ponawianie, które nie wysyłają dokumentu dwa razy,
- wznawianie sesji po awarii w połowie odpytywania,
- doczytywanie stronicowanych pozycji faktury ze Stripe,
- klasyfikacja VAT (krajowe, UE, eksport, konsument) razem z decyzją, czego świadomie nie składać,
- kursy NBP i pola
P_14_xW, - korekty KOR wskazujące oryginał,
- odtwarzalność dokumentu, czyli zapisanie znacznika
DataWytworzeniaFaobok skrótu, bo bez niego nie zbudujesz ponownie tych samych bajtów i nie odtworzysz kodu QR, - przechowywanie UPO i sensowna obsługa kodów odrzuceń,
- druga ścieżka uwierzytelniania na moment, w którym token przestanie wystarczać.
Jeśli w firmie jest osoba, która to utrzyma, to dobra droga. Jeśli integracja miałaby być jednorazowym projektem bez właściciela, będzie źródłem cichych problemów, bo błędy w KSeF nie manifestują się jako awaria, tylko jako faktura, której nie ma tam, gdzie powinna być. Więcej o samym API w KSeF API dla programistów, a o poligonie doświadczalnym w środowisko testowe KSeF.
Kod: złożenie faktury gemem ksef
Tak wygląda pełna ścieżka, z podziałem na wysyłkę i odpytywanie, czyli tak, jak powinno się to robić w tle:
require "ksef"
environment = Ksef::Environment.new(:test) # api-test.ksef.mf.gov.pl/api/v2
client = Ksef::Client.new(
env: environment,
authenticator: Ksef::Authenticator::Token.new(
environment: environment,
ksef_token: ENV.fetch("KSEF_TOKEN"),
context_nip: "1111111111"
)
)
invoice = Ksef::Fa3::Invoice.new(
number: "FV/2026/08/17",
issue_date: Date.current,
currency: "PLN",
seller: Ksef::Fa3::Party.new(name: "Moja Firma sp. z o.o.", nip: "1111111111",
country: "PL", address_line1: "ul. Przykładowa 1", address_line2: "00-001 Warszawa"),
buyer: Ksef::Fa3::Party.new(name: "Klient sp. z o.o.", nip: "2222222222",
country: "PL", address_line1: "ul. Testowa 7", address_line2: "30-001 Kraków"),
vat_buckets: [
Ksef::Fa3::VatBucket.new(rate: :standard_23, net: BigDecimal("1000"), vat: BigDecimal("230"))
],
lines: [
Ksef::Fa3::Line.new(name: "Abonament, sierpień 2026", net: BigDecimal("1000"), rate: :standard_23)
],
total: BigDecimal("1230")
)
# Wysyłka bez odpytywania: zapisz referencje, zanim zaczniesz czekać na wynik.
receipt = client.open_and_send(invoice)
receipt.session_reference # identyfikator sesji
receipt.invoice_reference # identyfikator faktury w sesji
receipt.invoice_hash # Base64URL SHA-256 wysłanych bajtów, czyli wyróżnik do kodu QR
receipt.generated_at # znacznik DataWytworzeniaFa tych bajtów
# Odpytywanie, bezpieczne do powtarzania: nic nie wysyła ponownie.
result = client.await(
session_reference: receipt.session_reference,
invoice_reference: receipt.invoice_reference
)
result.ksef_number # np. "1111111111-20260817-..."
result.upo.xml # UPO w oryginale, do przechowania
Kurs NBP i adres weryfikacyjny do kodu QR to osobne, drobne wywołania:
rate = Ksef::NbpRate.lookup(currency: "EUR", date: Date.current)
rate.rate # kurs średni PLN za 1 EUR
rate.effective_date # dzień roboczy, z którego pochodzi
Ksef::VerificationCode.new(
env: :production, nip: "1111111111",
issue_date: Date.current, invoice_hash: receipt.invoice_hash
).url
Kod biblioteki jest na
GitHubie (github.com/startupkit-app/ksef, katalog gems/ksef). Jeśli wolisz uruchomić całą
aplikację u siebie, opisujemy to w samodzielnym hostingu.
Co robi KSeF Kit
Po połączeniu Stripe i KSeF aplikacja robi to:
- Nasłuchuje
invoice.finalizedicredit_note.createdz Twojego konta Stripe i zapisuje payload jako niezmienny dokument źródłowy. - Buduje FA(3): klasyfikuje VAT z kraju nabywcy i jego numeru podatkowego, dobiera kubełek stawki,
ustawia
P_18, przelicza VAT na złote po kursie NBP. - Doczytuje pełną, stronicowaną listę pozycji z API Stripe, więc faktura na 40 pozycji nie zostaje obcięta do 10.
- Uwierzytelnia się tokenem albo certyfikatem, w środowisku TEST albo PROD, i trzyma oba połączenia obok siebie, żeby przejście na produkcję nie oznaczało odłączania testu.
- Składa dokument, zamyka sesję, odbiera numer KSeF i UPO, i przechowuje UPO do pobrania.
- Zapisuje numer KSeF z powrotem w metadanych faktury Stripe, a przy eksporcie dokłada adres weryfikacyjny do kodu QR.
- Notę kredytową zamienia na korektę KOR wskazującą numer KSeF oryginału i dopisuje numer korekty
do noty w Stripe, także w widocznym dla człowieka polu
memo. - Odmawia, kiedy nie jest pewne. Jeśli nabywcy nie da się zaklasyfikować, brakuje adresu albo stawka jest spoza tego, co potrafimy zbudować, faktura zostaje wstrzymana z wyjaśnieniem, zamiast pójść do KSeF jako błędne 23%. Dokument formalnie poprawny, ale merytorycznie zły, KSeF przyjmie, a to jest gorsze niż odrzucenie, bo nikt się o tym nie dowie.
- Pilnuje, żeby dokument poszedł dokładnie raz, także wtedy, gdy dwa procesy wystartują równolegle albo połączenie padnie w połowie.
Ile to kosztuje
Plan darmowy: 6 przyjętych faktur miesięcznie, bez karty. Plany płatne to 9 zł, 49 zł i 129 zł miesięcznie i podnoszą wyłącznie limit. Nigdy nie ograniczamy poprawności dokumentu: żaden plan nie odbiera Ci kodu QR, korekt ani eksportu.
Limit liczy tylko faktury przyjęte przez KSeF. Odrzucenie, wstrzymanie ani nieudana próba go nie zjadają. Nie płacisz za to, że coś nie wyszło.
Jak zacząć
Onboarding ma trzy kroki i tyle:
- Stripe. Autoryzujesz konto albo instalujesz aplikację z Marketplace'u.
- Dane firmy. NIP z weryfikacją w rejestrze MF (biała lista), nazwa i adres sprzedawcy. Kontrola sumy kontrolnej NIP-u dzieje się od razu, więc literówki nie dojdą do KSeF.
- KSeF. Wklejasz token albo wgrywasz certyfikat, wybierasz środowisko.
Zaczynaj od TEST. To środowisko z fikcyjnym uwierzytelnianiem, więc możesz tam wysłać cokolwiek
i niczego nie zepsujesz. Dopiero kiedy zobaczysz pierwszy numer KSeF i pierwsze UPO, przełączasz się
na PROD. Aplikacja podatnika, w której wygenerujesz token albo wniosek o certyfikat, to
ap-test.ksef.mf.gov.pl dla testu i ap.ksef.mf.gov.pl dla produkcji.
Jeśli prowadzisz jednoosobową działalność i zastanawiasz się, co dokładnie Cię dotyczy, zacznij od KSeF dla JDG. Jeśli wystawiasz kilka faktur miesięcznie, plan darmowy prawdopodobnie Ci wystarczy: zobacz darmowy KSeF dla Stripe.