Nordlet

← Blog

What Defines an Immutable Double-Entry Ledger API

A practical breakdown of the features that separate a real accounting ledger for EU marketplaces from a mutable balance table with good marketing.

Nordlet Team · · 11 min. czytania

O klasie księgi rachunkowej marketplace'u nie decyduje sam fakt, że rejestruje ona przepływy pieniężne. Większość systemów to potrafi. O jej wartości decyduje to, co dzieje się, gdy dostawca płatności wyśle ten sam webhook dwa razy, gdy zwrot towaru dotrze do systemu już po wypłaceniu środków sprzedawcy, albo gdy auditor zapyta, w jaki sposób saldo sprzedawcy osiągnęło swoją obecną wartość. Te momenty obnażają, czy masz do czynienia z niezmienną księgą o podwójnym zapisie (immutable double-entry ledger), czy po prostu z edytowalną tabelą sald z dobrym marketingiem.

W przypadku platformy marketplace krótka odpowiedź brzmi następująco: niezmienne API księgi o podwójnym zapisie rejestruje każde zdarzenie mające skutki finansowe jako zbilansowaną transakcję dziennika, księguje ją w sposób analitycznie spójny i niepodzielny (atomic), nigdy jej nie nadpisuje oraz pozwala wyznaczać salda, uzgadniać dane z systemami zewnętrznymi i programowo eksportować historię. Wszystko inne to tylko szczegóły wyrastające z tego fundamentu.

Zbilansowane zapisy w dzienniku, a nie pole bieżącego salda

Najprostszą miarą jakości jest to, w jaki sposób API reprezentuje saldo sprzedawcy. Jeśli saldo to liczba, którą Twoja aplikacja bezpośrednio inkrementuje, nie jest to księga o podwójnym zapisie. Jeśli saldo jest wyliczanym widokiem zaksięgowanych pozycji dziennika, to tak.

Każda transakcja powinna zawierać równe kwoty po stronie winien (debit) i ma (credit). Kiedy kupujący płaci 100 EUR za zamówienie, w którym marketplace pobiera 15 EUR prowizji, księga rejestruje obciążenie rachunku rozliczeniowego kwotą 100 EUR, uznanie zobowiązania wobec sprzedawcy kwotą 85 EUR oraz uznanie przychodów z prowizji kwotą 15 EUR. Obie strony zawsze sumują się do tej samej wartości. Ta reguła strukturalna wychytuje mnóstwo błędów, zanim jeszcze zdążą trafić do raportu.

Transakcja dziennika powinna udostępniać co najmniej:

  • Unikalny, niezmienny identyfikator transakcji
  • Pozycje po stronie winien i ma, każda z przypisanym kontem, kwotą i walutą
  • Datę operacji i znacznik czasu zaksięgowania
  • Typ zdarzenia gospodarczego (sprzedaż, zwrot, wypłata, chargeback)
  • Klucz idempotentności (idempotency key)
  • Odnośnik źródłowy do zamówienia, płatności lub zdarzenia u dostawcy
  • Status (oczekujący, zaksięgowany, odwrócony)
  • Usługę lub poświadczenie (credential), które wygenerowało wpis

Dostępne środki sprzedawcy stają się wówczas wynikiem zapytania skierowanego do tych pozycji, a nie wartością, którą ktoś zaktualizował w kodzie aplikacji. Ma to kluczowe znaczenie, ponieważ bezpośrednio modyfikowane saldo gubi przyczynę każdego ruchu. Model Nordlet traktuje księgę o podwójnym zapisie jako autorytatywną ścieżkę zapisu: każdy dokument generuje zbilansowane wpisy w dzienniku, a sama baza danych odrzuca te, które nie są zbilansowane. To właściwe podejście domyślne dla każdego, kto osadza księgowość w strukturze marketplace'u.

Księgowanie wyłącznie w trybie append-only z korektami kompensującymi

Słowo „niezmienna” (immutable) oznacza, że raz zaksięgowany dziennik nie może być edytowany w miejscu. Błędy naprawia się poprzez wpisywanie kolejnych operacji do przodu, a nie ich wymazywanie. Błędny wpis prowizji wymaga korekty odwracającej (reversal), która neutralizuje oryginał, a następnie poprawionego wpisu odzwierciedlającego zamierzony wynik. Oba wpisy odsyłają do oryginału, a historia audytowa pokazuje, kto zainicjował zmianę i kiedy to nastąpiło.

API powinno odrzucać zwykłe polecenia UPDATE i DELETE wykonywane na zaksięgowanych rekordach księgowych. Może natomiast pozwalać na dołączanie metadanych o charakterze niefinansowym, takich jak numer zgłoszenia w systemie wsparcia, o ile kwoty, konta i znaczniki czasu pozostają nienaruszone.

Pomaga to odróżnić od siebie trzy pojęcia, które często są ze sobą mylone:

  • Niezmienna operacyjność (operational immutability): użytkownicy aplikacji nie mogą modyfikować ani usuwać zaksięgowanych wierszy.
  • Niezmienna audytowość (audit immutability): system potrafi udowodnić, że historia nie uległa zmianie.
  • Prawny obowiązek przechowywania (legal retention): dokumentacja jest przechowywana przez okres wymagany przez obowiązujące przepisy.

Relacyjna baza danych typu append-only z rygorystycznymi uprawnieniami, kopiami zapasowymi i zdyscyplinowanymi procedurami odwracania zapisów zapewnia autentycznie niezmienną księgę. Blockchain nie jest tu wymagany, a w przypadku unijnych danych księgowych zazwyczaj generuje on problemy z prywatnością i korektami, które przewyższają korzyści w zakresie wykrywania manipulacji.

Atomowość i idempotencja

Zdarzenie w marketplace musi być księgowane w sposób atomowy (atomic). Albo zatwierdzone zostaną wszystkie linie dziennika, albo żadna. Zarejestrowanie wpływu 100 EUR bez zarejestrowania 15 EUR prowizji daje niezbilansowany, mylący wynik, który ktoś będzie musiał później wyjaśniać. Nordlet wymusza to poniżej warstwy aplikacji: odroczony wyzwalacz bazodanowy (deferred database trigger) sprawdza, czy każde księgowanie jest zbilansowane w momencie zatwierdzenia, dzięki czemu niezbilansowana transakcja w ogóle nie może trafić do bazy.

Idempotencja to obszar, w którym większość integracji potrafi po cichu zawieść. Systemy płatności ponawiają próby w przypadku błędów sieciowych, a pliki rozliczeniowe są odtwarzane wielokrotnie. Bez klucza idempotencji powiązanego z dzierżawcą (tenant) lub kontem, pojedyncze ponowione żądanie utworzy zduplikowane zapisy księgowe. Powtórzone żądanie z tym samym kluczem powinno zwrócić oryginalną transakcję, a nie tworzyć kolejną.

Klucz powinien być powiązany z pierwotnym zdarzeniem, typem zdarzenia, identyfikatorem zdarzenia u dostawcy, podmiotem prawnym oraz skrótem (hashem) ładunku żądania (payload). Jeśli ten sam klucz dotrze z inną kwotą lub walutą, API powinno potraktować to jako kolizję i odrzucić żądanie, zamiast cicho akceptować nowy ładunek. Cicha akceptacja to prosta droga do zepsucia ścieżki audytu. Nagłówek Idempotency-Key w API Nordlet działa właśnie w ten sposób: ponowienie żądania z tym samym kluczem i ładunkiem odtwarza zapisaną odpowiedź, natomiast ten sam klucz z innym ładunkiem jest odrzucany z komunikatem idempotency_key_reuse. To mała funkcja o ogromnym wpływie na proces uzgadniania danych.

Księgowanie z podziałem na wielu uczestników (split accounting)

Zamówienie w marketplace to nie jest jeden prosty przepływ. Pojedyncza sprzedaż może dotyczyć środków kupującego, należności sprzedawcy, prowizji marketplace'u, opłat za przetwarzanie płatności, podatku VAT od prowizji, kosztów wysyłki oraz rezerw. Księga wymaga struktur kont, które utrzymują te elementy w rozdzieleniu, zamiast sprowadzać je do jednej kwoty netto.

Warto obalić jedno powszechne założenie: funkcja „split payout” u dostawcy płatności to nie to samo co księgowość marketplace'u. Dzielenie środków pomiędzy odbiorców przesuwa gotówkę, ale nie daje kompletnego, niezmiennego rejestru zarobionej prowizji, pobranego VAT-u, należnych zwrotów czy utrzymywanych rezerw. Nadal potrzebujesz własnej księgi i nadal musisz uzgadniać jej stan z dostawcą.

Księga marketplace'u powinna również rozróżniać więcej niż jedno saldo sprzedawcy:

Stan salda Co oznacza
Oczekujące (Pending) Środki powiązane ze zdarzeniem, ale jeszcze niekwalifikujące się do wypłaty
Dostępne (Available) Środki spełniające reguły zwolnienia z rezerwy, zwrotów i sporów
Zablokowane / rezerwa (Held / reserved) Kwoty wstrzymane na poczet obciążeń zwrotnych (chargeback), zwrotów lub kontroli nadużyć
Wypłacone (Paid out) Kwoty przelane na rzecz sprzedawcy
Ujemne / do odzyskania (Negative / recoverable) Kwoty, które sprzedawca jest winien po tym, jak zwroty lub opłaty przewyższyły dostępne środki

Przeniesienie środków ze stanu oczekującego na dostępny samo w sobie powinno być zbilansowaną transakcją dziennika, a nie tylko zmianą etykiety pola.

Odwrócenia, zwroty i salda ujemne

Pieniądze w marketplace płyną w obu kierunkach, często w zaburzonym porządku czasowym. Trudne przypadki to zwroty dokonywane po wypłacie środków oraz chargebacki docierające po tygodniach. Rzetelna księga definiuje, co się dzieje, gdy dostępne saldo sprzedawcy nie pokrywa zwrotu: tworzy saldo ujemne, przenosi kwotę na należności od sprzedawcy, sięga po rezerwę lub ogranicza kolejne wypłaty.

Każde z tych zdarzeń powinno odnosić się do oryginalnej transakcji i zachowywać ją w nienaruszonym stanie. Księga rejestruje skutek księgowy zwrotu, a nie decyduje o polityce zwrotów marketplace'u czy jego odpowiedzialności prawnej. Utrzymanie tej granicy zapobiega wielu chaotycznym dyskusjom projektowym.

Waluty i precyzja

Marketplace'y transgraniczne wymagają precyzyjnej obsługi walut. Kwoty powinny wykorzystywać kody walut ISO 4217 oraz dokładną reprezentację w postaci całkowitych jednostek podrzędnych (minor units) lub ciągów dziesiętnych o stałej precyzji, nigdy zaś liczb zmiennoprzecinkowych (floats). Bez cichego zaokrąglania. W przypadku konwersji walut księga musi zachować oryginalną kwotę, kurs wymiany, źródło kursu, znacznik czasu oraz wynikową kwotę, przy czym różnice zaokrągleń należy księgować na zdefiniowanym koncie.

Pojedyncza zbilansowana transakcja nie powinna łączyć różnych walut bez jawnego mechanizmu wymiany. Jeśli to zrobisz, Twoje raporty zaczną rozmijać się z rzeczywistością w sposób niezwykle trudny do namierzenia na koniec miesiąca.

Uzgadnianie z systemami zewnętrznymi

Wewnętrznie zbilansowana księga nie jest autorytatywna sama w sobie. Musi być spójna ze światem zewnętrznym: transakcjami u dostawców płatności, opłatami operatorów, raportami rozliczeniowymi, wyciągami bankowymi, plikami wypłat i raportami chargeback.

Dojrzałe API obsługuje importowane zdarzenia zewnętrzne oraz stany dopasowania, takie jak: dopasowane, częściowo dopasowane, niedopasowane, duplikat, niezgodność kwot oraz wymagające przeglądu. Różnice uzgodnień powinny generować wyraźne rekordy wyjątków lub wpisy księgowe. Nigdy nie powinny po cichu nadpisywać historii księgi. Podejście Nordlet do uzgadniania wyciągów bankowych i dopasowywania płatności opiera się na tej zasadzie: importowane wyciągi i eksporty ze Stripe pomijają wszystko, co zostało już zaimportowane, sugestie płatności są oceniane pod kątem kwoty, referencji, kontrahenta i numeru IBAN, dopasowanie jednym kliknięciem obsługuje standardowe przypadki, a wyjątki są wyciągane na wierzch, zamiast być gdzieś ukrywane.

Granice unijne, których API powinno przestrzegać, oraz te, których nie może

To obszar, w którym obietnice marketingowe najczęściej rozmijają się z rzeczywistością. Księga pomaga w realizacji unijnych obowiązków, ale sama ich nie spełnia.

VAT. Księga powinna zachowywać wymiary istotne z punktu widzenia podatku: jurysdykcję, stawkę, kategorię podatkową oraz sposób wyznaczenia stawki. Powinna rozróżniać sprzedaż sprzedawcy na rzecz kupującego od prowizji marketplace'u, a także oddzielać VAT od opłat od kwot, które jedynie przez platformę przepływają. Nordlet obsługuje obliczanie podatku VAT dla poszczególnych krajów, walidację VIES oraz generowanie rejestrów i.SAF wraz ze scenariuszami OSS i IOSS, z którymi mierzą się unijne marketplace'y. Traktuj księgę jako dowód i silnik podatkowy, a nie jako doradztwo podatkowe.

DAC7. Reguły sprawozdawczości platform wymagają niezawodnych powiązań między tożsamością sprzedawcy, jurysdykcją, sumami transakcji, opłatami, zwrotami i wypłatami. Zbilansowana księga dostarcza dowodów transakcyjnych. Nie rozstrzyga jednak, czy dany sprzedawca podlega zgłoszeniu, ani nie zastępuje procedur KYC, wdrażania klientów (onboarding) czy procesu sprawozdawczego. Kwestie księgowości transakcyjnej i raportowania regulacyjnego należy traktować jako osobne zagadnienia.

PSD2 a powiernictwo środków. Rejestrowanie przepływów pieniężnych to nie to samo co posiadanie licencji krajowej instytucji płatniczej lub bezpieczne przechowywanie środków (safeguarding). Księga powinna jasno pokazywać przepływ funduszy i zaangażowane strony. Nie może jednak samodzielnie zapewniać autoryzacji usług płatniczych ani udowadniać, że gotówka faktycznie znajduje się na konkretnym rachunku. To kwestia Twojej roli regulacyjnej oraz wybranego dostawcy usług płatniczych (PSP).

RODO (GDPR). Niezmienność danych rodzi realny konflikt z zasadami ochrony prywatności. Najbezpieczniejsza architektura utrzymuje fakty finansowe w niezmiennym rdzeniu, a dane osobowe poza nim. W liniach dziennika należy stosować stabilne pseudonimizowane identyfikory sprzedawców i klientów. Zmienne dane osobowe należy przechowywać w osobnym, kontrolowanym pod względem dostępu systemie z własnym cyklem retencji i usuwania. „Niezmienność” nie oznacza zgody na wieczne przechowywanie każdego ładunku danych płatniczych.

Lista kontrolna do oceny API księgi

Etykiety funkcji są tanie. Przetestuj działanie w środowisku piaskownicy (sandbox). Uruchom następujące scenariusze i sprawdź dowody:

  • Zaksięgnij zamówienie na 100 EUR podzielone między sprzedawcę a marketplace i potwierdź zbilansowany dziennik z jawnymi kontami.
  • Wyślij to samo żądanie dwukrotnie i upewnij się, że powstała jedna transakcja, bez duplikatów.
  • Spróbuj edytować zaksięgowany wpis i potwierdź, że żądanie zostało odrzucone lub ograniczone do metadanych niefinansowych.
  • Skoryguj błędną prowizję i potwierdź powiązane odwrócenie wraz z poprawionym wpisem.
  • Dokonaj częściowego zwrotu po wypłacie i potwierdź identyfikowalny zwrot z należnością od sprzedawcy lub ujemnym saldem tam, gdzie to konieczne.
  • Odtwórz webhook od dostawcy i potwierdź wykrycie duplikatu.
  • Przetwarzaj rozliczenie wielowalutowe i potwierdź szczegóły wymiany walut oraz księgowanie konwersji.
  • Pobierz saldo sprzedawcy na koniec okresu rozliczeniowego i potwierdź odtwarzalny wynik ze zdefiniowaną datą graniczną (cut-off).
  • Zaimportuj rozliczenie od dostawcy i potwierdź dopasowanie ze statusem wyjątku, który pozostawia historię nienaruszoną.
  • Wyeksportuj miesiąc aktywności i potwierdź kompletny, podzielony na strony, powtarzalny wyciąg.

Najsilniejszym dowodem jest dokumentacja połączona z powtarzalnym testem. Słowa takie jak „w czasie rzeczywistym”, „gotowy do audytu” czy „niezmienny” nie znaczą nic bez modelu danych, semantyki błędów i mechanizmów retencji, które za nimi stoją.

Od czego zaczęlibyśmy my

Gdybyśmy jutro oceniali API księgi dla marketplace'u, zanim spojrzeliśmy na cokolwiek innego, zaczęlibyśmy od dwóch rzeczy. Po pierwsze, sprawdzilibyśmy, czy saldo sprzedawcy wynika z linii dziennika, a nie z modyfikowalnego pola, ponieważ wszystko inne zależy właśnie od tego. Po drugie, odtworzylibyśmy ten sam webhook i upewnili się, że skutek księgowy jest dokładnie jeden. Te dwa testy powiedzą Ci o jakości leżącego u podstaw projektu więcej niż jakakolwiek lista funkcji.

Poza tym kwestie zorientowane na API mają kluczowe znaczenie dla tempa wdrażania rozwiązań przez Twój zespół: typowane pakiety SDK, webhooki dla zdarzeń takich jak sale_invoice.paid, działająca piaskownica oraz blokowanie okresów w celu ochrony zamkniętych miesięcy. Nordlet został zbudowany wokół tego modelu, udostępniając ten sam zestaw funkcji zarówno przez API, jak i przez aplikację, co pozwala platformie prowadzić księgi gotowe do audytu we własnym produkcie zamiast doklejać zewnętrzną kasę (checkout). Szerszy obraz tego, jak taka księga wpisuje się w strukturę marketplace'u, znajdziesz w naszym przewodniku po API ksiąg o podwójnym zapisie dla księgowości marketplace'ów.

FAQ

Czy podwójny zapis gwarantuje poprawność księgowości?

Nie. Księga może być idealnie zbilansowana, a jednocześnie księgować środki na niewłaściwych kontach, stosować błędne stawki VAT lub przypisywać fundusze nie temu sprzedawcy. Bilans to kontrola strukturalna, która wychytuje błędy arytmetyczne i brakujące strony transakcji. Nie mówi nic o tym, czy logika biznesowa poprawnie odwzorowała zdarzenie. Właśnie dlatego testowanie w piaskownicy na prawdziwych scenariuszach jest ważniejsze niż samo sprawdzenie bilansu.

Czy księga dostawcy płatności wystarczy dla marketplace'u?

Zazwyczaj nie. Dostawca płatności (PSP) śledzi środki wewnątrz własnego systemu, co jest przydatne do obsługi przepływów i wypłat. Twój marketplace nadal potrzebuje własnych rejestrów dla przychodów z prowizji, zobowiązań wobec sprzedawców, VAT-u od opłat, zwrotów, rezerw, sporów i sprawozdawczości zarządczej. Oba systemy muszą zostać uzgodnione, a traktowanie widoku dostawcy jako własnej księgowości pozostawia luki, które ujawniają się w trakcie audytu.

Czy potrzebuję blockchaina, aby uczynić księgę niezmienną?

Nie. Relacyjna baza danych typu append-only z rygorystycznymi uprawnieniami do zapisu, kontrolowanymi przepływami korekt, dziennikiem zdarzeń (audit log) i niezawodnymi kopiami zapasowymi zapewnia operacyjną i audytową niezmienność. Blockchain dodaje rozproszone dowody odporności na manipulacje, ale przynosi problemy z prywatnością, wydajnością i korektami, które działają wbrew unijnym przepisom księgowym i RODO. Dla większości marketplace'ów rozwiązuje problem, którego nie mają.

Czy niezmienna księga może przechowywać dane wiecznie zgodnie z RODO?

Przechowywanie dokumentacji księgowo-podatkowej przez wymagany prawnie okres jest jak najbardziej w porządku. Bezterminowe przechowywanie pełnych danych osobowych lub ładunków płatniczych tylko dlatego, że księga jest niezmienna, już nie. Trzymaj fakty finansowe i pseudonimizowane referencje w niezmiennym rdzeniu, a dane osobowe przechowuj w osobnym systemie z właściwymi zasadami retencji i usuwania. Niezmienność dotyczy zdarzenia finansowego, a nie każdego elementu danych, który został do niego dołączony.