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

Журнал изменений

Журнал изменений

Что нового и что изменилось — сначала самое недавнее.

  1. API

    Четыре кода ошибки подтверждения платежа свели в один

    Когда подтверждение платежа не может открыть оплату в токене и сети, которые выбрал покупатель, теперь возвращается один 503 — payment_method_unavailable. Он заменяет no_available_address, address_lease_failed, bridge_unavailable и collection_disabled.

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

    Ничего не разветвляется: не было случая, когда старые четыре требовали бы от вас разных действий. Причины по-прежнему пишутся у нас — там, где они нужны поддержке.

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

    Полный список — на странице Коды ошибок.

  2. API

    Один код ошибки вывода переименован

    Ошибка 503, которую вывод возвращает, когда сеть назначения не может провести выплату, теперь называется withdrawal_network_unavailable. Раньше — hot_wallet_insufficient_liquidity.

    Когда она срабатывает, не изменилось: тот же эндпоинт, тот же 503, та же ситуация — этот токен в этой сети сейчас провести нельзя, а в другой сети или позже обычно можно. Изменились название и текст: они описывали нашу сторону выплаты вместо вашей.

    Если ваша интеграция ветвится по старой строке, поменяйте её сейчас. Старый код больше не отправляется, переходного периода, когда приходят оба, нет. Ссылка type в конверте ошибки идёт за новым именем, так что сохранённая ссылка на старый якорь не откроется.

    Полный список — на странице Коды ошибок.

  3. Дашборд

    Короткие суммы в кабинете, точность — по наведению

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

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

    В учётном регистре не округляется ничего. Короткая запись — только способ показать сумму на экране; точное значение лежит под ней и в расчёты идёт целиком.

  4. Выводы

    Выплаты в кабинете: одному или списком — в одном диалоге

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

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

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

  5. API

    Платёжные каналы — в каждом из восьми SDK

    Платёжные каналы, их вебхуки и лента депозитов появились во всех официальных клиентах: .NET, Go, Java, PHP, Python, Ruby, Rust и TypeScript. Подпись, повторы и типизированные ошибки закрывает библиотека, а в README каждого клиента разобран сценарий целиком, а не перечислены методы. Методы лежат в каждом клиенте, а сами каналы работают у тех мерчантов, кому их включили.

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

  6. Платёжные каналы

    Минимум депозита виден по каждому токену и сети

    Список токенов канала больше не состоит из одних символов. У каждой записи появился minimum_deposit — наименьший перевод, который этот маршрут зачислит. Минимум принадлежит паре «токен и сеть», и расходятся минимумы на порядки: один и тот же токен ограничен по-разному в дешёвой сети и в дорогой.

    Значение считается заново при каждом чтении, так что верное число — то, что пришло в текущем ответе, а не зашитое в код. Место ему рядом с адресом: перевод меньше минимума на баланс не попадёт и автоматически не вернётся.

    Заодно проект принимает символы токенов, а не пары «сеть и символ». Добавили сеть — заново подтверждать в ней каждый токен не нужно.

    Минимумы видны там, где каналы уже включены, — а включают их мерчантам по одному.

  7. Дашборд

    Способ подключения: один вопрос, пять ответов

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

    От ответа зависит, что проект показывает дальше. У проекта-бота быстрый старт заканчивается внутри Telegram; проект на плагине больше не предлагает встроить код, который ему не понадобится.

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

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

  8. Платёжные каналы

    Платёжные каналы: постоянный адрес для каждого плательщика

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

    Канал заводится по вашему же external_id, так что хранить ещё один идентификатор не придётся. Пара «проект + external_id» и есть ключ идемпотентности: повторный вызов возвращает тот же канал с ответом 200, а не открывает второй с 201.

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

    Канал можно заблокировать и разблокировать, а в тестовом режиме — сымитировать депозит.

    Каналы открываются мерчантам поштучно: пока их не включили вам, маршруты закрыты. Как всё устроено — в документации.

  9. Языки

    Немецкий и испанский: языков стало шесть

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

    Язык страницы оплаты подбирается сам — сначала по адресу, потом по cookie, потом по заголовку Accept-Language. Не совпало ничего — покупатель видит английский.

    Выбор при этом остаётся за покупателем: язык переключается прямо на оплате, счёт остаётся тем же и заново не выставляется.

  10. Оплата в Telegram

    Счёт, который оплачивают прямо в Telegram

    Проект теперь можно создать как Telegram-бот. У такого проекта payment_url счёта — не адрес страницы, а ссылка в бота: плательщик нажимает её, открывается чат, и токен с сетью он выбирает там же.

    На шаге пополнения бот показывает QR-код, адрес с кнопкой копирования и срок действия счёта. Уходить во вкладку браузера не нужно, заводить учётную запись в Paymos — тоже.

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

    Как включить — на странице Оплата в Telegram.

  11. Партнёрство

    Партнёрская программа

    Приведите мерчанта и получайте долю комиссии Paymos, которую он приносит. Уровней четыре — от 20 % до 40 %. Первые три зависят от того, сколько ваших мерчантов активны: 20 % с самого начала, 25 % на пяти, 30 % на двадцати. Верхний даётся по запросу, а не по порогу.

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

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

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

    Ваша ссылка и текущий уровень — в разделе Партнёрская программа.

  12. Дашборд

    Аналитика платежей

    Страница аналитики отвечает на три вопроса: сколько пришло, какая доля счетов оплачена и сколько времени покупатели тратили на оплату.

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

    Время до оплаты показано распределением, а не средним: 0–5 минут, 5–10, 10–15, 15–20 и 20 и больше. Оборот разложен по токенам, сетям и проектам — по пять первых в каждой разбивке, а не весь список. Активность по счетам разбита по дням недели и часам в том часовом поясе, который выберете вы.

    Открывается в разделе Аналитика.

  13. Аудит

    Журнал аудита значимых действий

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

    Действие названо явно — merchant.add_whitelisted_address, operator.engage_freeze, — а исполнитель сохраняется таким, каким был в тот момент, вместе с ролью. Повышение в следующем месяце не перепишет то, что «Наблюдатель» сделал в марте.

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

    Мерчант видит историю собственной учётной записи, включая входы с устройством и IP. Полный журнал платформы остаётся только у операторов: в нём действия других мерчантов, и безопасного способа его открыть не существует.

  14. Уведомления

    Уведомления на почту и в Telegram

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

    Движение средств покрыто: вывод создан, вывод завершён. Рядом — изменения в команде, вебхуки, доставка которых так и не удалась, и набор про безопасность: 2FA включили или выключили, passkey добавили или удалили, привязали способ входа, добавили или отозвали адрес из белого списка, сменили API-секрет, отозвали ключ.

    Обычные категории вы вправе отключить. Категории безопасности — нет, и настройки, которая их спрячет, не существует: сообщение о смене адреса вывода стоит лишнего письма куда больше, чем наоборот. SMS среди каналов нет.

  15. API

    Один формат ошибки

    Любой эндпоинт при ошибке отвечает в одной и той же форме: RFC 9457 Problem Details, application/problem+json.

    Ветвить логику нужно по code — это стабильная строка, смысл которой после публикации не меняется. title и detail написаны для человека: их могут переформулировать, дополнить или перевести между релизами, поэтому интеграция, которая разбирает detail, ломается от правки текста. Ошибка валидации по одному полю несёт field; если полей не прошло несколько, разбивку по ним даёт массив errors[].

    type ведёт прямо на строку документации с этим кодом — незнакомая строка в логе превращается в один переход. Полный список — на странице /docs/errors/codes.

  16. API

    Идемпотентное создание

    Ключ идемпотентности — external_order_id. Передайте его при создании инвойса, и повторный вызов вернёт уже созданный, а не сделает второй.

    Заголовок Idempotency-Key придумывать и хранить не нужно: значение, которое здесь важно, у вас уже есть — номер заказа, идентификатор корзины, ссылка на выплату. Новый инвойс отвечает 201 Created, повтор с тем же идентификатором — 200 OK и тот же инвойс. С выводами так же, и вот там от этого больше всего пользы: повторный вызов вернёт первый вывод, а не отправит средства дважды.

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

  17. API

    Белый список IP у каждого ключа

    У каждого API-ключа свой белый список: до 50 записей, IPv4 или IPv6, отдельные адреса или диапазоны CIDR. Пустой список означает, что по IP ключ не ограничен.

    У Payout-ключа пустым он не остаётся. Только что созданный Payout-ключ неактивен, пока в список не добавлен хотя бы один адрес: у ключа, украденного в день создания, просто нет места, откуда его вызвать. Payment-ключи по IP не проверяются — они создают инвойсы, а не двигают средства.

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

  18. API

    API-ключи с ограниченными правами

    Учётные данные бывают двух видов. Payment-ключ (pk_) создаёт инвойсы и читает их статус. Payout-ключ (rk_) создаёт и отменяет выводы и читает балансы.

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

    У API-секретов префикс sk_, у секретов для подписи вебхуков — whsec_. Среда тоже указана в префиксе, поэтому в конфиге pk_live_… и pk_test_… — заметно разные вещи, а не две похожие строки, в которые надо всматриваться.

    Оба вида ключей — в разделе Разработчик → API-ключи.

  19. Доступ

    Двухфакторная аутентификация

    TOTP включается на любой учётной записи: шестизначный код из приложения-аутентификатора, новый каждые тридцать секунд.

    Вход — меньшая половина пользы. Большая — усиленная повторная аутентификация: короткий список операций требует свежий код в момент выполнения и не доверяет сессии, прошедшей 2FA час назад. Добавление адреса вывода, его удаление, правка белого списка IP у API-ключа и отключение 2FA — у каждой операции своя область, поэтому перехваченный для одной код не разрешит другую.

    При включении и отключении на почту и в Telegram уходит уведомление о безопасности — что бы ни стояло в настройках уведомлений. Настройка — в разделе безопасность учётной записи.

  20. Доступ

    Вход по passkey

    Войти можно по passkey — через Face ID, Touch ID, Windows Hello или аппаратный ключ. Это WebAuthn и FIDO2. Пароля в этой схеме нет ни на одном шаге: его тут никогда и не было, поэтому выманивать нечего.

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

    На одну учётную запись можно завести несколько устройств. Добавление и удаление любого из них отправляет уведомление о безопасности, и отключить его нельзя. Ссылка-вход из письма, Google и Telegram работают как раньше: passkey — ещё один способ войти, а не замена остальным.

    Добавить — в разделе безопасность учётной записи.

  21. Поддержка

    Поддержка внутри Telegram-бота

    В боте Paymos есть ветка поддержки. Откройте «Обращения», напишите сообщение — оно дойдёт до операторов, которые отвечают со стороны платформы.

    Это один разговор, а не очередь заявок. Ответ приходит в тот же чат, последние сообщения остаются на экране, а второе сообщение до ответа оператора не отправляется: бот прямо об этом скажет, а не сложит его в очередь, которую никто не читает.

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

  22. Плагины

    Официальные плагины для восьми платформ

    Вышли плагины для WooCommerce, WHMCS, OpenCart, PrestaShop, Magento 2, Shopware 6, CS-Cart и Easy Digital Downloads.

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

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

    Инструкции по установке всех восьми — в документации.

  23. Сети

    Plasma — тринадцатая сеть

    Plasma принимает USDT. Это тринадцатая основная сеть — столько их в списке на сегодня.

    Актив на ней один. Токен появляется на странице оплаты в конкретной сети потому, что его там включили, а не потому, что сеть технически его потянет. Решает реестр — отдельно по сети и по токену. Из того, что где-то существует подходящий контракт, ничего не выводится.

    Тринадцать сетей и пять активов стоят теперь за одним вызовом создания счёта. Кто подключается сегодня, отправляет тот же запрос, что и подключившийся в январе: список сетей — это данные, а не версия API.

  24. API

    Серверные SDK для восьми языков

    Опубликованы официальные клиенты для TypeScript, Python, PHP, Go, .NET, Java, Ruby и Rust.

    Каждый закрывает контракт целиком, а не его часть: инвойсы, выводы, балансы, время сервера, курсорная разбивка на страницы, формат ошибки, повторы, подпись запроса и проверка вебхуков. Ради подписи библиотеку и стоит брать. Каноническую строку, окно метки времени и HMAC в base64 легко собрать почти правильно — и почти правильная подпись приходит обратно как 401, по которому больше ничего не понять.

    Проверка вебхука — вторая подпись, со своими правилами. Все клиенты берут сырые байты запроса до разбора JSON: подадите заново сериализованное тело — проверка не пройдёт, и это правильно.

    Репозитории, теги релизов и требования к среде перечислены на странице /docs/server-sdks.

  25. Токены

    XAUT — расчёты в золоте

    XAUT принимается в Ethereum. Это первый актив в списке, который не стейблкоин, и относиться к нему как к стейблкоину не стоит.

    Один XAUT — это тройская унция чистого золота в слитке стандарта London Good Delivery, поэтому баланс в XAUT повторяет цену металла, а не доллара. Кому золото на балансе нужнее долларов, тот ради этого его и принимает. Обратная сторона ровно та же: такой баланс ходит в обе стороны, чего от привязанного к доллару токена никто не ждёт.

    Механика при этом обычная. Только Ethereum, та же политика подтверждений по сумме, тот же баланс по активу, тот же белый список на выводе. В приёме теперь четыре стейблкоина и один актив, обеспеченный золотом.

  26. Сети

    Sui подключена — только USDC

    Sui принимает платежи. Актив на ней один — USDC.

    Sui не EVM и не форк чего-то из уже подключённого. Адрес занимает 32 байта и записывается как 0x плюс 64 шестнадцатеричных символа — вдвое длиннее EVM-адреса, и одного этого хватает, чтобы в записях мерчанта их не спутать. Модель монет тоже не похожа на баланс ERC20, поэтому обнаружение поступлений идёт здесь своим путём, а не заимствованным.

    Мерчанту всё это не видно. Включите Sui в проекте — она появится на странице оплаты рядом с остальными, а счёт, вебхук и баланс ведут себя ровно как в любой другой сети. Вывод — единственное исключение: в Sui баланс не выводится, для выплат остаются другие сети.

  27. Токены

    USD1 и DAI в приёме

    Принимаем ещё два стейблкоина: USD1 в Ethereum и Solana, DAI в Ethereum.

    Устроены они по-разному. USD1 обеспечен фиатными резервами, как USDT и USDC. У DAI обеспечение лежит в блокчейне: залог в криптоактивах вместо банковского депозита. Единица одна и та же — доллар, а модель обеспечения разная, и полезно понимать, в чём именно у вас баланс.

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

  28. Расчёты

    Глубина подтверждений зависит от суммы

    Политика подтверждений смотрит теперь на два параметра: сеть и долларовую сумму счёта. Счёт на 40 $ и счёт на 40 000 $ в одной сети больше не ждут одинакового числа блоков.

    В Ethereum это 2 подтверждения до 100 $, 6 до 1 000 $, 12 до 10 000 $ и 32 выше — примерно 24 секунды на нижней ступени и около шести минут на верхней. В Tron — 2, затем 6, дальше потолок в 19: столько нужно, чтобы блок подписали 19 из 27 суперпредставителей. Цифры Arbitrum выглядят огромными — 40 / 120 / 240 / 800, — только потому, что блок там короче секунды: по часам выходит то же, что в Base и Optimism.

    Сети с собственной финальностью ступеней не имеют. BSC, Polygon и Avalanche подтверждают по финальности сети, Solana — на уровне finalized, TON — на одном блоке, потому что каждый блок мастерчейна там уже окончательный.

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

  29. Сети

    Solana в работе

    Solana в работе. Принимаем на ней USDT, USDC и USD1.

    Подтверждения Solana считает не так, как EVM-сети, и платформа не подгоняет её под общий шаблон. Поступления сканируются на уровне finalized и подтверждаются в момент обнаружения — один порог, без разбивки по суммам. Что для Solana значит finalized, то у нас и значит подтверждённый платёж.

    Адреса для приёма — это открытые ключи ed25519 в кодировке base58, а не строки 0x. Спутать адрес Solana с EVM-адресом в собственных записях не выйдет. Баланс по-прежнему ведётся по активу: USDC, принятый в Solana, и USDC, принятый в Base, складываются в одну сумму.

  30. Сети

    Avalanche подключён

    Avalanche принимает платежи. USDT и USDC работают в C-Chain.

    Адреса и хеши транзакций здесь такие же, как в EVM-сетях: если вы уже сверяете Ethereum или Base, разбирать ничего нового не придётся. Ступеней по сумме здесь нет: финальность Snowman закрывает вопрос сразу для любого размера платежа, поэтому депозит зачисляется, когда сеть объявила его финальным. Так же устроены BSC и Polygon, а не ступенчатые счётчики блоков, которые ждут Ethereum и роллапы.

    Вывод в Avalanche уходит только на адрес, который уже есть в белом списке мерчанта. Комиссия маршрута и минимальная сумма показаны до подтверждения вывода.

  31. Инфраструктура

    Отказоустойчивость на нескольких серверах

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

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

    PostgreSQL хранит изменяемое состояние платформы. Кеш в памяти используется только для справочных данных, например точности токенов и констант сетей.

  32. Тарифы

    Комиссионные политики на проект

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

    Два параметра на проект: комиссия платформы (процент с мерчанта) и наценка для покупателя (доля этой комиссии, которая добавляется к отображаемой сумме и оплачивается покупателем). Оба на нуле — комиссию платит мерчант; наценка 100 % — комиссию полностью оплачивает покупатель.

    Комиссия хранится в самом инвойсе и не пересчитывается позже из суммы поступления: пересчёт — источник расхождений в учёте.

  33. Выводы

    Повторная отправка выводов по RBF

    Выводы, застрявшие в сети — не хватило газа, конфликт nonce, вытеснение из мемпула, — теперь отслеживает отдельный сторожевой процесс и отправляет повторно.

    В EVM-сетях он использует replace-by-fee: если транзакция не попала в блок за настроенный таймаут, она уходит повторно с более высокой ценой газа и тем же nonce. Исходная вытесняется из мемпула, идентификатор операции не меняется.

    Ошибки отправки платформа делит на понятные группы: revert (решает обработчик), конфликт nonce (повтор с новым значением), заниженная комиссия (повышение по RBF), нехватка средств (оповещение дежурной смене). Итог разбора виден в статусе вывода — причина сбоя не остаётся догадкой.

  34. Доступ

    Команды и роли

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

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

    Управление — в разделе Настройки.

  35. Тестирование

    Тестовый режим с симуляцией платежей

    Тестовый режим повторяет рабочий сценарий: те же методы API, подписи и вебхуки. Данные и ключи разделены между средами.

    Платёж можно симулировать без перевода в основную сеть. Передайте этап (paid, overpaid, underpay, cancel) в метод симуляции: Paymos рассчитает сумму и отправит те же события, что при реальной оплате. Формат вебхуков, подписи и расписание повторов не меняются.

    После проверки замените тестовый ключ рабочим. Интеграционный код и контракт API остаются прежними.

  36. Брендинг

    Страница оплаты под ваш бренд — логотип и цвета

    Готовая страница оплаты теперь оформляется в бренде мерчанта. Логотип, один из стилей, акцент, цвета фона и поверхностей, скругление углов — задаются один раз на проект и применяются ко всем счетам этого проекта.

    Конструктор виджетов опирается на те же настройки бренда: палитра и логотип проекта подтягиваются во встраиваемый виджет, поэтому сайт с JS-сниппетом выглядит так же, как готовая страница оплаты, на которую он ведёт.

    Настройка бренда — в разделе Форма оплаты. Конструктор виджетов — Low-Code.

  37. Вебхуки

    Подписанные вебхуки и доставка at-least-once

    Доставка вебхуков теперь работает через outbox-паттерн. Доменные события пишутся в outbox в той же транзакции базы, что меняет состояние бизнес-данных: либо событие сохранено надёжно, либо изменения не было. Отдельный воркер забирает события и доставляет.

    Каждое тело события подписывается HMAC-SHA256. Подпись считается по сырым байтам тела и заголовку timestamp, поэтому защита от replay встроена — приёмник отклоняет подписи старше настроенного окна. Секрет ротируется отдельно для каждого endpoint, прямо из дашборда.

    Доставка at-least-once. Расписание повторов: 1 минута, 2, 4, 8, 16, 32 минуты, далее 1, 2, 4, 8 часов — итого 11 попыток примерно за 16 часов. Приёмник должен быть идемпотентен по идентификатору события: он есть в теле события и в заголовке X-Webhook-Id.

  38. POS

    POS-терминал для офлайн-точек

    POS-терминал теперь часть платформы. Создание инвойса одним кликом со сгенерированным QR-кодом — кассир показывает клиенту телефон, клиент сканирует, платёж приходит на баланс мерчанта.

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

    Открывается на /pos.

  39. API

    Публичный API для мерчантов

    Публичный REST API принимает и возвращает JSON. Контракт опубликован в формате OpenAPI.

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

    Merchant API подписывает запросы через HMAC. Сервер проверяет среду, права ключа и принадлежность ресурса до выполнения операции. Ключ рабочего режима не читает данные тестового проекта, и наоборот.

    Управление ключами — в разделе Разработчик → API-ключи. Контракт и примеры запросов доступны в документации.

  40. Виджеты

    Конструктор виджетов с предварительным просмотром

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

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

    Откройте конструктор в разделе Low-Code.

  41. Архитектура

    CQRS-пайплайн с компилированной авторизацией

    Каждая команда и запрос проходят через типизированный пайплайн: Logging → Validation → Authorization → Retry → Transaction → Handler. Каждый шаг обобщён по типу запроса: новое поведение добавляется одной регистрацией в DI, без рефакторинга.

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

    Валидация идёт первой: отклонить неверные данные до обращения к базе — самый дешёвый отказ. Transaction — последний шаг перед обработчиком: обработчик не открывает транзакцию сам, её передают готовой.

  42. Страница оплаты

    Готовая страница оплаты

    Готовая страница оплаты открывается по одной ссылке. Клиент выбирает сеть, получает адрес и QR-код, а статус меняется на странице после обнаружения перевода.

    После выбора сети счёт получает адрес из пула платформы, а страница подписывается на поток статуса. Обновления приходят автоматически; клиенту не нужно перезагружать страницу или нажимать кнопку проверки.

    Один счёт покрывает все сети, включённые в проекте: выставьте его один раз, а клиент рассчитается в Tron, BSC или Polygon — смотря что у него есть. Адрес появляется именно от выбора: до него адреса нет, после него он ровно один, и сумма к оплате закрепляется за этим выбором.

    Доступно на /invoice/{invoice-id}.

  43. Дашборд

    Дашборд мерчанта

    Дашборд мерчанта доступен в рабочей среде. Blazor Server формирует страницу на сервере, а SignalR передаёт изменения без периодического опроса и перезагрузки.

    Что в первом срезе:

    • Обзор — дневной оборот, доля оплаченных счетов, события в очереди и последние поступления (Обзор →)
    • Инвойсы — история с фильтрами по статусу, разбивка по сетям, хронология поступлений (Инвойсы →)
    • Балансы — текущие суммы по токенам во всех включённых сетях и история выводов (Балансы →)
    • Проекты — настройки на проект, включённые сети и токены, брендинг (Проекты →)
    • API-ключи — учётные данные, адреса вебхуков и журнал событий (API-ключи →)

    Переключатель в шапке переводит дашборд между рабочим и тестовым режимами без потери текущего раздела.

  44. Надёжность

    Поздний платёж проверяется на границе счёта

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

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

    Регрессионные тесты проверяют этот инвариант при каждом изменении. Нарушение останавливает сборку до выпуска в рабочую среду.

  45. Расчёты

    Автоматическая консолидация средств

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

    В EVM-сетях консолидация проходит в два этапа: адрес получает газ, затем переводит токен. Оба этапа входят в комиссию за приём. В Tron Paymos также покрывает комиссию консолидации. Неудачные операции повторяются с увеличивающимся интервалом, а зависшие передаются на разбор оператору.

    Мерчант работает с единым балансом и не обслуживает адреса каждого счёта отдельно.

  46. Курсы

    Курсы в реальном времени

    Сервис курсов рассчитывает сумму счёта в стейблкоинах по актуальной рыночной котировке. Paymos не конвертирует полученный актив в фиат или другой токен: курс нужен только для цены счёта.

    Котировки приходят с рынка и лежат в коротком кеше: он снимает задержку на странице оплаты, но не успевает отстать от цены. Если мерчант выставляет счёт в EUR, сумма в USDT определяется в тот момент, когда плательщик выбрал токен и сеть, и дальше закрепляется за счётом: рынок продолжает двигаться, сумма к оплате — нет.

    При кратком сбое используется последняя допустимая котировка. Если её срок истёк, создание счёта с пересчётом останавливается — счёт не выставляется по непроверенной цене.

  47. Токены

    USDC во всех EVM-сетях

    USDC теперь принимается во всех шести EVM-сетях, которые мы поддерживаем: Ethereum, BSC, Polygon, Arbitrum, Optimism, Base. Реестр токенов хранит канонический адрес контракта для каждой сети — нативный USDC не перепутается с мостовой версией.

    Мерчант включает USDC для проекта на странице настроек. У каждого проекта свой список принимаемых токенов, а правила комиссий действуют на уровне токена, а не проекта.

  48. Сети

    TON подключён — восемь сетей в работе

    TON вошёл в список сетей. С Tron, шестью EVM-сетями и TON платформа проводит расчёты в восьми сетях через один API.

    Архитектура TON отличается от EVM: кошельки реализованы как смарт-контракты, а джеттоны используют мастер-контракт и отдельный контракт кошелька пользователя. Для TON добавлены собственные RPC-клиенты, вычисление адресов джеттон-кошельков и отдельный обработчик переводов.

    Транзакции TON используют совместимый с Ed25519 путь подписи вместо secp256k1, применяемой в ECDSA-сетях, и сохраняют те же ограничения адресов вывода и аудит, что и другие маршруты Paymos.

  49. Сети

    Приём в Arbitrum, Optimism и Base

    В список поддерживаемых сетей добавлены Arbitrum One, Optimism и Base. Все три используют общий процесс обработки EVM-транзакций, включая предварительную проверку и обработку реорганизаций блоков.

    Газ в роллапах заметно дешевле, чем в L1 Ethereum: приём USDC в Base или Arbitrum становится реальным вариантом для небольших чеков. Порог подтверждений настраивается для каждой сети — в Base и Optimism счёт закрывается по финальности секвенсера, как только набрана заданная глубина.

    Подключите их на проект в разделе Проекты.

  50. Сети

    Ethereum, BSC и Polygon подключены

    Paymos подключил основные сети Ethereum, BNB Smart Chain и Polygon PoS. Общий обработчик блоков использует отдельную политику подтверждений для каждой сети.

    Переводы обнаруживаются через eth_getLogs в скользящем диапазоне блоков. Фильтр ограничивает выборку поддерживаемыми контрактами токенов. При реорганизации цепи обработчик отмечает исключённые блоки и продолжает с новой точки ветвления.

    Для каждой сети настроено несколько RPC-узлов. При ограничении частоты или сбое запросы переходят на доступный узел с увеличивающимся интервалом повтора. Новая EVM-сеть подключается через конфигурацию общей инфраструктуры.

  51. Токены

    USDT-TRC20: от счёта до баланса

    USDT в сети Tron проходит весь сценарий: счёт, обнаружение перевода, подтверждение и зачисление на баланс. Комиссия за консолидацию адреса входит в тариф Paymos и не вычитается отдельной строкой из поступления мерчанта.

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

  52. Сети

    Приём USDT в сети Tron

    Paymos принимает USDT-TRC20 в сети Tron. Цикл проходит целиком на платформе: счёт, обнаружение перевода, политика подтверждений, зачисление на баланс мерчанта.

    Число подтверждений зависит от суммы: небольшие платежи не ждут столько же, сколько крупные. Самый глубокий порог ждёт, пока блок подпишут 19 из 27 суперпредставителей Tron, — после этого сеть считает его окончательным, и платёж дороже 1 000 $ проходит этот порог примерно за минуту. Обработчик сети использует несколько RPC-узлов и переключается между ними при недоступности одного из источников.

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

  53. Хранение средств

    Контроль адресов для исходящих переводов

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

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

    Оператор также может остановить все исходящие операции или заморозить конкретную пару актива и сети на время расследования.

  54. Учёт

    Учёт по двойной записи

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

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

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

  55. Архитектура

    Доменно-ориентированный фундамент

    Доменный слой готов. Богатые модели с приватными сеттерами, фабричные методы, которые проверяют каждый входной параметр, и value-объекты для всего, что касается денег.

    Money — это value-объект, привязанный к токену, а не сырое decimal. Арифметика между разными токенами не проходит ни при компиляции, ни во время работы: сложить USDT и TRX нельзя.

    Бизнес-операции возвращают Outcome<T, Error>, а не бросают исключения. Исключения остаются только для настоящих ошибок в коде. Ожидаемые отказы передаются значениями через весь пайплайн.

  56. Разработка

    Старт разработки

    Сегодня началась разработка Paymos. Стек: .NET 10 и Blazor Server для хост-слоя, PostgreSQL и EF Core 9 для хранения данных, MediatR для пайплайна команд и запросов.

    Кодовая база разделена на четыре слоя — домен, приложение, инфраструктура, хост — со строгой инверсией зависимостей. Домен не зависит ни от чего. Инфраструктура адаптируется к портам, объявленным в приложении. Хост соединяет всё вместе.

    Test-first — правило, а не исключение. CI прогоняет полный набор тестов на каждой отправке в репозиторий.