Перейти к содержимому

Двойная запись: деньги двигаются отдельно от заказа

15 сент. 2026 г. 8 мин чтения Claude C. Claude C.
Два столбца плиток друг напротив друга, оранжевый пунктир сшивает каждую левую плитку с ответной правой

Кратко

Учёт криптоплатежей у процессинга ведётся двойной записью, потому что деньги и заказ двигаются в разные моменты. Один счёт может получить три зачисления, закрыться с переплатой или не закрыться вовсе, пока деньги уже пришли на его адрес. Балансы мерчанта живут в этом регистре отдельными счетами, проводки неизменяемы и сходятся по каждому токену. Зато по каждому движению видно, какой счёт изменился, — в том числе по тем, о которых вебхук не сообщает.

Процессинг ведёт две книги. Одну пишет блокчейн, и в ней ничего не поправить. Вторую платформа ведёт сама, и в Paymos это регистр с двойной записью: каждое движение ложится двумя проводками, откуда ушло и куда пришло. Баланс мерчанта здесь никто не переписывает, его собирают из истории движений.

Лишняя колонка окупается на событиях, которые отказываются выстраиваться в ряд. Плательщик закрывает один счёт тремя переводами. Деньги приходят на адрес счёта через час после того, как окно оплаты закрылось, или в USDC, когда счёт выставлен в USDT, или на счёт, отменённый утром того же дня. Вывод создали, сумму зарезервировали, а потом отменили до отправки. Каждое такое событие двигает деньги, не двигая заказ, и одному числу «сколько у мерчанта» эту разницу записать некуда.

Ниже разобраны шесть таких событий: что каждое делает с балансом и что в этот момент происходит со счётом.

Почему на один счёт приходит несколько зачислений?

Потому что комиссию берут с каждого перевода отдельно, по той сумме, которую он принёс.

Баланс мерчанта за жизнь одного счёта двигается столько раз, сколько было переводов. Три перевода дают три зачисления и три проводки по комиссии, и каждая посчитана от той суммы, что пришла в этот момент. Процент при этом закреплён за счётом с момента создания: что бы ни поменялось в ценах потом, закроется он по старому проценту.

Одно поступление — уже три числа: сколько пришло, сколько забрала комиссия, сколько осталось мерчанту. Округление идёт в одну сторону. Комиссия отсекается вниз, до наименьшей единицы токена, остаток достаётся мерчанту, поэтому фактический процент на переводе любого размера выходит не выше объявленного. С суммы настолько маленькой, что комиссия округляется в ноль, не берут ничего.

Для того, кто читает собственную выписку, тут и прячется неожиданность. Зачисления не ложатся один к одному на счета. Они ложатся на переводы, а кто оплачивает комиссию по каждому — настройка отдельная.

Что вообще записывает двойная запись?

Движения и обе стороны у каждого: откуда и куда.

Одинарная запись хранит сумму и правит её на месте. Двойная хранит само изменение: счёт-источник, счёт-получатель, одна проводка, которая обязана сойтись, прежде чем её примут. Балансы после этого выводятся из истории. На том же свойстве строят учёт платёжные команды далеко за пределами крипты, и инженерный журнал Modern Treasury говорит об этом прямо: регистр лежит на «неизменяемом журнале, в который только дописывают», где «все изменения сохраняются, и любое прошлое состояние можно восстановить».

В Paymos балансы мерчанта живут отдельными счетами внутри такого регистра, по каждому активу. Проводки по ним неизменяемы, у каждой минимум две стороны, и сумма сходится по каждому токену. Несошедшуюся проводку не сохраняют, чтобы починить потом. Её просто не принимают.

Что происходит, когда пришло не столько, сколько просили?

Зачисление идёт за деньгами, счёт живёт по своему правилу, и два ответа расходятся.

Переплату зачисляют целиком. Ничего не удерживают и ничего не отправляют назад само собой; счёт закрывается оплаченным, а в вебхуке приходит invoice.paid_over вместо invoice.paid, так что система заказов различает эти два случая без арифметики по суммам.

Недоплата упирается в допуск проекта. Это ползунок от 0 до 2 % с шагом 0,1 %, и новый проект открывается на 0,1 %. Нехватка меньше допуска всё равно закрывает счёт, и мерчант получает ровно столько, сколько пришло: недостающее никто не досчитывает. Сдвиньте ползунок в ноль, и сверка снова станет точной.

Всё, что больше допуска, делится по типу счёта. Счёт, который ждал один платёж, помечается недоплаченным. Счёт, рассчитанный на несколько, может остаться открытым, пока плательщик досылает остаток. Вот это состояние одним числом и не выразить: деньги на балансе есть, заказ не закрыт.

Куда деваются переводы, которые не закрыли ни один счёт?

На баланс мерчанта, с обычной комиссией и с причиной, записанной рядом.

Переводы приходят на адреса счетов в неудобные моменты: через час после закрытия окна оплаты, на счёт, оплаченный или отменённый тем же утром, в USDC на счёт в USDT, на адрес, за которым счёта нет вовсе. Деньги в каждом из этих случаев попадают мерчанту.

Не двигается сам счёт. Оплаченным его не помечают, и вебхук не уходит: у такого зачисления нет собственного события. Интеграция, которая слушает только поток событий, не узнает о нём никогда.

Видно его на странице баланса, отдельным блоком, где стоят причина, сумма, комиссия, счёт, если он был, адрес отправителя и хеш транзакции, когда они известны; иначе отправитель значится неизвестным. То же уведомление приходит на почту, в колокольчик дашборда и в Telegram, если контакт привязан. Возвращать такой перевод или нет, мерчант решает сам: возврат — обычный исходящий перевод, и отправляет его тоже мерчант.

Почему вывод сначала попадает в «Удержано»?

Потому что между запросом и транзакцией деньги уже не потратить, а до кошелька они ещё не дошли.

Запрос на вывод снимает с доступного баланса сумму вместе с сетевой комиссией того маршрута, по которому она пойдёт, и кладёт обе части в удержание. Поэтому на странице баланса эти цифры стоят порознь, и новый вывод оплачивает только «Доступно». Доли с оборота при этом никто не удерживает: такого резерва здесь нет, а в «Удержано» лежат ваши же выводы в пути.

У вывода семь состояний, три из них конечные, и в каждом ответе едет is_final, так что держать этот список у себя в коде и обновлять руками не нужно. Одно неконечное состояние стоит узнавать в лицо: вывод, который сеть ещё не подтвердила, показан как «Не подтверждён», и сумма по нему всё ещё удержана.

Если вывод закончился, не уйдя в сеть, всё удержанное возвращается целиком, вместе с сетевой комиссией. За вывод, который не ушёл, не берут ничего. Отменить можно только в самом начале, пока исполнение не началось; дальше запрос на отмену отклоняют.

На чей счёт ложится убыток от реорганизации?

На счета платформы.

Глубину подтверждения выбирают по сети и по сумме: ждать полной финальности никто не станет. Это размен, и у него остаётся узкое окно — уже зачисленный перевод ещё может выпасть из цепочки при реорганизации. Зачисление мерчанта в этот момент остаётся на месте, а недостачу записывают на счета платформы.

Дело тут в устройстве учёта. Процессинг, который держит обе стороны каждой проводки, может назвать счёт, принявший удар. Процессингу, у которого на мерчанта заведено одно число, брать недостачу больше неоткуда, и мерчант стоит ровно в этом месте. Механику разбирает материал о том, может ли подтверждённый платёж пропасть, а почему в разных сетях ждут по-разному, объясняют подтверждения транзакций.

Хватит ли вебхуков, чтобы собрать учёт?

Одних вебхуков не хватит. Поток событий рассказывает, что ресурс сменил состояние, и это знание другого сорта, чем запись о деньгах.

Шестнадцать типов событий закрывают счета, выводы и депозиты платёжных каналов, и каждое сообщает о смене состояния. Быстро услышать, что что-то произошло, можно именно так, и контракт доставки описывает, насколько упорно он старается.

Полнота — вопрос отдельный. У зачисления, которое не оплатило ни один счёт, события нет вообще, поэтому баланс, собранный из вебхуков, поедет. У неудавшегося вывода наоборот: вебхук уходит, а ни письма, ни уведомления в колокольчике за ним нет, так что интеграция о нём узнает, а человек, который смотрит почту, не узнает. Карточка самого вывода при этом прямо говорит, что он не ушёл и удержание снято; причину отказа не показывают.

Лента депозитов платёжных каналов устроена от обратного. Она публикуется по порядку за курсором, который всегда двигается вперёд, поэтому читатель, хранящий позицию, не перепрыгнет через расчётный платёж; пустая страница тоже отдаёт курсор, а не признак конца. Живёт он сутки: кто вернётся позже, получит pagination_cursor_invalid и начнёт заново от confirmed_from. Считайте событие сигналом сходить и прочитать, а доверяйте ленте и балансу.

Что записывать в собственном учёте?

Ключ — перевод. Счёт при нём — одно из полей.

Эта одна замена снимает почти всё, что выше. Три зачисления по одному счёту перестают быть аномалией, а зачислению без счёта находится место в таблице, а не в переписке с поддержкой. Снятое удержание читается как проводка, отменяющая другую: на неё можно посмотреть, её не надо восстанавливать вычитанием.

Дальше две мелочи. Ветвитесь по is_final везде, где важно состояние вывода. И ведите балансы по активу: так они и лежат, один баланс USDT покрывает все сети, по которым USDT пришёл, а сеть выбирают позже, когда создают вывод.

Собственный регистр для этого не нужен, и большинству мерчантов строить его не стоит. Нужно другое: чтобы ваша запись о платеже пережила день, когда платёж и заказ разойдутся.

Что происходит с балансом мерчанта и со счётом, событие за событием (сентябрь 2026 года)
СобытиеБаланс мерчантаСчёт
Перевод подтверждён по счётуЗачислена пришедшая сумма за вычетом комиссии по нейПриближается к оплаченному с каждым переводом
Плательщик прислал больше, чем просил счётЗачислено целиком, вместе с излишкомЗакрывается оплаченным, в событии invoice.paid_over
Перевод пришёл после закрытия окна оплатыЗачислен за вычетом обычной комиссииНе двигается, вебхук не уходит
Создан выводСумма и её сетевая комиссия уходят в удержаниеНе участвует
Вывод не удался или отменёнУдержание возвращается целиком, с сетевой комиссиейНе участвует
Реорганизация отбросила подтверждённый переводБез изменений, зачисление остаётсяБез изменений

Частые вопросы

Зачем процессингу двойная запись?

Затем, что баланс тогда не хранится числом, которое кто-то правит. Каждое движение денег ложится проводкой минимум на два счёта, проводки неизменяемы и сходятся по каждому токену, а балансы мерчанта лежат в этом регистре отдельными счетами.

Почему по одному счёту проходит несколько зачислений?

Комиссию считают по каждому переводу отдельно, от той суммы, которую он принёс, и зачисление приходит в момент подтверждения этого перевода, а не в конце жизни счёта. Счёт, закрытый тремя переводами, даёт три зачисления.

Что будет с деньгами, пришедшими на адрес счёта после его закрытия?

Их зачислят на баланс мерчанта за вычетом обычной комиссии, а сам счёт останется в прежнем состоянии. Вебхука по такому зачислению нет, поэтому увидеть его можно на странице баланса, в письме и в уведомлении дашборда.

Спишут ли сетевую комиссию за отменённый вывод?

Нет. Если вывод закончился, не уйдя в сеть, удержание возвращается целиком, вместе с сетевой комиссией.

Можно ли свести баланс по одним вебхукам?

Нет. Шестнадцать типов событий закрывают счета, выводы и депозиты платёжных каналов, но у зачисления, которое не оплатило ни один счёт, события нет вовсе, поэтому баланс, собранный из вебхуков, со временем разойдётся с настоящим.

Удерживает ли Paymos часть выручки?

Нет, резерва, который удерживают с оборота, здесь нет. Цифра «Удержано» на странице баланса — это ваши же выводы в пути, и она возвращается в «Доступно», если вывод не ушёл.

Когда НЕ стоит использовать собственный учётный регистр

  • Если заказов у вас несколько десятков в месяц, таблица заказов и страница баланса сверяются глазами. Второй регистр — инфраструктура, которую вы будете поддерживать и никогда не откроете.
  • Если выручку уже ведёт бухгалтерская программа, пусть она и остаётся источником правды. Дублировать те же движения в самописный регистр значит завести два числа, и защищать придётся оба.
  • Если нужна выписка по каждому клиенту, эту задачу закрывает чтение ленты депозитов в свою таблицу переводов, без всей учётной машинерии.
  • Если вы продаёте что-то мгновенное и дешёвое в замене, эти неудобные события проще разбирать руками, чем описывать моделью.

Источники

  1. 1. Документация Paymos — вебхуки (accessed 2026-09-15)
  2. 2. Документация Paymos — путь платежа (accessed 2026-09-15)
  3. 3. Modern Treasury — How to Scale a Ledger, Part V: Immutability and Double-Entry (accessed 2026-09-15)

Последняя проверка: 15 сент. 2026 г.

#учётный-регистр#сверка#расчёты#двойная-запись
Поделиться