Перейти к содержимому
Последнее обновление

Счета

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

Прежде чем начать

Нужен ключ проекта с api:invoice:read и api:invoice:write. Сначала зарегистрируйте адрес, который контролируете вы.

5 состояний жизненного цикла Получено + подтверждено Публичное представление счёта Граница expires_at не включена

Жизненный цикл счёта

status описывает жизненный цикл. Суммы независимо отражают текущие факты о платежах:

СтатусЗначение
openОкно оплаты открыто. Счёт может подтвердиться до окончания срока.
processingОкно закрыто; ещё ожидаются проверки платежей, подтверждения или действия оператора.
confirmedПодтверждена достаточная сумма ожидаемого токена. Конечное состояние.
cancelledОтменён по правилам ниже. Конечное состояние.
expiredОкно закрыто, проверки завершены, действительных платежей нет. Конечное состояние.
созданopen
срок истёк
processing
достаточно подтверждений
конечныйconfirmed
confirmed

Возможен переход прямо из open, если достаточная сумма подтверждена до окончания срока.

cancelled

Нужны проверки отмены, описанные ниже; частичные платежи остаются связаны со счётом.

expired

Переход из processing после завершения проверок при отсутствии действительных платежей.

Окно оплаты начинается в created_at и заканчивается непосредственно перед expires_at либо раньше при переходе в confirmed или cancelled. Учитывается время включения транзакции в блок по данным сети, а не время получения webhook. Подходящий платёж может набрать подтверждения уже после срока. Наступление срока само по себе не означает expired; частичная оплата может оставить счёт в processing.

amount - запрошенная сумма, received_amount - сумма текущих действительных платежей ожидаемым токеном, попавших в окно, confirmed_amount - её подтверждённая часть. В аутентифицированном API все три поля являются строками с целым числом базовых единиц. Реорганизация может уменьшить суммы. Конечное решение жизненного цикла сохраняется даже при изменении данных сети; перед дальнейшими действиями приложения сверяйте текущие суммы и связи с транзакциями.

Создать счёт на криптоплатёж

Создайте счёт через POST /invoices. Передайте зарегистрированный адрес, CAIP-19 asset_gid, сумму в базовых единицах и будущий expires_at.

Окна оплаты счетов на одном адресе не могут пересекаться. Если на адресе уже есть счёт с открытым окном оплаты, тот же актив и сумма вернут существующий счёт с 200; другие актив или сумма вернут 409 Conflict. При 200 срок и metadata существующего счёта не меняются. Проверьте возвращённые ID, срок и metadata, прежде чем связывать счёт с заказом.

Создайте Idempotency-Key и срок один раз, затем сохраните их вместе с полным телом запроса. Повторы используют тот же ключ и тело. Для токена с 6 десятичными знаками 42.5 единицы передаются как "42500000". Перед расчётом суммы прочитайте метаданные точной сети и контракта; символ не определяет число знаков.

При неизвестном результате повторяйте с тем же ключом и телом. Если ID счёта известен, прочитайте его текущее состояние; иначе поиск результата ограничен доступными списками и фильтрами. Не создавайте новый ключ автоматически. См. Идемпотентность.

Сохраните возвращённый item.id, чтобы проверять счёт и связывать его с заказом.

status_logs содержит переходы жизненного цикла: status, допускающий null comment и changed_at. Это не история каждого изменения сумм. metadata видит только мерчант; декодированные ключи и значения вместе могут занимать не более 4096 байт UTF-8.

Поделиться страницей оплаты

Публичное представление API не требует аутентификации. Счёт может прочитать любой, у кого есть его UUID, поэтому передавайте ссылку только предполагаемым получателям. Для своей информационной страницы оплаты используйте GET /public/invoices/{invoice_id} - публичный счёт.

Ответ использует PublicInvoice: поля amount, received_amount и confirmed_amount содержат base и необязательную строку formatted. Показывайте форматированное значение, если оно есть; иначе явно обозначайте базовые единицы. Не подставляйте фиксированный символ токена. Публичное представление скрывает metadata и комментарии истории. Оно отличается от аутентифицированного Invoice, где три поля сумм являются строками.

Проверить статус счёта

Читайте GET /invoices/{invoice_id} - сведения о счёте. О завершении судите по самому счёту. Уведомление о транзакции - повод перечитать его, а не доказательство статуса confirmed.

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

Проверяйте связи в item.transactions вместе с суммами. is_active означает, что транзакция ещё актуальна в сети, но не доказывает оплату счёта. Кандидат Bitcoin из мемпула может быть активен без учтённой суммы. Депозиты отражают чистый положительный вклад по активу; is_matched отмечает ожидаемый токен. Другие активы не входят в запрошенную сумму.

При реорганизации или замене сохранённая связь становится неактивной, её депозиты пустеют. Связь остаётся, поэтому тот же перевод не оплатит другой счёт. Сводки активных транзакций находятся в references.transactions[chain_gid][txid]; у неактивной связи сводки там нет. Сводки используют details.family и поля своего семейства.

Частичные платежи и переплаты

Сравнивайте базовые единицы через BigInt. Для запроса "42500000" с 6 знаками полученные "20000000" - частичная оплата 20 единиц, а "45000000" - 45 единиц с превышением на 2.5. Достаточная полученная сумма ещё не означает достаточную подтверждённую, а отменённый или просроченный счёт не завершён оплатой.

Публичного действия ручного подтверждения нет. Читайте текущие status, received_amount, confirmed_amount и связи с транзакциями; не переносите категории оплаты из приложения в ответ API.

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

Список счетов

Используйте GET /invoices - список счетов. Фильтруйте по status жизненного цикла; повторяйте параметр для альтернативных значений (до 10). Чтобы выделить частичную оплату или превышение, сравнивайте суммы в приложении.

Список возвращает InvoiceSummary без status_logs и transactions. Для подробностей перечитайте отдельный счёт.

Отменить счёт

Счёт в статусе open или processing можно отменить, если среди уже учтённых действительных платежей нет неподтверждённых, а подтверждённая сумма меньше amount. Полностью подтверждённая частичная оплата не препятствует отмене. Если условие отмены не выполнено, API возвращает 422.

Вызовите POST /invoices/{invoice_id}/actions/cancel - отмена счёта. Используйте отдельный ключ отмены и сохраните его, идентификатор счёта и необязательное тело для повторов.

Успех возвращает 204 No Content; повторная отмена уже отменённого счёта тоже возвращает 204. Комментарий необязателен, до 64 символов; тело можно оставить пустым или не передавать. Отмена меняет жизненный цикл мониторинга и не перемещает и не возвращает средства.

После отмены

После отмены новые платежи не связываются со счётом, даже если время их включения в блок попадает в его прежнее окно оплаты. Существующие связи с платежами сохраняются, а received_amount и confirmed_amount могут меняться при изменении данных сети. Статус остаётся cancelled. Связанные платежи не переносятся в новый счёт, а адрес можно использовать снова.

Чтобы использовать адрес снова, создайте новый счёт, соблюдая требования к созданию и используя новый Idempotency-Key. У нового счёта будет собственное окно оплаты.