Nordlet

← Блог

Що визначає API незмінного бухгалтеричного реєстру за методом подвійного запису

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

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

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

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

Збалансовані запити в журналі, а не поле динамічного балансу

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

Кожна транзакція повинна містити рівні дебети та кредити. Коли покупець сплачує €100 за замовлення, де маркетплейс бере комісію €15, реєстр фіксує дебет транзитного рахунку на €100 проти кредиту заборгованості перед продавцем на €85 та кредиту доходу від комісії на €15. Обидві сторони завжди в сумі дають однаковий показник. Це структурне правило виявляє велику кількість помилок ще до того, як вони потраплять у звіт.

Транзакція журналу повинна містити щонайменше:

  • Унікальний ідентифікатор транзакції, який неможливо змінити
  • Дебетові та кредитові рядки, кожен із зазначенням рахунку, суми та валюти
  • Дату валютування та мітку часу проведення
  • Тип бізнес-події (продаж, повернення, виплата, чарджбек)
  • Ключ ідемпотентності
  • Посилання на джерело - замовлення, платіж або подію провайдера
  • Статус (в очікуванні, проведено, сторновано)
  • Сервіс або облікові дані, які створили запис

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

Проведення лише з додаванням та компенсаційні коригування

Слово „незмінний“ (immutable) має означати, що вже проведений запис у журналі не можна редагувати на місці. Помилки виправляються вперед, а не стираються. Неправильний запис комісії отримує сторно, яке анулює оригінальний запис, а потім виправлений запис, що фіксує потрібний результат. Обидва посилаються на оригінал, а аудиторська історія показує, хто і коли ініціював зміни.

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

Корисно розділяти три поняття, які часто плутають:

  • Операційна незмінність: користувачі застосунку не можуть змінювати або видаляти проведені рядки.
  • Аудиторська незмінність: система може довести, що історія не змінилася.
  • Юридичне зберігання: записи зберігаються протягом терміну, передбаченого чинним законодавством.

Реляційна база даних із принципом лише додавання (append-only), суворими дозволами, резервними копіями та чіткими робочими процесами сторнування забезпечує справді незмінний реєстр. Блокчейн тут не потрібен, а для європейських бухгалтерських даних він зазвичай створює проблеми з конфіденційністю та виправленням даних, які перевищують переваги додаткового захисту від втручання.

Атомарність та ідемпотентність

Подія на маркетплейсі повинна проводитися атомарно. Або фіксуються всі рядки журналу, або жоден. Запис надходження €100 без фіксації комісії €15 створює незбалансований і хибний результат, який комусь доведеться розплутувати пізніше. Nordlet забезпечує це нижче рівня застосунку: відкладений тригер бази даних перевіряє, чи збалансована кожна проводка в момент фіксації (commit), тому незбалансована транзакція взагалі не може бути збережена.

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

Ключ повинен бути прив'язаний до початкової події, типу події, ідентифікатора події провайдера, юридичної особи та хешу корисного навантаження (payload) запису. Якщо той самий ключ надходить з іншою сумою чи валютою, API повинен сприймати це як колізію та відхиляти його, замість того щоб мовчки приймати новий запит. Мовчазне прийняття руйнує аудиторські сліди. Заголовок Nordlet Idempotency-Key працює саме так: повторна спроба з тим самим ключем і даними відтворює збережену відповідь, а той самий ключ із іншими даними відхиляється з помилкою idempotency_key_reuse. Це невелика функція з величезним впливом на звірку.

Багатостороння розділена бухгалтерія

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

Існує поширене припущення, проти якого варто заперечити: функція „розподіленої виплати“ (split payout) платіжного провайдера не дорівнює бухгалтерії маркетплейса. Розподіл грошей між одержувачами спрямовує готівку. Він не дає повного і незмінного запису про заробітну комісію, зібраний ПДВ, заборгованість за поверненнями чи утримувані резерви. Вам усе одно потрібен власний реєстр, і його все одно потрібно звіряти з провайдером.

Реєстр маркетплейса повинен також розрізняти кілька балансів продавця:

Стан балансу Що він представляє
В очікуванні (Pending) Кошти, прив'язані до події, але ще не доступні для виведення
Доступні (Available) Кошти, які пройшли правила розблокування, резервування, повернення та арбітражу
Утримувані / зарезервовані (Held / reserved) Суми, затримані для чарджбеків, повернень або контролю шахрайства
Виплачені (Paid out) Суми, переказані продавцю
Від'ємні / підлягають стягненню (Negative / recoverable) Суми, які продавець винен після того, як повернення або комісії перевищили доступні кошти

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

Сторнування, повернення та від'ємні баланси

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

Кожна з таких подій повинна посилатися на первинну транзакцію та зберігати її. Реєстр фіксує бухгалтерські наслідки повернення коштів. Він не визначає політику повернень маркетплейса чи його юридичну відповідальність. Чітке дотримання цієї межі запобігає багатьом заплутаним обговоренням дизайну.

Валюти та точність

Транскордонні маркетплейси потребують чіткої роботи з грошима. Суми повинні використовувати коди валют ISO 4217 та точне представлення - цілі мінорні одиниці або десяткові рядки з фіксною точністю, але ніколи не числа з плаваючою комою (floats). Жодних мовчазних округлень. Під час конвертації реєстр повинен зберігати початкову суму, курс обміну, джерело курсу, мітку часу та кінцеву суму, причому різниці округлення проводяться на визначений рахунок.

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

Звірка із зовнішніми системами

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

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

Межі ЄС, які API повинен дотримуватися, і ті, які не може

Саме тут маркетинг зазвичай випереджає реальність. Реєстр допомагає виконувати зобов'язання в ЄС, але сам по собі він їх не закриває.

ПДВ (VAT). Реєстр повинен зберігати податкові виміри: юрисдикцію, ставку, категорію податку та спосіб визначення ставки. Він повинен відрізняти продаж продавця покупцю від комісії маркетплейса, а також відокремлювати ПДВ з комісій від сум, які просто проходять транзитом. Nordlet обробляє розрахунки ПДВ для кожної країни, перевірку VIES та створення реєстрів i.SAF разом зі сценаріями OSS та IOSS, з якими стикаються європейські маркетплейси. Ставтеся до реєстру як до доказу та податкового двигуна, а не як до податкової консультації.

DAC7. Правила звітності платформ вимагають надійних зв'язків між ідентифікатором продавця, юрисдикцією, загальними сумами транзакцій, комісіями, поверненнями та виплатами. Збалансований реєстр надає докази транзакцій. Він не визначає, чи підлягає продавець звітності, і не замінює KYC, онбординг чи робочий процес звітності. Розділяйте облік транзакцій та регуляторну звітність як різні завдання.

PSD2 та зберігання коштів. Реєстрація руху грошей не дорівнює ліцензії платіжного сервісу чи захисту коштів. Реєстр повинен чітко показувати рух грошей та залучені сторони. Сам по собі він не може забезпечити авторизацію платіжних послуг або довести, що готівка зберігається на певному рахунку. Це залишається питанням вашої регуляторної ролі та вашого платіжного провайдера (PSP).

GDPR. Незмінність створює справжню напругу з принципами захисту даних. Найбезпечніша архітектура зберігає грошові факти в незмінному ядрі, а персональні дані поза ним. Використовуйте стабільні псевдонімні посилання на продавців і покупців у рядках журналу. Зберігайте змінні персональні дані в окремій системі з контролем доступу, зі власним робочим процесом зберігання та видалення. „Незмінність“ - це не дозвіл зберігати кожне платіжне повідомлення вічно.

Чек-лист для оцінки API реєстру

Ярлики функцій коштують дешево. Протестуйте поведінку на пісочниці (sandbox). Запустіть ці сценарії та перевірте результати:

  • Проведіть замовлення на €100, розділене між продавцем і маркетплейсом, і підтвердіть збалансований журнал із явними рахунками.
  • Надішліть той самий запит двічі та переконайтеся, що створено лише одну транзакцію без дублікатів.
  • Спробуйте відредагувати вже проведений запис і переконайтеся, що він відхилений або обмежений нефінансовими метаданими.
  • Виправте помилкову комісію та переконайтеся у наявності пов'язаного сторно плюс виправленого запису.
  • Здійсніть часткове повернення коштів після виплати та переконайтеся в наявності відстежуваного повернення з дебіторською заборгованістю продавця або від'ємним балансом там, де це необхідно.
  • Відтворіть вебхук провайдера і переконайтеся у виявленні дублікатів.
  • Обробіть багатолютне розрахункове відправлення та підтвердьте наявність деталей FX і конвертаційного обліку.
  • Зробіть запит щодо балансу продавця на кінець періоду та підтвердьте відтворюваний результат із документованою відсічкою.
  • Імпортуйте розрахунки провайдера та підтвердьте зіставлення зі статусом винятку, який залишає історію недоторканою.
  • Експортуйте місяць активності та підтвердьте повний, пагінований витяг, який можна повторити.

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

З чого ми б почали перевірку

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

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

FAQ

Чи гарантує подвійний запис правильність моєї бухгалтерії?

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

Чи достатньо реєстру платіжного провайдера для маркетплейса?

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

Чи потрібен мені блокчейн, щоб зробити реєстр незмінним?

Ні. Реляційне сховище з принципом лише додавання (append-only), суворими дозволами на запис, контрольованими робочими процесами коригування, журналюванням аудитів та надійними резервними копіями забезпечує операційну незмінність та незмінність для аудиту. Блокчейн додає захист від маніпуляцій, що розподіляється між учасниками, але приносить труднощі з конфіденційністю, продуктивністю та виправленнями, які суперечать вимогам бухгалтерського обліку ЄС та GDPR. Для більшості маркетплейсів він вирішує проблему, якої у них немає.

Чи може незмінний реєстр зберігати дані вічно відповідно до GDPR?

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