Nordlet

← Блог

API под подвійний запис для обліку на маркетплейсах

Технічний посібник про те, як працюють незмінні API леджоерів під подвійний запис, навіщо вони маркетплейсам і на що зважати під час вбудовування бухгалтерського обліку у свою платформу.

Nordlet Team · · 10 хв читання

Більшість маркетплейсів розуміють, що мають проблему з бухгалтерським обліком, у той самий спосіб: приходить новий фінансист, відкриває таблицю виплат і запитує, хто насправді обліковує зобов'язання перед продавцями в проміжку між моментом оплати покупцем і моментом виходу коштів з рахунку платформи. Інженерна команда вказує на таблицю transactions. Фінансист зазначає, що таблиця подій – це ще не бухгалтерська книга. Цю прірву між даними про події та реальним обліком покликане закрити API леджоера під подвійний запис (double-entry ledger API).

Це технічне питання з юридичними наслідками. Маркетплейси тримають чужі гроші, розраховують ПДВ у різних юрисдикціях та виставляють інвойси від імені продавців. Використання для цього власної таблиці транзакцій працює доти, доки аудитор, податковий орган чи серйозний інвестор не попросять доказів.

Що таке API леджоера під подвійний запис насправді

API леджоера під подвійний запис – це програмований бухгалтерський рушій, доступний через HTTP. Кожна фінансова подія, яку реєструє ваша платформа, записується як збалансований запис журналу (journal entry): щонайменше один дебет і один кредит, рівні за загальною сумою, які проводяться на конкретні рахунки в план рахунків (chart of accounts). API гарантує цей баланс у момент запису та зберігає записи так, щоб їх не можна було непомітно відредагувати пізніше.

Концепція «подвійного запису» – це чотиристатвірне бухгалтерське правило про те, що кожна транзакція зачіпає принаймні два рахунки. Концепція «API» означає, що викликачем є ваш продукт, а не бухгалтер-людина. Концепція «незмінності» (immutability) означає, що виправлення відбуваються через сторнуючі запису (reversing entries), а не редагування історії. Разом ці три властивості роблять отриману звітність готовою до аудиту, а не просто охайною.

Корисне робоче визначення:

API леджоера під подвійний запис приймає фінансові події від вашого додатку, перетворює кожну з них на збалансований запис журналу за визначеним планом рахунків, незмінно зберігає ці записи та надає доступ до отриманого леджоера, оборотно-сальдової відомості (trial balance) та фінансових звітів через передбачувані ендпоінти.

Nordlet створений навколо саме цієї ідеї: реальна бухгалтерська звітність як API, де леджоер, логіка ПДВ, виставлення інвойсів та звірка доступні з того ж набору ендпоінтів, з якими ваш продукт уже взаємодіє.

Чому це потрібно саме маркетплейсам

SaaS-компанія з одним продавцем часто може дозволити собі синхронізацію із загальною бухгалтерською системою раз на день. Маркетплейси – ні, з трьох причин.

По-перше, вони знаходяться посередині руху грошей. Покупець платить платформі, платформа утримує кошти, а потім платить продавцям за мінусом комісій. Кожен із цих рухів є окремою бухгалтерською подією, що зачіпає різні рахунки: готівку, кредиторську заборгованість перед продавцями, дохід платформи, зобов'язання з ПДВ, резерви на повернення коштів. Таблиця payments зі стовпчиком status цього не відображає.

По-друге, вони працюють у різних податкових юрисдикціях. Маркетплейс в ЄС із продавцями в Литві, Німеччині та Польщі й покупцями по всьому блоку повинен застосовувати правильний режим ПДВ для кожної транзакції, перевіряти номери платників ПДВ продавців через VIES та подавати звіти, які задовольняють місцеві органи влади. Реалізація цього в коді додатка з подальшою звіркою з окремою бухгалтерською системою – це те, на чому більшість маркетплейсів тихо ламаються.

По-третє, обсяги занадто великі для ручного ведення бухгалтерії. Платформа, що проводить десять тисяч замовлень на місяць, створює десятки тисяч записів журналу. Це має бути повністю автоматизовано, інакше фінансовий відділ стане вузьким місцем для зростання.

Як працює API: крок за кроком

Механіка простіша, ніж здається на перший погляд. Типовий процес для замовлення на маркетплейсі виглядає так:

1. Ваша платформа генерує фінансову подію. Покупець завершує оформлення замовлення. Ваш бекенд викликає API леджоера з такими даними: ID замовлення, покупець, продавець, брутто-сума, ставка ПДВ, комісія платформи, валюта та ключ ідемпотентності (idempotency key).

2. Леджоер формує запис журналу. API перетворює цю подію на дебети та кредити. Для простого продажу на маркетплейсі це може означати дебетування транзитного рахунку готівки, кредитування рахунку кредиторської заборгованості перед продавцем на чисту суму, кредитування рахунку доходу платформи на суму комісії та кредитування рахунку зобов'язань з ПДВ на податкову частину. Усе збалансовано. Усе проведено атомарно.

3. Запис створюється незмінно. Після проведення запис отримує ідентифікатор і мітку часу та не може бути змінений. Якщо щось не так, ви створюєте сторнуючий і виправлений записи. Аудиторський слід (audit trail) і є головною метою.

4. Звіти оновлюються в реальному часі. Оборотно-сальдова відомість, залишки заборгованості перед продавцями, зведення ПДВ та звіт про прибутки і збитки (P&L) відображають новий запис миттєво. Жодних нічних завдань, експортів чи періодів звірки, коли цифри "устоюються".

5. Вебхуки (webhooks) сповіщають вашу систему. Події на кшталт sale_invoice.paid або bank_transaction.matched надсилаються на ваші ендпоінти, тому продукт може реагувати без опитування (polling). У поєднанні з ключами ідемпотентності це означає, що повторні спроби безпечні, а дублікати не просочуються у разі збоїв у мережі.

Важливий архітектурний момент: леджоер є джерелом правди про те, що сталося у фінансовому плані. База даних вашого додатку є джерелом правди про стан продукту. Обидві системи узгоджуються, оскільки леджоер заповнюється на основі подій додатку, а не навпаки.

План рахунків – це місце, де створюється архітектура

Більша частина інтелектуальної роботи під час налаштування леджоера для маркетплейсу припадає на план рахунків. Це список іменованих розділів, куди надходять дебети та кредити: рахунки готівки за банками, рахунки кредиторської заборгованості перед продавцями (часто по одному на продавця або сукупний з субледжоерами), доходи платформи за категоріями, зобов'язання з ПДВ за країнами, резерви на повернення, резерви на чарджбеки тощо.

Кілька закономірностей, які повторюються на маркетплейсах:

  • Кошти продавців є зобов'язанням, а не доходом. Гроші, які ви тримаєте від імені продавців, є кредиторською заборгованістю. Ставитися до них як до доходу, а виплату списувати на витрати пізніше – це класична помилка, яка спливає під час належної обачності (due diligence).
  • ПДВ є окремим зобов'язанням для кожної країни. Якщо ви працюєте в юрисдикціях ЄС, вам потрібні окремі рахунки зобов'язань з ПДВ по кожній країні, щоб звітність формувалася чітко.
  • Комісії мають моделюватися в момент їх заробітку, а не під час виплати. Метод нарахування (accrual accounting) тут не є опціональним.
  • Повернення коштів, чарджбеки та суперечки вимагають власних рахунків, щоб звіт про прибутки і збитки відображав реальність, а не хаос із позитивних і негативних продажів.

Якісний API леджоера дозволяє визначити цю структуру один раз і далі впевнено проводити по ній операції, замість того щоб заново вигадувати бухгалтерську логіку всередині коду оформлення замовлення.

Незмінність, блокування періодів і чому це важливо для аудиторів

Незмінність звучить як технічна деталь бази даних. Насправді це різниця між бухгалтерською звітністю, яку підпише аудитор, і тією, яку він відхилить.

Якщо маркетплейс може непомітно відредагувати записи минулого кварталу, то цифри за минулий квартал у бухгалтерському розумінні неможливо визнати достовірними. Незмінний леджоер запроваджує правило: історія є історією. Виправлення видно саме як виправлення. Блокування періодів доповнює це: щойно місяць закривається, жодні нові записи чи редагування не можуть потрапити в цей період без явного відкриття, яке саме по собі логується.

Для платформ, які згодом залучатимуть фінансування, продаватимуться або проходитимуть податковий аудит, це не просто приємна функція. Це те, що робить звітність захищеною. Леджоер Nordlet розроблений саме так за замовчуванням: незмінна структура подвійного запису та блокування періодів вбудовані одразу, а не прикручені згодом.

ПДВ в ЄС: те, що забирає час інженерів

ПДВ – це те місце, де більшість бухгалтерських проєктів маркетплейсів виходять за межі бюджету й термінів. Правила не зводяться до простого «застосувати відсоток». Вони залежать від того, де знаходиться покупець, де продавець, що саме продається, чи зареєстрований продавець платником ПДВ, чи вважається маркетплейс уповноваженим постачальником (deemed supplier) за правилами електронної комерції 2021 року, і який режим звітності діє на місцях.

Серйозний API леджоера для ЄС опрацьовує принаймні таке:

  • Перевірку VIES для номерів платників ПДВ продавців і покупців, ідеально з кешуванням результатів і фіксацією на транзакції
  • Логіку ставок ПДВ за країнами, включно зі зниженими ставками та пільгами
  • Генерацію реєстру i.SAF для литовської звітності та еквівалентні структуровані формати, якщо їх вимагають інші держави-члени
  • Е-інвойсинг Peppol BIS 3.0 для юрисдикцій, що переходять на обов'язковий електронний обмін рахунками
  • Обробку OSS/IOSS для транскордонних продажів B2C

Реалізація цього в коді додатків для кожної країни – це робота цілої інженерної команди, яка ніколи не завершується, оскільки правила постійно змінюються. Перенесення цього на рівень леджоера є прагматичним рішенням.

Звірка – це те, де проявляється економія часу

Коли леджоер стає джерелом правди, звірка банківських виписок перестає бути щомісячним випробуванням. Надходять банківські виписки, леджоер уже знає, що там має бути, і зіставлення відбувається здебільшого автоматично.

Реалістична картина полягає не в «нульовій ручній роботі», а в тому, що «винятки спливають самі». Процес звірки в один клік для 90% транзакцій, які ідеально збігаються, плюс черга з 10%, які потребують рішення людини – це приблизно те, що забезпечує добре спроектоване API звірки. Розумне зіставлення платежів обробляє часткові платежі, переплати та платежі, що покривають кілька інвойсів, без необхідності для людини писати правила для кожного окремого випадку.

Експорт SEPA (формат pain.001) для виплат постачальникам і продавцям замикає цикл вихідних платежів. Ви затверджуєте виплати у своєму продукті, леджоер генерує файл SEPA, ваш банк обробляє його, і отриманий рух коштів звіряється автоматично.

Розробка власними силами vs купівля vs вбудовування

Команди маркетплейсів зазвичай розглядають три шляхи. Ось як вони порівнюються за важливими критеріями:

Підхід Час до виходу на ринок Готовність до аудиту Обробка ПДВ в ЄС Інтеграція у ваш продукт
Розробка власного леджоера Від 12 до 24+ місяців Повністю залежить від вашої команди Ви розробляєте її самостійно для кожної країни Так
Синхронізація з Xero/QuickBooks Тижні Добре для бухгалтерії, слабко для специфіки маркетплейсів Частково, потрібні доповнення Ні, працює в окремому інструменті
Вбудовування API леджоера (напр., Nordlet) Тижні Забезпечено завдяки незмінному леджоеру та блокуванню періодів Вбудовано для ЄС, включно з VIES та i.SAF Так, через API та SDK

Самостійна розробка виправдана, якщо бухгалтерія і є вашим продуктом. Для всіх інших економіка такого рішення рідко спрацьовує. Синхронізація з традиційним бухгалтерським інструментом підходить для бізнесу з однією юридичною особою, але дає збій на потоках маркетплейсу: спліт-платежі, субледжоєри продавців, ПДВ за країнами та сценарії платформи як уповноваженого постачальника погано мапляться на інструменти, створені для книг однієї компанії.

Вбудовування API-first леджоера – це шлях, до якого схиляються більшість сучасних платформ. Облік живе всередині інтерфейсу вашого продукту, продавці бачать власні фінанси у вашому UI, а складні завдання з дотримання законодавства вирішуються на рівні інфраструктури.

На що зважати під час оцінки API леджоера

Короткий чекліст, який варто тримати відкритим під час розмов із постачальниками:

  • Незмінне сховище подвійного запису з виправленнями через сторнуючі записи, а не редаговані рядки
  • Блокування періодів із логуванням дій з їх відкриття
  • Ключі ідемпотентності на кожному ендпоінті запису
  • Вебхуки для подій, на які ваш продукт має реагувати, а не лише API опитування
  • Типізовані SDK мовами, які реально використовує ваша команда
  • Логіка ПДВ за країнами, включно з VIES, i.SAF чи еквівалентами, а також OSS/IOSS
  • Підтримка кількох компаній (multi-company), якщо ви керуєте кількома юридичними особами або плануєте це робити
  • Рольовий доступ достатньо деталізований, щоб відокремити розробників, бухгалтерів і глядачів
  • Експорт звітів у форматах XLSX, PDF та JSON із повідомленнями через вебхуки, коли великі звіти готові
  • Тестове середовище (sandbox), що повторює поведінку продакшну, а не спрощена демо-версія

Якщо постачальник не може продемонструвати перші три пункти під час технічної розмови, решта не має значення.

З чого варто почати

Якщо маркетплейс починає цю роботу з нуля, послідовність дій, яка заощадить найбільше зусиль:

  1. Зобразіть реальні потоки грошей на дошці перед написанням будь-якого коду. Хто кому винен, у який момент, у якій валюті, з яким оподаткуванням ПДВ.
  2. Складіть проєкт плану рахунків на основі цієї схеми. Кредиторська заборгованість продавців, дохід платформи, зобов'язання з ПДВ за країнами, резерви. Залучіть бухгалтера для перевірки до запуску в продакшн.
  3. Виберіть рівень леджоера. Розробка, синхронізація чи вбудовування. Будьте чесні щодо того, що ваша команда реально здатна створити й підтримувати.
  4. Реалізуйте один потік від початку до кінця: замовлення -> інвойс -> виплата -> звірка. Доведіть, що він збалансований. Потім масштабуйте.
  5. Увімкніть блокування періодів одразу після чистого закриття першого місяця. Ця дисципліна приносить накопичувальний ефект.

Команди, які роблять це правильно, сприймають леджоер як базову інфраструктуру, а не як звітність «на потім». У цьому полягає зміна парадигми, і саме це робить розмову про фінанси з аудитором, інвестором чи податковою короткою, а не виснажливою.

FAQ

Чи є API леджоера під подвійний запис тим самим, що й бухгалтерська інтеграція?

Ні. Інтеграція синхронізує дані з вашого продукту в зовнішній бухгалтерський інструмент, зазвичай із затримкою. API леджоера – це сама бухгалтерська система, куди дані записуються безпосередньо в реальному часі. Ця різниця важлива, тому що інтеграції втрачають точність на межах: часткові платежі, мультивалютність, розділення коштів на маркетплейсі. API леджоера фіксує це нативно.

Чи не можна просто скористатися звітами Stripe або Adyen?

Звіти платіжних систем показують те, що пройшло через процесор. Це не книги подвійного запису. Вони нічого не знають про вашу заборгованість перед продавцями, яка ще не виплачена, про зобов'язання з ПДВ у різних країнах або про витрати, що не проходять через платіжний процесор. Вони є лише одним із вхідних джерел для леджоера, але не його замінником.

Наскільки незмінним є незмінний леджоер на практиці?

Записи не можна редагувати. Виправлення є новими записами, що посилаються на оригінальні. Це архітектурне рішення, а не технологічне. Будь-який компетентний леджоер забезпечуватиме це. Причина дбати про це полягає в тому, що практика «ми відредагували його, щоб збіглося з банком» – це саме те, що робить бухгалтерську звітність недостовірною.

А як щодо маркетплейсів поза межами ЄС?

Механіка подвійного запису є універсальною. Податкова логіка – ні. API леджоера, налаштований на ПДВ в ЄС, добре впорається з операціями, орієнтованими на Європу, і може підтримувати транзакції поза ЄС, але якщо ваш основний ринок пов'язаний із податками з продажів у США або режимами електронних інвойсів у Латинській Америці, перевірте конкретне покриття комплаєнсу перед тим, як приймати рішення.

Скільки насправді триває впровадження?

Для маркетплейсу з чіткою моделлю подій вбудовування API леджоера до моменту запуску повного робочого циклу зазвичай займає кілька тижнів інженерної роботи. Повна міграція зі старої системи, включно з історичними даними, триває довше. Змінною величиною майже завжди є стан наявних даних, а не саме API.