Subkonta sprzedawców w marketplace'ach: Przychód a zobowiązania
Praktyczny przewodnik po rozdzielaniu środków klientów, prowizji platformy, zobowiązań wobec sprzedawców, rezerw i wypłat za pomocą zbilansowanych zapisów księgowych oraz działającego modelu danych od zamówienia do wypłaty.
Najczęstszym błędem w księgowości marketplace'ów jest traktowanie wpłaty brutto od kupującego jako przychodu platformy. Klient płaci 100 EUR, te 100 EUR trafia na konto operatora płatności, a ktoś księguje całą kwotę jako sprzedaż. Księgi bilansują się przez chwilę, przychód wygląda świetnie, a potem audytor pyta, gdzie jest zobowiązanie wobec sprzedawcy. Nie ma go, ponieważ kwota 90 EUR należna sprzedawcy nigdy nie została zarejestrowana jako dług.
Rozwiązanie ma charakter strukturalny, a nie kosmetyczny. Marketplace potrzebuje modelu księgi głównej (general ledger), który od pierwszego zapisu oddziela pięć distinctnych pul: środki klientów w transycie, przychody z prowizji platformy, zobowiązania wobec sprzedawców, opłaty oraz rezerwy. Wypłaty to szóste zdarzenie, które rozlicza zobowiązanie, a nie samodzielny przychód czy koszt. Ten przewodnik przedstawia zbilansowane zapisy oraz model danych, które utrzymują te pule w rozdziale.
Zacznij od ustalenia, czy platforma działa jako pryncypał, czy agent
Zanim jakikolwiek układ kont zacznie mieć znaczenie, platforma musi zdecydować, co właściwie sprzedaje. Zgodnie ze standardem ASC 606 jest to oceniane dla każdego określonego towaru lub usługi, a wynik decyduje o tym, czy przychód ujmuje się w kwocie brutto, czy netto. Platforma może być pryncypałem w przypadku jednego przepływu i agentem w przypadku innego.
W typowej sprzedaży na marketplace towary należą zazwyczaj do sprzedawcy, a platforma działa jako agent. Organizuje ona dostarczenie produktu sprzedawcy do kupującego, nie ponosi ryzyka zapasów (inventory risk), a jej wynagrodzeniem jest prowizja. Wytyczne Deloitte dotyczące roli pryncypała i agenta w ramach ASC 606 opierają test na kwestii kontroli: odpowiedzialność za wykonanie zobowiązania, ryzyko zapasów oraz swoboda w kształtowaniu cen są wskaźnikami, a nie listą kontrolną zastępującą ocenę faktycznej kontroli.
Powód, dla którego ta analiza musi znaleźć się w projekcie księgi, a nie tylko w notatce służbowej, jest taki, że ten wniosek napędza każdy kolejny zapis. Jeśli platforma jest agentem, udział sprzedawcy staje się zobowiązaniem w momencie jego zarobienia. Jeśli platforma jest pryncypałem w zakresie usługi fulfillmentu lub gwarancji, ta część stanowi jej przychód. Zapisz ten wniosek w postaci danych:
principal_agent_rolespecified_good_or_servicecommission_rule_idcontrol_assessment_versioneffective_from/effective_to
Audytor analizujący pozycję prowizji netto dwa lata później powinien widzieć, dlaczego nie zastosowano wartości brutto. Jak zauważa BillingPlatform w swoim opracowaniu na temat ASC 606 dla relacji pryncypał-agent, samo określenie „marketplace” nie rozstrzyga sprawy. Robi to analiza kontroli.
Zdefiniuj saldo sprzedawcy, zanim napiszesz choćby jedną regułę księgowania
„Saldo sprzedawcy” to nie jest jedna liczba. Sprzedawca może mieć świetne saldo historyczne i jednocześnie zero środków dostępnych do wypłaty, ponieważ pieniądze są wciąż weryfikowane lub zatrzymane jako rezerwa. Jeśli zsumujesz te stany, błędnie raportujesz kwotę, którą sprzedawca może wypłacić, oraz to, co platforma nadal jest mu winna.
Minimum, które należy śledzić, obejmuje:
- Oczekujące (Pending): zarobione lub pobrane, ale jeszcze niekwalifikujące się do wypłaty
- Dostępne (Available): kwalifikujące się do wypłaty zgodnie z regulaminem platformy
- Zarezerwowane (Reserved): zatrzymane na poczet spodziewanych zwrotów, sporów lub obciążeń zwrotnych (chargeback)
- Wypłacone (Paid out): przelane lub przekazane do rozliczenia
- Ujemne (Negative): kwota, którą sprzedawca jest winny platformie, podlegająca potrąceniu z przyszłych wpływów
- Do wyjaśnienia (Suspense): otrzymane, ale sprzedawca lub sposób rozliczenia nie zostały jeszcze ustalone
Dostawcy płatności już teraz uwzględniają ten podział w swoich modelach. Stripe dzieli każde powiązane konto na saldo oczekujące i dostępne oraz utrzymuje rezerwę na poziomie platformy dla określonych ujemnych sald sprzedawców. Jeśli operator płatności tak to dzieli, księga główna również musi, w przeciwnym razie uzgodnienie (reconciliation) nigdy się nie spepnie.
Plan kont i wymiary, które mają znaczenie
Działająca struktura początkowa oddziela konta rozrachunkowe (clearing), zobowiązania i przychody oraz przypisuje wymiar (dimension) sprzedawcy do każdego istotnego księgowania.
| Przeznaczenie | Konto lub wymiar | Traktowanie księgowe |
|---|---|---|
| Środki u operatora oczekujące na rozliczenie | Rachunek rozliczeniowy operatora płatności | Aktywa rozliczeniowe |
| Wypłata z operatora zaksięgowana w banku | Rachunek bankowy | Aktywa |
| Kwota zarobiona przez sprzedawcę, ale nieopłacona | Zobowiązania wobec sprzedawców | Pasywa (Zobowiązania) |
| Szczegóły na poziomie sprzedawcy | Wymiar seller_id |
Atrybut zobowiązania, a nie przychód |
| Prowizja platformy | Przychody z prowizji | Przychody |
| VAT lub podatek od sprzedaży | Zobowiązania podatkowe | Pasywa (Zobowiązania) |
| Opłaty operatora płatności | Koszty obsługi płatności | Koszty |
| Rezerwy sprzedawcy | Zobowiązania z tytułu rezerw | Zależne od kontraktu |
| Zwroty | Korekta przychodów lub zwroty | Odwrócenie pierwotnego ujęcia |
| Obciążenia zwrotne (chargeback) | Strata, należność lub odzyskanie od sprzedawcy | Zależnie od tego, kto ponosi stratę |
| Wypłaty oczekujące na potwierdzenie banku | Rachunek rozliczeniowy wypłat dla sprzedawców | Konto rozliczeniowe |
| Kwoty nieprzypisane | Konto oczekujące (Suspense) | Tymczasowy wyjątek |
Każdy istotny zapis powinien zawierać wymiar sprzedawcy, zamówienia, partii wypłat, operatora płatności, waluty, podmiotu prawnego, traktowania podatkowego, typu zdarzenia, referencji zewnętrznej oraz ewentualnego odniesienia do korekty. Bez tego subkonto sprzedawcy nie jest w stanie udowodnić pojedynczego salda, a księga główna całości.
Subkonto można wdrożyć jako jedno konto zobowiązań dla każdego sprzedawcy, jedno zagregowane konto zobowiązań z wymiarem seller_id lub jako podział na zobowiązania, rezerwy i rozliczenie wypłat. Podejście oparte na agregacji i wymiarach skaluje się lepiej po przekroczeniu kilkudziesięciu sprzedawców. Wybierz model wspólnie ze swoją księgowością, ponieważ zasady safeguardingu oraz lokalne regulacje płatnicze mogą wpływać na sposób prezentacji tych środków. Mechanika stojąća za tymi zapisami została omówiona w naszym artykule o API księgi podwójnego zapisu dla marketplace'ów, na którym bazuje ten model.
Księgowanie sprzedaży z oddzielnymi liniami dla sprzedawcy i platformy
Rozważmy sprzedaż w modelu agencyjnym: klient płaci 100 EUR, prowizja platformy wynosi 10 EUR, sprzedawca zarabia 90 EUR. W momencie, gdy prowizja i należność sprzedawcy stają się zarobione:
| Konto | Winien (Debit) | Ma (Credit) |
|---|---|---|
| Rachunek rozliczeniowy operatora płatności | 100 EUR | |
| Zobowiązania wobec sprzedawcy – Sprzedawca A | 90 EUR | |
| Przychód z prowizji | 10 EUR |
Kluczowa zasada kontrolna: kwota 90 EUR zasila stronę Ma jako zobowiązanie, a nie przychód. Platforma rozpoznaje 10 EUR przychodu. Jest to rezultat, do którego dąży przykład marketplace w standardzie ASC 606 dla agenta, gdzie platforma ujmuje swoją prowizję, a nie pełną kwotę sprzedaży sprzedawcy.
Jeśli podatek jest pobierany osobno, dodaj pozycję zobowiązania podatkowego i odpowiednio pomniejsz kwotę sprzedawcy lub platformy zgodnie z analizą podatkową. Nie łącz podatku z prowizją ani zobowiązaniem wobec sprzedawcy dla wygody.
Trzymaj opłaty operatora z dala od kalkulacji przychodów i zobowiązań
Trzy rzeczy są ze sobą nieustannie mylone: prowizja platformy, opłata operatora płatności (gateway/processing fee) oraz kwota wypłaty. Są to różne wielkości, które trafiają na inne konta.
Klient płaci 100 EUR, prowizja wynosi 10 EUR, operator zatrzymuje 3 EUR.
- Przychód z prowizji wynosi nadal 10 EUR, o ile tak stanowi umowa.
- Opłata operatora w wysokości 3 EUR jest kosztem.
- Zobowiązanie wobec sprzedawcy wynosi 90 EUR, chyba że umowa ze sprzedawcą stanowi, że to on ponosi koszty obsługi płatności. Dopiero wtedy kwota ta spada do 87 EUR przy jednoczesnym obciążeniu sprzedawcy kwotą 3 EUR.
Zaksięgowanie wyłącznie kwoty netto 97 EUR, która wpływa na rachunek bankowy, jednym ruchem zaciera sprzedaż brutto, prowizję oraz opłatę. Nasz artykuł poświęcony uzgadnianiu płatności wskazuje na to samo: rozłóż rozliczenie na czynniki pierwsze, traktuj opłaty operatora jak koszty i nigdy nie pozwalaj, aby czysty wpływ netto zastępował przychód.
Modeluj dostępność środków, rezerwy i wypłaty jako osobne zdarzenia
Pieniądze zmieniają swój status wielokrotnie w drodze od autoryzacji do rozliczonych środków. Każda zmiana statusu zasługuje na własny zapis, a rezerwa nigdy nie jest niewyjaśnionym ucięciem przychodu.
Gdy dostępne środki trafiają do rezerwy:
| Konto | Winien (Debit) | Ma (Credit) |
|---|---|---|
| Zobowiązania wobec sprzedawcy – Sprzedawca A | 15 EUR | |
| Zobowiązanie z tytułu rezerwy sprzedawcy | 15 EUR |
Gdy rezerwa jest zwalniana, odwróć ten zapis. Całkowite zobowiązanie wobec sprzedawcy się nie zmieniło, zmienił się jedynie jego status. Stripe dokumentuje transakcje rezerw, które zwiększają i zwalniają rezerwy, a także transfery windykacyjne dla długoterminowych sald ujemnych – dlatego proces ten wymaga identyfikowalnych kont zamiast pojedynczego zapisu netto.
Wypłaty przechodzą dwuetapowy proces. W momencie zatwierdzenia:
| Konto | Winien (Debit) | Ma (Credit) |
|---|---|---|
| Zobowiązania wobec sprzedawcy – Sprzedawca A | 90 EUR | |
| Rachunek rozliczeniowy wypłat dla sprzedawców | 90 EUR |
W momencie potwierdzenia rozliczenia przez bank:
| Konto | Winien (Debit) | Ma (Credit) |
|---|---|---|
| Rachunek rozliczeniowy wypłat dla sprzedawców | 90 EUR | |
| Rachunek bankowy | 90 EUR |
Jeśli wypłata się nie powiedzie, odwróć pozycję rozliczeniową z powrotem na zobowiązania wobec sprzedawcy. Wypłata to rozliczenie zobowiązania, a nie koszt. Traktowanie jej jako kosztu powoduje podwójne ich ujęcie w stosunku do sprzedaży, która już wcześniej zarejestrowała zobowiązanie. Stripe rozdziela status wypłaty (pending, in_transit, paid, failed, canceled) oraz oczekiwaną datę doręczenia od momentu jej zainicjowania, a te daty nie powinny być spłaszczane do jednego znacznika czasu (timestamp).
Model danych od zamówienia do wypłaty
Subkonto funkcjonuje w oparciu o zdarzenia, a nie o aktualny status zamówienia w aplikacji. Każde zdarzenie wpływające na sytuację sprzedawcy posiada ten sam zestaw danych (envelope):
seller_id,event_id,order_idevent_type(sale, refund, chargeback, reserve_hold, reserve_release, payout, adjustment)effective_date,posting_datecurrency,direction,gross,commission,fees,reserverefund_ref/dispute_refpayout_batch_idreversal_ofsource_status,idempotency_key
Na podstawie tych zdarzeń obliczasz saldo końcowe zamiast przechowywać zmienne pole (mutable field):
Saldo końcowe sprzedawcy
= saldo początkowe
+ uznania na rzecz sprzedawcy (credits)
− obciążenia sprzedawcy (debits)
− wypłaty
± ruchy rezerw
± korekty
Każde zdarzenie zewnętrzne potrzebuje trwałego klucza idempotencji (idempotency key), aby ponowienia i duplikaty webhooków nie powodowały podwójnego uznania konta sprzedawcy lub podwójnej wypłaty. Wzorce, które się sprawdzają:
- Zdarzenie dziennika sprzedawcy:
seller_id:order_id:event_type:version - Partia wypłat:
processor:payout_id - Zdarzenie operatora płatności:
processor:event_type:processor_event_id
Wytyczne Stripe dotyczące webhooków ostrzegają, że zdarzenia zduplikowane się zdarzają, więc wykrywanie duplikatów nie jest opcjonalne. Zaksięgowane wpisy pozostają niemutowalne (immutable). Korekty przeprowadzane są poprzez zapis korygujący (odwracający) oraz zapis prawidłowy, przy czym to Twoja koperta zdarzenia niesie odnośnik reversal_of oraz powód korekty. Księga przechowuje wpisy, a nie ten odnośnik: Nordlet udostępnia operacje tworzenia, pobierania i listowania transakcji dziennika w swojej dokumentacji API bez funkcji edycji i usuwania, więc korekta jest zawsze nową transakcją, a nie edycją istniejącej.
Zwroty i obciążenia zwrotne mają swoje odnośniki i nigdy nie wiszą w próżni
Zwrot, który pojawia się w przyszłotygodniowej wypłacie, nigdy nie powinien stawać się nową ujemną sprzedażą powiązaną z tą wypłatą. Powiąż go z oryginalną transakcją i zachowaj pierwotną alokację dla sprzedawcy. W zależności od umowy:
- Odwróć prowizję, jeśli umowa przewiduje jej zwrot
- Obciąż zobowiązanie wobec sprzedawcy, jeśli to on ponosi koszt zwrotu
- Obciąż konto strat platformy, jeśli to ona bierze to na siebie
- Zwiększ rezerwę na czas trwania sporu, a po jego rozstrzygnięciu zwolnij ją lub pomniejsz
Obciążenia zwrotne (chargeback) po wypłacie to moment, w którym pojawiają się ujemne salda. Pieniądze sprzedawcy już zniknęły, więc platforma albo odzyskuje je z przyszłych wpływów, albo bierze stratę na siebie. Model musi dopuszczać ujemne salda sprzedawców i definiować regułę ich windykacji. Raporty marketplace'u Adyen pokazują zwroty i obciążenia zwrotne generujące osobne wiersze debetowe na jednego posiadacza konta – i do takiego poziomu granularności należy dążyć.
Uzgadniaj salda według wypłat, a nie co miesiąc
Przeanalizuj i rozłóż na czynniki pierwsze każde rozliczenie od operatora przed jego zaksięgowaniem, uzgadniając każdą wypłatę osobno zamiast agregować cały miesiąc:
Opłaty brutto (Gross charges)
− zwroty
− opłaty operatora płatności
− obciążenia zwrotne (chargebacks)
± rezerwy i korekty
= czysta wypłata netto od operatora
Następnie udowodnij zgodność czterech sald dla każdego sprzedawcy i waluty: subkonta sprzedawcy, salda sprzedawcy u operatora, raportu wypłat oraz rachunku rozliczeniowego banku. Gdy występują różnice, sklasyfikuj je (timing, brakujące zdarzenie, duplikat, błędne przypisanie, zła waluta, nieudana wypłata, chargeback przypisany do niewłaściwej strony). Ukrywanie różnic poprzez netgowanie (netting) sprawia, że błędy się znoszą i docierają nienaruszone do zamknięcia okresu.
Agregowanie całego miesiąca pozwala różnicom czasowym wzajemnie się znnieść i ukrywa rzeczywiste rozbieżności. Dopasowywanie transakcji wypłata po wypłacie, oparte na identyfikatorze wypłaty i referencji transakcji zamiast na kwocie i dacie, pozwala je wychwycić.
Typowe błędy i wzorce awarii
| Typ błędu | Dlaczego to szkodzi | Kontrola / Działanie |
|---|---|---|
| Wpłata brutto klienta zaksięgowana jako przychód | Sztucznie pompuje przychód, ukrywa zobowiązanie wobec sprzedawcy | Rozdziel zobowiązanie i prowizję w momencie zarobienia środków |
| Księgowane wyłącznie wpłaty netto | Zniekształca kwoty brutto, opłaty, zwroty i rezerwy | Rozbijaj każde rozliczenie na czynniki pierwsze |
| Wypłata zaksięgowana jako koszt | Fałszywie przedstawia rozliczenie zobowiązania | Obciążaj zobowiązanie wobec sprzedawcy przy wypłacie |
| Jedno pole salda sprzedawcy | Miesza środki oczekujące, dostępne, zarezerwowane i wypłacone | Śledź stany sald w sposób jawny |
| Prowizja naliczana w momencie wypłaty | Przychód śledzi harmonogram wypłat | Rozpoznawaj prowizję w momencie jej zarobienia |
| Rezerwa traktowana jako obcięcie przychodu | Zaciemnia kwestie czasu wystąpienia i ryzyka | Śledź zatrzymanie, zwolnienie i konsumpcję rezerwy osobno |
| Zwrot przypisany do ostatniej wypłaty | Narusza powiązanie z zamówieniem | Powiąż zwrot z oryginalną transakcją |
| Edycja zaksięgowanych wpisów | Niszczy ścieżkę audytu | Odwracaj zapis i twórz nowy (reversal & repost) |
| Powtórzone webhooki | Duplikaty uznaniowe i wypłaty | Klucze idempotencji, wykrywanie duplikatów |
| Dopasowywanie wyłącznie po kwocie i dacie | Różne pozycje kolidują ze sobą | Dopasowuj po ID wypłaty, ID transakcji, sprzedawcy i walucie |
Co zrobiłbym w pierwszej kolejności
Zamapuj przepływ pieniędzy przed dotknięciem planu kont. Wypisz każde zdarzenie od pobrania płatności do zwolnienia rezerwy i zaznacz, które z nich tworzą przychód, które zobowiązanie, a które jedynie zmieniają status.
Następnie zbuduj jeden pełny przepływ od początku do końca i udowodnij, że się bilansuje: normalna sprzedaż, zwrot częściowy, obciążenie zwrotne po wypłacie, rezerwa zatrzymana i zwolniona oraz nieudana wypłata. Uruchom te scenariusze dla znanych, oczekiwanych sald. Jeśli konto kontrolne zobowiązań wobec sprzedawców równa się sumie subkont, rozliczenie operatora zgadza się z raportem rozliczeniowym, a wpłata bankowa pasuje do ID wypłaty, masz działający kręgosłup systemu.
Włącz blokowanie okresów (period locking) dopiero wtedy, gdy pierwszy miesiąc zamknie się czysto, z zerowym saldem na koncie oczekującym. Zbyt wczesne zablokowanie zamraża jedynie popełnione błędy.
Nordlet księguje rozliczenia zgodnie z tymi zasadami już w standardzie: prowizja platformy trafia na przychód z prowizji, udział sprzedawcy na zobowiązanie wobec sprzedawcy, opłaty operatora na koszty obsługi płatności, a wszystko, co nieprzypisane, na konto oczekujące. Okresy w księdze pozostają otwarte do momentu ich jawnego zablokowania, dzięki czemu pierwszy miesiąc można zamknąć, gdy konto oczekujące jest puste. Strona funkcji zawiera listę tego, co wchodzi w skład systemu.
FAQ
Czy wpłata kupującego jest kiedykolwiek przychodem platformy?
Tylko w przypadku konkretnych towarów lub usług, w ramach których platforma działa jako pryncypał. W przypadku sprzedaży w marketplace agencyjnym, gdzie sprzedawane są towary należące do osoby trzeciej, przychodem jest prowizja, a udział sprzedawcy jest zobowiązaniem. Platforma może być pryncypałem w zakresie usługi logistycznej i agentem w zakresie samego towaru w ramach tego samego zamówienia, dlatego ocenę przeprowadza się dla każdego określonego towaru lub usługi, a nie dla firmy ogółem.
Czy rezerwy powinny pomniejszać przychód?
Nie. Rezerwa to alokacja czasu i ryzyka, a nie korekta przychodu. Przenieś środki ze zobowiązań wobec sprzedawcy na zobowiązanie z tytułu rezerwy, gdy je zatrzymujesz, i odwróć ten zapis przy ich zwolnieniu. Przychody i prowizje pozostają nieniezależne od tego, czy pieniądze sprzedawcy są aktualnie w rezerwie.
Jak zatrzymać podwójne wypłaty wynikające z ponowień webhooków?
Dołącz klucz idempotencji do każdego zdarzenia zewnętrznego, takiego jak processor:payout_id dla partii wypłat, i wykrywaj zduplikowane zdarzenia przy zapisie. Dostawcy wyraźnie ostrzegają, że dostawy zduplikowanych webhooków występują, więc księga musi odrzucić drugą próbę zamiast księgować ją ponownie.
Czy saldo sprzedawcy może spaść poniżej zera?
Tak, a model musi na to zezwalać. Obciążenie zwrotne (chargeback), które trafia do systemu po wypłaceniu środków sprzedawcy, pozostawia platformę z należnością od sprzedawcy lub stratą, którą musi wziąć na siebie. Maskowanie ujemnych sald ukrywa jedynie nieurejestrowane zobowiązanie.
Dlaczego warto uzgadniać każdą wypłatę osobno zamiast sumy miesięcznej?
Ponieważ różnice czasowe i błędy znoszą się wzajemnie przy agregacji miesięcznej, co sprawia, że sumy się zgadzają, podczas gdy poszczególne transakcje są błędne. Uzgadnianie na poziomie wypłat, dopasowane po identyfikatorach wypłat i transakcji, ujawnia brakujące zdarzenia, duplikaty i błędnie przypisane obciążenia zwrotne przed zamknięciem okresu.