Nordlet

← Блог

Какво определя едно API за неизменяем счетоводен регистър на двустранно записване

Практически преглед на характеристиките, които отличават истинския счетоводен регистър за европейски маркетплейси от изменяема таблица с баланси и добро маркетинг представяне.

Nordlet Team · · 11 мин четене

Маркетплейс регистърът не се определя от това дали съхранява движения на парични средства. Повечето системи правят това. Той се определя от това какво се случва, когато доставчик на плащания изпрати един и същ уебхук (webhook) два пъти, когато възстановяване на сума пристигне, след като на търговеца вече е било изплатено, или когато одитор попита как салдото на даден търговец е достигнало текущата си стойност. Тези моменти разкриват дали разполагате с неизменяем регистър на двустранно записване (double-entry ledger), или с изменяемо поле с надеждно звучащо име.

За една маркетплейс платформа кратктият отговор е следният: API за неизменяем регистър на двустранно записване отчита всяко финансово значимо събитие като балансирана дневникова транзакция, записва я атомно, никога не я презаписва и ви позволява да извеждате салда, да правите съпоставки (reconciliation) с външни системи и да експортирате историята програматично. Всичко останало е детайл, надграждащ тази основа.

Балансирани дневникови записи, а не поле за текущо салдо

Най-ясният тест е как API представя салдото на търговеца. Ако салдото е число, което вашето приложение увеличава директно, това не е регистър на двустранно записване. Ако салдото е производно извлечение (derived view) от публикувани дневникови редове, то може и да е такъв.

Всяка транзакция трябва да съдържа равни дебити и кредити. Когато купувач плати 100 евро за поръчка, при която маркетплейсът взема 15 евро комисиона, регистърът отчита дебитиране на разчетната сметка със 100 евро срещу кредитиране на задължения към търговеца с 85 евро и кредитиране на приходи от комисиони с 15 евро. Двете страни винаги се събират до една и съща сума. Това структурно правило улавя голяма част от грешките, преди те да стигнат до даден отчет.

Дневниковата транзакция трябва да показва поне:

  • Уникален, неизменен идентификатор на транзакцията (transaction ID)
  • Дебитни и кредитни редове, всеки с сметка, сума и валута
  • Дата на възникване (effective date) и времеви печат на публикуване (posting timestamp)
  • Тип бизнес събитие (продажба, възстановяване, изплащане, оспорване/chargeback)
  • Ключ за идепотентност (idempotency key)
  • Изходна референция към поръчката, плащането или събитието от доставчика
  • Статус (в очакване, публикувано, анулирано)
  • Услугата или удостоверението (credential), което го е създало

Наличните средства на търговеца се превръщат в заявка към тези редове, а не в стойност, която някой е актуализирал в кода на приложението. Това е важно, тъй като директно промененото салдо губи причината за всяко движение. Моделът на Nordlet третира регистъра на двустранно записване като авторитетен път за запис: всеки документ публикува балансирани дневникови записи, а самата база данни отказва небалансираните такива. Това е правилната настройка по подразбиране за всеки, който вгражда счетоводство в маркетплейс.

Добавяне само чрез нови записи (append-only) с компенсиращи корекции

„Неизменяемост“ трябва да означава, че публикуваният дневник не може да се редактира на място. Грешките се коригират чрез нови записи напред, а не чрез изтриване. Неправилният запис на комисиона получава сторниране (reversal), което анулира оригинала, последвано от коригиран запис, който отчита желания резултат. И двете препращат към оригинала, а одитната история показва кой е инициирал промяната и кога.

API трябва да отхвърля обикновени заявки UPDATE и публикувани счетоводни записи. То може да позволи прикачване на нефинансови метаданни, като например референция към запис в поддръжката, при условие че сумите, сметките и времевите печати остават непокътнати.

Помага да се разграничат три неща, които хората често бъркат:

  • Оперативна неизменяемост: потребителите на приложението не могат да променят или изтриват публикувани редове.
  • Одитна неизменяемост: системата може да докаже, че историята не е променяна.
  • Законоустановено съхранение: документите се пазят за срока, изискван от приложимото законодателство.

Релационна база данни, допускаща само добавяне (append-only), със строги разрешения, резервни копия и дисциплинирани работни потоци за сторниране предоставя наистина неизменяем регистър. Блоковата верига (blockchain) не е задължителна тук, а за европейските счетоводни данни тя обикновено създава проблеми с поверителността и коригирането, които надвишават добавената полза от защитата срещу подправяне.

Атомност и идепотентност

Събитието в маркетплейса трябва да се публикува атомно. Или всички дневникови редове се записват успешно, или никой от тях. Записването на постъплението от 100 евро при неуспех за записване на комисионата от 15 евро води до небалансиран, подвеждащ резултат, който някой трябва да разплита по-късно. Nordlet налага това под нивото на приложението: отложен тригер в базата данни проверява дали всеки запис е балансиран в момента на потвърждаването (commit), така че небалансирана транзакция изобщо да не може да бъде записана.

Идепотентността е мястото, където повечето интеграции тихо се чупят. Платежните системи правят опити за повторение при мрежови грешки, а файловете за сетълмент се пускат повторно. Без ключ за идепотентност, обвързан с тенанта или акаунта, едно повторно заявлено искане създава дублирано счетоводство. Повторената заявка със същия ключ трябва да върне оригиналната транзакция, а не втора такава.

Ключът трябва да бъде свързан с изходното събитие, типа събитие, ID на събитието на доставчика, юридическото лице и хеш на полезния товар (payload) на заявката. Ако същият ключ пристигне с различна сума или валута, API трябва да третира това като сблъсък и да го отхвърли, вместо тихо да приеме новия полезен товар. Тихото приемане е начинът, по който одитните следи се разпадат. Хедърът Idempotency-Key на Nordlet [%link%] работи по този начин: повторен опит със същия ключ и полезен товар връща записания отговор, а същият ключ с различен полезен товар се отхвърля с грешка idempotency_key_reuse. Това е малка функция с изключително голям ефект върху съпоставката.

Многостранно сплит счетоводство (split accounting)

Поръчката в маркетплейс не е едно единствено движение. Една единствена продажба може да засегне средствата на купувача, постъпленията на търговеца, маркетплейс комисионата, таксите за обработка на плащането, ДДС върху комисионата, доставката и резервите. Регистърът се нуждае от счетоводни структури, които ги поддържат отделно, вместо да ги сливат в една нетна сума.

Има едно общо предположение, срещу което си струва да се възрази: функцията за „сплит изплащане“ (split payout) на платежния доставчик не е същото като маркетплейс счетоводството. Разделянето на пари между получатели насочва парични потоци. То не ви дава пълен, неизменяем запис за спечелена комисиона, събран ДДС, дължими възстановявания или задържани резерви. Все още се нуждаете от собствен регистър и все още трябва да го съпоставите с доставчика.

Маркетплейс регистърът трябва също така да разграничава повече от едно салдо на търговеца:

Състояние на салдото Какво представлява
В очакване (Pending) Средства, обвързани със събитие, но все още не отговарящи на условията за теглене
Налични (Available) Средства, които преминават правила за освобождаване, резерви, възстановяване и спорове
Задържани / резервирани (Held / reserved) Суми, запазени за оспорвания (chargebacks), връщания или контрол срещу измами
Изплатени (Paid out) Суми, преведени на търговеца
Отрицателни / подлежащи на събиране (Negative / recoverable) Суми, които търговецът дължи, след като възстановяванията или таксите надвишат наличните средства

Преместването на пари от състояние „в очакване“ към „налични“ само по себе си трябва да бъде балансирана дневникова транзакция, а не преименувано поле.

Сторнирания, възстановявания и отрицателни салдота

Паричните потоци в маркетплейсите текат в двете посоки, често извънредно. Трудните случаи са възстановявания на суми след изплащане и оспорвания, които пристигат седмици по-късно. Един сериозен регистър определя какво се случва, когато наличното салдо на търговеца не може да покрие възстановяване: създаване на отрицателно салдо, преместване на сумата към вземания от търговеца, използване на резерв или ограничаване на бъдещи изплащания.

Всяко от тези събития трябва да препраща към оригиналната транзакция и да я запазва. Регистърът отчита счетоводните последици от възстановяването. Той не определя политиката за възстановяване на суми или правната отговорност на маркетплейса. Поддържането на тази граница ясна предотвратява много объркани дискусии по проекта.

Валути и точност

Трансграничните маркетплейси се нуждаят от изрично боравене с парични средства. Сумите трябва да използват кодове на валути по ISO 4217 и точно представяне – или целочислени помощни единици (minor units), или десетични низове с фиксирана прецизност, никога плаваща запетая (floats). Без тихи закръгления. Когато се извършва конвертиране, регистърът трябва да запази оригиналната сума, валутния курс, източника на курса, времевия печат и получената сума, като разликите от закръглението се отчитат по дефинирана сметка.

Една единствена балансирана транзакция не трябва да смесва валути без изричен механизъм за валутен курс. Ако го направи, вашите отчети ще се разминават с реалността по начини, които са болезнени за проследяване в края на месеца.

Съпоставка (reconciliation) с външни системи

Вътрешно балансираният регистър сам по себе си не е авторитетен. Той трябва да съвпада с външния свят: транзакции на платежния доставчик, такси на доставчика, отчети за сетълмент, банкови извлечения, файлове за изплащане и отчети за оспорвания.

Едно зряло API поддържа импортирани външни събития и състояния на съвпадение, като например съпоставено, частично съпоставено, несъпоставено, дублирано, несъответствие в сумата и изискващо преглед. Разликите при съпоставката трябва да създават изрични записи за изключения или счетоводни статии. Те никога не трябва тихо да пренаписват историята на регистъра. Подходът на Nordlet към банковото съпоставяне и съвпадението на плащания се основава на този принцип: импортираните извлечения и експорти от Stripe проскачат всичко, което вече е импортирано, предложенията за плащане се оценяват по сума, референция, контрагент и IBAN, съвпадението с едно кликване се справя с рутинните случаи, а изключенията се извеждат на повърхността, вместо да се поглъщат.

Европейски регулаторни граници, които API трябва да спазва, и тези, които не може

Тук маркетинговите твърдения обикновено изпреварват реалността. Регистърът помага за изпълнението на задълженията в ЕС, но сам по себе си не ги удовлетворява.

ДДС. Регистърът трябва да запазва данъчно значими измерения: юрисдикция, ставка, данъчна категория и начина, по който е определена ставката. Той трябва да разграничава продажбата на търговеца към купувача от комисионата на маркетплейса и да отделя ДДС върху таксите от сумите, които просто преминават през системата. Nordlet се справя с изчисленията на ДДС за отделните държави, VIES валидацията и генерирането на регистри, наред със сценариите OSS и IOSS, с които европейските маркетплейси се сблъскват. Възприемайте регистъра като доказателство и данъчен двигател, а не като данъчен съвет.

DAC7. Правилата за отчетност на платформите изискват надеждни връзки между самоличността на търговеца, юрисдикцията, общите суми на транзакциите, таксите, възстановяванията и изплащанията. Балансираният регистър произвежда доказателствата за транзакциите. Той не определя дали търговец подлежи на отчетност и не замества познаването на клиента (KYC), онбординга или работния процес по отчетността. Поддържайте счетоводството на транзакциите и регулаторното отчитане като отделни сфери.

PSD2 и попечителство над средства. Записването на движения на парични средства не е същото като да бъдете лицензиран платежен услугодател или да пазите средства. Регистърът трябва да прави потока от средства и страните изрични. Той не може сам по себе си да предостави разрешение за предоставяне на платежни услуги или да докаже, че паричните средства се съхраняват в определена сметка. Това остава въпрос на вашата регулаторна роля и вашия PSP.

GDPR. Неизменяемостта създава реално напрежение с принципите за защита на данните. Най-безопасната архитектура запазва монетарните факти в неизменяемото ядро и личните данни извън него. Използвайте стабилни псевдонимни референции на търговци и клиенти в дневниковите редове. Съхранявайте променливите лични данни в отделна система с контролиран достъп и със собствен работен процес за запазване и изтриване. „Неизменяемост“ не е лиценз за запазване на всеки полезен товар на плащане завинаги.

Чеклист за оценка на API за счетоводен регистър

Етикетите на функциите са евтини. Вместо това тествайте поведението в пясъчник (sandbox). Изпълнете тези сценарии и проверете доказателствата:

  • Публикувайте поръчка за 100 евро, разделена между търговец и маркетплейс, и потвърдете балансиран дневник с изрични сметки.
  • Изпратете същата заявка два пъти и потвърдете една транзакция, без дублиране.
  • Опитайте се да редактирате публикуван запис и потвърдете, че той се отхвърля или е ограничен до нефинансови метаданни.
  • Коригирайте грешна комисиона и потвърдете свързано сторниране плюс коригиран запис.
  • Издайте частично възстановяване след изплащане и потвърдете проследимо възстановяване с вземане от търговец или отрицателно салдо, където е необходимо.
  • Пуснете повторно уебхук на доставчик и потвърдете разпознаването на дубликати.
  • Обработвайте сетълмент в множество валути и потвърдете детайлите за валутния курс и счетоводството на конвертирането.
  • Направете заявка за салдо на търговец в края на периода и потвърдете възпроизводим резултат с документиран момент на отчитане (cut-off).
  • Импортирайте сетълмент от доставчик и потвърдете съвпадението със статус на изключение, който оставя историята непокътната.
  • Експортирайте активност за един месец и потвърдете пълен, пагиниран и повтарящ се екстракт.

Най-силното доказателство е документацията плюс възпроизводим тест. Думи като „в реално време“, „готово за одит“ и „неизменяемо“ не означават нищо без модела на данните, семантиката на грешките и поведението при съхранение зад тях.

Какво бихме проверили първи

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

След това съображенията, свързани на първо място с API, са от значение за това колко бързо вашият екип пуска продукти на пазара: типизирани SDK-та, уебхукове за събития като sale_invoice.paid, работещ пясъчник и заключване на периоди за защита на приключените месеци. Nordlet е изграден около този модел, със същия набор от функции, изложен както през API, така и през приложението, което позволява на платформата да управлява готови за одит счетоводни книги вътре в собствения си продукт, вместо да добавя чекаут на трета страна. За по-общата картина за това как такъв регистър се впива в маркетплейс стек, вижте нашето ръководство за API за регистри с двустранно записване за маркетплейс счетоводство.

FAQ

Гарантира ли двустранното записване, че счетоводството ми е правилно?

Не. Регистърът може да бъде напълно балансиран, докато публикува по грешни сметки, прилага грешно третиране по ДДС или приписва средства на грешен търговец. Балансът е структурен контрол, който улавя аритметични грешки и липсващи страни на транзакцията. Той не казва нищо за това дали вашата бизнес логика е картографирала събитието правилно. Ето защо тестването в пясъчник срещу реални сценарии е по-важно от самата проверка на баланса.

Достатъчен ли е регистърът на платежния доставчик за един маркетплейс?

Обикновено не. Един PSP проследява средствата вътре в собствената си система, което е полезно за движенията и изплащанията. Вашият маркетплейс все още се нуждае от собствени записи за приходи от комисиони, задължения към търговци, ДДС върху такси, възстановявания, резерви, спорове и управленско отчитане. Двете системи трябва да бъдат съпоставени, а третирането на изгледа на доставчика като ваше счетоводство оставя празнини, които излизат наяве по време на одит.

Трябва ли ми блокова верига (blockchain), за да направя регистъра неизменяем?

Не. Релационно хранилище, допускащо само добавяне, със строги разрешения за запис, контролирани работни потоци за корекция, одитни логове и надеждни резервни копия, ви дава оперативна и одитна неизменяемост. Блоковата верига добавя разпределена защита срещу подправяне, но носи трудности с поверителността, производителността и корекцията, които работят срещу изискванията на европейското счетоводство и GDPR. За повечето маркетплейси тя решава проблем, който те нямат.

Може ли неизменяемият регистър да запазва данни завинаги съгласно GDPR?

Запазването на счетоводни записи за законоустановения срок е напълно нормално. Запазването на пълни лични данни или полезни товари от плащания за неопределено време само защото регистърът е неизменяем, не е. Съхранявайте монетарните факти и псевдонимните референции в неизменяемото ядро, а личните данни пазете в отделна система с подходящо съхранение и изтриване. Неизменяемостта се отнася за финансовото събитие, а не за всяка частица от данни, прикачена към него.