Документация AlfaBit API
Полноценный REST API для интеграции всех функций AlfaBit в ваши приложения.
Основной счёт — главный кошелёк для пополнений, выводов, переводов. Торговый счёт — общий баланс для биржевой торговли; через API на нём доступен стакан USDT/RUB, крипто-обмен по API идёт с основного счёта.
Для начала создайте API ключи в разделе Консоль разработчика.
Быстрый старт
Начните работу с API за 5 минут. Этот гайд проведёт вас от создания ключа до первой торговой операции.
Создайте API ключ
Перейдите в Консоль разработчика → API Keys → Создать ключ. Выберите нужные права доступа и сохраните Secret Key — он показывается только один раз.
Настройте подпись запросов
Каждый запрос подписывается HMAC-SHA256. Скопируйте готовый код из раздела Аутентификация (Python / JavaScript) — он работает из коробки.
Проверьте подключение
Отправьте первый запрос — получите профиль аккаунта:
GET /api/v1/integration/account/profile
→ Если видите свой email и ID — всё работает!Посмотрите балансы
Убедитесь, что на счёте есть средства для операций:
GET /api/v1/integration/account/wallets
→ Увидите все кошельки с балансами и адресами для пополнения.Сделайте первую операцию
Выберите что хотите сделать и перейдите к нужному разделу:
- Курсы крипто спота — тикеры BTC, ETH, все пары (публичный)
- Курсы фиатного спота — стакан USDT/RUB, инструменты, статистика (публичный)
- Курсы конвертера — крипто/крипто и крипто/фиат с фиксированным курсом (публичный)
- Торговля крипто спот — market/limit ордера BTC ↔ ETH
- Торговля фиат спот — ордера в стакане USDT/RUB
- Обмен через конвертер — мгновенный обмен по фиксированному курсу
- Выпустить карту — Visa/Mastercard за крипту
- Принять оплату — инвойсы для вашего бизнеса
Архитектура платформы
Прежде чем начать, важно понять как устроена платформа. Это поможет выбрать правильные эндпоинты и избежать ошибок.
Два типа счетов
Основной счёт (Funding)
Основной счёт. Здесь хранятся все ваши средства. С него выполняются: пополнения, выводы, крипто-обмены, переводы, оплата услуг и карт.
Торговый счёт (Trading)
Общий баланс для биржевой торговли — в терминале личного кабинета с него торгуются все пары. Через API на нём сейчас работает стакан USDT/RUB с market и limit ордерами: перед торговлей переведите средства через /funding/transfer/to-trading. Крипто-пары через API обмениваются мгновенным market-свопом с основного счёта (/integration/spot/crypto) — стакан и лимитные ордера для них по API пока недоступны.
Код валюты в примерах ниже (например RUB или USDT) показан для иллюстрации структуры запроса. Актуальный список поддерживаемых валют для вашей интеграции согласуется отдельно на этапе подключения.
Способы обмена — когда какой использовать?
| Модуль | Что это | Публичные курсы | Торговля | Пары |
|---|---|---|---|---|
| Крипто Спот | Крипто-рынки — крипто ↔ крипто | GET /spot/crypto/tickersGET /spot/crypto/market-info | Market / Limit ордера | BTC/USDT, ETH/USDT |
| Фиат Спот | Биржевой стакан AlfaBit — крипто ↔ фиат | GET /spot/fiat/orderbookGET /spot/fiat/statsGET /spot/fiat/instruments | Market / Limit ордера | USDT/RUB |
| Конвертер | Мгновенный обмен с фиксированным курсом | GET /converter/crypto/rateGET /converter/fiat/rate | Обмен по котировке | BTC → ETH, USDT → RUB |
Каждый из трёх модулей имеет публичные эндпоинты (курсы, тикеры, стакан), доступные без API ключа — для интеграции виджетов, мониторинга цен и аналитики. Торговые операции (ордера, обмен) требуют API ключ с соответствующими правами.
Общий формат ответа
Все ответы API имеют единый формат. Успешные операции возвращают данные в поле data, ошибки — в поле error:
{ "success": true, "data": { ... }, "ts": 1706000000 }{ "success": false, "error": { "code": "...", "message": "..." }, "ts": 1706000000 }Аутентификация
Все запросы должны быть подписаны HMAC-SHA256 с использованием секретного ключа.
HTTP Headers
| Header | Обязательный | Описание |
|---|---|---|
X-API-Key | Обяз. | Публичный ключ pk_live_xxx |
X-API-Signature | Обяз. | HMAC-SHA256 подпись |
X-API-Timestamp | Обяз. | Unix timestamp (секунды) |
X-Device-Id | Опционально | Идентификатор устройства / fingerprint (антифрод). Если есть — передавайте. |
Все запросы, создающие операции (депозиты, выводы, переводы, обмены, инвойсы), логируются на нашей стороне: IP источника запроса, User-Agent и X-Device-Id (если передан). Данные используются для безопасности API-ключей и антифрод-скоринга и не влияют на выполнение операций. Для KYC-API чекаута действуют отдельные обязательные поля payer_ip и external_payment_id (см. раздел «KYC-API чекаут»).
Ограничение по IP
Каждому ключу можно задать список разрешённых адресов — в Консоли разработчика, поле «IP Whitelist» при создании ключа или в его настройках. Пока список пуст, ключ принимается с любого адреса. Как только в нём появляется хотя бы одна запись, запросы со всех остальных адресов отклоняются: HTTP 403, код ошибки IP_NOT_ALLOWED.
Принимаются точный адрес (203.0.113.10), подсеть в нотации CIDR (203.0.113.0/24) и IPv6. Запись вида ::ffff:203.0.113.10 считается тем же адресом, что и 203.0.113.10. Несколько значений перечисляются через запятую, очистка поля снимает ограничение. Сверяется внешний адрес, с которого запрос дошёл до платформы, поэтому для сервера за NAT указывайте его внешний IP, а не адрес внутренней сети.
IP_NOT_ALLOWED приходит и при полностью корректной подписи — если получаете 403 после смены хостинга или добавления нового сервера, сначала проверьте список адресов ключа. Ограничение по IP — самый надёжный способ обезопасить ключ: даже утёкший секрет бесполезен с чужого адреса. Для боевых интеграций указывайте его всегда.
Формула подписи
message = timestamp + method + path + body
signature = HMAC-SHA256(secret_key, message)Примеры кода
import hmac, hashlib, time, requests, json
API_KEY = "pk_live_xxxxxxxxxxxxx"
SECRET_KEY = "sk_live_xxxxxxxxxxxxx"
BASE_URL = "https://alfabit.org"
def sign_request(method, path, body=""):
timestamp = str(int(time.time()))
message = f"{timestamp}{method.upper()}{path}{body}"
signature = hmac.new(
SECRET_KEY.encode(), message.encode(), hashlib.sha256
).hexdigest()
return {
"X-API-Key": API_KEY,
"X-API-Signature": signature,
"X-API-Timestamp": timestamp,
"Content-Type": "application/json"
}
# Получить балансы кошельков
path = "/api/v1/integration/account/wallets"
resp = requests.get(f"{BASE_URL}{path}", headers=sign_request("GET", path))
print(resp.json())
# {"success": true, "data": [{"symbol": "USDT", "available": "1250.00", ...}], "ts": 1706000000}
# Создать ордер на крипто обмен
path = "/api/v1/integration/spot/crypto/order"
body = json.dumps({"from_symbol": "USDT", "to_symbol": "BTC", "from_amount": "100"})
resp = requests.post(f"{BASE_URL}{path}", headers=sign_request("POST", path, body), data=body)
print(resp.json())Лимиты запросов
Лимит запросов настраивается индивидуально для каждого API ключа. Значение задаётся при создании ключа (поле rate_limit_per_minute). При превышении лимита API вернёт ошибку 429.
Обработка ошибок
{
"success": false,
"error": {
"code": "INVALID_SIGNATURE",
"message": "Invalid request signature",
"details": null
},
"ts": 1706000000
}| Code | HTTP | Описание |
|---|---|---|
INVALID_API_KEY | 401 | Неверный API ключ |
INVALID_SIGNATURE | 401 | Неверная подпись |
SIGNATURE_EXPIRED | 401 | Timestamp устарел (>5 мин) |
API_KEY_EXPIRED | 401 | Срок действия ключа истёк |
API_KEY_INACTIVE | 401 | Ключ отключён владельцем |
IP_NOT_ALLOWED | 403 | Адрес запроса не входит в список разрешённых IP ключа |
PERMISSION_DENIED | 403 | Нет доступа |
INSUFFICIENT_BALANCE | 400 | Недостаточно средств |
DEEP_PAGINATION_NOT_SUPPORTED | 400 | Слишком глубокая страница ленты транзакций (page × limit > 2000) — сузьте период |
Ошибки стакана (Фиатный Спот)
Отказы POST /spot/fiat/order, DELETE /spot/fiat/order/{id} и переводов торгового счёта приходят отдельным кодом, а числа для решения — в details. Пишите логику на code, а не на текст сообщения: message и details.reason_text могут меняться.
{
"success": false,
"error": {
"code": "INSUFFICIENT_LIQUIDITY",
"message": "Not enough counter liquidity in the orderbook to fill this market order",
"details": {
"quote_amount": "3041.770000",
"quote_currency": "RUB",
"available_liquidity": "0.654719",
"base_currency": "USDT",
"min_order_size": "1.000000",
"reason": "available_liquidity_below_min_order_size",
"hint": "Retry later, reduce the order, or place a limit order to wait in the book."
}
},
"ts": 1706000000
}| Code | HTTP | Описание | Что делать |
|---|---|---|---|
INSUFFICIENT_LIQUIDITY | 400 | Встречной стороны стакана не хватает на ваш рыночный ордер: либо она пуста, либо остатка меньше минимального лота. details: available_liquidity, min_order_size, reason. | Повторить позже, уменьшить ордер или поставить лимитный — увеличение ордера тут не помогает. |
ORDER_BELOW_MIN_SIZE | 400 | Присланный amount меньше минимального лота пары. details.min_order_size. | Увеличить amount до min_order_size. |
ORDER_ABOVE_MAX_SIZE | 400 | Ордер больше максимального для пары. details.max_order_size. | Разбить на несколько ордеров. |
ORDER_BELOW_MIN_VALUE | 400 | Сумма ордера (amount × price) меньше минимальной. details.min_order_value. | Увеличить amount или price. |
QUOTE_AMOUNT_TOO_SMALL | 400 | quote_amount не покрывает даже минимальный лот пары. | Увеличить quote_amount, лимиты — в GET /spot/fiat/market-info. |
PRICE_OUT_OF_BAND | 400 | Лимитная цена слишком далеко от рыночной. details: allowed_price_min, allowed_price_max. | Поставить цену внутрь диапазона из details. |
PRICE_NOT_ON_TICK | 400 | Цена не кратна шагу цены пары. details.price_step. | Округлить цену до price_step. |
PRICE_REFERENCE_UNAVAILABLE | 400 | Нет рыночного ориентира, чтобы проверить лимитную цену. | Повторить через несколько секунд. |
INSUFFICIENT_BALANCE | 400 | Не хватает средств на торговом счёте. details: currency, required, available, account. | Пополнить: POST /funding/transfer/to-trading. |
BALANCE_LOCK_FAILED | 400 | Баланс изменился параллельно с приёмом ордера. | Перечитать баланс и повторить с новым Idempotency-Key. |
PAIR_NOT_FOUND | 400 | Такой пары нет. details.pair. | Взять пару из GET /spot/fiat/instruments. |
PAIR_NOT_ACTIVE | 400 | Пара временно закрыта. details: pair, pair_status. | Дождаться статуса active в GET /spot/fiat/instruments. |
ORDER_NOT_FOUND | 404 | Ордер с таким id не найден. | Проверить id в GET /spot/fiat/orders. |
ORDER_ACCESS_DENIED | 403 | Ордер принадлежит другому аккаунту. | Проверить id и API-ключ. |
ORDER_NOT_CANCELLABLE | 400 | Ордер уже исполнен или отменён. details.order_status. | Считать финальное состояние: GET /spot/fiat/order/{id}. |
INVALID_ORDER_REQUEST | 400 | Некорректное тело запроса. details.field. | Сверить поля с документацией. |
STOCKBOOK_ERROR | 4xx / 5xx | Отказ, который пока не разложен на код. details: upstream_status, reason_text, upstream_body (устаревшее поле, оставлено для совместимости). | Повторить позже; при повторе прислать reason_text в поддержку. |
STOCKBOOK_UNAVAILABLE | 502 | Торговая система недоступна (сеть/таймаут). | Повторить через несколько секунд с тем же Idempotency-Key. |
Аккаунт
Профиль пользователя и управление криптовалютными кошельками. Просмотр балансов, создание кошельков и получение депозитных адресов.
При первом подключении начните с GET /account/profile чтобы убедиться, что аутентификация работает. Затем получите список кошельков через GET /account/wallets. Если нужного кошелька нет — создайте его через POST /account/wallets (это также вернёт депозитный адрес).
/api/v1/integration/account/walletsВозвращает список всех кошельков пользователя с балансами и адресами для пополнения. Если кошелёк ещё не создан для валюты — он не будет в списке.
{
"success": true,
"data": [
{
"symbol": "USDT",
"is_active": true,
"balance": "1250.00",
"available": "1250.00",
"pending_deposit": "0.00",
"pending_withdraw": "0.00",
"balance_usdt": "1250.00",
"balance_source": "ledger",
"addresses": [
{ "network": "TRX", "address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE" },
{ "network": "ETH", "address": "0x742d35Cc6634C0532925a3b..." }
]
},
{
"symbol": "BTC",
"is_active": true,
"balance": "0.05432100",
"available": "0.05432100",
"pending_deposit": "0.00",
"pending_withdraw": "0.00",
"balance_usdt": "2150.50",
"balance_source": "ledger",
"addresses": []
}
],
"ts": 1706000000
}/api/v1/integration/account/wallets/{symbol}Возвращает баланс и адреса конкретной валюты. Если кошелёк не найден — вернёт 404.
{
"success": true,
"data": {
"symbol": "USDT",
"is_active": true,
"balance": "1250.00",
"available": "1250.00",
"pending_deposit": "0.00",
"pending_withdraw": "0.00",
"balance_usdt": "1250.00",
"balance_source": "ledger",
"addresses": [
{ "network": "TRX", "address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE" }
]
},
"ts": 1706000000
}/api/v1/integration/account/walletsСоздаёт кошелёк для указанной валюты и сети. Если кошелёк уже существует — вернёт существующий с адресом для пополнения. Используйте для получения депозитного адреса.
{
"symbol": "USDT",
"network": "TRX"
}{
"success": true,
"data": {
"symbol": "USDT",
"available": "0.00",
"addresses": [
{ "network": "TRX", "address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE" }
]
},
"ts": 1706000000
}/api/v1/integration/account/profileВозвращает информацию о профиле: ID, email, статус KYC, тариф.
{
"success": true,
"data": {
"id": 12345,
"username": "john_doe",
"email": "john@example.com",
"email_verified": null,
"kyc_status": "verified",
"tariff": null,
"sso_client_id": "wallet-web",
"created_at": "1700000000"
},
"ts": 1706000000
}Пополнения
Пополнение основного счёта криптовалютой и фиатом. Крипто — через депозитные адреса, фиат — через банковский перевод или СБП.
- Получите депозитный адрес: GET /funding/deposit/crypto/address
- Отправьте криптовалюту на полученный адрес из внешнего кошелька
- Отслеживайте статус через GET /transactions
- Узнайте доступные методы: GET /funding/deposit/fiat/methods — в ответе code (SBER, TINKOFF, …)
- Создайте заявку: POST /funding/deposit/fiat с currency, amount и payment_provider_alias_code из списка методов
- Оплатите по invoice_public_url, requisites_qr_code или requisites — это одна и та же ссылка СБП. Если все три ещё null — GET /funding/deposit/fiat/{transaction_id}
Для крипто-депозита достаточно один раз получить адрес — он не меняется. Сохраните его на своей стороне и повторно используйте.
/api/v1/integration/funding/deposit/crypto/addressПолучить адрес для пополнения криптовалюты. Если адрес ещё не сгенерирован — он будет создан автоматически. Параметры: symbol (обязательный), network (опциональный).
{
"success": true,
"data": {
"symbol": "USDT",
"addresses": [
{ "network": "TRX", "address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE" }
]
},
"ts": 1706000000
}/api/v1/integration/funding/deposit/fiat/methodsВозвращает доступные методы пополнения фиата: банки, СБП и т.д. Параметр currency (по умолчанию RUB).
{
"success": true,
"data": {
"methods": [
{ "code": "SBER", "name": "Сбербанк", "type": "sbp" },
{ "code": "TINKOFF", "name": "Т-Банк", "type": "sbp" },
{ "code": "ALFA", "name": "Альфа-Банк", "type": "sbp" }
]
},
"ts": 1706000000
}/api/v1/integration/funding/deposit/fiatСоздаёт заявку на пополнение фиата. payment_provider_alias_code берите из GET /funding/deposit/fiat/methods (SBER, TINKOFF, ALFA, …). Внутренние коды каналов передавать не нужно. В ответе invoice_public_url, requisites_qr_code и requisites — одна ссылка СБП для перехода клиента к оплате. Если все три ещё null, повторите GET /funding/deposit/fiat/{transaction_id}. amount — сумма заявки; credited_amount — сколько зачислено на баланс после комиссии; fee — комиссия. Пока факта нет, credited_amount и fee равны null.
{
"currency": "RUB",
"amount": "10000",
"payment_provider_alias_code": "SBER"
}{
"success": true,
"data": {
"transaction_id": "7ad2bfd0-673f-455a-b75b-95a949a7476a",
"status": "processing",
"currency": "RUB",
"amount": "10000",
"credited_amount": null,
"fee": null,
"payment_provider_alias_code": "SBER",
"requisites": "https://qr.nspk.ru/...",
"requisites_qr_code": "https://qr.nspk.ru/...",
"invoice_public_url": "https://qr.nspk.ru/...",
"expires_at": "2026-08-14T12:00:00Z",
"created_at": "2026-08-14T11:00:00Z"
},
"ts": 1706000000
}/api/v1/integration/funding/deposit/fiat/{transaction_id}Статус заявки на пополнение. transaction_id — UUID из POST /funding/deposit/fiat. invoice_public_url, requisites_qr_code и requisites — одна ссылка СБП. status: processing | success | failed. Терминальный исход также приходит вебхуками deposit.confirmed / deposit.failed (data.kind=fiat). Это не invoice.paid: Invoice V2 — отдельный продукт. amount — сумма заявки; credited_amount — фактическое зачисление на баланс после комиссии; fee — комиссия. Сверяйте зачисление по credited_amount, не по amount.
{
"success": true,
"data": {
"transaction_id": "7ad2bfd0-673f-455a-b75b-95a949a7476a",
"status": "success",
"currency": "RUB",
"amount": "6500",
"credited_amount": "6383",
"fee": "117",
"payment_provider_alias_code": "SBER",
"requisites": "https://qr.nspk.ru/...",
"requisites_qr_code": "https://qr.nspk.ru/...",
"invoice_public_url": "https://qr.nspk.ru/...",
"expires_at": "2026-08-14T12:00:00Z",
"created_at": "2026-08-14T11:00:00Z"
},
"ts": 1706000000
}Выводы
Вывод средств с основного счёта на внешние адреса и по СБП. Криптовалюта выводится на блокчейн-адрес, фиат (RUB) — по номеру телефона СБП на выбранный банк.
Вывод списывает средства с основного счёта. Убедитесь, что баланс достаточен (GET /account/wallets). Для вывода больших сумм может потребоваться пройти KYC верификацию.
/api/v1/integration/funding/withdraw/cryptoСоздаёт заявку на вывод криптовалюты на внешний адрес. Средства списываются с основного счёта. Требуется указать символ, сеть, адрес и сумму.
{
"symbol": "USDT",
"amount": "100",
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"bch_code": "TRX",
"idempotency_key": "unique-withdraw-key-123"
}{
"success": true,
"data": {
"transaction_id": "...",
"symbol": "USDT",
"amount": "100",
"fee": "1.0",
"total": "101.0",
"address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"network": "TRX",
"status": "processing"
},
"ts": 1706000000
}amount — сумма, которая уйдёт получателю. fee — полная комиссия, списываемая сверх amount. total — итоговое списание с баланса (amount + fee). Сверяйте баланс по total, не по amount. withdraw_service_fee из справочника валют — базовая ставка сети; фактический quote приходит в ответе на этот POST. Передавайте idempotency_key: повтор с тем же ключом в течение 24 ч вернёт первую заявку (даже если она уже failed) — для новой попытки нужен новый ключ. Без ключа обрыв ответа + повтор = риск второй выплаты. Терминальный исход — вебхуки withdrawal.processing / .completed / .failed (kind=crypto).
Точность суммы и лимиты сети
Каждая сеть принимает своё число знаков после запятой. У USDT в TRX это 6 знаков, у той же USDT в BSC — 8. Лишние знаки не являются ошибкой: сумма усекается вниз до точности сети, остаток остаётся на вашем балансе. В ответе поле amount содержит фактически принятую сумму — сверяйте её, а не то, что отправили.
Точность, минимум, максимум и доступность вывода по каждой паре монета+сеть отдаёт справочник GET /api/v1/integration/market/currencies — поля withdraw_amount_decimals, min_withdraw_amount, max_withdraw_amount, withdraw_service_fee, is_withdraw_active.
/api/v1/integration/funding/withdraw/fiat/banksСправочник банков для СБП-вывода. Возвращает публичные bank_code (TINKOFF, SBER, …) — передавайте их в POST /withdraw/fiat. Внутренние коды провайдера Pay в API не отдаются.
{
"success": true,
"data": {
"currency": "RUB",
"banks": [
{ "bank_code": "TINKOFF", "name": "T-Pay" },
{ "bank_code": "SBER", "name": "S-Pay" },
{ "bank_code": "ALFA", "name": "A-Pay" }
]
},
"ts": 1706000000
}/api/v1/integration/funding/withdraw/fiatСоздаёт заявку на вывод RUB по СБП на телефон получателя. Канал выплаты (provider) резолвится на стороне AlfaBit из назначения профиля — передавать его не нужно. Перед созданием проверяется баланс Ledger (сумма + комиссия).
{
"currency": "RUB",
"amount": "500",
"recipient": "79992122496",
"bank_code": "TINKOFF",
"idempotency_key": "unique-fiat-withdraw-key-456"
}| Поле | Тип | Описание |
|---|---|---|
amount | string | Сумма к получению (без комиссии), строка |
recipient | string | Телефон СБП в формате 7XXXXXXXXXX |
bank_code | string | Код банка из GET /withdraw/fiat/banks |
currency | string? | Только RUB (по умолчанию RUB) |
idempotency_key | string? | Ключ идемпотентности, 24 ч. После failed тот же ключ вернёт первую заявку, не создаст новую — нужен новый ключ. |
{
"success": true,
"data": {
"transaction_id": "68182a10-9f8a-4c06-a1bf-4d5d66841284",
"currency": "RUB",
"amount": "500.00",
"amount_fact": null,
"fee": "15.00",
"total": "515.00",
"status": "processing",
"recipient": "7999****96",
"bank_code": "TINKOFF"
},
"ts": 1706000000
}amount — сумма к получению (без комиссии). fee — комиссия. total — списание с баланса (amount + fee). Баланс проверяется по total до создания заявки. Передавайте idempotency_key: TTL 24 ч; после failed тот же ключ новую выплату не создаст. Терминальный исход — вебхуки withdrawal.completed / withdrawal.failed (kind=fiat); processing у СБП нет.
/api/v1/integration/funding/withdraw/fiat/{transaction_id}Статус фиат-вывода по transaction_id из POST /withdraw/fiat. Терминальный исход также приходит вебхуками withdrawal.completed / withdrawal.failed (data.kind=fiat). События withdrawal.processing у СБП нет — пока заявка в полёте, опрашивайте эту ручку (status: processing | success | failed). amount — к получению; fee — комиссия; total — списание с баланса; amount_fact — фактическая сумма получателю, когда выплата завершена. Банковского референса СБП в ответе нет.
{
"success": true,
"data": {
"transaction_id": "68182a10-9f8a-4c06-a1bf-4d5d66841284",
"status": "success",
"currency": "RUB",
"amount": "500.00",
"amount_fact": "500.00",
"fee": "15.00",
"total": "515.00",
"bank_code": "TINKOFF",
"recipient": "7999****96",
"created_at": 1706000000,
"updated_at": 1706000120,
"error": null
},
"ts": 1706000120
}Переводы
Три типа переводов: внутренний (другому пользователю), на торговый счёт и обратно. Внутренние переводы мгновенны и бесплатны.
Если вы хотите торговать на фиатном споте (USDT/RUB стакан), средства должны быть на торговом счёте. Используйте /funding/transfer/to-trading перед торговлей и /funding/transfer/from-trading чтобы вернуть средства обратно после торговли.
/api/v1/integration/funding/transfer/internalПеревод средств другому пользователю по username или ID. Средства списываются с основного счёта отправителя и зачисляются на счёт получателя.
Ручка принимает только криптовалютные символы; отправить RUB через API нельзя. Рублёвый перевод делает сам пользователь в интерфейсе кошелька — вы можете дать ему готовую ссылку с заполненными реквизитами (см. «Ссылка на предзаполненный перевод»). Приход к вам наблюдается одинаково для обеих валют: вебхуком transfer.received и записью в GET /integration/transactions.
{
"symbol": "USDT",
"amount": "100",
"to_username": "john_doe",
"to_user_id": null,
"comment": "Payment for services",
"idempotency_key": "unique-transfer-key-789"
}{
"success": true,
"data": {
"task_id": "celery-task-id-...",
"symbol": "USDT",
"amount": "100",
"to": "john_doe",
"status": "processing"
},
"ts": 1706000000
}/api/v1/integration/funding/transfer/to-tradingПеревод с основного счёта на торговый счёт. Необходим для торговли на фиатном споте. Принимает символ валюты (USDT или RUB) и сумму.
{
"currency": "USDT",
"amount": "1000"
}{
"success": true,
"data": {
"status": "ok"
},
"ts": 1706000000
}/api/v1/integration/funding/transfer/from-tradingПеревод с торгового счёта обратно на основной счёт. Принимает символ валюты (USDT или RUB) и сумму.
{
"currency": "USDT",
"amount": "500"
}{
"success": true,
"data": {
"status": "ok"
},
"ts": 1706000000
}Крипто Спот
Торговля криптовалютными парами. Поддерживаются рыночные (market) и лимитные (limit) ордера. Операции выполняются с основного счёта.
- Изучите тикеры: GET /spot/crypto/tickers — текущие цены всех пар (публичный, без ключа)
- Узнайте детали пары: GET /spot/crypto/market-info?from_symbol=BTC&to_symbol=USDT (публичный, без ключа)
- Проверьте доступные пары для торговли: GET /spot/crypto/pairs (требует API ключ)
- Создайте ордер: POST /spot/crypto/order с type="market" (мгновенно) или type="limit" (по своей цене)
- Отслеживайте статус: GET /spot/crypto/orders
market— мгновенное исполнение по текущей рыночной цене. Можно указать from_amount ИЛИ to_amount. Идеально для быстрого обмена.limit— ордер по заданной цене. Исполняется когда рыночная цена достигает указанной. Обязательны from_amount и order_price. Подходит для DCA-стратегий и покупки на просадках.
Market — когда важна скорость (обмен прямо сейчас). Limit — когда важна цена (хотите купить дешевле текущей). Лимитный ордер можно отменить пока он не исполнен через DELETE /spot/crypto/order/{order_id}.
Публичные данные (без API ключа)
/api/v1/integration/spot/crypto/tickersТекущие тикеры всех крипто пар — цены, bid/ask, объёмы за 24 часа. Данные кешируются и обновляются каждые ~3 минуты. Не требует API ключа.
Параметры запроса
| Параметр | Тип | Описание |
|---|---|---|
symbol | string | Фильтр по базовому символу: BTC, ETH (опционально) |
{
"success": true,
"data": [
{
"pair": "BTC-USDT",
"base": "BTC",
"quote": "USDT",
"last_price": "97450.50",
"bid_price": "97448.00",
"ask_price": "97453.00",
"volume_24h": "12450000",
"high_24h": "98100.00",
"low_24h": "96800.00",
"price_change_24h": "0.0124"
}
],
"ts": 1706000000
}/api/v1/integration/spot/crypto/market-infoПодробная информация по конкретной торговой паре: текущий курс, мин/макс суммы, торговые фильтры. Не требует API ключа.
Параметры запроса
| Параметр | Тип | Описание |
|---|---|---|
from_symbol * | string | Исходная валюта: BTC |
to_symbol * | string | Целевая валюта: USDT |
{
"success": true,
"data": {
"symbol": "BTCUSDT",
"priceTo": "71114.201",
"priceOut": "69706.098",
"price": "70410.2",
"mainSymbol": "BTC",
"minorSymbol": "USDT",
"quote_asset_precision": 7,
"base_asset_precision": 6,
"step": "0.000001",
"minValue": "0.000001",
"min_value_minor": "5",
"maxValue": "230",
"max_value_minor": "8000000",
"limit_price_step": "0.005",
"price_step": "0.1"
},
"ts": 1706000000
}Торговля (требует API ключ)
/api/v1/integration/spot/crypto/pairsСписок доступных торговых пар с лимитами. Требует API ключ с правом can_spot_crypto_read.
Параметры запроса
| Параметр | Тип | Описание |
|---|---|---|
symbol | string | Фильтр по символу (опционально) |
{
"success": true,
"data": ["NAKA", "SIGN", "ARKM", "BTC", "ETH", "SOL"],
"ts": 1706000000
}/api/v1/integration/spot/crypto/pair-infoИнформация по паре: текущий курс, минимальная и максимальная сумма обмена.
Параметры запроса
| Параметр | Тип | Описание |
|---|---|---|
from_symbol | string | Исходная валюта (обязательно) |
to_symbol | string | Целевая валюта (обязательно) |
{
"success": true,
"data": {
"symbol": "BTCUSDT",
"priceTo": "71114.201",
"priceOut": "69706.098",
"price": "70410.2",
"mainSymbol": "BTC",
"minorSymbol": "USDT",
"quote_asset_precision": 7,
"base_asset_precision": 6,
"step": "0.000001",
"minValue": "0.000001",
"min_value_minor": "5",
"maxValue": "230",
"max_value_minor": "8000000",
"limit_price_step": "0.005",
"price_step": "0.1"
},
"ts": 1706000000
}/api/v1/integration/spot/crypto/orderРыночный ордер (Market)
Мгновенный обмен по текущей рыночной цене. Указывайте from_amount (сколько отдать) ИЛИ to_amount (сколько получить).
Параметры тела запроса
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
from_symbol | string | да | Исходная валюта (например USDT) |
to_symbol | string | да | Целевая валюта (например BTC) |
from_amount | string | да* | Сумма в исходной валюте |
to_amount | string | да* | Сумма в целевой валюте |
type | string | нет | "market" (по умолчанию) |
* Укажите from_amount ИЛИ to_amount, но не оба.
{
"from_symbol": "USDT",
"to_symbol": "BTC",
"from_amount": "100",
"type": "market"
}{
"success": true,
"data": {
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"from_symbol": "USDT",
"to_symbol": "BTC",
"from_amount": "100",
"to_amount": "0.00231",
"type": "market",
"order_price": null,
"status": "processing"
},
"ts": 1706000000
}/api/v1/integration/spot/crypto/orderЛимитный ордер (Limit)
Ордер по указанной цене. Будет исполнен, когда рыночная цена достигнет заданного уровня. Для limit-ордера обязательны from_amount и order_price.
Параметры тела запроса
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
from_symbol | string | да | Исходная валюта (например USDT) |
to_symbol | string | да | Целевая валюта (например BTC) |
from_amount | string | да | Сумма в исходной валюте |
type | string | да | "limit" |
order_price | string | да | Желаемая цена исполнения (например "42000.00") |
{
"from_symbol": "USDT",
"to_symbol": "BTC",
"from_amount": "500",
"type": "limit",
"order_price": "42000.00"
}{
"success": true,
"data": {
"order_id": "550e8400-e29b-41d4-a716-446655440001",
"from_symbol": "USDT",
"to_symbol": "BTC",
"from_amount": "500",
"to_amount": null,
"type": "limit",
"order_price": "42000.00",
"status": "processing"
},
"ts": 1706000000
}/api/v1/integration/spot/crypto/order/{order_id}Отменить лимитный ордер. Работает только для ордеров с type=limit, которые ещё не исполнены.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
order_id | string | ID ордера из ответа POST /order |
{
"success": true,
"data": {
"cancelled": true,
"order_id": "550e8400-e29b-41d4-a716-446655440001",
"status": "cancelled"
},
"ts": 1706000000
}// Ордер не найден
{ "success": false, "error": { "code": "ORDER_NOT_FOUND", "message": "Order not found" } }
// Ордер не является лимитным
{ "success": false, "error": { "code": "CANCEL_FAILED", "message": "Not a limit order" } }
// Ордер уже отменён
{ "success": false, "error": { "code": "CANCEL_FAILED", "message": "Order already cancelled" } }/api/v1/integration/spot/crypto/ordersИстория ордеров на крипто обмен с пагинацией. Включает market и limit ордера.
Параметры запроса
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
limit | integer | 50 | Кол-во записей (1-100) |
page | integer | 1 | Номер страницы |
{
"success": true,
"data": [
{
"order_id": "...",
"from_symbol": "USDT", "to_symbol": "BTC",
"from_amount": "100", "to_amount": "0.00231",
"type": "market",
"status": "completed", "created_at": "2024-01-15T14:30:00Z"
},
{
"order_id": "...",
"from_symbol": "USDT", "to_symbol": "ETH",
"from_amount": "500", "to_amount": null,
"type": "limit", "order_price": "2100.00",
"status": "processing", "created_at": "2024-01-15T15:00:00Z"
}
],
"ts": 1706000000
}Фиат Спот
Полноценный стакан USDT/RUB с market и limit ордерами. Работает на собственном торговом движке AlfaBit. В отличие от Крипто Спота, здесь вы видите реальный стакан заявок и можете контролировать цену.
Торговля идёт с отдельного торгового баланса. Перед первой сделкой переведите средства:
POST /api/v1/integration/funding/transfer/to-trading
{ "currency": "USDT", "amount": "1000" }- Переведите RUB на торговый счёт: POST /funding/transfer/to-trading
- Проверьте баланс: GET /spot/fiat/balance
- Изучите стакан и текущую цену: GET /spot/fiat/orderbook и GET /spot/fiat/stats
- Примите ордер: POST /spot/fiat/order — сразу вернётся id (обычно status=new). Не ждите filled в этом ответе.
- Отслеживайте fill: GET /spot/fiat/order/{id} / GET /spot/fiat/orders или webhook order.filled
- Верните USDT на основной счёт: POST /funding/transfer/from-trading
Публичные данные (без API ключа)
/api/v1/integration/spot/fiat/instrumentsСписок торговых инструментов (пар) и их статусы.
{
"success": true,
"data": [
{ "trading_pair": "USDT/RUB", "status": "active", "base": "USDT", "quote": "RUB" }
],
"ts": 1706000000
}/api/v1/integration/spot/fiat/balanceБалансы торгового счёта: USDT и RUB (available, locked).
{
"success": true,
"data": {
"USDT": { "available": "5000.00", "locked": "100.00" },
"RUB": { "available": "150000.00", "locked": "0.00" }
},
"ts": 1706000000
}/api/v1/integration/spot/fiat/orderbook?pair=USDT/RUB&depth=20Стакан заявок: bids (покупка) и asks (продажа). Параметр depth — глубина стакана (по умолчанию 20).
{
"success": true,
"data": {
"bids": [
{ "price": "92.45", "amount": "5000" },
{ "price": "92.40", "amount": "12000" }
],
"asks": [
{ "price": "92.55", "amount": "3000" },
{ "price": "92.60", "amount": "8000" }
]
},
"ts": 1706000000
}/api/v1/integration/spot/fiat/trades?pair=USDT/RUB&limit=50Лента публичных сделок. Не требует API ключа.
{
"success": true,
"data": [
{ "id": "...", "price": "92.50", "amount": "100", "side": "buy", "time": "2024-01-15T14:30:00Z" }
],
"ts": 1706000000
}/api/v1/integration/spot/fiat/stats?pair=USDT/RUBСтатистика за 24 часа: объём, максимум, минимум, последняя цена.
{
"success": true,
"data": {
"pair": "USDT/RUB", "last": "92.50", "high": "93.10",
"low": "91.80", "volume": "1250000", "change": "+0.5%"
},
"ts": 1706000000
}Торговля (требует API ключ)
/api/v1/integration/spot/fiat/orderПринять ордер. Ответ — тот же JSON с id (обычно status=new). Исполнение идёт асинхронно: не ждите filled в этом POST. Смотрите GET /spot/fiat/order/{id}, GET /spot/fiat/orders или webhook order.filled. 4xx (баланс, стакан, лимиты) по-прежнему синхронны — ордер в этом случае не создаётся.
Market Order
{
"pair": "USDT/RUB",
"side": "buy",
"type": "market",
"amount": "100"
}Market Order — на сумму в рублях (quote_amount)
Если вы пришли с рублями и не знаете, сколько USDT получится купить — передайте quote_amount (сумма в котируемой валюте, которую готовы потратить) вместо amount. Движок сам подберёт объём базовой валюты по текущему стакану так, чтобы не превысить бюджет. Поддерживается только для market buy. amount и quote_amount взаимоисключающи. Неиспользованный остаток бюджета возвращается; в быстром рынке фактически купленный объём может незначительно отличаться (как у любого market-ордера).
{
"pair": "USDT/RUB",
"side": "buy",
"type": "market",
"quote_amount": "10000"
}Limit Order
{
"pair": "USDT/RUB",
"side": "sell",
"type": "limit",
"amount": "500",
"price": "93.00"
}{
"success": true,
"data": {
"order_id": "ord_limit_xyz789",
"pair": "USDT/RUB",
"side": "sell",
"type": "limit",
"amount": "500",
"price": "93.00",
"status": "open"
},
"ts": 1706000000
}/api/v1/integration/spot/fiat/order/{order_id}Отменить лимитный ордер по ID. Market ордера отменить нельзя — они исполняются мгновенно.
/api/v1/integration/spot/fiat/ordersСписок ваших открытых и исполненных ордеров на фиатном споте.
{
"success": true,
"data": [
{ "id": "...", "pair": "USDT/RUB", "side": "buy", "type": "limit",
"price": "92.00", "amount": "100", "filled": "0", "status": "open" }
],
"ts": 1706000000
}/api/v1/integration/spot/fiat/my-tradesВаши исполненные сделки на фиатном споте.
{
"success": true,
"data": [
{ "id": "...", "pair": "USDT/RUB", "side": "buy",
"price": "92.45", "amount": "100", "fee": "0.1", "time": "2024-01-15T14:30:00Z" }
],
"ts": 1706000000
}Дополнительные публичные данные
/api/v1/integration/spot/fiat/tickersСводные тикеры по всем активным парам: цена, bid/ask, объёмы 24ч, изменение. Аналог /spot/crypto/tickers для фиатных пар.
/api/v1/integration/spot/fiat/market-info?pair=USDT/RUBДетальная информация по конкретной паре: текущая цена, спред, мин/макс объёмы, шаги цены и количества, precision.
/api/v1/integration/spot/fiat/instruments/{pair}Подробности одной пары (статус, base/quote, лимиты).
/api/v1/integration/spot/fiat/currenciesСправочник валют торгового счёта (USDT, RUB и т.д.) с symbol и precision.
Дополнительные приватные ручки (требуют API ключ)
/api/v1/integration/spot/fiat/balance/{symbol}Торговый баланс по конкретной валюте (например USDT или RUB).
/api/v1/integration/spot/fiat/order/{order_id}Детали одного ордера по ID: статус, заполнение, средняя цена, комиссии.
{
"success": true,
"data": {
"id": "3f1c9a2e-8b7d-4e6a-9c11-2a5f4d7e0b9c",
"order_number": 10432,
"user_id": "b2c9e7a1-4f83-4d2a-9e6b-1c0f5a8d3e21",
"side": "buy",
"type": "market",
"price": null,
"amount": "100",
"filled": "100",
"status": "filled",
"created_at": "2026-07-24T14:28:00.123456",
"trading_pair": "USDT/RUB",
"execution_message": "Order executed successfully",
"avg_execution_price": "92.35",
"total_fee": "9.235",
"user_input_price": null,
"user_input_price_total": "10000",
"user_input_amount": null,
"locked_quote_amount": "10000"
},
"ts": 1753363680
}Числовые поля приходят строками (сохранение precision). price и avg_execution_price = null, пока не заданы/ордер не исполнен.
id— ID ордера (UUID).order_number— человекочитаемый номер ордера.user_id— внутренний ID пользователя.side— buy или sell.type— market или limit.price— цена лимитного ордера; null для market.amount— объём ордера в базовой валюте (USDT).filled— заполнение — сколько базовой валюты уже исполнено (в единицах amount).status— new / partially_filled / filled / cancelled.created_at— время создания (ISO-8601).trading_pair— торговая пара, напр. USDT/RUB.execution_message— сообщение об исполнении (актуально для market); может быть null.avg_execution_price— средняя цена исполнения; null пока сделок нет.total_fee— суммарная комиссия по ордеру.user_input_price,user_input_price_total,user_input_amount— исходный ввод пользователя (только для отображения). Для market buy с quote_amount поле user_input_price_total содержит заданный бюджет.locked_quote_amount— сколько котируемой валюты (RUB) заблокировано под BUY.
/api/v1/integration/spot/fiat/trading/operationsИстория операций пополнения/вывода торгового счёта с пагинацией. Фильтры: currency_id, operation_type (deposit/withdraw), status (pending/completed/failed).
/api/v1/integration/spot/fiat/trading/settings/{symbol}Лимиты deposit/withdraw и fee_percent для конкретной валюты.
Идемпотентность
Для POST /spot/fiat/order и DELETE /spot/fiat/order/{id} поддерживается заголовок Idempotency-Key (1-128 символов: буквы/цифры/-/_, рекомендуется UUID). Повторный POST с тем же ключом не создаст второй ордер (TTL 24 ч). Для create на retry вернётся актуальный ордер из движка (не застывший снимок accept) — так можно безопасно повторить запрос после обрыва сети и узнать status/filled.
X-API-Key: pk_live_...
X-API-Signature: ...
X-API-Timestamp: ...
Idempotency-Key: 4b8c8a1e-3f2c-4f3a-9c0d-2b3a4b5c6d7eWebSockets
Real-time канал для интеграторов. Один WS-сервер для всех топиков: торговые события Spot Fiat, изменения баланса, статус инвойсов, обновления конвертера.
wss://alfabit.org/wallet-web/ws/wsАутентификация (auth_api_key)
WS использует упрощённую подпись HMAC-SHA256(secret, timestamp + api_key) — без method/path/body. Допустимое расхождение timestamp ±300 сек.
const ws = new WebSocket('wss://alfabit.org/wallet-web/ws/ws');
// 1) handshake
ws.send(JSON.stringify({
action: 'auth_api_key',
api_key: 'pk_live_xxxxxxxxxxxx',
timestamp: '1714210000',
signature: '<hmac-sha256(secret, timestamp + api_key) hex>',
}));
// 2) subscribe
ws.send(JSON.stringify({
action: 'subscribe',
topics: [
'spot.fiat.balance',
'spot.fiat.order',
'spot.fiat.orderbook.USDT/RUB'
]
}));import hashlib, hmac, time
ts = str(int(time.time()))
sig = hmac.new(secret_key.encode(), (ts + api_key).encode(), hashlib.sha256).hexdigest()Публичные топики (без авторизации)
Стакан, лента сделок, статистика, чарты — индустриальный стандарт.
spot.fiat.orderbook.{pair}— Снимок стакана (bids/asks) для пары.spot.fiat.trades.{pair}— Лента сделок для пары.spot.fiat.stats.{pair}— 24ч-статистика для пары.spot.fiat.chart.{symbol}.{resolution}— TradingView-свечи для пары и интервала (1, 5, 15, 30, 60, 240, D, W, M).
Приватные топики (требуют can_spot_fiat_read)
Свои ордера и торговый баланс — фильтруются по profile_id, видны только владельцу API-ключа.
spot.fiat.order— Изменения статуса ваших ордеров (created, filled, partially_filled, cancelled).spot.fiat.balance— Изменения торгового баланса.
Реконнект
При обрыве соединения переподключайтесь с экспоненциальным backoff: 1s → 2s → 4s → ... до 30s. После реконнекта повторите auth_api_key и subscribe.
Конвертер
Быстрая конвертация с фиксированным курсом. Поддерживает крипто-крипто и крипто-фиат обмен. В отличие от Спота, конвертер гарантирует цену — вы получите ровно столько, сколько показала котировка.
Котировка фиксирует курс на ограниченное время (см. expires_in_seconds в ответе). За это время вызовите /execute с полученным quote_id. Если не успеете — запросите новую котировку.
Конвертер — для разовых операций с гарантированной ценой (отправить клиенту ровно $100 в ETH). Спот — для регулярной торговли и стратегий (DCA, лимитные ордера, большие объёмы).
Крипто конвертер
Курсы и символы доступны без API ключа. Обмен требует авторизацию.
/api/v1/integration/converter/crypto/symbolsСписок криптовалют доступных для конвертации. Не требует API ключа.
/api/v1/integration/converter/crypto/rate?from=BTC&to=ETHКонечный курс обмена, лимиты и время жизни котировки. Не требует API ключа.
{
"success": true,
"data": {
"from_symbol": "BTC",
"to_symbol": "ETH",
"rate": "16.468",
"min_amount_usdt": "10",
"max_amount_usdt": "50000",
"expires_in_seconds": 30
},
"ts": 1706000000
}/api/v1/integration/converter/crypto/estimateПолучить фиксированную котировку. Возвращает quote_id, который нужно передать в /execute. Время жизни котировки указано в поле expires_in_seconds.
{
"from_symbol": "BTC",
"to_symbol": "ETH",
"from_amount": "0.5"
}{
"success": true,
"data": {
"quote_id": "qt_abc123def456",
"from_symbol": "BTC",
"to_symbol": "ETH",
"from_amount": "0.5",
"to_amount": "8.234",
"rate": "16.468",
"expires_in_seconds": 30
},
"ts": 1706000000
}/api/v1/integration/converter/crypto/executeВыполнить конвертацию по ранее полученной котировке. Если котировка истекла — вернёт ошибку. Необязательный idempotency_key (действует 24 ч): повторный запрос с тем же ключом не создаст вторую конвертацию — вернётся тот же результат (защита от retry). Идентичный запрос, ещё выполняющийся, вернёт HTTP 409.
{
"quote_id": "qt_abc123def456",
"idempotency_key": "your-unique-key-123"
}{
"success": true,
"data": {
"uid": "conv_op_abc123",
"from_symbol": "BTC",
"to_symbol": "USDT",
"from_amount": "0.01",
"to_amount": "704.10",
"rate": "70410.2",
"status": "completed"
},
"ts": 1706000000
}Фиат конвертер
Конвертация крипты в фиат и обратно (например USDT → RUB). Курсы доступны без API ключа, обмен требует авторизацию.
/api/v1/integration/converter/fiat/currenciesФиатные валюты, открытые для конвертации прямо сейчас. Не требует API ключа. Читайте его перед запросом курса: набор валют меняется, и запрос с кодом, которого нет в этом ответе, будет отклонён.
{
"success": true,
"data": [
{
"code": "RUB",
"name": "Российский рубль",
"symbol": "₽",
"decimals": 2,
"min_amount": "100.00",
"max_amount": "250000.00"
}
],
"ts": 1706000000
}decimals— точность суммы в этой валюте. Округляйте по ней, а не по своему формату.min_amount/max_amount— лимиты одной конвертации в фиатных единицах. null означает, что ограничение не задано.
/api/v1/integration/converter/fiat/crypto-symbolsПлоский массив символов криптовалют, разрешённых в паре с фиатом. Не требует API ключа. Список длинный и меняется — не зашивайте его в код, запрашивайте и кешируйте у себя.
{
"success": true,
"data": ["0G", "1INCH", "AAVE", "ADA", "BTC", "ETH", "USDT", "..."],
"ts": 1706000000
}/api/v1/integration/converter/fiat/rate?crypto=USDT&fiat=RUB&direction=sellТекущий курс крипто/фиат. Параметры: crypto (символ), fiat (код), direction (buy/sell).
{
"success": true,
"data": {
"crypto": "USDT", "fiat": "RUB", "direction": "sell",
"rate": "92.50", "min_amount": "10", "max_amount": "100000"
},
"ts": 1706000000
}/api/v1/integration/converter/fiat/estimateПолучить котировку для фиат конвертации.
{
"crypto_symbol": "USDT",
"fiat_code": "RUB",
"direction": "sell",
"amount": "100"
}{
"success": true,
"data": {
"quote_id": "qt_fiat_abc123",
"crypto_symbol": "USDT",
"fiat_code": "RUB",
"direction": "sell",
"crypto_amount": "100",
"fiat_amount": "9250.00",
"rate": "92.50",
"fee": "1.00",
"expires_at": "2024-01-20T12:35:00Z"
},
"ts": 1706000000
}/api/v1/integration/converter/fiat/executeВыполнить фиат конвертацию по котировке. Тело то же, что у /fiat/estimate (crypto_symbol, fiat_code, direction), сумма в from_amount, плюс quote_id из ответа estimate. Одного quote_id недостаточно — без остальных полей API отвечает 422. Отдельного idempotency_key нет: повтор с тем же quote_id вернёт уже созданную операцию. Котировка прямого обмена живёт 30 секунд. Статус — GET /converter/operations; успех также приходит вебхуком conversion.completed.
{
"crypto_symbol": "USDT",
"fiat_code": "RUB",
"direction": "sell",
"from_amount": "100",
"quote_id": "qt_fiat_xyz789"
}{
"success": true,
"data": {
"uid": "fiat_conv_xyz789",
"crypto_symbol": "USDT",
"fiat_code": "RUB",
"direction": "sell",
"crypto_amount": "100",
"fiat_amount": "9250.00",
"status": "completed"
},
"ts": 1706000000
}/api/v1/integration/converter/operations?limit=20История всех конвертаций (крипто + фиат). Параметр type: crypto или fiat.
{
"success": true,
"data": [
{ "uid": "...", "type": "crypto", "from_symbol": "BTC", "to_symbol": "ETH",
"from_amount": "0.5", "to_amount": "8.234", "status": "completed" }
],
"ts": 1706000000
}Виртуальные карты
Выпуск и управление виртуальными банковскими картами Visa/Mastercard. Оплачивайте подписки, рекламу и покупки используя криптовалюту.
SHOPPING — для онлайн-покупок. ADVERTISING — для рекламных платформ. Типы и доступные опции зависят от вашего тарифа.
- Изучите условия: GET /cards/settings (комиссии, лимиты) и GET /cards/meta (регионы, платёжные системы)
- Узнайте курс: GET /cards/rate (USDT → USD для расчёта стоимости)
- Выпустите карту: POST /cards (amount + payment_method: balance_usdt | onchain_usdt | rub_sbp). Готовая карта появится в GET /cards (для balance_usdt — асинхронно, также придёт webhook card.transaction)
- Пополните карту: POST /cards/{card_id}/topup — средства конвертируются в USD
- Используйте карту для оплаты и отслеживайте транзакции: GET /cards/{card_id}/transactions
/api/v1/integration/cards/settingsНастройки карт: типы, комиссии за выпуск (buy_fee), комиссия пополнения (top_up_fee), обязательное пополнение.
/api/v1/integration/cards/metaМета-информация: доступные валюты, регионы, платёжные системы (Visa/Mastercard), Apple Pay.
/api/v1/integration/cards/rateТекущий курс USDT/RUB для расчёта стоимости выпуска и пополнения.
/api/v1/integration/cardsСписок всех карт пользователя: тип, статус, баланс, платёжная система.
/api/v1/integration/cardsВыпустить виртуальную карту (book + оплата). amount обязателен. Способ оплаты задаётся в payment_method: balance_usdt (списание с баланса), onchain_usdt (перевод USDT, нужна сеть) или rub_sbp (оплата по СБП). Актуальные region / payment_system / currency смотрите в GET /cards/meta.
{
"amount": "10",
"payment_method": "balance_usdt",
"source_symbol": "USDT",
"card_type": "SHOPPING",
"is_apple_pay_available": false
}// rub_sbp — в ответе qr/ссылка на оплату
{ "amount": "10", "payment_method": "rub_sbp", "card_type": "SHOPPING" }
// onchain_usdt — в ответе адрес депозита
{ "amount": "10", "payment_method": "onchain_usdt", "onchain_network": "trc20", "card_type": "SHOPPING" }| Параметр | Описание |
|---|---|
amount | Обязателен. Сумма начального пополнения карты (USD). |
payment_method | balance_usdt, onchain_usdt, rub_sbp |
source_symbol | Актив списания для balance_usdt (по умолч. USDT). |
onchain_network | trc20 | erc20 — обязателен для onchain_usdt. |
card_type | SHOPPING или ADVERTISING |
region / payment_system | Опционально. Актуальные значения из GET /cards/meta (сейчас HK / mastercard). Если не переданы — подбираются автоматически. |
idempotency_key | Опционально (uuid4). Защита от дублей выпуска. |
Для balance_usdt выпуск идёт асинхронно: в ответе — заказ, готовую карту смотрите в GET /cards и через webhook card.transaction. Для rub_sbp/onchain_usdt сначала оплатите по возвращённым реквизитам.
/api/v1/integration/cards/{card_id}Данные карты: номер, CVV, срок действия, статус (ACTIVE, FROZEN, BLOCKED).
{
"success": true,
"data": {
"id": 123, "card_type": "SHOPPING", "status": "ACTIVE",
"number": "4111 **** **** 1234", "cvc": "***",
"date_expired": "12/27", "payment_system": "VISA",
"balance": "150.00", "region": "WW"
},
"ts": 1706000000
}/api/v1/integration/cards/{card_id}/balanceТекущий баланс карты в USD.
/api/v1/integration/cards/{card_id}/topupПополнить карту. Сумма конвертируется в USD. Способ: crypto, fiat_wallet или sbp.
{
"amount": "50",
"source_symbol": "USDT",
"payment_method": "crypto"
}/api/v1/integration/cards/{card_id}/transactionsТранзакции карты: покупки, пополнения, возвраты.
/api/v1/integration/cards/transactions/allТранзакции по ВСЕМ картам пользователя. Можно фильтровать по card_type.
Подарочные карты
Покупка подарочных карт и сертификатов популярных сервисов (Steam, PlayStation, Spotify и др.) за криптовалюту. Код сертификата приходит мгновенно.
Сначала найдите нужный продукт в каталоге, затем узнайте сколько он стоит в крипте через /estimate, и наконец купите через /purchase.
/api/v1/integration/giftcards/catalogКаталог доступных подарочных карт. Поддерживает фильтрацию по категории, поиск по названию и пагинацию.
/api/v1/integration/giftcards/categoriesСписок категорий: Игры, Развлечения, Музыка, Маркетплейсы и др.
{
"success": true,
"data": [
{ "id": 1, "title": "Игры", "slug": "games", "is_active": true, "products_count": 42 },
{ "id": 2, "title": "Развлечения", "slug": "entertainment", "is_active": true, "products_count": 18 },
{ "id": 3, "title": "Музыка", "slug": "music", "is_active": true, "products_count": 7 }
],
"ts": 1706000000
}/api/v1/integration/giftcards/estimateРасчёт стоимости подарочной карты в криптовалюте перед покупкой. Показывает итоговую сумму с учётом комиссии.
{
"product_id": 123,
"face_value": 1000,
"symbol": "USDT"
}{
"success": true,
"data": {
"product_id": 123,
"face_value": 1000,
"crypto_amount": "10.85",
"symbol": "USDT",
"fee": "0.15",
"total": "11.00"
},
"ts": 1706000000
}/api/v1/integration/giftcards/purchaseПокупка подарочной карты. Средства списываются с крипто-кошелька. Код сертификата доступен в ответе (GET /giftcards/orders/{order_id}).
{
"product_id": 123,
"face_value": 1000,
"symbol": "USDT",
"email": "user@example.com"
}{
"success": true,
"data": {
"order_id": "gc_ord_abc123",
"product_id": 123,
"face_value": 1000,
"crypto_amount": "11.00",
"symbol": "USDT",
"status": "processing"
},
"ts": 1706000000
}/api/v1/integration/giftcards/ordersИстория покупок подарочных карт с кодами сертификатов и статусами.
{
"success": true,
"data": [
{ "id": "...", "product": "Steam 1000₽", "face_value": 1000,
"cost_usdt": "11.50", "status": "completed", "code": "XXXX-YYYY-ZZZZ" }
],
"ts": 1706000000
}Оплата услуг
Каталог услуг для перепродажи: мобильная связь, интернет, игры, ЖКХ и другие сервисы. Вы покупаете услугу со своего баланса AlfaBit (RUB или USDT) и продаёте своему клиенту по своей цене. Наценку считаете и берёте сами — в API её нет.
Каталог и категории доступны без ключа. Оценка, проверка реквизита, оплата и заказы — с API-ключом: can_services_read (чтение) и can_services_pay (списание). В каталоге только подключённые услуги. Если список пуст — напишите в поддержку, витрину откроем.
- GET /services/catalog — покажите своему клиенту доступные услуги. Поля формы берите из inputs; если массив пустой — из required_fields.
- POST /services/estimate — сумма к списанию с вашего баланса в RUB или USDT (client_amount / client_currency).
- Если requires_check=true или payment_type=REQUISITES — POST /services/check-requisite. Реквизит: поле requisite либо field_values.account / field_values.phone.
- POST /services/pay — списывает ваш баланс. Свою цену клиенту выставляете сами. Статус: webhook service_payment.* или GET /services/orders/{id}.
/api/v1/integration/services/categoriesСписок категорий: Мобильная связь, Игры, Интернет, ТВ и др. Не требует API-ключа. Фильтр: country.
/api/v1/integration/services/catalogКаталог услуг с пагинацией. Не требует API-ключа. Фильтры: category (alias), category_id, country, search, page, page_size.
/api/v1/integration/services/catalog/{service_id}Карточка услуги: inputs, required_fields, payment_type, fixed_payment, requires_check, инструкция. Не требует API-ключа.
{
"success": true,
"data": {
"id": 2,
"name": "MegaCom",
"category_alias": "mobile",
"country": "Кыргызская Республика",
"payment_type": "SIMPLIFIED",
"fixed_payment": false,
"requires_check": false,
"inputs": [
{ "name": "account", "required": true, "title": "Номер", "regexp": "^0\\d{9}$" }
],
"required_fields": []
},
"ts": 1706000000
}/api/v1/integration/services/estimateРасчёт суммы к списанию с вашего баланса. debit_currency: RUB или USDT. Для fixed_payment client_amount можно не передавать — сумму вернёт ответ. Право: can_services_read.
{
"service_id": 2,
"debit_currency": "RUB",
"client_amount": 500
}{
"success": true,
"data": {
"service_id": 2,
"service_name": "MegaCom",
"client_amount": "512.40",
"client_currency": "RUB",
"quote_expires_at": "1706000300",
"payment_type": "SIMPLIFIED",
"fixed_payment": false,
"requires_check": false
},
"ts": 1706000000
}/api/v1/integration/services/check-requisiteПроверка номера или счёта. Обязательна, если requires_check=true или payment_type=REQUISITES. Реквизит: requisite либо field_values.account / phone. В pay передайте agent_transaction_id и check_snapshot из ответа. Право: can_services_read.
{
"service_id": 2,
"debit_currency": "RUB",
"client_amount": "512.40",
"field_values": { "account": "0555123456" }
}{
"success": true,
"data": {
"success": true,
"agent_transaction_id": "agent-tx-uuid",
"client_amount": "512.40",
"client_currency": "RUB",
"requires_identity": false,
"check_snapshot": { "agent_transaction_id": "agent-tx-uuid" }
},
"ts": 1706000000
}/api/v1/integration/services/payОплата с вашего баланса (RUB или USDT). Передайте quote_expires_at из estimate. Если был check-requisite — agent_transaction_id и check_snapshot. Webhook: service_payment.*. Право: can_services_pay.
{
"service_id": 2,
"debit_currency": "RUB",
"client_amount": "512.40",
"field_values": { "account": "0555123456" },
"quote_expires_at": "1706000300"
}{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"service_id": 2,
"status": "CREATED",
"status_for_client": "wait",
"client_amount": "512.40",
"client_currency": "RUB",
"requisite": "0555123456"
},
"ts": 1706000000
}/api/v1/integration/services/ordersИстория оплат с вашего профиля. Параметры: limit, offset. Право: can_services_read. Ориентир для витрины — status_for_client: wait, success, failed.
/api/v1/integration/services/orders/{order_id}Детали заказа. Тот же DTO, что в ответе pay. Можно поллить вместо webhook.
Инвойсы — приём платежей
Полноценный инвойсинг для бизнеса: одноразовые счета, постоянные QR/шаблоны для касс, донат-ссылки, открытая сумма, отложенный выбор валюты плательщиком, автоматическое хеджирование, оплата из баланса AlfaBit без сети, встраиваемый Checkout-виджет и webhooks. Подходит для интернет-магазинов, фрилансеров, благотворительности, физических точек продаж и POS-кассы.
Все ручки инвойсов живут под префиксом /api/v2/integration/invoices/.... v1 эндпоинты выпилены 25.04.2026 — используйте только v2.
Права API-ключа: can_invoices_create для создания/отмены, can_invoices_read для чтения и получения ссылки.
Что умеет
- Одноразовый инвойс. Фиксированная сумма + TTL до 30 дней. Крипто-счёт в сети создаётся без жёсткой суммы: зачисляется фактически полученное. Переплата — тот же success / invoice.paid с большим amount_received. Недоплата ≥ минимума сети — тоже success / invoice.paid с меньшим amount_received, не expired. expired ставится только если к TTL нет txid (платежа не было). Ниже минимума сети — failed, invoice.paid не уходит.
- Открытая сумма (донаты). Не передавайте поле amount — плательщик сам впишет её на странице оплаты в пределах глобальных min/max.
- Отложенный выбор валюты. Не передавайте symbol/bch_code — плательщик выберет монету и сеть на странице. Удобно для маркетплейсов.
- Постоянный QR (шаблон). Один QR навсегда — каждый платёж порождает отдельный child invoice. Подходит для касс, парикмахерских, донат-страниц.
- POS-API. Касса бьёт чек по шаблону через POST .../payments с idempotency_key и external_payment_id — повторный POST не создаёт дубль и доставляется обратно в webhook.
- Хеджирование (автоконвертация). Получили USDT, а нужно хранить в BTC — флаг is_hedging + hedging_symbol сделают автоматический обмен после зачисления.
- AlfaBit Checkout — оплата из баланса. У плательщика-юзера AlfaBit есть кнопка «Оплатить из AlfaBit». Перевод между балансами происходит мгновенно, без блокчейна и сетевой комиссии (payment_source="alfabit_balance", txid=null).
- Komшия плательщика (shift_to_payer). Глобальная настройка платформы: либо комиссию вычитаем у получателя, либо увеличиваем сумму к оплате — плательщик платит сверху.
- Webhooks. События invoice.created / paid / expired / cancelled / refunded / hedged (+ template.deactivated). URL задаётся отдельно через POST /api/v1/integration/webhooks — не в теле создания инвойса. HMAC-подпись, payload как GET /invoices/{invoice_id}.
- Embed-виджет. AlfaBit Checkout встраивается прямо на ваш сайт через iframe / JS SDK / React / Vue без редиректа покупателя.
- Получите комиссии и лимиты:
GET /api/v2/integration/invoices/settings. - Создайте инвойс:
POST /api/v2/integration/invoicesс заголовком Idempotency-Key (свой UUID на каждый счёт) — получите invoice_id и payment_url. При таймауте повторите запрос с тем же ключом: вернётся тот же счёт, без дубля. - Отправьте payment_url покупателю (ссылка/QR/iframe).
- Подпишитесь на webhook invoice.paid (раздел Webhooks).
- Опционально, опросите статус:
GET /api/v2/integration/invoices/{invoice_id}.
Сценарии использования
Реальные паттерны, которые покрываются текущим API. Каждый сценарий — это связка эндпоинтов и параметров, которые работают на проде.
1. Интернет-магазин — счёт за конкретный заказ
Известна сумма и валюта. Хотите получить ровно её и отслеживать оплату по своему order_id.
{
"symbol": "USDT",
"bch_code": "TRX",
"amount": "100",
"currency": "USDT",
"description": "Order #ORD-12345 — iPhone case",
"life_time_minutes": 30,
"payment_policy": "all",
"payer_email": "client@example.com",
"show_receiver_publicly": false
}В webhook `invoice.paid` вы получите тот же uid (invoice_id) — найдите его в своей БД по сохранённому маппингу order_id↔invoice_id и закройте заказ.
2. Фрилансер — счёт «оплати как удобно»
Сумма известна (в USDT), но клиенту удобнее заплатить TON или BTC. Дайте плательщику выбрать монету.
{
"amount": "250",
"currency": "USDT",
"description": "Frontend audit — May 2026"
}Не передаём `symbol` и `bch_code` — на странице оплаты появится выбор монеты/сети. После выбора плательщиком эти поля заполнятся в ответе GET и в webhook.
3. Донаты / чаевые — открытая сумма
Получатель один, плательщиков много, каждый платит сколько хочет. Лучше оформить как постоянный QR (см. сценарий 5).
{
"symbol": "USDT",
"bch_code": "TRX",
"description": "Buy me a coffee ☕"
}Нет `amount` → инвойс с открытой суммой. Плательщик вводит её в пределах min/max из GET /settings (в USDT-эквиваленте).
4. Получаю USDT — храню в BTC (хеджирование)
{
"symbol": "USDT",
"bch_code": "TRX",
"amount": "1000",
"is_hedging": true,
"hedging_symbol": "BTC"
}После оплаты USDT автоматически конвертируется в BTC по курсу конвертера. В GET /settings виден `hedging_commission_percent` — это доп. комиссия за хеджирование.
Сколько BTC зачислено по факту — поля `hedged_amount` и `hedged_symbol` в GET /api/v2/integration/invoices/{invoice_id}. Конвертация выполняется уже после оплаты, поэтому в момент webhook `invoice.paid` они ещё null; готовый результат приходит отдельным событием `invoice.hedged`.
5. Постоянный QR на стене кафе
Один QR — много оплат. Каждый платёж становится отдельным child-инвойсом со своим адресом и TTL.
{
"symbol": "USDT",
"bch_code": "TRX",
"description": "Coffee Shop on Tverskaya 7",
"show_payments_count_publicly": true
}Возвращается `template_uid` и `payment_url` — печатайте QR из URL. Плательщик с публичной страницы заводит свой child invoice (вводит сумму), оплачивает — приходит webhook `invoice.paid` с `parent_template_uid`. Счётчик `show_payments_count_publicly` показывает плательщикам сколько уже задонатили.
6. POS-касса — выбиваем чек по шаблону
Магазин уже один раз создал шаблон (см. сценарий 5). Теперь касса на каждый чек дёргает POST .../payments с idempotency_key и external_payment_id (свой ID чека).
{
"amount": "12.50",
"currency": "USDT",
"description": "Receipt POS-AAA-9876",
"external_payment_id": "POS-AAA-9876",
"life_time_minutes": 15,
"idempotency_key": "pos-aaa-9876-2026-05-15"
}Повторный POST с тем же `idempotency_key` вернёт ТОТ ЖЕ child — никаких дублей. В webhook `invoice.paid` придёт `external_payment_id` и `parent_template_uid`, чтобы касса автоматически закрыла свой чек.
7. Принимаем только из AlfaBit (закрытое сообщество)
{
"symbol": "USDT",
"amount": "10",
"payment_policy": "alfabit_only"
}Поле payment_policy: «all» (по умолчанию — обе кнопки), «alfabit_only» (только из баланса AlfaBit), «external_only» (только blockchain — кнопку «Оплатить из AlfaBit» не показываем).
Настройки и комиссии
Один эндпоинт чтобы получить актуальные комиссии, лимиты и доступность фич. Используйте перед созданием инвойса, чтобы валидировать сумму и показать комиссии плательщику.
/api/v2/integration/invoices/settingsТребуемое право: can_invoices_read.
{
"success": true,
"data": {
"is_active": true,
"invoice_commission_percent": "0.5",
"hedging_commission_percent": "0.5",
"shift_commission_to_payer": false,
"is_hedging_enabled": true,
"min_invoice_amount_usdt": "1",
"max_invoice_amount_usdt": "10000000",
"default_lifetime_minutes": 1440,
"min_lifetime_minutes": 5,
"max_lifetime_minutes": 43200
}
}Поля
| Поле | Описание |
|---|---|
is_active | Инвойсы v2 включены глобально на платформе. |
invoice_commission_percent | Базовая комиссия за приём платежа в %. |
hedging_commission_percent | Дополнительная комиссия при is_hedging=true. |
shift_commission_to_payer | true — комиссия добавляется к сумме (плательщик платит сверху). false — вычитается из получаемой суммы. |
is_hedging_enabled | Хеджирование доступно (если false — поле is_hedging в POST игнорируется). |
min_invoice_amount_usdt | Минимальная сумма инвойса в USDT-эквиваленте. Для не-USDT — пересчёт по курсу. |
max_invoice_amount_usdt | Максимальная сумма инвойса в USDT-эквиваленте. |
default_lifetime_minutes | TTL по умолчанию в минутах — если не передаёте life_time_minutes. |
min_lifetime_minutes | Минимально допустимый TTL. |
max_lifetime_minutes | Максимально допустимый TTL (43200 = 30 дней). |
Создать инвойс
/api/v2/integration/invoicesПраво: can_invoices_create. Возвращает payment_url и (если symbol/bch_code заданы) реквизиты для оплаты.
Рекомендуем передавать заголовок Idempotency-Key (приоритетнее body.idempotency_key): 8–36 символов A–Z a–z 0–9 - _, удобнее UUID. Один ключ = один счёт. Повтор с тем же ключом в течение 24 ч возвращает уже созданный инвойс — так безопасно ретраить после таймаута или обрыва. Новый ключ создаёт новый счёт. Если первый запрос ещё не успел сохраниться, повтор может вернуть HTTP 409 — подождите 2–3 секунды и повторите с тем же ключом.
Тело запроса
| Поле | Тип | Описание |
|---|---|---|
symbol | string? | Валюта (USDT, BTC, ETH...). Если NULL — плательщик выберет на странице. |
bch_code | string? | Сеть (TRX, ETH, TON...). Если NULL — выбирает плательщик. |
amount | string? | Сумма как строка-decimal. NULL = открытая сумма. |
currency | string? | Валюта суммы. По умолчанию = symbol. Поддерживает USDT/USD как «единицу учёта». |
description | string? (≤500) | Видно плательщику на странице и в QR-описании. |
life_time_minutes | int (1..43200) | TTL в минутах. По умолчанию 60. Максимум 30 дней. |
is_hedging | bool | После зачисления автоматически конвертировать в hedging_symbol. |
hedging_symbol | string? | Целевая монета хеджирования (например BTC). |
payer_email | string? | Email плательщика (опционально). Подставляется в AlfaBit Checkout; в GET Integration API не возвращается. |
payment_policy | enum | all (default) / alfabit_only / external_only. |
show_receiver_publicly | bool (default true) | Показывать ли имя/email получателя на публичной странице. |
idempotency_key | string? (8..36) | Ключ идемпотентности в теле. Если передан и заголовок Idempotency-Key — побеждает заголовок. |
curl -X POST "https://alfabit.org/api/v2/integration/invoices" \
-H "X-API-Key: pk_live_..." \
-H "X-API-Signature: ..." \
-H "X-API-Timestamp: ..." \
-H "Idempotency-Key: 4b8c8a1e-3f2c-4f3a-9c0d-2b3a4b5c6d7e" \
-H "Content-Type: application/json" \
-d '{"amount":"100","currency":"RUB","payment_policy":"alfabit_only"}'{
"symbol": "USDT",
"bch_code": "TRX",
"amount": "100"
}{
"symbol": "USDT",
"bch_code": "TRX",
"amount": "250.50",
"currency": "USDT",
"description": "Order #ORD-12345",
"life_time_minutes": 180,
"is_hedging": true,
"hedging_symbol": "BTC",
"payment_policy": "all",
"show_receiver_publicly": false,
"idempotency_key": "4b8c8a1e-3f2c-4f3a-9c0d-2b3a4b5c6d7e"
}{
"success": true,
"data": {
"invoice_id": "01J7HZ...",
"status": "wait",
"symbol": "USDT",
"network": "TRX",
"address": "TXa1B2...",
"memo_tag": null,
"amount_requested": "250.50",
"amount_requested_currency": "USDT",
"amount_to_pay": "250.50",
"exchange_rate": null,
"commission": {
"commission_percent": "0.5",
"commission_amount": "1.25",
"is_paid_by_payer": false
},
"amount_received": null,
"txid": null,
"payment_source": "blockchain",
"description": "Order #ORD-12345",
"is_hedging": true,
"hedging_symbol": "BTC",
"is_payer_marked_paid": false,
"payment_url": "https://alfabit.org/en/pub/invoice/order/01J7HZ...",
"alfabit_payment_policy": "all",
"is_open_amount": false,
"show_receiver_publicly": false,
"created_at": "1747325000",
"expires_at": "1747335800"
}
}Поля symbol/network/address/memo_tag будут NULL, если вы создаёте инвойс с отложенным выбором валюты — заполнятся после того, как плательщик выберет монету и сеть на публичной странице.
Получить детали инвойса
/api/v2/integration/invoices/{invoice_id}Право: can_invoices_read. Тот же DTO, что в POST /invoices. Дополнительно содержит alfabit_payment_route и alfabit_payer_symbol/network — если оплата прошла через AlfaBit Checkout. Для QR+KYC в payer_name приходит ФИО плательщика («И. Иван Иванович») из верификации; если связи нет — поля нет. Для инвойсов с автоконвертацией (is_hedging=true) здесь же лежит её итог: hedged_amount и hedged_symbol — фактически зачисленная сумма и монета. Конвертация идёт после оплаты, поэтому сразу после invoice.paid поля ещё null; момент готовности лучше ловить событием invoice.hedged, а не опросом.
{
"success": true,
"data": {
"invoice_id": "01J7HZ...",
"status": "success",
"symbol": "USDT",
"network": "TRX",
"address": "TXa1B2...",
"amount_requested": "250.50",
"amount_received": "250.50",
"txid": null,
"payment_source": "alfabit_balance",
"alfabit_payment_route": "direct_internal_transfer",
"alfabit_payer_symbol": "USDT",
"alfabit_payer_network": "TRX",
"alfabit_payment_intent_uid": "intent_01J...",
"is_payer_marked_paid": true,
"payer_name": "И. Иван Иванович",
"payment_url": "https://alfabit.org/en/pub/invoice/order/01J7HZ...",
"show_receiver_publicly": false,
"created_at": "1747325000",
"expires_at": "1747335800"
}
}Список инвойсов
/api/v2/integration/invoicesПраво: can_invoices_read. Пагинация курсорная по page/limit. Каждый элемент — тот же объект, что в GET /invoices/{invoice_id}.
Query-параметры
| Параметр | Тип / диапазон | Описание |
|---|---|---|
status | string? | Фильтр: wait / success / failed. |
limit | int (1..100, default 50) | Размер страницы. |
page | int (≥1, default 1) | Номер страницы. |
{
"success": true,
"data": [ /* массив объектов как в GET /invoices/{invoice_id} */ ],
"pagination": {
"total": 137,
"limit": 20,
"offset": 0
}
}Отменить инвойс
/api/v2/integration/invoices/{invoice_id}/cancelПраво: can_invoices_create. Отменить можно только в статусе wait. Переводит инвойс в failed. Если оплата уже получена (success / aml / blocked) — 409 INVALID_STATUS.
{
"success": true,
"data": { /* тот же объект инвойса со status="failed" */ }
}{
"success": false,
"error": {
"code": "INVALID_STATUS",
"message": "Cannot cancel invoice in status 'success'"
}
}Ссылка на оплату
/api/v2/integration/invoices/{invoice_id}/payment-urlПраво: can_invoices_read. Ссылка публичная — её можно отдать плательщику. Точно та же URL уже есть в поле payment_url любого ответа GET /invoices/{invoice_id}, эта ручка нужна когда не хочется тащить весь объект.
{
"success": true,
"data": {
"payment_url": "https://alfabit.org/en/pub/invoice/order/01J7HZ..."
}
}Постоянный QR / шаблон
Permanent invoice — это «шаблон». Один template_uid живёт вечно, каждая реальная оплата создаёт отдельный child invoice со своим адресом и TTL. Идеально для касс, постоянных QR на стене, donate-ссылок и POS-терминалов.
Сам шаблон не платёж — webhook invoice.created на него НЕ приходит. События invoice.paid / invoice.expired приходят на каждый child и содержат parent_template_uid + external_payment_id (если передан).
Лимит активных child одного шаблона — поле template_max_active_children в ответе GET шаблона (по умолчанию 100).
Зашить сумму в публичную ссылку/QR: добавьте к payment_url параметры ?amount=500¤cy=RUB&fixed=1 — страница оплаты покажет сумму как фиксированную (ценник), плательщик изменить её не сможет. Без параметров — открытая сумма.
Создать шаблон
/api/v2/integration/invoices/v2/permanentПраво: can_invoices_create. Создаёт шаблон без разового платёжного ордера и без TTL (живёт пока is_active=true).
Тело запроса
| Поле | Тип | Описание |
|---|---|---|
symbol | string? | Целевая валюта получателя. NULL = плательщик выберет на чеке. |
bch_code | string? | Сеть. Если задана — наследуется в каждый child. |
currency | string? | Дефолтная валюта суммы для child-чеков. |
description | string? (≤500) | Публичное описание шаблона (видно всем плательщикам). |
life_time_minutes | int (1..43200, default 60) | Дефолтный TTL для child-чеков. |
is_hedging | bool | Хеджирование наследуется в child-чеки. |
hedging_symbol | string? | Целевая монета хеджирования. |
payment_policy | enum | all / alfabit_only / external_only. |
show_receiver_publicly | bool | Показывать имя/email получателя на странице. |
show_payments_count_publicly | bool | Показывать счётчик SUCCESS-чеков на публичной странице. |
{
"success": true,
"data": {
"template_uid": "01J8AB...",
"status": "wait",
"is_active": true,
"payment_url": "https://alfabit.org/en/pub/invoice/permanent/01J8AB...",
"invoice_currency": "USDT",
"description": "Coffee Shop on Tverskaya 7",
"payments_total": 0,
"is_hedging": false,
"hedging_symbol": null,
"payment_policy": "all",
"show_receiver_publicly": true,
"show_payments_count_publicly": true,
"template_max_active_children": 100,
"created_at": "1747325000"
}
}/api/v2/integration/invoices/v2/permanent/{template_uid}Текущее состояние шаблона + payments_total (счётчик SUCCESS-child). Право: can_invoices_read.
Выбить чек по шаблону (POS-API)
/api/v2/integration/invoices/v2/permanent/{template_uid}/paymentsПраво: can_invoices_create. Создаёт обычный child invoice с собственным адресом, TTL и ссылкой. Идемпотентно: повторный POST с тем же idempotency_key вернёт ТОТ ЖЕ child.
Тело запроса
| Поле | Тип | Описание |
|---|---|---|
amount | string (обяз.) | Сумма чека (decimal-строка > 0). |
currency | string? | Валюта суммы. NULL — наследуется из шаблона. |
life_time_minutes | int? (1..43200) | TTL чека. NULL = 60. |
description | string? (≤500) | Видно плательщику на странице чека. |
external_payment_id | string? (≤128) | Ваш ID чека на стороне POS. Прилетает обратно в webhook invoice.paid / invoice.expired. |
idempotency_key | string (8..64, обяз.) | Защита от дубля чека. Повторный POST с тем же ключом не создаст второй child. |
{
"success": true,
"data": {
"invoice_id": "01J8CD...",
"status": "wait",
"symbol": "USDT",
"network": "TRX",
"address": "TXa1B2...",
"amount_requested": "12.50",
"amount_requested_currency": "USDT",
"amount_to_pay": "12.50",
"payment_source": "blockchain",
"description": "Receipt POS-AAA-9876",
"payment_url": "https://alfabit.org/en/pub/invoice/order/01J8CD...",
"alfabit_payment_policy": "all",
"show_receiver_publicly": true,
"created_at": "1747326000",
"expires_at": "1747326900",
"parent_template_uid": "01J8AB...",
"external_payment_id": "POS-AAA-9876"
}
}Список чеков шаблона
/api/v2/integration/invoices/v2/permanent/{template_uid}/paymentsПраво: can_invoices_read. Все child-чеки данного шаблона с пагинацией. Поддерживает фильтры по status и external_payment_id (точное совпадение).
Query-параметры
| Параметр | Тип / диапазон | Описание |
|---|---|---|
status | string? | wait / success / failed / expired. |
external_payment_id | string? | Точное совпадение с переданным ранее ID чека. |
limit | int (1..200, default 50) | Размер страницы. |
page | int (≥1, default 1) | Номер страницы. |
{
"uid": "01J8CD...",
"status": "success",
"invoice_amount": "12.50",
"invoice_currency": "USDT",
"amount_received": "12.50",
"symbol": "USDT",
"bch_code": "TRX",
"txid": "0x1a2b3c...",
"public_comment": "Receipt POS-AAA-9876",
"external_payment_id": "POS-AAA-9876",
"created_at": "1747326000",
"finished_at": "1747326200"
}Статусы и payment_source
Поле status в GET /invoices/{invoice_id} и в webhook data.status — одно и то же. Смотрите таблицу ниже. Не путайте status (состояние счёта) с event (имя webhook-события).
status
| Значение | Что значит | Webhook event |
|---|---|---|
wait | Счёт создан, ждём оплату. TTL ещё не истёк. | invoice.created |
success | Оплата получена и зачислена. amount_received — факт прихода; он может быть больше или меньше amount_requested, если сумма ≥ минимума сети. | invoice.paid |
expired | Истёк TTL и txid пустой: платежа не было. Если ончейн-перевод уже пришёл — счёт не уйдёт в expired. | invoice.expired |
failed | Отмена мерчантом через POST /cancel — либо ончейн-платёж ниже минимума сети / пыль. Технический сбой создания инвойса статуса не даёт: инвойса нет. | invoice.cancelled (только cancel; ниже минимума — хука нет, смотрите GET) |
refunded | Провайдер вернул платёж плательщику (например, несовпадение ФИО на QR+KYC). Деньги мерчанту не зачислялись. | invoice.refunded |
aml | Оплата получена, но заморожена AML. Решает саппорт. | — |
blocked | Блок по политике безопасности. | — |
Вебхуков invoice.aml / invoice.blocked нет: заморозку AML смотрите опросом GET /api/v2/integration/invoices/{invoice_id}. После invoice.paid со status=success переход в aml / blocked не предусмотрен — AML выполняется до зачисления. Второй перевод на тот же адрес после записанного txid тот же invoice_id повторно не закрывает.
payment_source
| Значение | Что значит |
|---|---|
blockchain | Оплата on-chain. Есть txid и сетевая комиссия. По умолчанию для status=wait. |
alfabit_balance | Оплата с баланса AlfaBit. txid=null. Заполнены alfabit_payment_route / alfabit_payer_symbol / alfabit_payer_network / alfabit_payment_intent_uid. |
Webhooks инвойсов
Поля callback_url / webhook_url в теле создания инвойса нет и не будет. Адрес задаётся один раз на аккаунт через Integration Webhooks API (или Developer Console → Webhooks). После подписки события по всем вашим инвойсам уходят на этот URL.
1. Как подключить
{
"url": "https://your.domain/hooks/alfabit",
"events": [
"invoice.created",
"invoice.paid",
"invoice.expired",
"invoice.cancelled",
"invoice.refunded",
"invoice.hedged"
]
}Ответ вернёт secret один раз — сохраните его для проверки HMAC (заголовок X-Webhook-Signature). Управление: GET/PATCH/DELETE /api/v1/integration/webhooks/{id}, логи доставки: GET .../webhooks/{id}/logs. Тот же список событий: GET /api/v1/integration/webhooks/events.
2. Формат доставки
Headers:
Content-Type: application/json
X-Webhook-Event: invoice.paid
X-Webhook-Signature: <hmac-sha256 hex>
Body:
{
"event": "invoice.paid",
"timestamp": "2026-07-21T11:17:55Z",
"signature": "<same hmac>",
"data": { /* см. ниже */ }
}Подпись считается от конверта {event, timestamp, data} без поля signature, приведённого к каноническому JSON — точный алгоритм и примеры проверки на Python / Node.js см. в разделе Webhooks → «Проверка подписи (HMAC)».
3. События и status в data
| event | data.status | Когда |
|---|---|---|
invoice.created | wait | Сразу после успешного POST /api/v2/integration/invoices (и UI). На шаблон permanent НЕ шлётся. |
invoice.paid | success | Оплата зачислена (blockchain или AlfaBit balance), в т.ч. child permanent. Сверяйте amount_received: он может отличаться от номинала (переплата или недоплата ≥ минимума сети). |
invoice.expired | expired | Истёк TTL и txid пустой. Недоплата с уже пришедшим платежом сюда не попадает. |
invoice.cancelled | failed | Мерчант вызвал POST /api/v2/integration/invoices/{invoice_id}/cancel. |
invoice.refunded | refunded | Провайдер вернул платёж плательщику. Деньги мерчанту не зачислялись. |
invoice.hedged | success | Автоконвертация (is_hedging) завершена: в data приходят hedged_amount и hedged_symbol — сколько фактически зачислено в целевой монете. |
invoice.template.deactivated | — | Деактивирован шаблон permanent invoice. |
Отдельного event invoice.failed нет. Отмену мерчантом отслеживайте по invoice.cancelled, просрочку без платежа — по invoice.expired, возврат провайдера — по invoice.refunded. Платёж ниже минимума сети ставит status=failed без вебхука — смотрите GET. Заморозку AML тоже только GET (status=aml / blocked).
4. Поля data
{
"invoice_id": "9b854097-3de2-42aa-9f9c-1c0412058c73",
"status": "success",
"symbol": "USDT",
"network": "BSC",
"address": "0x9760...",
"memo_tag": null,
"amount_requested": "10",
"amount_requested_currency": "USDT",
"amount_received": "10",
"txid": "0x1a2b...",
"description": null,
"is_hedging": false,
"hedging_symbol": null,
"is_payer_marked_paid": false,
"payer_name": "И. Иван Иванович",
"payment_source": "blockchain",
"payment_url": "https://alfabit.org/en/pub/invoice/order/9b854097-...",
"created_at": "1784631832.0136988",
"expires_at": "1784632732.0136988",
"fee_breakdown": {
"invoice_fee_mode": "deduct_from_amount",
"fiat_topup_fee_mode": "payer",
"currency": "USDT"
},
"alfabit_payment_intent_uid": null,
"alfabit_payment_route": null,
"alfabit_payer_symbol": null,
"alfabit_payer_network": null,
"parent_template_uid": null,
"external_payment_id": null
}Поля совпадают с ответом GET /api/v2/integration/invoices/{invoice_id} (data). Для оплаты с баланса AlfaBit: txid=null, payment_source=alfabit_balance, заполнены alfabit_*. Для child permanent: parent_template_uid; external_payment_id — если передавали в POS-API. Для QR+KYC: payer_name — ФИО плательщика («И. Иван Иванович») из верификации; если связи нет — поля нет.
{
"invoice_id": "9b854097-3de2-42aa-9f9c-1c0412058c73",
"hedged_amount": "0.01324718",
"hedged_symbol": "BTC"
}Приходит только для инвойсов с is_hedging=true и только после успешной автоконвертации — то есть уже ПОСЛЕ invoice.paid, отдельным запросом. hedged_amount — фактически зачисленная сумма в hedged_symbol (курс и комиссия хеджирования уже учтены). Те же два поля доступны в GET /api/v2/integration/invoices/{invoice_id}: пока конвертация не завершилась, они null.
KYC-API чекаут (KYC+QR)
Второй, равноправный способ приёма RUB-платежей — целиком через API, без нашей платёжной страницы. Весь UI (форма, загрузка документов, показ QR) — на вашей стороне; плательщик остаётся на вашем сайте. Подходит обменникам и криптопроектам, которым нужен полный контроль над UX.
1) Hosted invoice: POST /integration/invoices → payment_url → плательщик оплачивает на нашей странице (KYC на нашей стороне). 2) KYC-API чекаут (эта секция): вы сами собираете документы плательщика, отправляете их нам, получаете QR и показываете его в своём интерфейсе. Какой флоу доступен вашему аккаунту — определяется профилем приёма (назначает AlfaBit).
Флоу
1. POST /api/v1/integration/checkout/payments
{ amount, payer_phone, payer_ip, external_payment_id, ... }
→ status=kyc_required (инвойс НЕ создаётся)
2. POST /api/v1/integration/checkout/payers/{phone}/documents
(multipart: doc_type + file — паспорт главная стр., прописка)
→ kyc_status=pending, processing=true (это НЕ финальный статус)
3. GET /api/v1/integration/checkout/payers/{phone}
опрашивать каждые 1–2 сек, пока processing=true
→ kyc_status=approved + expected_payer_name
→ processing=false и pending / manual_review=true → ручная сверка
(те же фото заново не отправлять)
→ kyc_status=retry, client_action_required=true → нужны новые документы:
покажите плательщику retry_comment и вернитесь к шагу 2
4. POST /api/v1/integration/checkout/payments (обязательно повторно)
→ payment_uid, status=created (без этого шага QR не будет)
5. GET /api/v1/integration/checkout/payments/{uid}
→ qr_url / qr_payload (СБП-реквизиты, когда готовы)
6. Webhook invoice.paid (оплата прошла, ФИО плательщика совпало)
или invoice.refunded (провайдер вернул платёж, например ФИО не совпало)
Телефон в PATH — только цифры, без «+»:
/payers/79001234567
В JSON-теле payer_phone можно передавать +79001234567 — мы нормализуем.
Вебхука на смену KYC плательщика нет: статус только GET (или повторный POST /payments)./api/v1/integration/checkout/paymentsПраво: can_invoices_create. Создаёт RUB-платёж. Если профиль приёма требует верификацию плательщика и телефон ещё не approved — вернёт kyc_required: инвойс и QR на этом шаге не создаются. После загрузки документов и GET-статуса approved этот же POST нужно вызвать повторно — иначе QR не появится. payer_phone — ключ верификации: один раз проверенный плательщик далее платит без повторной загрузки документов. Обязательные антифрод-поля: payer_ip (IP конечного плательщика, IPv4/IPv6) и external_payment_id (номер заявки в вашей системе, для сверки — не защищает от дубля). Опционально: payer_user_agent, payer_device_id (fingerprint устройства).
amount — всегда сумма, которую вы получите на баланс. Кто платит нашу комиссию приёма — опциональное поле invoice_fee_mode: deduct_from_amount (по умолчанию, комиссия вычитается из amount при зачислении — как раньше) или payer (сумма в СБП QR увеличивается на комиссию сверху, вы получаете полный amount). Точная ставка и суммы — в ответе ниже (commission_percent, commission_amount, amount_to_pay) и заранее в GET /channels.
Передавайте idempotency_key (8–64 символа), если хотите безопасно ретраить при обрыве связи: повтор с тем же ключом в течение 24 ч не создаст второй платёж — вернётся уже созданный (тот же payment_uid/QR); если исходный запрос ещё выполняется — HTTP 409 IDEMPOTENCY_IN_FLIGHT, повторить с тем же ключом позже. external_payment_id сам по себе от дубля не защищает — это просто ваш ID для сверки. Ключ действует только на сам факт создания платежа: на ответ kyc_required не влияет, и тот же ключ нужно переиспользовать в повторном POST на шаге 4 (после approve плательщика) — так и задумано, платёж создастся один раз.
{
"amount": "5000.00",
"external_payment_id": "MM-1234",
"idempotency_key": "order-mm-1234-attempt-1",
"description": "Order #1234",
"payer_phone": "+79001234567",
"payer_ip": "203.0.113.10",
"payer_user_agent": "Mozilla/5.0 ...",
"payer_device_id": "fp_7c9e6679",
"invoice_fee_mode": "deduct_from_amount"
}{
"success": true,
"data": {
"status": "kyc_required",
"kyc_required": true,
"payer_status": "not_started",
"processing": false,
"manual_review": false,
"client_action_required": false,
"retry_comment": null,
"required_documents": ["passport_main", "passport_registration"],
"commission_percent": "1.0",
"upload_documents_endpoint": "/api/v1/integration/checkout/payers/79001234567/documents",
"poll_status_endpoint": "/api/v1/integration/checkout/payers/79001234567"
}
}{
"success": true,
"data": {
"payment_uid": "01J8...",
"external_payment_id": "MM-1234",
"status": "created",
"amount": "5000.00",
"amount_to_pay": "5000.00",
"currency": "RUB",
"invoice_fee_mode": "deduct_from_amount",
"commission_percent": "1.0",
"commission_amount": "50.00"
}
}amount_to_pay — сумма, реально зашитая в СБП QR (то, что должен отправить плательщик). При invoice_fee_mode=payer она больше amount ровно на commission_amount; при deduct_from_amount (как в примере выше) она равна amount, а commission_amount будет вычтен из зачисления.
/api/v1/integration/checkout/payers/{phone}/documentsПраво: can_invoices_create. Multipart-загрузка документа плательщика: поля doc_type (passport_main | passport_registration | selfie) и file (JPEG/PNG/PDF, до 25 МБ). Рекомендуемые антифрод-поля (form-data): payer_ip, payer_user_agent, payer_device_id.
Ответ приходит сразу после приёма файлов, с processing: true — это не финальный статус. Распознавание идёт в фоне несколько секунд. Финальный статус только GET /payers/{phone} (путь в poll_status_endpoint): пока processing: true — опрашивайте. Когда kyc_status=approved — повторите POST /payments. processing: false при pending / manual_review=true — заявка у оператора, те же файлы заново не отправляйте. А вот при kyc_status=retry загрузка нужна: оператор оставил замечание в retry_comment и ждёт новый комплект — те же самые фото присылать бесполезно. В path телефона «+» не ставьте (иначе + декодируется как пробел): /payers/79001234567, не /payers/+79001234567.
{
"success": true,
"data": {
"phone": "+79001234567",
"kyc_status": "pending",
"expected_payer_name": null,
"low_confidence": false,
"processing": true,
"poll_status_endpoint": "/api/v1/integration/checkout/payers/79001234567"
}
}Из главной страницы паспорта распознаётся ФИО — после approved верните его плательщику с предупреждением «оплата ожидается именно от {ФИО}»: банк сверит фактического отправителя с паспортом. Имя отдаёт GET /payers/{phone} в поле expected_payer_name — в маскированном виде «И. Иван Иванович» (инициал фамилии + имя + отчество), как принято в СБП. Плательщик по нему узнаёт себя, а полная фамилия наружу не уходит.
Повторная отправка запроса безопасна: тот же файл, загруженный ещё раз под тем же doc_type, не создаёт дубликат документа.
/api/v1/integration/checkout/payers/{phone}Право: can_invoices_read. Статус верификации плательщика по телефону: not_started | pending | retry | approved | rejected. pending — проверяем мы, retry — ждём новые документы от плательщика. Телефон в URL — 11 цифр без «+» (/payers/79001234567). Используйте после загрузки документов (опрос, пока processing=true) и перед повторным POST /payments. Вебхука на смену KYC нет.
processing: true — OCR ещё идёт, статус не финальный, опросите через 1–2 секунды. processing: false и kyc_status=approved — повторите POST /payments, получите QR. processing: false при pending / manual_review=true — автоматическая проверка закончилась, заявка у оператора; это не «зависший OCR». kyc_status=retry и client_action_required=true — к документам есть замечание: сам по себе статус уже не изменится, покажите плательщику текст из retry_comment и загрузите новый комплект (POST /documents).
{
"success": true,
"data": {
"phone": "+79001234567",
"kyc_status": "approved",
"verified_at": "2026-07-27T10:39:26.657298+00:00",
"expected_payer_name": "И. Иван Иванович",
"required_documents": ["passport_main", "passport_registration"],
"processing": false,
"manual_review": false,
"client_action_required": false,
"retry_comment": null
}
}/api/v1/integration/checkout/payments/{uid}Право: can_invoices_read. Статус платежа + СБП-реквизиты: qr_url (ссылка NSPK) и qr_payload появляются, как только платёжная система их сгенерирует (обычно секунды). Терминальные статусы приходят также webhook’ами invoice.paid / invoice.expired / invoice.refunded. Для QR+KYC оба имени — payer_name и expected_payer_name — приходят в маскированном виде «И. Иван Иванович».
{
"success": true,
"data": {
"payment_uid": "01J8...",
"status": "success",
"amount": "5000.00",
"currency": "RUB",
"qr_url": "https://qr.nspk.ru/...",
"qr_payload": "https://qr.nspk.ru/...",
"expected_payer_name": "И. Иван Иванович",
"payer_name": "И. Иван Иванович"
}
}/api/v1/integration/checkout/channelsПраво: can_invoices_read. Набор СБП-каналов приёма, назначенных вашему аккаунту (код, название, комиссия). Конкретный канал для платежа можно выбрать полем channel при создании — из своего набора.
{
"success": true,
"data": {
"channels": [
{ "code": "sbp_1", "name": "SBP #1", "fee_percent": 1.0 }
],
"commission_percent": "1.0"
}
}commission_percent (верхнего уровня) — эффективная ставка нашей комиссии приёма для вашего аккаунта. Это авторитетное значение для планирования amount/invoice_fee_mode в POST /payments заранее, до создания платежа; fee_percent внутри channels — информативное поле конкретного канала.
Встраиваемый виджет (Embed)
Встраивайте платёжный виджет AlfaBit Checkout прямо на свой сайт — модальное окно, inline-блок или iframe. Юзер не покидает страницу и не редиректится. Аналог Stripe Elements / PayPal Buttons.
- Создайте инвойс через POST /api/v2/integration/invoices — получите invoice_id (uid)
- Подключите SDK с CDN или через npm @alfabit/checkout-js
- Откройте виджет: AlfaBitCheckout.open(uid) или mount(...)
- Слушайте события onSuccess / onError или подпишитесь на postMessage
1. Pure iframe (без JS)
Простейший вариант — для статичных лендингов и Telegram-mini-app. Просто <iframe>:
<iframe
src="https://alfabit.org/{lang}/embed/invoice/order/{uid}?theme=dark&primary=9ee248"
width="100%"
height="640"
frameborder="0"
allow="payment *; camera; microphone">
</iframe>2. JS SDK (modal popup)
Кнопка «Оплатить» рядом с товаром — клик открывает модалку:
<script src="https://alfabit.org/checkout/v1/checkout.umd.js"></script>
<button onclick="AlfaBitCheckout.open('{uid}')">Pay</button>3. Inline-mount
Виджет встраивается в layout сайта, без модалки:
<div id="alfabit-checkout"></div>
<script>
AlfaBitCheckout.mount('#alfabit-checkout', {
invoice: '{uid}',
theme: 'auto',
primary: '#9ee248',
locale: 'ru',
onSuccess: (e) => { window.location = '/thank-you' },
});
</script>4. React / Vue
// React
import AlfaBitCheckout from '@alfabit/checkout-js';
<button onClick={() => AlfaBitCheckout.open('{uid}', { theme: 'dark' })}>
Pay
</button>События (postMessage)
| Event | Payload | Когда |
|---|---|---|
alfabit:ready | { invoice_uid, currency, amount } | iframe загрузился |
alfabit:resize | { height } | для inline |
alfabit:payment.completed | { invoice_uid, amount, currency } | оплачено |
alfabit:payment.failed | { invoice_uid, error, message } | отклонено |
alfabit:payment.cancelled | { invoice_uid } | юзер закрыл |
alfabit:payment.expired | { invoice_uid } | истёк |
Параметры виджета
| Параметр | Тип / Default | Описание |
|---|---|---|
invoice | string (required) | uid инвойса из POST /api/v2/integration/invoices |
type | 'order' | 'permanent' / 'order' | Одноразовый или постоянный QR |
theme | 'auto' | 'light' | 'dark' / 'auto' | Тема виджета |
primary | hex / '#9ee248' | Акцентный цвет (6 hex) |
locale | 'ru' | 'en' / 'ru' | Язык |
height | number / 640 | Высота для inline |
onSuccess | function | Колбэк при успешной оплате |
После создания счёта в кошельке в success-modal есть кнопка «Встроить на сайт». Откроется модалка с готовыми snippet'ами для всех 5 платформ (HTML, JS SDK, React, Vue, Telegram), live preview виджета и настройками темы / цвета. Просто скопируйте код.
Реальные страницы /pub/invoice/* защищены X-Frame-Options: SAMEORIGIN. Виджет загружается с отдельного префикса /embed/invoice/* с CSP frame-ancestors *. SDK фильтрует postMessage по origin (только alfabit.org или ваш baseUrl). primary валидируется regex (6 hex chars), theme/locale — строгий enum. Авторизация юзера для оплаты «с баланса AlfaBit» — через popup-окно SSO, не в самом iframe.
SDK подключается с CDN: https://alfabit.org/checkout/v1/checkout.umd.js или через npm: @alfabit/checkout-js
Travel
Бронирование авиабилетов и отелей за криптовалюту, фиат или со счёта Wallet. API поддерживает полный цикл от поиска до управления заказами.
Криптовалюта (USDT, BTC, ETH), фиат (RUB) через инвойс, или мгновенная оплата со счёта Wallet.
Раздел находится в разработке. Пока используйте Production-окружение для интеграции.
| Окружение | Base URL | API ключ |
|---|---|---|
| Production | https://alfabit.org | Создайте API ключ в Developer Console |
Чтение данных (поиск, заказы) — can_travel_read. Бронирование и оплата — can_travel_book. Возврат денег — can_travel_refund (для refund-ручек avia/order/refund и cancel оплаченной брони). Старые ключи с can_travel_book автоматически получают и refund-доступ — обратная совместимость не нарушена.
Все мутирующие endpoint'ы поддерживают заголовок Idempotency-Key. Передавайте уникальный UUID на каждую операцию — повторный запрос с тем же ключом в течение 24 часов вернёт ранее сохранённый ответ без второго списания/брони.
Поддерживается на:
- Отели:
book,pay/crypto,pay/wallet,cancel,create-order,create-order-with-view,create-order-and-select-room,select-room - Авиа:
book,pay/crypto,pay/wallet,order/{uuid}/cancel,order/{uuid}/refund
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000Формат ключа: A-Z, a-z, 0-9, дефис, подчёркивание (1-128 символов). Пробелы, двоеточия и спецсимволы — 400 INVALID_IDEMPOTENCY_KEY.
Вместо постоянного polling /order/status подпишитесь на события через POST /api/v1/integration/webhooks. Доступные события для отелей:
travel.hotel_order.created— создан черновик заказаtravel.hotel_order.booked— забронирован у провайдера, ожидает оплатыtravel.hotel_order.paid— заказ оплаченtravel.hotel_order.confirmed— отель подтвердил броньtravel.hotel_order.cancelled— заказ отменёнtravel.hotel_order.refunded— возврат средств выполненtravel.hotel_order.failed— ошибка бронирования/оплаты
Для авиа аналогичные события: travel.avia_order.created/booked/paid/cancelled/refunded/failed.
Каждый шаг возвращает данные, необходимые для следующего. Например, search возвращает recommendation_id, который используется в create-order.
Общее
/api/v1/integration/travel/ratesТекущие курсы USDT/RUB и USDT/KGS для расчёта стоимости.
{ "success": true, "data": { "usdt_rub": 92.5, "usdt_kgs": 89.1 }, "ts": 1706000000 }✈️ Авиабилеты
/api/v1/integration/travel/avia/searchПоиск авиарейсов с рекомендациями. Укажите сегменты маршрута, количество пассажиров по типам и класс обслуживания. Возвращает recommendation_id, которые используются в /create-order.
{
"adt": 1, // adults: 1-9
"chd": 0, // children: 0-9
"inf": 0, // infants: 0-9
"trip_class": "e", // e / b / f
"segments": [ // массив сегментов (1 = OW, 2 = RT, 3+ = multi-city)
{ "from": "SVO", "to": "LED", "date": "2026-06-15" },
{ "from": "LED", "to": "SVO", "date": "2026-06-20" }
],
"lang": "ru"
}{
"success": true,
"data": {
"flights": [
{
"id": "21DKEASYOWE100...", // длинный ID рейса
"recommendation_id": "21DKEASYOWE100...", // алиас на id (для удобства)
"duration": 185, // общая длительность в минутах
"segments_direction": [
{
"direction": 0,
"segments": [
{
"dep": { "city": "Frankfurt", "airport_code": "FRA", "datetime": "15.06.2026 17:35:00", "ts": 1781534100 },
"arr": { "city": "Istanbul", "airport_code": "SAW", "datetime": "15.06.2026 21:40:00", "ts": 1781548800 },
"flight_info": { "flight_number": "996", "airline": "Pegasus Airlines", "airline_code": "PC" },
"baggage": { "is_baggage": false, "baggage_pieces": 0 }
}
]
}
],
"short_result": {
"duration": 185,
"isBaggage": true, "baggageWeight": 20, "baggagePiece": 1,
"transfers": []
},
"price": { /* цены в разных валютах */ },
"hash": "ce7069..."
}
]
},
"ts": 1714063200
}
// Используйте flights[N].recommendation_id (или flights[N].id) для:
// GET /avia/fare-families?recommendation_id=...
// POST /avia/create-order { recommendation_id, ... }
// POST /avia/book { recommendation_id, ... }/api/v1/integration/travel/avia/fare-families?recommendation_id=...&lang=ruСемейства тарифов для выбранного рейса: багаж, возврат, обмен.
/api/v1/integration/travel/avia/create-orderСоздать заказ на авиабилеты по выбранной рекомендации.
/api/v1/integration/travel/avia/select-tariffВыбрать тариф (эконом, бизнес и т.д.) для заказа.
/api/v1/integration/travel/avia/bookБронирование рейса с данными пассажиров. РЕКОМЕНДУЕТСЯ передавать Idempotency-Key — повторный запрос не создаст вторую бронь.
{
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"recommendation_id": "REC_12345", // ОБЯЗАТЕЛЬНО. Если выбирали тариф — nonUpgradedId /
// upgradeId из /avia/fare-families, иначе тот же id,
// что в /avia/create-order
"client_email": "user@example.com",
"client_phone": "+79001234567",
"passengers": [
{
"first_name": "IVAN", // КАК В ПАСПОРТЕ — латиницей для международных рейсов
"last_name": "IVANOV",
"type": "adt", // adt / chd / inf
"birth_date": "1990-01-15", // YYYY-MM-DD
"document_type": "passport", // passport / national_id / birth_certificate (для inf)
"document_number": "1234567890",
"document_expire": "2030-01-15",
"citizenship": "RU",
"sex": "M" // M / F
}
],
"lang": "ru"
}Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000{
"success": true,
"data": {
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"billing_number": "BN-AVIA-2026-78901",
"status": "booked",
"ticket_time_limit": "2026-04-25T22:00:00Z" // до этого времени надо оплатить
},
"ts": 1714063200
}/api/v1/integration/travel/avia/pay/cryptoОплата криптой/фиатом через инвойс. Возвращает адрес/QR для оплаты. Поддерживает Idempotency-Key.
{
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"currency_in_code": "USDT_TRC20" // USDT_TRC20 / BTC / ETH / RUB / ...
}{
"success": true,
"data": {
"invoice_id": "INV-AVIA-12345",
"deposit_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"qr_code_url": "https://...",
"amount": "95.50",
"currency": "USDT_TRC20",
"expires_at": "2026-04-25T22:00:00Z"
},
"ts": 1714063200
}/api/v1/integration/travel/avia/pay/walletМгновенная оплата со счёта Wallet. Средства списываются сразу. КРИТИЧНО передавать Idempotency-Key — иначе повторный запрос спишет дважды.
{
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"currency": "USDT"
}Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000{
"success": true,
"data": {
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"status": "paid",
"paid_at": "2026-04-25T20:05:00Z",
"amount_charged": "95.50",
"currency": "USDT",
"balance_after": "1054.50",
"ticket_status": "issued" // issued / pending / failed
},
"ts": 1714063200
}/api/v1/integration/travel/avia/wallet/balance?currency=USDTБаланс Wallet для оплаты авиабилетов.
/api/v1/integration/travel/avia/ordersВсе ваши заказы на авиабилеты.
/api/v1/integration/travel/avia/order/{order_uuid}Детали заказа: маршрут, пассажиры, статус, стоимость.
/api/v1/integration/travel/avia/order/{order_uuid}/statusСтатус заказа: created, booked, pay_waiting, ticketed, cancelled, refunded.
/api/v1/integration/travel/avia/order/{order_uuid}/pdfСкачать PDF маршрутной квитанции / электронного билета.
/api/v1/integration/travel/avia/order/{order_uuid}/cancelОтмена бронирования авиабилета.
/api/v1/integration/travel/avia/order/{order_uuid}/refundВозврат средств за авиабилет (добровольный или вынужденный).
/api/v1/integration/travel/avia/passengersСохранённые пассажиры для быстрого бронирования.
🏨 Отели
Справочники
/api/v1/integration/travel/hotels/destination?part=Mosc&lang=ruАвтокомплит городов и регионов для поиска отелей.
/api/v1/integration/travel/hotels/cities/search?q=Mosc&limit=15Поиск канонических городов по нашему словарю (быстрый, не идёт к провайдеру). Это отдельный справочник: его hotel_city_id НЕ подходит для поля city в поиске отелей — там нужен id из /hotels/destination.
/api/v1/integration/travel/hotels/avia-bridge?hotel_id=12345Связка «отель → IATA города → аэропорты рядом» — для кросс-продажи авиабилетов после выбора отеля.
Поиск
/api/v1/integration/travel/hotels/searchСинхронный поиск отелей по городу, датам и количеству гостей. Может занимать 30-60 сек. Для UX рекомендуется /search/async.
{
"city": "7000546", // числовой id из /hotels/destination.
// НЕ название города и НЕ hotel_city_id из /hotels/cities/search
"check_in": "15.05.2026", // строго dd.mm.yyyy — с точками, иначе 400
"check_out": "20.05.2026",
"adults": 2, // 1-6
"children": [{ "child_age": 5 }], // optional
"lang": "ru"
}{
"success": true,
"data": {
"search": { "city": "7000546", "check_in": "15.05.2026", ... },
"hotels": [
{
"id": "12345",
"name": "Hotel Example",
"stars": 4,
"city": "Москва",
"country": "Россия",
"address": "...",
"photos": [{ "url": "...", "thumb": "...", "is_default": true }],
"rooms": [...],
"hs": "search-hash-for-view"
}
],
"is_completed": true
},
"ts": 1714063200
}/api/v1/integration/travel/hotels/search/asyncАсинхронный поиск с Redis-кэшем и gzip-стримом. Возвращает первую порцию + agent_hash для polling. Рекомендуется для UX с прогрессивной загрузкой.
{
"city": "7000546", // числовой id из /hotels/destination
"check_in": "15.05.2026", // строго dd.mm.yyyy
"check_out": "20.05.2026",
"adults": 2,
"children": [],
"lang": "ru"
}/api/v1/integration/travel/hotels/search/async-by-hash?search_hash=...&search_params_hash=...&lang=ruPolling асинхронного поиска. Дёргайте, пока в ответе не придёт is_completed: true. Тело отдаётся gzip-стримом.
/api/v1/integration/travel/hotels/search/create-hashНизкоуровнево: создать только agent_hash без запуска поиска. Обычно достаточно /search/async.
/api/v1/integration/travel/hotels/search/by-idsПоиск предложений по списку известных hotel_ids — для избранного, истории просмотров.
/api/v1/integration/travel/hotels/search/viewДоступные номера в конкретном отеле с ценами и условиями отмены.
{
"hotel_id": "12345",
"check_in": "15-05-2026", // dd-mm-yyyy
"check_out": "20-05-2026",
"adults": 2,
"children": [{ "child_age": 5 }],
"lang": "ru"
}{
"success": true,
"data": {
"hs": "eyJob3RlbF9pZCI6IjQxODUzMyIsImhzIjpudWxsLCJjaGVja19pbiI6...",
// передавайте строку как есть в /check-rate и /book.
// Это base64 параметров просмотра; при поиске по hotel_id
// внутри лежит "hs": null — это нормально, не блокирует бронь
"hotel": {
"id": "12345",
"name": "Hotel Example",
"rooms": [
{
"id": "149e71dd-3257-43e3-8f06-9bb51208a270", // UUID, внутренний ключ.
// НЕ передавайте его в rate_id — провайдер его не знает
"identifier": "418533..roomOnly..Улучшенный..19082026..835828f9..30,30",
// ЭТО и есть идентификатор тарифа:
// → recommendation_id в /select-room
// → rate_id в /check-rate и /book
"name": "Standard Double",
"type": "DBL",
"price": 12500.00, // в валюте провайдера
"totalAmount": 12500.00,
"mealType": "BB", // BB / HB / FB / AI
"isFreeCancellation": true,
"freeCancellationBefore": "...",
"is_non_refundable": false,
"cancelationRules": [...], // → cancellation_policy_rules для /book
"available_count": 3
}
]
}
},
"ts": 1714063200
}/api/v1/integration/travel/hotels/search/view-by-hash?hotel_id=...&hs=...&lang=ruБыстрый просмотр номеров по hs из шага поиска (без повторного запроса /view).
/api/v1/integration/travel/hotels/hotel/{hotel_id}?lang=ruДанные об отеле: описание, фото, рейтинг, удобства.
/api/v1/integration/travel/hotels/check-rateФинальная проверка цены и правил отмены ОБЯЗАТЕЛЬНО перед /book. Если цена/правила изменились — покажите пользователю и попросите подтвердить новые условия.
{
"hs": "rooms-search-hash",
"hotel_id": "12345",
"rate_id": "418533..roomOnly..Улучшенный..19082026..835828f9..30,30", // rooms[].identifier
"price": 12500.00,
"is_not_refundable": false,
"free_cancellation_before": "2026-05-13T12:00:00+00:00",
"cancellation_policy_rules": [
{
"isPossible": true,
"amount": 0,
"UTCDateFrom": "2026-04-25T00:00:00+00:00",
"UTCDateTo": "2026-05-13T12:00:00+00:00"
}
],
"lang": "ru"
}{
"success": true,
"data": {
"rate_id": "ROOM_ID",
"check_price_changes": {
"old": { "totalAmount": 12500, "price": 12500 },
"new": { "totalAmount": 12500, "price": 12500 }
},
"cancellation_policy_rules_changes": {
"old": [...],
"new": [...]
}
},
"ts": 1714063200
}Заказ и бронирование
/api/v1/integration/travel/hotels/create-orderСоздать пустой черновик заказа на отель. Поддерживает Idempotency-Key.
{
"order_uuid": "550e8400-e29b-41d4-a716-446655440000", // сгенерируйте UUID v4
"hotel_id": "12345",
"search_hash": "rooms-search-hash", // optional, hs из /view
"hotel_name": "Hotel Example", // для отображения
"lang": "ru"
}{
"success": true,
"data": {
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"order_id": 78901,
"status": "created",
"datetime": "2026-04-25T20:00:00Z"
},
"ts": 1714063200
}/api/v1/integration/travel/hotels/create-order-with-viewАтомарно: создать заказ + сразу получить view отеля (номера, цены) одним запросом. Удобно для сценария «выбрали отель по названию» — без поиска и /view.
{
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"view": {
"hotel_id": "12345",
"check_in": "15-05-2026",
"check_out": "20-05-2026",
"adults": 2,
"children": [],
"lang": "ru"
}
}{
"success": true,
"data": {
"order": { "order_uuid": "...", "order_id": 78901, "status": "created" },
"view": { /* такой же формат, как у /search/view */ }
},
"ts": 1714063200
}/api/v1/integration/travel/hotels/select-roomВыбрать конкретный номер и тариф в существующем заказе.
{
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"recommendation_id": "ROOM_IDENTIFIER", // identifier из /view → rooms[].identifier
"payload": "{\"...full room JSON from /view...\"}" // payload номера, как пришёл из /view
}{
"success": true,
"data": {
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"status": "room_selected"
},
"ts": 1714063200
}/api/v1/integration/travel/hotels/create-order-and-select-roomАтомарно: создать заказ + сразу выбрать номер. Если выбор номера упал — заказ удаляется автоматически (без черновиков). Самый удобный путь, если уже знаете отель и номер.
{
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"hotel_id": "12345",
"search_hash": "rooms-search-hash",
"hotel_name": "Hotel Example",
"lang": "ru",
"recommendation_id": "ROOM_IDENTIFIER",
"payload": "{\"...room JSON...\"}"
}{
"success": true,
"data": {
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"order_id": 78901,
"status": "room_selected",
"myagent_price": 12500.00,
"alfabit_price": 13125.00 // включая нашу маржу
},
"ts": 1714063200
}/api/v1/integration/travel/hotels/bookФинальное бронирование с гостями, контактами и согласованными правилами отмены. Перед вызовом ОБЯЗАТЕЛЬНО /check-rate. Рекомендуется передавать Idempotency-Key — повторный сетевой запрос не создаст вторую бронь.
{
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"client_email": "user@example.com",
"client_phone": "+79001234567",
"guests": [
{ "first_name": "Ivan", "last_name": "Ivanov", "type": "adt" },
{ "first_name": "Anna", "last_name": "Ivanova", "type": "chd", "age": 5 } // age обязателен для chd/inf
],
"hs": "rooms-search-hash",
"hotel_id": "12345",
"hotel_name": "Hotel Example",
"rate_id": "418533..roomOnly..Улучшенный..19082026..835828f9..30,30",
// тот же rooms[].identifier, что в /select-room и /check-rate
"price": 12500.00, // из /check-rate
"is_not_refundable": false,
"free_cancellation_before": "2026-05-13T12:00:00+00:00",
"cancellation_policy_rules": [ // из /check-rate
{
"isPossible": true,
"amount": 0,
"UTCDateFrom": "2026-04-25T00:00:00+00:00",
"UTCDateTo": "2026-05-13T12:00:00+00:00"
}
],
"lang": "ru"
}Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000{
"success": true,
"data": {
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"billing_number": "BN-2026-78901",
"status": "booked" // booked / failed
},
"ts": 1714063200
}Оплата
/api/v1/integration/travel/hotels/pay/cryptoСоздаёт инвойс на оплату заказа криптой или фиатом. Возвращает адрес кошелька, QR-код и время жизни инвойса. Поддерживает Idempotency-Key.
{
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"currency_in_code": "USDT_TRC20", // USDT_TRC20 / BTC / ETH / RUB / ...
"use_miles": false,
"miles_to_redeem": null // если use_miles=true
}{
"success": true,
"data": {
"invoice_id": "INV-12345",
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"currency": "USDT_TRC20",
"amount": "100.00",
"deposit_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"qr_code_url": "https://...",
"expires_at": "2026-04-25T21:00:00Z",
"status": "pending"
},
"ts": 1714063200
}/api/v1/integration/travel/hotels/pay/walletМгновенная оплата отеля со счёта Wallet (списание с баланса). КРИТИЧНО передавать Idempotency-Key — иначе повторный запрос спишет средства дважды.
{
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"currency": "USDT", // валюта баланса
"use_miles": false,
"miles_to_redeem": null
}Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000{
"success": true,
"data": {
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"status": "paid",
"paid_at": "2026-04-25T20:05:00Z",
"amount_charged": "100.00",
"currency": "USDT",
"balance_after": "1150.00"
},
"ts": 1714063200
}/api/v1/integration/travel/hotels/wallet/balance?currency=USDTБаланс Wallet для оплаты отеля. Используйте перед /pay/wallet чтобы убедиться, что средств достаточно.
currency=USDT // USDT / BTC / ETH / RUB{
"success": true,
"data": {
"user_id": "sso-id-of-user",
"currency": "USDT",
"balance": "1250.00"
},
"ts": 1714063200
}Мили (программа лояльности)
/api/v1/integration/travel/hotels/miles/preview?order_uuid=...Сколько миль можно списать с конкретного заказа (с учётом лимитов и баланса).
/api/v1/integration/travel/hotels/miles/balanceБаланс программы лояльности и публичные настройки начисления.
Управление заказами
/api/v1/integration/travel/hotels/ordersВсе ваши заказы на отели.
/api/v1/integration/travel/hotels/order/{order_uuid}Детали заказа отеля: номер, даты, гости, стоимость, ваучер.
{
"success": true,
"data": {
"order_id": 78901,
"status": "paid",
"expire": "2026-04-25T21:00:00Z",
"guests": [
{ "first_name": "Ivan", "last_name": "Ivanov", "type": "adt" },
{ "first_name": "Anna", "last_name": "Ivanova", "type": "chd", "age": 5 }
],
"hotel": { /* такой же формат, как у /search/view */ },
"price": 12500.00,
"billing_number": "BN-2026-78901",
"receipt": "https://...voucher.pdf",
"client_email": "user@example.com"
},
"ts": 1714063200
}/api/v1/integration/travel/hotels/order/{order_uuid}/statusСтатус заказа отеля. Возможные значения: created, room_selected, booked, paid, confirmed, cancelled, refunded, failed.
{
"success": true,
"data": {
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"status": "paid",
"updated_at": "2026-04-25T20:05:00Z"
},
"ts": 1714063200
}/api/v1/integration/travel/hotels/order/{order_uuid}/cancelОтмена бронирования отеля. Тело запроса опционально. Если бронь оплачена и отмена влечёт возврат денег — также требуется can_travel_refund. Поддерживает Idempotency-Key.
{
"reason": "hotel_other_reason", // optional
"reason_comment": "Изменились планы" // обязателен только если reason='hotel_other_reason'
}{
"success": true,
"data": {
"order_uuid": "550e8400-e29b-41d4-a716-446655440000",
"status": "cancelled",
"refund_amount": "12500.00", // если был paid
"refund_currency": "RUB"
},
"ts": 1714063200
}/api/v1/integration/travel/hotels/guestsСохранённые гости для быстрого бронирования.
Webhooks
Единая система вебхуков для всех продуктов. URL задаётся один раз на аккаунт (не в теле операций). После подписки события по кошельку, торговле, картам, инвойсам, оплате услуг и Travel уходят на ваш URL.
Всегда сверяйте имена событий с этим эндпоинтом — он возвращает актуальный каталог. Таблица ниже совпадает с ним 1:1. Точки — часть имени (например service_payment.created, card.transaction), НЕ маска service.payment.*.
/api/v1/integration/webhooksСоздать подписку: передайте url и массив events (имена из таблицы ниже). В ответе один раз вернётся secret — сохраните его для проверки HMAC.
{
"url": "https://your-domain.com/webhook",
"events": [
"invoice.paid",
"card.transaction",
"service_payment.confirmed",
"travel.avia_order.paid"
]
}Управление: GET / PATCH / DELETE /api/v1/integration/webhooks/{id}. Изменить набор событий — PATCH с новым events. Логи доставки: GET .../webhooks/{id}/logs.
Проверка подписи (HMAC)
Каждый запрос содержит заголовки X-Webhook-Event (имя события) и X-Webhook-Signature (HMAC-SHA256 hex на secret вашей подписки — том, что вернулся один раз при создании вебхука, не на API secret). То же значение дублируется в поле signature внутри тела: сверяйте с любым из двух.
X-Webhook-Event: invoice.paid
X-Webhook-Signature: <hmac-sha256 hex>
Content-Type: application/jsonПодписывается конверт события {event, timestamp, data} БЕЗ поля signature, приведённый к каноническому JSON. Хешировать сырое тело запроса нельзя: signature в него уже добавлена, а порядок ключей не совпадает с каноническим. Распарсите тело, уберите signature и сериализуйте заново.
message = canonical_json({"event": ..., "timestamp": ..., "data": {...}})
signature = HMAC-SHA256(webhook_secret, message) → hex- Поле signature исключено из подписываемого объекта.
- Ключи отсортированы по алфавиту рекурсивно — включая ключи внутри data. На верхнем уровне порядок получается data, event, timestamp.
- Разделители без пробелов: "," и ":".
- Не-ASCII символы экранируются как \uXXXX (эквивалент json.dumps с ensure_ascii=True).
import hashlib, hmac, json
WEBHOOK_SECRET = "your_webhook_secret"
def verify(body: dict) -> bool:
received = body.get("signature", "")
payload = {k: v for k, v in body.items() if k != "signature"}
message = json.dumps(payload, separators=(",", ":"), sort_keys=True)
expected = hmac.new(
WEBHOOK_SECRET.encode(), message.encode(), hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, received)- Хешируется сырое тело запроса как есть — порядок ключей в нём не отсортирован.
- Хешируется только объект data — подписывается весь конверт, вместе с event и timestamp.
- Поле signature осталось внутри подписываемого объекта.
- JSON сериализован с пробелами после "," и ":".
- Взят secret от API-ключей вместо secret вебхука.
Полный каталог событий
| Event | Описание |
|---|---|
| Кошелёк | |
deposit.pending | Пополнение обнаружено в сети (только крипта) |
deposit.confirmed | Пополнение подтверждено и зачислено (крипта и рубли) |
deposit.failed | Рублёвое пополнение не прошло или возвращено |
withdrawal.processing | Вывод принят и обрабатывается (только крипта; у СБП этого события нет) |
withdrawal.completed | Вывод завершён (крипта и рубли) |
withdrawal.failed | Вывод не удался, средства возвращены (крипта и рубли) |
transfer.received | Получен внутренний перевод |
conversion.completed | Конвертация выполнена |
| Торговля (Spot) | |
order.created | Ордер создан |
order.filled | Ордер полностью исполнен |
order.partially_filled | Ордер частично исполнен |
order.cancelled | Ордер отменён |
trade.executed | Сделка исполнена (fill по ордеру) |
trading.deposit.completed | Пополнение торгового счёта (Spot Fiat) |
trading.withdraw.completed | Вывод с торгового счёта (Spot Fiat) |
trading.balance.updated | Обновление торгового баланса (Spot Fiat) |
| Инвойсы | |
invoice.created | Инвойс создан |
invoice.paid | Инвойс оплачен |
invoice.expired | Истёк TTL, txid пустой (платежа не было). Недоплата с пришедшим платежом сюда не попадает |
invoice.cancelled | Инвойс отменён мерчантом |
invoice.refunded | Провайдер вернул платёж плательщику |
invoice.hedged | Автоконвертация инвойса завершена, средства зачислены в целевой монете |
invoice.template.deactivated | Деактивирован шаблон permanent-инвойса |
| Карты | |
card.transaction | Транзакция по карте (в т.ч. выпуск/пополнение) |
| Оплата услуг | |
service_payment.created | Платёж за услугу создан |
service_payment.confirmed | Платёж за услугу подтверждён |
service_payment.failed | Платёж за услугу не удался |
service_payment.cancelled | Платёж за услугу отменён |
| Travel — Отели | |
travel.hotel_order.created | Черновик заказа отеля создан |
travel.hotel_order.booked | Отель забронирован (ожидает оплаты) |
travel.hotel_order.paid | Заказ отеля оплачен |
travel.hotel_order.confirmed | Бронь отеля подтверждена (финал) |
travel.hotel_order.cancelled | Заказ отеля отменён |
travel.hotel_order.refunded | Возврат по заказу отеля |
travel.hotel_order.failed | Ошибка заказа отеля |
| Travel — Авиа | |
travel.avia_order.created | Черновик авиазаказа создан |
travel.avia_order.booked | Билет забронирован (ожидает оплаты) |
travel.avia_order.paid | Авиазаказ оплачен (билет выписан) |
travel.avia_order.cancelled | Авиазаказ отменён |
travel.avia_order.refunded | Возврат по авиазаказу |
travel.avia_order.failed | Ошибка авиазаказа |
Отдельного события giftcard.* НЕТ — статус покупки подарочной карты отслеживайте через GET /giftcards/orders. Маски вида service.payment.* / card.* не поддерживаются: подписывайтесь на точные имена из таблицы.
Пополнения и выплаты: крипта и рубли в одних событиях
События deposit.confirmed, withdrawal.completed и withdrawal.failed приходят и по криптовалютным операциям, и по рублёвым заявкам СБП. Наборы полей у них разные, поэтому в data есть признак kind: crypto или fiat. Событие deposit.failed бывает только фиатным. withdrawal.processing и deposit.pending — только крипта: у СБП промежуточного вебхука нет, пока заявка в полёте опрашивайте GET /funding/deposit/fiat/{id} или GET /funding/withdraw/fiat/{id}.
{
"event": "deposit.confirmed",
"timestamp": "2026-08-28T09:14:02Z",
"data": {
"kind": "fiat",
"transaction_id": "6a2a0425-d681-4b8c-9792-4ce15d46ef0c",
"status": "success",
"currency": "RUB",
"amount": "10000.00",
"credited_amount": "9820.00",
"fee": "180.00",
"payment_provider_alias_code": "SBER",
"error": null,
"error_code": null
},
"signature": "..."
}{
"event": "withdrawal.failed",
"timestamp": "2026-08-28T09:41:55Z",
"data": {
"kind": "fiat",
"transaction_id": "6f05ad6f-6cd2-47f9-880b-87ed1b58abdc",
"status": "failed",
"currency": "RUB",
"amount": "500.00",
"amount_fact": "0.00",
"fee": "10.00",
"total": "510.00",
"bank_code": "GAZPROM",
"recipient": "7900****67",
"error": "Проведение операции невозможно",
"error_code": "generic_refund"
},
"signature": "..."
}| Поле | Описание |
|---|---|
kind | crypto или fiat. Различайте направление по нему, а не по наличию отдельных ключей. |
transaction_id | Тот же идентификатор, что вернул POST на создание заявки и что принимают GET /funding/deposit/fiat/{id} и GET /funding/withdraw/fiat/{id}. Дедуплицируйте повторные доставки по нему. |
credited_amount | Факт зачисления рублей. null, если рубли не зачислялись — например у счёта под конвертацию: там зачисленную криптовалюту приносит conversion.completed. |
amount_fact | Сумма, фактически ушедшая получателю. У отказа 0.00. |
error / error_code | Причина отказа и её код. Заполняются только у терминального отказа; если причины нет — null, вместо повтора слова failed. |
recipient | Реквизиты получателя в маскированном виде — так же, как в ответе GET-ручки вывода. |
Событие отправляется только по терминальному исходу заявки: промежуточные статусы вебхуком не дублируются. Суммы приходят в копейках — тем же форматом, что отдают GET-ручки приёма и вывода.
transfer.received
Приход внутреннего перевода на ваш баланс. Формат одинаковый для криптовалют и рублей.
{
"event": "transfer.received",
"timestamp": "2026-07-30T10:37:15Z",
"data": {
"transfer_id": "2b8bc516-e49a-40eb-b8c1-1a0fa02c2cfe",
"transaction_uid": "2b8bc516-e49a-40eb-b8c1-1a0fa02c2cfe",
"symbol": "RUB",
"amount": "3872.01",
"status": "credited",
"user_comment": "AB-7K3QF9XM",
"sender_profile_id": 904016,
"sender_email": "payer@example.com",
"recipient_profile_id": 7504,
"method": null
},
"signature": "..."
}| Поле | Описание |
|---|---|
transfer_id | Идентификатор перевода. Совпадает с transaction_uid и с uid операции в GET /integration/transactions — по нему же дедуплицируйте повторные доставки. |
status | Всегда credited: событие отправляется только после фактического зачисления, средства уже доступны получателю. |
user_comment | Комментарий отправителя (до 500 символов), null если не заполнен. |
sender_email | Email отправителя, null если у профиля его нет. |
method | Способ адресации крипто-перевода (tg / email / phone). Для рублёвых переводов всегда null — способ не сохраняется. |
Повторная доставка НЕ байт-идентична: при ретрае timestamp пересчитывается, а значит меняется и signature. Объект data при этом тот же. Дедуплицируйте по transfer_id, а не по хешу тела.
Ответ, отличный от 2xx, и таймаут (10 сек) приводят к повтору: всего 3 попытки — сразу, через 30 секунд и через 2 минуты.
Ссылка на предзаполненный перевод
Ссылка открывает форму внутреннего перевода уже заполненной. Отправку она не выполняет: получателя проверяет платформа, сумму — правила поля, а подтверждение нажимает сам пользователь.
https://alfabit.org/ru/user/transfer?to=user%40example.com&method=email&symbol=USDT&amount=25&comment=Order%20A-1042| Параметр | Описание |
|---|---|
to | Получатель: email, @telegram_username или телефон в формате +71234567890. |
method | email, telegram_username или phone. Можно не указывать — способ определится по формату to. |
symbol | Монета перевода, например USDT или RUB. Если не указана, пользователь выбирает её сам. |
amount | Сумма без разделителей разрядов, точка как десятичный разделитель. Значение подставляется в поле и проходит обычную проверку баланса и лимитов. |
comment | Комментарий отправителя, до 140 символов. Дойдёт до получателя в истории и в вебхуке transfer.received как user_comment. |
Все параметры необязательны, некорректные молча игнорируются — форма просто откроется с пустым полем. Ссылка требует авторизации: неавторизованный пользователь сначала попадёт на вход, а после него — на заполненную форму.
Справочник валют и сетей
Единый источник правды по монетам и сетям: точность суммы, лимиты, комиссии и доступность операций. Читайте его перед выводом и перед выставлением счёта — параметры различаются от сети к сети и меняются без предупреждения (сеть могут временно закрыть на стороне блокчейна).
/api/v1/integration/market/currenciesМассив записей — по одной на пару монета+сеть. Не требует API ключа.
{
"success": true,
"data": [
{
"symbol": "USDT",
"bch_code": "TRX",
"withdraw_amount_decimals": "6",
"min_withdraw_amount": "3",
"max_withdraw_amount": "150000",
"withdraw_service_fee": "2.5",
"is_withdraw_active": true,
"is_deposit_active": true,
"min_deposit_amount": "1",
"is_memo_tag_required": false,
"net_confirmations": 20
},
{
"symbol": "USDT",
"bch_code": "BSC",
"withdraw_amount_decimals": "8",
"min_withdraw_amount": "10",
"max_withdraw_amount": "150000",
"withdraw_service_fee": "1.2",
"is_withdraw_active": true
}
],
"ts": 1706000000
}symbol+bch_code— монета и сеть. Эту же пару передавайте в вывод и в счёт.withdraw_amount_decimals— сколько знаков после запятой принимает сеть на выводе. Лишние знаки усекаются вниз.min_withdraw_amount/max_withdraw_amount— лимиты одной заявки на вывод в этой сети.withdraw_service_fee— комиссия за вывод в единицах монеты.is_withdraw_active/is_deposit_active— открыты ли операции в этой сети прямо сейчас.is_memo_tag_required— нужен ли memo/tag получателю (XRP, TON и подобные).
Ответ большой — кешируйте его у себя и обновляйте раз в несколько минут, а не перед каждой операцией.
/api/v1/integration/market/ratesСтоимость монет в USDT — по одной записи на символ. Не требует API ключа.
{
"success": true,
"data": [
{ "symbol": "USDT", "rate_usdt": "1" },
{ "symbol": "BTC", "rate_usdt": "78635.6" },
{ "symbol": "ETH", "rate_usdt": "2470.64" },
{ "symbol": "TRX", "rate_usdt": "0.3438" }
],
"ts": 1706000000
}Значения годятся для витрины, оценки портфеля и предварительного расчёта. Цену, по которой пройдёт операция, возвращает котировка конкретного продукта — /converter/crypto/estimate или /converter/fiat/estimate: она учитывает направление, объём и комиссию и действует ограниченное время. Не считайте сумму к списанию по rate_usdt.
Тарифы и комиссии
Информация о текущем тарифном плане и ставках комиссий для всех типов операций.
/api/v1/integration/market/tariffsТарифная сетка: комиссии за вывод, обмен, пополнение карт и другие операции. Не требует API ключа.
{
"tariff": "standard",
"fees": {
"withdraw_btc": "0.0001",
"withdraw_usdt_trc20": "1",
"exchange_fee": "0.1%",
"card_topup_fee": "2%"
}
}Транзакции
Единая история всех операций: пополнения, выводы, переводы, обмены, покупки. В один фид сведены и криптовалютные операции, и рублёвые — различить их можно по полю source.
/api/v1/integration/transactionsВсе транзакции с фильтрами по валюте и периоду. Поддерживает пагинацию и поиск.
| Parameter | Type | Описание |
|---|---|---|
symbol | string | Фильтр по валюте (USDT, BTC, RUB). Значение RUB оставляет в фиде только рублёвые операции, любая другая валюта — только криптовалютные. |
limit | number | Количество записей (default: 50, max: 100) |
page | number | Номер страницы (default: 1) |
start_period | number | Начало периода (Unix timestamp) |
end_period | number | Конец периода (Unix timestamp) |
search_term | string | Поиск по транзакциям |
{
"success": true,
"data": {
"page": 1,
"limit": 50,
"count": 156,
"results": [
{
"source": "fiat",
"uid": "0f3c1a7e-1b9d-4f2a-9c11-6a0d5e7b8c34",
"type": "deposit",
"symbol": "RUB",
"amount": "5000.00",
"status_for_client": "success",
"is_final_state": true,
"method": null,
"fee": "0.0",
"sender_id": 7504,
"receiver_id": 9001,
"user_comment": "order-12345",
"sender": { "email": "client@example.com", "telegram_username": null },
"receiver": { "email": "shop@example.com", "telegram_username": null },
"created_at": 1753812345.0
},
{
"source": "crypto",
"uid": "a1b2c3d4-...",
"type": "deposit",
"symbol": "USDT",
"amount": "500.00",
"status_for_client": "success",
"is_final_state": true,
"method": "email",
"created_at": 1753810000.0
}
]
},
"ts": 1706000000
}Поля записи
| Поле | Описание |
|---|---|
source | "crypto" — криптовалютная операция, "fiat" — рублёвая. |
uid | Идентификатор операции. Для внутреннего перевода совпадает с transfer_id из вебхука transfer.received — используйте его как ключ идемпотентности. |
type | Тип с точки зрения владельца ключа: входящая операция — deposit, исходящая — withdraw. Внутренний перевод разворачивается по роли: у получателя это deposit. |
status_for_client | wait | success | failed | blocked | aml. |
is_final_state | Статус окончателен. Пока false — состояние ещё может измениться, зачислять рано. |
method | Способ адресации перевода (email, telegram, phone). У рублёвых операций всегда null — поле оставлено для единообразия разбора. |
sender / receiver | Участники перевода (email, telegram_username). Именно по sender.email сверяется плательщик. |
user_comment | Комментарий отправителя — удобно просить клиента указать в нём номер заказа. |
created_at | Время создания, Unix timestamp (число, не строка). |
Чтобы принимать пополнения переводом внутри AlfaBit, подпишитесь на вебхук transfer.received — он приходит только по факту зачисления и содержит transfer_id, сумму, sender_email и комментарий отправителя. Этот фид используйте как резервный канал сверки: фильтруйте записи с type = deposit и is_final_state = true, дедуплицируйте по uid.
Глубокая пагинация объединённого фида ограничена: page × limit не должно превышать 2000, иначе вернётся 400 DEEP_PAGINATION_NOT_SUPPORTED. Для выгрузки истории сужайте период через start_period / end_period.
/api/v1/integration/transactions/{transaction_id}Детали конкретной транзакции: сумма, статус, комиссия, дата, участники. В transaction_id передаётся uid из фида (он же transfer_id вебхука); ручка ищет операцию и среди криптовалютных, и среди рублёвых.
{
"success": true,
"data": {
"source": "fiat",
"uid": "0f3c1a7e-1b9d-4f2a-9c11-6a0d5e7b8c34",
"type": "deposit",
"symbol": "RUB",
"amount": "5000.00",
"status_for_client": "success",
"is_final_state": true,
"fee": "0.0",
"sender_id": 7504,
"receiver_id": 9001,
"user_comment": "order-12345",
"created_at": 1753812345.0
},
"ts": 1706000000
}