Инвойсы позволяют запрашивать криптоплатежи на определённый адрес в конкретном токене и сумме. Vilna отслеживает входящие транзакции в реальном времени, определяет частичные платежи и переплаты, а также подтверждает оплату после достижения необходимой глубины блоков. У каждого инвойса есть публичный URL, которым можно поделиться с плательщиком — аутентификация с его стороны не требуется.
Вам понадобится API-ключ Vilna с правами api:invoice:read и api:invoice:write. Подробнее — в разделе Аутентификация.
Инвойс проходит через следующие статусы:
| Статус | Описание |
|---|---|
pending | Ожидание оплаты. Транзакции ещё не поступали. |
underpaid | Получена частичная оплата. Сумма меньше запрошенной. |
paid | Полная сумма получена. Ожидание подтверждений блоков. |
confirmed | Платёж подтверждён достаточным количеством блоков. |
overpaid | Получено больше запрошенной суммы. |
cancelled | Отменён мерчантом. |
expired | Срок оплаты истёк, полная сумма не поступила. |
Чтобы создать инвойс, укажите адрес депозита, токен (в формате CAIP-19), сумму в базовых единицах и срок действия. Адрес должен принадлежать вашему проекту и не иметь активного инвойса.
curl -X POST "https://${VILNA_NAMESPACE}.vilna.app/invoices" \
-H "X-Api-Key: ${VILNA_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
"asset_gid": "eip155:56/bep20:0x55d398326f99059fF775485246999027B3197955",
"amount": "42500000",
"expires_at": "2024-06-15T18:00:00Z",
"metadata": {
"order_id": "ORD-20240615-1042",
"customer": "john@example.com"
}
}'Ответ (сокращённый):
{
"item": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
"asset_gid": "eip155:56/bep20:0x55d398326f99059fF775485246999027B3197955",
"amount": "42500000",
"received_amount": "0",
"status": "pending",
"expires_at": "2024-06-15T18:00:00Z",
"metadata": {
"order_id": "ORD-20240615-1042",
"customer": "john@example.com"
},
"created_at": "2024-06-15T10:30:00Z",
"updated_at": "2024-06-15T10:30:00Z",
"status_logs": [
{
"status": "pending",
"comment": null,
"changed_at": "2024-06-15T10:30:00Z"
}
],
"transactions": []
},
"references": {
"tokens": {},
"blockchains": {}
}
}Ключевые поля:
amount— запрошенная сумма в базовых единицах (наименьшая единица токена). Для USDT на BSC с 6 десятичными знаками"42500000"равно 42,5 USDT.metadata— необязательные пары ключ-значение для привязки инвойсов к вашим внутренним записям.expires_at— крайний срок оплаты. После этого времени инвойс переходит в статусexpired, если полная оплата не поступила.
На одном адресе может быть только один активный инвойс. Попытка создать второй инвойс для того же адреса вернёт ошибку 409 Conflict.
У каждого инвойса есть публичный эндпоинт, не требующий аутентификации. UUID инвойса выступает в роли токена доступа — любой, у кого есть ссылка, может просмотреть детали оплаты.
curl "https://${VILNA_NAMESPACE}.vilna.app/public/invoices/550e8400-e29b-41d4-a716-446655440000"Публичный ответ содержит адрес, сумму, статус и историю транзакций — всё, что нужно плательщику. Поля, предназначенные только для мерчанта (например, metadata), исключены.
Используйте этот эндпоинт для создания собственных страниц оплаты или направляйте плательщиков на ваш платёжный интерфейс.
Получите полную информацию об инвойсе, включая историю статусов и обнаруженные транзакции.
curl "https://${VILNA_NAMESPACE}.vilna.app/invoices/550e8400-e29b-41d4-a716-446655440000" \
-H "X-Api-Key: ${VILNA_API_KEY}"Когда поступает платёж, ответ включает детали транзакции:
{
"item": {
"status": "paid",
"received_amount": "42500000",
"transactions": [
{
"hash": "0xabc123def456789012345678901234567890123456789012345678901234abcd",
"block_number": 12345678,
"is_success": true,
"detected_at": "2024-06-15T12:05:00Z",
"confirmed_at": null,
"deposits": [
{
"asset_gid": "eip155:56/bep20:0x55d398326f99059fF775485246999027B3197955",
"amount": "42500000",
"is_matched": true
}
]
}
],
"status_logs": [
{ "status": "pending", "comment": null, "changed_at": "2024-06-15T10:30:00Z" },
{ "status": "paid", "comment": null, "changed_at": "2024-06-15T12:05:00Z" }
]
}
}Каждая транзакция содержит:
is_success— успешна ли транзакция в блокчейне. Неуспешные транзакции отображаются в списке, но не учитываются при расчёте оплаты.confirmed_at—nullдо тех пор, пока транзакция не наберёт необходимое количество подтверждений блоков.deposits— отдельные перемещения токенов внутри транзакции. Флагis_matchedуказывает, совпадает ли токен с тем, который ожидает инвойс.
Vilna отслеживает каждый депозит и автоматически обновляет статус инвойса:
- Частичная оплата: инвойс переходит в статус
underpaid. Полеreceived_amountотражает текущую сумму. Дополнительные платежи накапливаются до достижения полной суммы. - Полная оплата: инвойс переходит в статус
paid, а затем вconfirmedпосле получения достаточного количества подтверждений блоков. - Переплата: если полученная сумма превышает запрошенную, статус переходит в
overpaid. Возвраты обрабатывайте в логике вашего приложения.
Отслеживайте эти переходы, опрашивая эндпоинт инвойса, или настройте вебхук-уведомления об изменении статуса инвойса.
Получите все инвойсы с возможностью фильтрации по статусу и пагинацией.
# List all pending and underpaid invoices
curl "https://${VILNA_NAMESPACE}.vilna.app/invoices?status=pending&status=underpaid&limit=20&page=1" \
-H "X-Api-Key: ${VILNA_API_KEY}"Эндпоинт списка возвращает объекты InvoiceSummary (без status_logs и transactions). Для получения полной информации об инвойсе используйте GET /invoices/{invoice_id}.
Отмените активный инвойс, чтобы освободить адрес для новых инвойсов. Отменить можно только инвойсы в статусе pending или underpaid. При желании добавьте комментарий (до 64 символов) с причиной отмены.
curl -X POST "https://${VILNA_NAMESPACE}.vilna.app/invoices/550e8400-e29b-41d4-a716-446655440000/actions/cancel" \
-H "X-Api-Key: ${VILNA_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"comment": "Customer requested cancellation"
}'Успешная отмена возвращает 204 No Content. Операция идемпотентна — повторная отмена уже отменённого инвойса вернёт тот же ответ.
Поле comment необязательное. Можно отправить пустое тело или вовсе не включать тело запроса.
События и мониторинг
Настройте вебхуки для получения обновлений статуса инвойса в реальном времени вместо поллинга
Основные концепции
Узнайте о CAIP-идентификаторах, суммах в базовых единицах и паттерне ответа-обёртки
Паттерны интеграции
Обнаружение депозитов, обработка платежей и другие типичные сценарии интеграции
Справочник Platform API
Полный каталог эндпоинтов, включая инвойсы, со схемами запросов и ответов