Notell API Docs
English

Интеграция

Колбэки кошелька

Платформа не хранит собственного баланса. На каждое действие игрока, затрагивающее деньги, она вызывает ваш endpoint кошелька. Вы реализуете один HTTPS-endpoint, который обрабатывает несколько значений method.

Transport#

СвойствоЗначение
URLPOST <URL колбэка>/<валюта>, например https://casino.example/wallet/EUR. Валюта в пути — любой из 157 кодов со страницы Валюты.
Где задать URLАдмин-панель → Projects → ваш проект → Integration (см. Админ-панель)
ТелоJSON-объект с отсортированными ключами; содержит api_key. Суммы — JSON-числа с двумя знаками (1.50).
ЗаголовкиContent-Type: application/json, X-Notell-Timestamp, X-Notell-Signature (Подпись колбэков)
Аутентификацияapi_key проекта в теле: сравнивайте его со своим ключом. Каждый запрос также подписан.
Таймаут2 секунды на попытку; редиректы не выполняются
УспехHTTP 2xx с JSON-ответом из раздела Ответ. Статус не 2xx считается сбоем, даже если в теле ok
ИдемпотентностьКаждый bet / win / refund несёт уникальный meta.transaction; повтор содержит тот же id и тело

Соединения. Если хост вашего URL колбэка не за Cloudflare, платформа держит соединения с ним открытыми (простаивающие закрываются через 60 секунд, а запрос, упавший на переиспользованном соединении, один раз повторяется на новом). Иначе каждый запрос отправляется с Connection: close. Если кошелёк находится за Cloudflare или скрывает свой origin, настройка проекта Direct IP (админ-панель, Integration) привязывает соединение к публичному IP-адресу вне Cloudflare (имя в TLS-сертификате по-прежнему проверяется).

Если у проекта не задан URL колбэка, платформа использует встроенный тестовый кошелёк (начальный баланс 10 000.00 на аккаунт), чтобы вы могли попробовать игры до готовности вашего кошелька.

Подпись колбэков#

Каждый колбэк несёт два заголовка, по которым можно убедиться, что запрос пришёл от платформы и не изменён (api_key в теле остаётся как был; проверка подписи необязательна, но рекомендуется):

ЗаголовокЗначение
X-Notell-TimestampUnix-время в секундах, когда подписана эта попытка (повтор подписывается заново)
X-Notell-Signaturev1= + HMAC-SHA256 в hex строчными буквами

Каноническая строка (UTF-8, строки разделены одним \n, без завершающего перевода строки):

<X-Notell-Timestamp>
POST
<URL path of the request, e.g. /wallet/EUR>
<raw request body, byte for byte>

Секрет. По умолчанию он выводится из api_key проекта: secret = hex(HMAC-SHA256(key = api_key, message = "notell-callback-signing-v1")), поэтому сам ключ никогда не используется как ключ HMAC, а перевыпуск API-ключа меняет секрет. Если нужен независимый секрет, попросите менеджера задать его для вашего проекта.

Считайте подпись по исходным байтам тела как они получены. Суммы записаны как 1.50; парсер, который пересериализует JSON, превратит их в 1.5, и подпись перестанет совпадать.

js
import {createHmac, timingSafeEqual} from 'node:crypto';
const secret = createHmac('sha256', API_KEY).update('notell-callback-signing-v1').digest('hex');
function verify(req, rawBody) {            // rawBody: точные полученные байты
  const ts = req.headers['x-notell-timestamp'], sig = req.headers['x-notell-signature'] ?? '';
  if (!/^\d{9,12}$/.test(ts ?? '') || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;   // окно защиты от повтора
  const mac = createHmac('sha256', secret).update(`${ts}\nPOST\n${new URL(req.url, 'http://x').pathname}\n${rawBody}`).digest('hex');
  return sig.length === mac.length + 3 && timingSafeEqual(Buffer.from(sig), Buffer.from('v1=' + mac));
}

Тестовый вектор. При api_key = YOUR_API_KEY секрет равен

43a216923c5d33308ab3944616a873baed88975e9781a84ab18618cb710b0942

Для timestamp 1800000000, пути /wallet/EUR и исходного тела (минимальное тело; реальные содержат больше полей meta)

json
{"amount":1.50,"api_key":"YOUR_API_KEY","meta":{"round_id":"b2a7c1d4-5e60-4f1b-9a3c-7d2e8f901234","transaction":"6f1d0c9e-3b7a-4c52-8e14-a9d05b6c7e21"},"method":"bet","player_id":"player-1024"}

заголовок равен

X-Notell-Signature: v1=78d40d425a7ed15ef7a9eaeaedb28baba83babc3d25b2d1c84873f4db608932b

IP-адреса наших колбэков#

Колбэки уходят с фиксированных адресов. GET /capabilities перечисляет их в callbackSourceIps; разрешите на файрволе именно их. Значения для окружений — на странице Окружения. Сообщите менеджеру, прежде чем переносить кошелёк в новый диапазон адресов; сам URL колбэка задаётся в админ-панели.

Ответ#

Любой метод отвечает одним и тем же JSON-объектом, в том числе когда сообщает об ошибке:

json
{"status": "ok", "balance": 998.50, "currency": "EUR"}
ПолеТипОбязательноОписание
statusenumда"ok" или "error".
balancenumberдаБаланс игрока после операции, JSON-число (не строка): неотрицательное, не более 2 знаков после запятой, до 13 цифр до точки, без экспоненты (998.5, 1000, 0.50 допустимы; 1e3, -1, 988.5000000001 — нет). Обязателен и в ответах "error".
currencystringдаДолжна совпадать с валютой в пути запроса, иначе ответ отвергается как недопустимый. Обязательна и в ответах "error".
messagestringсо status "error"Код, например INSUFFICIENT_FUNDS.

Ответ, нарушающий эти правила (нет balance или он некорректен, неверная currency, не JSON), читается не как отказ, а как неисправный кошелёк: INVALID_CALLBACK_RESPONSE. Операция при этом считается неизвестной (см. Повторы и сбои), а запуск завершается ошибкой.

session_info#

CALLBACKsession_info

Отправляется один раз при запуске игры (не при возобновлении незавершённого раунда). Ничего не меняется; ответьте текущим балансом.

Запрос#

curl
curl -X POST https://casino.example/wallet/EUR \
  -H 'Content-Type: application/json' \
  -d '{"api_key":"YOUR_API_KEY","method":"session_info","player_id":"player-1024","session_id":"9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21"}'
JSON
{
  "api_key": "YOUR_API_KEY",
  "method": "session_info",
  "player_id": "player-1024",
  "session_id": "9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21"
}
ПолеТипОбязательноОписание
methodstringда"session_info".
player_idstringдаВаш идентификатор игрока.
session_idstringдаСессия, созданная запуском.
api_keystringдаAPI-ключ вашего проекта.

Ответ#

json
{"status": "ok", "balance": 1000.00, "currency": "EUR"}
FieldTypeDescription
status, balance, currencyКак в разделе Ответ.

Ошибки#

КодHTTPКогда
BALANCE_UNAVAILABLE400 (возвращает запуск)Вы ответили "status":"error"; запуск завершается ошибкой, сессия не создаётся.
CALLBACK_HTTP_ERROR400 (возвращает запуск)Вы ответили HTTP-статусом не 2xx.
INVALID_CALLBACK_RESPONSE400 (возвращает запуск)Ответ недопустим.

bet#

CALLBACKbet

Отправляется до розыгрыша платного раунда. Спишите amount и ответьте.

Запрос#

curl
curl -X POST https://casino.example/wallet/EUR \
  -H 'Content-Type: application/json' \
  -d '{"amount":1.50,"api_key":"YOUR_API_KEY","meta":{"round_id":"b2a7c1d4-5e60-4f1b-9a3c-7d2e8f901234","session_id":"9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21","symbol":"gates-of-olympus","time":1800000000,"transaction":"6f1d0c9e-3b7a-4c52-8e14-a9d05b6c7e21"},"method":"bet","player_id":"player-1024"}'
JSON
{
  "amount": 1.50,
  "api_key": "YOUR_API_KEY",
  "meta": {
    "round_id": "b2a7c1d4-5e60-4f1b-9a3c-7d2e8f901234",
    "session_id": "9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21",
    "symbol": "gates-of-olympus",
    "time": 1800000000,
    "transaction": "6f1d0c9e-3b7a-4c52-8e14-a9d05b6c7e21"
  },
  "method": "bet",
  "player_id": "player-1024"
}
JSON (раунд фриспинов)
{
  "amount": 0.00,
  "api_key": "YOUR_API_KEY",
  "meta": {
    "freespins": {"external_id": "welcome-2027-01", "grant_id": "7b1c4e92-0a3d-4f68-b5c1-2e9d8a6f3b40", "nominal_bet": 1, "remaining": 9},
    "is_freespins": true,
    "round_id": "d4e8a1b6-93c2-4075-8f1e-5b0a7c2d9e63",
    "session_id": "9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21",
    "symbol": "gates-of-olympus",
    "time": 1800000300,
    "transaction": "0b6e5d3a-8c14-4f97-a2d0-1e7c9b4f6a58"
  },
  "method": "bet",
  "player_id": "player-1024"
}
ПолеТипОбязательноОписание
methodstringда"bet".
player_idstringдаВаш идентификатор игрока.
amountnumberдаСтавка в единицах валюты, положительная; 0 для раунда фриспинов.
meta.transactionstringдаУникальный id этого списания; повтор содержит тот же.
meta.round_idstringдаИдентификатор раунда.
meta.session_idstringдаИдентификатор сессии.
meta.symbolstringдаИдентификатор игры.
meta.timeintegerдаUnix-время в секундах.
meta.is_freespinsbooleanраунды фриспиновtrue, если раунд относится к выдаче фриспинов оператора; принимайте нулевую ставку.
meta.freespinsobjectраунды фриспиновgrant_id, external_id (или null), nominal_bet (число) и remaining — оставшиеся спины.
api_keystringдаAPI-ключ вашего проекта.

Ответ#

Спишите ставку и ответьте новым балансом:

json
{"status": "ok", "balance": 998.50, "currency": "EUR"}

При реальной нехватке средств ответьте HTTP 200 с телом:

json
{"status": "error", "message": "INSUFFICIENT_FUNDS", "balance": 0.50, "currency": "EUR"}

Раунд отклоняется, ничего не разыгрывается. Возвращайте этот код только при реальной нехватке средств.

Ошибки#

КодHTTPКогда
INSUFFICIENT_FUNDS200Ваш ответ: недостаточно средств. Раунд отклоняется сразу; повторов нет.
TRANSACTION_CANCELLED200Ваш ответ: списание пришло после того, как вы записали refund по этой транзакции.
любой другой4xx, кроме 408 и 429Ваш HTTP-статус: окончательный отказ. Раунд отклоняется сразу, ставится в очередь refund.
любой другой5xx, 408, 429, таймаутСписание неизвестно и повторяется (Повторы и сбои).

win#

CALLBACKwin

Отправляется, когда раунд выиграл. amount — общий выигрыш раунда (положительный; нулевые выигрыши не отправляются).

Запрос#

curl
curl -X POST https://casino.example/wallet/EUR \
  -H 'Content-Type: application/json' \
  -d '{"amount":12.75,"api_key":"YOUR_API_KEY","meta":{"round_id":"b2a7c1d4-5e60-4f1b-9a3c-7d2e8f901234","session_id":"9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21","symbol":"gates-of-olympus","time":1800000012,"transaction":"0b6e5d3a-8c14-4f97-a2d0-1e7c9b4f6a58"},"method":"win","player_id":"player-1024"}'
JSON
{
  "amount": 12.75,
  "api_key": "YOUR_API_KEY",
  "meta": {
    "round_id": "b2a7c1d4-5e60-4f1b-9a3c-7d2e8f901234",
    "session_id": "9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21",
    "symbol": "gates-of-olympus",
    "time": 1800000012,
    "transaction": "0b6e5d3a-8c14-4f97-a2d0-1e7c9b4f6a58"
  },
  "method": "win",
  "player_id": "player-1024"
}
JSON (итоговое начисление фриспинов)
{
  "amount": 23.50,
  "api_key": "YOUR_API_KEY",
  "meta": {
    "freespins": {"external_id": "welcome-2027-01", "final_credit": true, "grant_id": "7b1c4e92-0a3d-4f68-b5c1-2e9d8a6f3b40", "nominal_bet": 1, "total_win": 23.5},
    "is_freespins": true,
    "round_id": "e7a02c58-1f94-4b36-9d8a-3c5e6b7f0a12",
    "session_id": "9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21",
    "symbol": "gates-of-olympus",
    "time": 1800000900,
    "transaction": "a3f6c1d8-52e7-4b09-8c14-7d2e9a0b5f63"
  },
  "method": "win",
  "player_id": "player-1024"
}
ПолеТипОбязательноОписание
methodstringда"win".
player_idstringдаВаш идентификатор игрока.
amountnumberдаОбщий выигрыш раунда, положительный. Для итогового начисления фриспинов — сумма всех выигрышей выдачи.
meta.transactionstringдаУникальный id этого начисления; повтор содержит тот же.
meta.round_id, meta.session_id, meta.symbol, meta.timeдаКак в bet. Для итогового начисления round_id — последний раунд выдачи, он может отличаться от раунда более ранней bet.
meta.is_freespinsbooleanитоговое начисление фриспиновtrue.
meta.freespinsobjectитоговое начисление фриспиновgrant_id, external_id (или null), nominal_bet, total_win (равен amount) и final_credit: true.
api_keystringдаAPI-ключ вашего проекта.

Выигрыши фриспинов выплачиваются один раз. Выигрыши раундов выдачи фриспинов оператора не отправляются по каждому спину. После последнего спина платформа отправляет один win на всю выдачу с meta.freespins.final_credit: true перед итоговым freespins_finished. total_win итога равен этому начислению. Не ждите win на каждый выигрышный спин и не сверяйте такой win с bet его round_id.

Ответ#

json
{"status": "ok", "balance": 1011.25, "currency": "EUR"}

Ошибки#

КодHTTPКогда
любойлюбойНачисление никогда не отменяется: если вы не ответили ok, оно повторяется до подтверждения.

refund#

CALLBACKrefund

Отправляется, когда раунд отменён после того, как его bet мог быть списан: ставка осталась неподтверждённой дольше политики отмены (10 минут или 600 попыток, что наступит раньше), кошелёк окончательно отказал ей статусом 4xx, либо вы отменили раунд через round_cancel.

Запрос#

curl
curl -X POST https://casino.example/wallet/EUR \
  -H 'Content-Type: application/json' \
  -d '{"amount":1.50,"api_key":"YOUR_API_KEY","meta":{"original_transaction":"6f1d0c9e-3b7a-4c52-8e14-a9d05b6c7e21","reason":"wallet_unconfirmed","round_id":"b2a7c1d4-5e60-4f1b-9a3c-7d2e8f901234","session_id":"9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21","symbol":"gates-of-olympus","time":1800000600,"transaction":"c41e8a07-6d2b-4f35-9e1c-0a8b7d3f5c92"},"method":"refund","player_id":"player-1024"}'
JSON
{
  "amount": 1.50,
  "api_key": "YOUR_API_KEY",
  "meta": {
    "original_transaction": "6f1d0c9e-3b7a-4c52-8e14-a9d05b6c7e21",
    "reason": "wallet_unconfirmed",
    "round_id": "b2a7c1d4-5e60-4f1b-9a3c-7d2e8f901234",
    "session_id": "9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21",
    "symbol": "gates-of-olympus",
    "time": 1800000600,
    "transaction": "c41e8a07-6d2b-4f35-9e1c-0a8b7d3f5c92"
  },
  "method": "refund",
  "player_id": "player-1024"
}
ПолеТипОбязательноОписание
methodstringда"refund".
player_idstringдаВаш идентификатор игрока.
amountnumberдаРавна сумме ставки.
meta.transactionstringдаId самого возврата.
meta.original_transactionstringдаmeta.transaction возвращаемой ставки.
meta.reasonenumдаwallet_unconfirmed или operator_cancel.
meta.round_id, meta.session_id, meta.symbol, meta.timeдаКак в bet.
api_keystringдаAPI-ключ вашего проекта.

Правила для вашего кошелька:

  • Исходная ставка была списана и ещё не возвращена: верните amount на баланс, ответьте ok с новым балансом.
  • Исходная ставка к вам не приходила (или вы её отклонили): запомните, что этот id транзакции отменён, ничего не меняйте и ответьте ok. Если эта ставка придёт позже, откажите ей ответом {"status":"error","message":"TRANSACTION_CANCELLED","balance":1000.00,"currency":"EUR"}.
  • Повтор того же возврата (тот же meta.transaction) возвращает первый ответ. Одна ставка возвращается не более одного раза.
  • Ответ с ошибкой повторяется, пока вы не ответите ok; после создания возврата платформа больше не отправляет эту ставку.

Ответ#

json
{"status": "ok", "balance": 1000.00, "currency": "EUR"}

Ошибки#

КодHTTPКогда
любойлюбойЕсли вы не ответили ok, возврат повторяется (2 с, с удвоением, не более 5 минут) до подтверждения.

round_info#

CALLBACKround_info

Информационное уведомление о раунде: сохраните его, ничего не меняйте, ответьте ok с текущим балансом. На раунд приходят два, по порядку: start (после подтверждения списания) и finish (после подтверждения начисления или после раунда без выигрыша). finish доставляется только после подтверждения start.

Запрос#

curl
curl -X POST https://casino.example/wallet/EUR \
  -H 'Content-Type: application/json' \
  -d '{"api_key":"YOUR_API_KEY","bet_amount":1.50,"bet_type":"spin","bonus_buy":false,"bonus_trigger":true,"currency":"EUR","game_symbol":"gates-of-olympus","has_win":true,"method":"round_info","multiplier":8.5,"player_id":"player-1024","round_id":"b2a7c1d4-5e60-4f1b-9a3c-7d2e8f901234","session_id":"9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21","status":"finish","timestamp":1800000015,"win_amount":12.75}'
JSON
{
  "api_key": "YOUR_API_KEY",
  "bet_amount": 1.50,
  "bet_type": "spin",
  "bonus_buy": false,
  "bonus_trigger": true,
  "currency": "EUR",
  "game_symbol": "gates-of-olympus",
  "has_win": true,
  "method": "round_info",
  "multiplier": 8.5,
  "player_id": "player-1024",
  "round_id": "b2a7c1d4-5e60-4f1b-9a3c-7d2e8f901234",
  "session_id": "9d0c3f7e-41b8-4a52-9c0e-6d3f5a7b8c21",
  "status": "finish",
  "timestamp": 1800000015,
  "win_amount": 12.75
}
ПолеТипОбязательноОписание
methodstringда"round_info".
statusenumдаstart или finish.
player_id, round_id, session_id, game_symbol, currencystringдаИдентификаторы раунда.
timestampintegerдаUnix-время в секундах.
bet_amountnumberдаСтавка раунда (номинальная ставка для раундов фриспинов).
bet_typestringдаТип ставки раунда, например spin или purchase.
bonus_buybooleanдаРаунд был покупкой бонуса.
bonus_triggerbooleanдаРаунд запустил бонусную функцию.
win_amountnumberпри finishОбщий выигрыш раунда.
multipliernumberпри finishВыигрыш, делённый на ставку.
has_winbooleanпри finishПоложителен ли выигрыш.
forcedbooleanнетtrue, если раунд создан под целевой исход оператора.
api_keystringдаAPI-ключ вашего проекта.

Уведомление finish — итог раунда: используйте его для отчётности; деньги уже прошли через bet и win.

Ответ#

json
{"status": "ok", "balance": 1011.25, "currency": "EUR"}

Ошибки#

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

freespins_finished#

CALLBACKfreespins_finished

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

Запрос#

curl
curl -X POST https://casino.example/wallet/EUR \
  -H 'Content-Type: application/json' \
  -d '{"api_key":"YOUR_API_KEY","bet":"1.00","currency":"EUR","external_id":"welcome-2027-01","finished_at":"2027-01-15T12:30:00.000Z","game":"gates-of-olympus","grant_id":"7b1c4e92-0a3d-4f68-b5c1-2e9d8a6f3b40","method":"freespins_finished","played":10,"player_id":"player-1024","status":"used","total":10,"total_win":"23.50"}'
JSON
{
  "api_key": "YOUR_API_KEY",
  "bet": "1.00",
  "currency": "EUR",
  "external_id": "welcome-2027-01",
  "finished_at": "2027-01-15T12:30:00.000Z",
  "game": "gates-of-olympus",
  "grant_id": "7b1c4e92-0a3d-4f68-b5c1-2e9d8a6f3b40",
  "method": "freespins_finished",
  "played": 10,
  "player_id": "player-1024",
  "status": "used",
  "total": 10,
  "total_win": "23.50"
}
ПолеТипОбязательноОписание
methodstringда"freespins_finished".
grant_idstringдаИдентификатор выдачи.
external_idstringнетВаш id выдачи, если вы его задавали.
player_id, currency, gamestringдаИгрок, валюта и игра выдачи.
statusenumдаИтоговый статус выдачи, например used; значения: Фриспины.
totalintegerдаВыдано спинов.
playedintegerдаСыграно спинов.
betmoneyдаСтавка каждого спина.
total_winmoneyдаОбщий выигрыш выдачи; равен amount итогового win.
finished_atstringдаВремя в формате ISO 8601.
api_keystringдаAPI-ключ вашего проекта.

Ответ#

json
{"status": "ok", "balance": 1011.25, "currency": "EUR"}

Ошибки#

КодHTTPКогда
любойлюбойЕсли вы не ответили ok, повтор: 10 с × 2<sup>попытки</sup>, не более 1 часа.

Порядок вызовов в раунде#

bet  ->  (debit confirmed)  ->  round_info start  ->  [play]  ->  win (if > 0)  ->  (credit confirmed)  ->  round_info finish

Выдачи фриспинов: bet (сумма 0) на каждый спин, без win на спин, затем один win с meta.freespins.final_credit: true, затем freespins_finished.

Повторы и сбои#

СитуацияЧто делает платформа
На bet ответ INSUFFICIENT_FUNDSРаунд отклоняется; повторов нет
На bet HTTP 4xx, кроме 408 и 429Окончательный отказ: раунд сразу отклоняется, ставится в очередь refund
bet с HTTP 5xx, 408, 429, таймаутом, сетевой ошибкой или недопустимым ответомСписание неизвестно и повторяется с тем же id транзакции и телом: первые 4 попытки сразу, затем через 1 с с удвоением до 60 с. Если через 10 минут или 600 попыток (что наступит раньше) оно всё ещё не подтверждено, раунд отменяется и отправляется refund. Всё это время раунд ожидает
То же для winПовторяется до подтверждения (выигрыш никогда не отменяется)
refund без ответа okПовторяется с растущими задержками (2 с с удвоением, не более 5 минут) до подтверждения
round_info без ответа okПовторяется позже; проект, который не отвечает, на время пропускается, чтобы не блокировать остальных
freespins_finished без ответа okПовторяется с растущими задержками: 10 с × 2<sup>попытки</sup>, не более 1 часа

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

Чек-лист для вашего кошелька#

  • [ ] Проверяйте api_key; работайте только по HTTPS; отвечайте за 2 секунды.
  • [ ] Разбирайте amount как десятичное; возвращайте balance JSON-числом (неотрицательным, не более 2 знаков) в каждом ответе, включая ошибки.
  • [ ] Возвращайте в currency валюту из пути URL.
  • [ ] Идемпотентность по meta.transaction (тот же id, то же тело → тот же ответ).
  • [ ] INSUFFICIENT_FUNDS как HTTP 200; никаких HTTP 4xx для временных проблем.
  • [ ] Принимайте amount: 0 для bet при meta.is_freespins равном true; ожидайте один итоговый win на выдачу фриспинов.
  • [ ] Отвечайте ok на round_info и freespins_finished (status, balance, currency).
  • [ ] Реализуйте refund (идемпотентно, с пометкой об отмене для неизвестных транзакций) и, если можете, проверяйте X-Notell-Signature по исходному телу.
  • [ ] Разрешите IP-адреса колбэков из /capabilities.
  • [ ] При тестировании используйте Test connection в админ-панели и следите за API Logs.
Документация для операторов и интеграторов.Платформа TEST_ONLY: невыводимые единицы, реальные платежи не используются.