Nordlet

← Blog

Automatyzacja krajowych rozliczeń VAT i walidacji VIES

Praktyczny przewodnik dla deweloperów wdrażających zgodność z przepisami dotyczącymi unijnego VAT-u na platformach handlowych i marketplace'ach przy użyciu chmurowego API księgowego.

Nordlet Team · · 12 min. czytania

Większość błędów związanych z podatkiem VAT w kodzie platform wynika z jednego założenia: że ważny wynik w systemie VIES oznacza możliwość zastosowania stawki 0%. Tak nie jest, a budowanie systemów na tym skrócie prowadzi do deklaracji, które wyglądają poprawnie do momentu, w którym audytor zapyta, dlaczego zastosowano zwolnienie wewnątrzwspólnotowe bez dowodu transportu lub spójnego zapisu miejsca świadczenia. Przepaść między komunikatem „numer VAT jest poprawny” a stwierdzeniem „ta dostawa jest traktowana prawidłowo” to miejsce, w którym najczęściej dochodzi do cichych błędów w integracjach.

Ten przewodnik pokazuje krok po kroku, jak zautomatyzować krajowe raportowanie VAT i walidację VIES za pomocą chmurowego API księgowego, opierając się na API księgowym Nordlet jako kontekście implementacyjnym. Celem jest stworzenie systemu, który gromadzi odpowiednie dowody w momencie sprzedaży, księguje niezmienne wpisy w księdze głównej i generuje dane gotowe do deklaracji, pogrupowane według procedur i państw członkowskich, bez konieczności późniejszego ręcznego składania sum w arkuszu kalkulacyjnym.

Co tak naprawdę oznacza wynik z VIES, a czego nie wyjaśnia

VIES to unijny system wymiany informacji o VAT (EU VAT Information Exchange System). Po podaniu kodu kraju i numeru VAT system w czasie rzeczywistym odpytuje odpowiednią krajową bazę danych i zwraca informację, czy dane podatkowe są ważne, czy nieważne. Na tym kończy się jego rola. Potwierdza on jedynie, że numer jest zarejestrowany, a tam, gdzie kraj członkowski na to pozwala, aktywowany do handlu wewnątrzwspólnotowego.

System ten nie daje jednak prawa do zwolnienia z VAT dostawy wewnątrzwspólnotowej. Komisja Europejska mówi o tym wprost. Ważna odpowiedź z VIES to zaledwie jeden z dowodów. Wciąż musisz potwierdzić, że klient jest rzeczywistym odbiorcą, że transakcja kwalifikuje się jako wewnątrzwspólnotowa, że istnieją dowody transportu lub wysyłki oraz że faktura zawiera wymagane adnotacje o odwrotnym obciążeniu (reverse charge).

Dlatego pierwsza decyzja projektowa ma charakter strukturalny: rozdziel status VIES i traktowanie podatkowe (VAT treatment) na osobne pola. Nigdy nie łącz bezpośrednio viesStatus: valid z zeroRated: true. W momencie, gdy połączysz te pojęcia w jedno, tracisz możliwość obrony przyjętego traktowania podatkowego w przypadku kwestionowania dowodów.

Krok po kroku przed napisaniem kodu integracji

Zanim wywołasz jakikolwiek endpoint, musisz zdefiniować zakres tego, co raportujesz. Ta część bywa nudna, ale jej pominięcie jest kosztowne.

  • Kraje, w których firma posiada siedzibę lub stałe miejsca prowadzenia działalności.
  • Kraje, w których posiada rejestracje do celów VAT.
  • Charakter sprzedaży: towary, usługi, usługi cyfrowe lub ich miks.
  • Charakter transakcji: B2B, B2C lub oba.
  • Stosowane procedury: krajowe rejestracje, OSS, IOSS, odwrotne obciążenie (reverse charge) lub zasady domniemanego dostawcy (deemed-supplier) dla platform handlowych.
  • Oczekiwane wyniki z API: dane do deklaracji krajowych, dane OSS/IOSS, rejestry faktur (takie jak litewski i.SAF), same wpisy księgowe lub pakiety danych dla zewnętrznego dostawcy oprogramowania do składania deklaracji.

Jest to kluczowe, ponieważ procedura OSS nie obejmuje każdej transakcji. Usługi świadczone w kraju, w którym firma posiada stałe miejsce prowadzenia działalności, zazwyczaj podlegają krajowej deklaracji tego państwa, a nie deklaracji OSS. Modeluj stałe miejsca prowadzenia działalności (fixed establishments) niezależnie od samego początku, w przeciwnym razie w momencie agregacji dane zostaną błędnie skierowane.

Nie należy również wpisywać na sztywno jednej stawki VAT na kraj. Unia Europejska stosuje stawki standardowe, obniżone, super-obniżone, parkingowe, stawki zero oraz stawki specyficzne dla produktów, a przepisy te ulegają zmianom. Wiarygodnym źródłem informacji o stawkach dla konkretnego produktu w danym państwie członkowskim jest urząd skarbowy tego kraju, natomiast unijna baza TEDB oferuje przegląd stawek w ujęciu międzypaństwowym. Zapisuj źródło i wersję stojącą za każdą decyzją o stawce, aby późniejsza aktualizacja tabeli stawek nie zmieniła potajemnie sposobu wyświetlania historycznych transakcji.

Modelowanie kwalifikacji podatkowej, a nie tylko samej stawki

Rdzeniem trwałości integracji jest warstwa kategorii podatkowych umieszczona pomiędzy produktami a stawkami. Mapuj produkty na kategorie, kategorie na kody podatkowe specyficzne dla danego kraju, a następnie na stawki z określoną datą obowiązywania:

produkt/usługa
    → kategoria podatkowa
    → kod podatkowy właściwy dla kraju
    → stawka z datą obowiązywania i sposób opodatkowania

Niebezpiecznym podejściem, które prowadzi do rozbieżności w raportowaniu, jest schemat SKU produktu → 21% VAT. Ten sam produkt ma różne stawki w różnych krajach, a stawka może zmienić się w środku okresu rozliczeniowego. Oficjalne wytyczne Nordlet dotyczące zgodności z VAT zalecają dokładnie takie mapowanie oparte na kategoriach, zamiast wiązać produkty bezpośrednio z procentami.

Twoja taksonomia kategorii podatkowych powinna być stabilna i wewnętrzna: towary opodatkowane stawką standardową, towary opodatkowane stawką obniżoną, usługi świadczone drogą elektroniczną, usługi zwykłe, dostawy zwolnione, dostawy opodatkowane stawką 0%, wewnątrzwspólnotowe transakcje B2B z odwrotnym obciążeniem, wewnątrzwspólnotowa sprzedaż wysyłkowa, import IOSS, transakcje z domniemanym dostawcą. Wszystkie procesy downstream bazują na tej taksonomii.

Walidacja VIES jako asynchroniczny przepływ dowodów

Oficjalna usługa VIES udostępnia interfejs SOAP/WSDL przyjmujący dwuliterowy kod kraju oraz numer VAT. Opisane w dokumentacji błędy mają kluczowe znaczenie dla obsługi wyjątków: nieprawidłowe dane wejściowe, globalne i krajowe limity równoległych zapytań, niedostępność usługi, niedostępność systemów państwa członkowskiego oraz przekroczenia limitu czasu (timeouts). Traktuj je jako odrębne rezultaty, a nie jako jeden uniwersalny worek z napisem „błąd”.

Przepływ pracy odporny na obciążenie i audyt wygląda następująco:

  1. Normalizuj numer VAT: zamień prefiks na wielkie litery, usuń dozwolone spacje lub znaki interpunkcyjne, a oryginalną wartość wprowadzoną przez użytkownika zachowaj osobno.
  2. Przed wykonaniem zapytania sieciowego zweryfikuj lokalnie format kodu kraju oraz kształt numeru.
  3. Wyślij znormalizowany numer do systemu VIES.
  4. Zapisz znormalizowany identyfikator, znaczniki czasu żądania i odpowiedzi, status (ważny / nieważny / nieprzetworzony), surową odpowiedź, wszelkie błędy usługi, identyfikatory klienta i faktury oraz podjętą decyzję systemową.
  5. Pamięć podręczna (cache) dla pomyślnych wyników powinna działać przez określony, udokumentowany okres.
  6. Ponawiaj próby obsługi tymczasowych błędów technicznych z zastosowaniem strategii wycofywania wykładniczego (backoff).
  7. Kieruj nierozstrzygnięte lub sprzeczne przypadki do weryfikacji manualnej.
  8. Dokonaj ponownej walidacji, gdy zbuforowany wynik się przedawni lub przed przeprowadzeniem transakcji, w której dowód ma kluczowe znaczenie.

Nordlet sprawdza unijny numer VAT w momencie dodawania klienta i ponawia sprawdzenie przed wystawieniem faktury, jeśli wcześniejszy wynik jest przestarzały. Jest to zachowanie, które warto replikować niezależnie od tego, czy weryfikacja odbywa się na platformie, czy we własnym kodzie.

Złota zasada: nie uzależniaj procesu finalizacji zakupu (checkout) od synchronicznej komunikacji z VIES. Awaria usługi to nie to samo co nieważny numer. Jeśli w trakcie sprzedaży wystąpi przekroczenie czasu oczekiwania VIES, wstrzymaj transakcję do weryfikacji lub przypisz jej status tymczasowy. Blokowanie zakupu ze względu na dostępność usług Komisji to generator zgłoszeń do supportu, a błędne zaklasyfikowanie dobrego klienta jako nieważnego jest jeszcze gorsze.

Oddzielenie statusu walidacji od kwalifikacji podatkowej

Gdy znasz już wynik VIES, silnik decyzyjny ma przed sobą dalszą pracę. Zapisuj te dane jako odrębne pola:

{
  "viesStatus": "valid",
  "vatTreatment": "intra_eu_b2b_reverse_charge",
  "evidenceStatus": "reviewed",
  "placeOfSupply": "DE"
}

Przed zastosowaniem odwrotnego obciążenia lub zwolnienia silnik powinien przetestować, czy klient faktycznie jest odbiorcą, czy kraj klienta i prefiks VAT są ze sobą spójne, czy dostawa kwalifikuje się jako wewnątrzwspólnotowa, czy mają zastosowanie specjalne reguły miejsca świadczenia, czy istnieją dowody transportu, czy sprzedawca działa jako domniemany dostawca oraz czy faktura zawiera wymagane sformułowania. Ważny status VIES, który nie przechodzi żadnego z tych testów, nie jest zielonym światłem.

Tworzenie niezmiennego rozstrzygnięcia podatkowego w momencie fakturowania

Podczas wystawiania faktury zapisz pełną decyzję wraz z nią, a nie tylko ostateczną stawkę:

faktura
  ├─ kategoria podatkowa pozycji
  ├─ miejsce świadczenia
  ├─ procedura VAT
  ├─ stawka właściwa dla kraju
  ├─ wersja tabeli stawek
  ├─ odniesienie do dowodu VIES
  ├─ odniesienia do dowodów lokalizacji
  ├─ odniesienie do podstawy prawnej
  └─ flagi roli marketplace'u

Przepisy unijne dotyczące fakturowania wymagają podania danych dostawcy i nabywcy, numeru faktury, opisu, kwoty opodatkowanej, stawki VAT, kwoty VAT oraz wszelkich informacji o odwrotnym obciążeniu lub zwolnieniu. Faktury korygujące i modyfikacje muszą zawierać jednoznaczne odwołanie do faktury pierwotnej.

Księga główna Nordlet jest niezmienna (immutable), co oznacza, że korekty odbywają się poprzez nowe wpisy, takie jak faktury korygujące lub zapisy odwracające, a nie poprzez edycję zamkniętych rekordów. Oprzyj architekturę systemu na tym modelu, nawet jeśli Twoja baza danych technicznie pozwalałaby na nadpisywanie danych. Edycja zamkniętej faktury niszczy powiązanie między pierwotną deklaracją a korektą, czyli dokładnie ten ślad rewizyjny, po którym porusza się audytor.

Księgowanie, webhooks i idempotencja

Sprzedaż generuje wpisy księgowe metodą podwójnego zapisu, które zachowują zarówno transakcję handlową, jak i zobowiązanie z tytułu VAT w rozbiciu na kraje i procedury. Sprzedaż krajowa może wygenerować następujące księgowanie:

Wn Należności od odbiorców / rozliczenie płatności
    Ma Przychód ze sprzedaży
    Ma VAT należny - DE - krajowy

Wewnątrzwspólnotowa transakcja B2B z odwrotnym obciążeniem generuje przychód bez podatku należnego oraz odnośnik do dowodu zastosowania odwrotnego obciążenia. Sam plan kont zależy od Ciebie; liczy się to, aby wymiary raportowe były przypisane do każdego zapisu: państwo członkowskie, procedura, kategoria podatkowa, stawki, okres, faktura źródłowa oraz ślad powiązań korekt.

Steruj zmianami stanu za pomocą webhooków zamiast odpytywania (polling). Nordlet emituje zdarzenia takie jak sale_invoice.paid, podpisuje doręczenia i ponawia próby w przypadku niepowodzenia z użyciem strategii backoff. Nadaj każdemu zapisowi deterministyczny klucz idempotencji:

sale:{platform_order_id}:invoice:{invoice_version}

Twój odbiorca webhooków również musi być idempotentny. Webhook może dotrzeć dwukrotnie, opóźnić się lub wywołać zdarzenie po tym, jak pierwotne żądanie już zakończyło się sukcesem. Weryfikuj podpisy, rejestruj identyfikator zdarzeń, odizolowuj nieprawidłowe komunikaty, przetwarzaj je przez trwałą kolejkę (durable queue) i regularnie uzgadniaj stan webhooków z API. Jeśli nie pracowałeś wcześniej z podpisanymi webhookami i kluczami idempotencji, to właśnie tam czają się najsubtelniejsze błędy zduplikowanych zapisów.

Agregacja dla celów OSS i generowanie danych gotowych do deklaracji

W przypadku kwalifikujących się transakcji OSS, pogrupuj dane z księgi głównej według procedury, państwa członkowskiego konsumpcji, rodzaju dostawy, kategorii stawki, samej stawki, kwoty opodatkowanej, kwoty VAT, państwa członkowskiego wysyłki lub siedziby, waluty oraz okresu korekt.

Deklaracja w ramach unijnej procedury OSS rozdziela dostawy według państw członkowskich konsumpcji i odróżnia usługi świadczone z państwa członkowskiego identyfikacji, usługi ze stałych miejsc prowadzenia działalności w innych krajach oraz towary wysyłane z różnych państw członkowskich. Raportuje ona kwoty opodatkowane i kwoty VAT oddzielnie dla stawek standardowych i obniżonych. Dostawy zwolnione i opodatkowane stawką 0% w ogóle nie trafiają do deklaracji OSS.

Kilka szczegółów operacyjnych, które często zaskakują:

  • Okresy rozliczenia OSS (unijnego i nieunijnego) są kwartalne; dla IOSS okres jest miesięczny. Deklaracje i płatności są wymagalne do końca miesiąca następującego po okresie rozliczeniowym.
  • Deklaracja zerowa (nil return) jest wymagana za każdy okres, nawet jeśli nie dokonano w nim żadnych istotnych dostaw. Wygeneruj listę kontrolną okresów i automatycznie twórz zwroty o wartości zerowej.
  • Deklaracje OSS są sporządzane w euro, przy użyciu kursu wymiany EBC z ostatniego dnia okresu podatkowego, jeśli wymagane jest przeliczenie. Zapisz walutę źródłową, kurs wymiany, datę kursu, kwotę po przeliczeniu oraz zastosowaną metodę.

Eksport danych powinien pochodzić z zablokowanej księgi głównej, nigdy z bocznego arkusza kalkulacyjnego. Sumy w arkuszach tracą informacje o korektach, krajach wysyłki, stawkach i dowodach. Eksport zawiera okres rozliczeniowy, procedurę, państwo członkowskie konsumpcji, kraj wysyłki, kategorię dostawy, stawkę, kwoty opodatkowane i VAT, walutę i zastosowany kurs wymiany, kwoty korekt bieżącego i poprzednich okresów, identyfikatory faktur źródłowych, odniesienia do faktur korygujących oraz sumy uzgodnienia.

Bądź precyzyjny co do tego, co dostarcza w tym zakresie samo API. Nordlet oblicza deklaracje OSS i IOSS na podstawie faktur i księgi głównej (włączając korekty za poprzednie okresy), dostarcza pakiety deklaracji krajowych dla Litwy (FR0600), Niemiec (UStVA) i Polski (JPK_V7M) oraz generuje gotowe dla VMI rejestry i.SAF dla Litwy. To są dane gotowe do deklaracji. Jedno wywołanie API nie wysyła deklaracji VAT każdego kraju przez każdą krajową bramkę, a żadna deklaracja nie jest składana do urzędu w Twoim imieniu. Traktuj księgowość, generowanie deklaracji, eksport, przesyłanie przez bramki i potwierdzenie płatności jako odrębne stany w swoim systemie. Przewodnik po unijnym silniku VAT dokumentuje, które przypadki silnik rozwiązuje i kiedy uruchamiają się jego ostrzeżenia.

Zamknięcie okresu

Po przeglądzie i zatwierdzeniu uzgodnij faktury z wpisami w księdze głównej, uzgodnij salda VAT z zestawieniem danych do deklaracji, wyeksportuj deklarację, zarejestruj dane dotyczące złożenia i płatności, a następnie zamknij okres. Nordlet blokuje księgowania do zablokowanego miesiąca, również za pośrednictwem API. Korekty po zamknięciu okresu trafiają do okresu późniejszego z wyraźnymi odnośnikami do dokumentu pierwotnego oraz dotkniętego korektą okresu deklaracyjnego.

Typowe scenariusze błędów i sposoby ich unikania

Scenariusz błędu Dlaczego do niego dochodzi Sposób mitygacji
Traktowanie ważnego wyniku VIES jako wystarczającego do zastosowania stawki 0% VIES nie potwierdza prawa do zwolnienia Przechowuj dowody dotyczące klienta, dostawy, transportu i faktury obok samego wyniku
Traktowanie nieważnego wyniku jako dowodu braku rejestracji Numer może nie być aktywowany do handlu wewnątrzwspólnotowego lub baza danych może mieć opóźnienia Rozróżniaj statusy: nieważny, nieprzetworzony i błąd techniczny; spory kieruj do weryfikacji
Uzależnienie finalizacji zakupu od synchronicznego VIES Limity równoległych zapytań, przekroczenia czasu, awarie Walidacja asynchroniczna, krótkotrwałe buforowanie, backoff, stany tymczasowe
Wieczne buforowanie wyników w cache Status rejestracji i aktywacji ulega zmianie Zapisuj znaczniki czasu i ważność; sprawdzaj ponownie przed fakturowaniem, jeśli dane są przestarzałe
Bezpośrednie mapowanie produktów na stawki procentowe Stawki i zwolnienia zależą od kraju i daty Produkt na kategorię, kategoria na kod kraju, a następnie stawka z datą obowiązywania
Rekonstrukcja OSS z arkuszy kalkulacyjnych Sumy pomijają korekty, kraje wysyłki, dowody Wyprowadzaj dane z niezmiennej księgi głównej z wymiarami przypisanymi do każdego wpisu
Uwzględnianie usług świadczonych w ramach stałego miejsca prowadzenia działalności w OSS Niektóre usługi podlegają deklaracji krajowej Modeluj stałe miejsca działalności oddzielnie, kieruj ruch według procedur przed agregacją
Pomijanie zerowych deklaracji Procedura OSS wymaga deklaracji w każdym okresie Generuj listę kontrolną i automatycznie twórz deklaracje o wartości zerowej
Edycja zamkniętych faktur w celu dokonania korekty Niszczy powiązanie między deklaracją a korektą Używaj faktur korygujących i wpisów odwracających w późniejszym okresie

Od czego zaczęlibyśmy w pierwszej kolejności

Gdybyśmy zaczynali tę integrację jutro, najpierw zbudowalibyśmy warstwę kategorii podatkowych oraz rejestr decyzji dotyczących VAT, zanim dotknęlibyśmy jakiegokolwiek endpointu raportującego. Ustabilizowalibyśmy taksonomię, zmapowali produkty do kategorii i zapewnili, że rejestr decyzji gromadzi surowe sygnały z krajów wraz z uzasadnieniem wyboru miejsca świadczenia. Wszystko inne (VIES, księgowanie, agregacja OSS, eksport) zależy od poprawności tego modelu.

Następnie zaimplementowalibyśmy VIES jako asynchroniczny krok zbierający dowody z podziałem na cztery stany i uruchomili go na środowisku piaskownicowym (sandbox) z zestawem danych testowych dla trudnych przypadków (przekroczenia czasu, wyniki nieprzetworzone, niedopasowane prefikсы), zanim dopuścimy go w pobliże środowiska produkcyjnego. Opisane powyżej błędy można w niemal stu procentach wyeliminować, jeśli model danych od pierwszego zapisu przenosi dowody i wymiary raportowe.

FAQ

Czy ważna odpowiedź z VIES oznacza, że mogę zastosować stawkę 0% do wewnątrzwspólnotowej transakcji B2B?

Nie. VIES potwierdza, że numer VAT jest zarejestrowany i, tam gdzie jest to wspierane, aktywowany do handlu wewnątrzwspólnotowego. Prawo do zwolnienia dostawy wewnątrzwspólnotowej zależy od dodatkowych dowodów: faktu, że klient jest rzeczywistym odbiorcą, dowodów transportu lub wysyłki, prawidłowego miejsca świadczenia oraz wymaganych adnotacji na fakturze. Traktuj wynik VIES jako jeden z danych wejściowych, a nie jako gotową decyzję.

Czy walidacja VIES powinna blokować proces finalizacji zakupu?

Nie powinna. System VIES może zgłosić przekroczenie czasu oczekiwania lub osiągnąć limity równoległych zapytań, a awaria nie jest tym samym co nieważny numer. Przeprowadzaj walidację asynchronicznie, buforuj pomyślne wyniki przez określony czas, ponawiaj próby przy błędach przejściowych, a przypadki niejednoznaczne kieruj do weryfikacji ze stanem tymczasowym zamiast przerywać sprzedaż.

Czy chmurowe API księgowe może automatycznie składać moje deklaracje VAT?

Może ono generować dane gotowe do deklaracji, pogrupowane według procedur i państw członkowskich, obliczone na podstawie niezmiennej księgi głównej uwzględniającej korekty. To, czy system przesyła je również przez bramki poszczególnych krajów, zależy od produktu i kraju. Nordlet oblicza deklaracje OSS i IOSS, dostarcza pakiety deklaracji krajowych dla Litwy, Niemiec i Polski oraz generuje gotowe dla VMI rejestry i.SAF dla Litwy, ale nie wysyła niczego w imieniu podatnika do organu podatkowego. Traktuj księgowość, generowanie deklaracji, eksport, przesyłanie przez bramki i płatności jako odrębne stany, zamiast zakładać, że jedno wywołanie załatwia sprawę wszędzie.

Jak obsługiwać korekty po zamknięciu okresu rozliczeniowego?

Należy je zaksięgować w kolejnym okresie z wyraźnymi odnośnikami do dokumentu pierwotnego oraz okresu, którego dotyczy korekta. Nordlet blokuje nowe wpisy do zablokowanego miesiąca, również poprzez API, dlatego korekty przechodzą przez faktury korygujące lub zapisy odwracające, a nie edycję. Zapewnia to zachowanie ciągłości między pierwotnym rozliczeniem a korektą.

Dalsza lektura