SportAPI Документация
RU
C Документация продуктаCoupon API
v1
Услуга и цены ↗ Получить доступ ↗
Coupon API / Переход со старого API

Переход со старого API

Этот документ сравнивает старое описание old_api_calc.txt с клиентским OpenAPI 1.2.0. Он нужен существующим интеграторам, которые уже работают с /api/v2/login, /bet/place и /coupons/**.

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

Главное

Старые маршруты продолжают поддерживаться в совместимом режиме, и их удаление в настоящее время не планируется. Для новых интеграций рекомендуется /api/partner/**. Переход можно выполнять поэтапно, но нельзя предполагать, что новый маршрут возвращает старую структуру ответа.

Изменения маршрутов

ОперацияБылоСталоЧто изменить у клиента
АвторизацияPOST /api/v2/loginPOST /api/partner/loginПерейти на расширенный ответ и новые правила HTTP 401/403.
Создание купонаPOST /bet/placePOST /api/partner/coupons/placeЧитать массив body.coupons, а не купон непосредственно из body.
Получение купонаGET /coupons/getGET /api/partner/coupons/getИспользовать новый полный формат купона.
Купоны за периодGET /coupons/listPOST /api/partner/coupons/resultsПередавать JSON с start_date и end_date.
Купоны по кодамНе было отдельного режимаPOST /api/partner/coupons/resultsПередавать до 100 значений в coupon_ids.
Недавние расчетыGET /coupons/calculatedGET /api/partner/coupons/calculatedЛогика окна до 120 минут сохранена, формат купона расширен.
Активные купоныНе были полноценно описаныGET /api/partner/coupons/activeМожно получать все активные купоны клиента.
БалансНе было отдельного метода чтения.GET /api/partner/balanceДобавлен read-only запрос своего клиентского баланса. Создание купона автоматически списывает средства с этого баланса.
Cashout quoteGET /coupons/cashoutНового маршрута пока нетФункция не протестирована и находится в разработке; не использовать в production до отдельного объявления.

Авторизация и доступ

БылоСтало
Основное поле логина — login.Основное поле — username, при этом login остается совместимым алиасом.
Все отказы входа преобразовывались в error_code = 99, Wrong login or password.Новый login различает неполный запрос (1002), неверные данные (1003), отключенный аккаунт (1004), истекший доступ (1006) и недостаточный баланс (1007). Все эти бизнес-ошибки приходят с HTTP 200 и code = 0.
Неверный токен на старых маршрутах возвращает HTTP 200, code = 0, error_code = 1003.Новые защищенные маршруты используют HTTP 401; неподходящая роль — HTTP 403.
Старый документ не описывал надежную изоляцию данных клиента.Владелец определяется только по подписанному клиентскому JWT. Чужой и неизвестный купон неразличимы.

Формат ответа

БылоСтало
Оболочка: code, body, error_code, error_message, date.Добавлены диагностические поля time_ms и path.
Успешное создание возвращало один купон непосредственно в body.body.coupons всегда является массивом, потому что multi = true может создать несколько купонов.
Клиент часто ориентировался на наличие HTTP-успеха.Бизнес-ошибка обычно по-прежнему приходит с HTTP 200; обязательно проверять code.

Новый клиент должен считать создание успешным только при одновременном выполнении условий:

HTTP 200
code = 1
body.coupons содержит созданный купон или купоны

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

Код купона

БылоСтало
В примерах использовались коды разной длины: "0934412", "1009982318".Публичный coupon_code — строка, обычно содержащая 12 цифр, например "000000000272".
Код можно было ошибочно хранить числом.Код нужно хранить строкой, чтобы не потерять ведущие нули.
Разделение публичного кода и ID базы не было явно описано.coupon_code не равен внутреннему ID записи.

Указатель ставки

Старый документ:

<type_line>#<game_id>|<bet_group_id>|<bet_id>|<param>#<coefficient>

Новый канонический формат:

line_type#game_id#group_id#type_id#rate#coefficient[#player_id]

Точечные изменения:

  • названия позиций унифицированы: line_type, group_id, type_id, rate;
  • добавлен необязательный player_id для персональных рынков;
  • официально допускаются разделители # и |, включая совместимый смешанный формат;
  • сервер проверяет формат, наличие, блокировку и актуальный коэффициент исхода;
  • неверный формат имеет отдельный код 11.

Параметры создания

ПолеБылоСтало
list_betsОдин или несколько строковых указателей.Сохранено; минимум один элемент.
amountfloat.Десятичное положительное число; обязательное поле.
currencyВалюта ставки.Сохранено как необязательное строковое поле. Можно использовать любую обычную, виртуальную, внутреннюю или вымышленную валюту; код ISO 4217 не обязателен.
callback_urlURL результата.Сохраняется отдельно для каждого купона; пустое значение отключает callback этого купона.
langВ примерах использовались отдельные языковые коды.Передается двухбуквенный код языка; API поддерживает около 50 языков. Язык фиксируется при создании, получить существующий купон в другом переводе сейчас нельзя. Полный перечень языков не публикуется.
modeaccept или reject.Сохранено; в новом API значение по умолчанию — reject.
mode_type1, 2, 3.Общая логика направлений сохранена.
multiЧисло 0/1, функция была отмечена как разрабатываемая.Boolean false/true; при true каждый исход создает отдельный купон.

При multi = true значение amount применяется к каждому созданному ординару. Например, два исхода и amount = 10 создают два отдельных купона с общей суммой списания 20.

Списание клиентского баланса

Успешное создание в новом API атомарно списывает общую сумму с баланса клиентского аккаунта SportAPI:

  • multi = false — один amount;
  • multi = trueamount × количество создаваемых купонов.

Если общей суммы недостаточно, API возвращает HTTP 200, code = 0, error_code = 507, Insufficient balance. Ни один купон не создается и клиентский баланс не изменяется. Частичный успех при multi = true невозможен.

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

При multi = false несколько исходов формируют один экспресс. В одном экспрессе допускается не более 15 событий. Также нельзя объединять несколько ставок из одного дерева матча: например, основной матч и угловые либо угловые и фолы. Такая комбинация возвращает error_code = 506.

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

СитуацияСтарое поведениеНовое поведение
Коэффициент изменилсяОбщая ошибка 501.501, сведения находятся в body.changes[].
Исход отсутствует501, статус nodata.Отдельная ошибка 502, статус no_data.
Исход заблокирован501, статус block.Отдельная ошибка 503, статус block.
Проверка исхода завершилась ошибкойОбщая серверная ошибка.Отдельная бизнес-ошибка 504, статус error.

В новом API body.changes всегда является массивом. Клиенту больше не нужно поддерживать разный тип body для ординара и экспресса.

Поле change_type имеет только числовой формат:

  • 1 — коэффициент повысился;
  • 2 — коэффициент понизился;
  • null — исход заблокирован, отсутствует либо его проверка завершилась ошибкой.

Строковые значения increase и decrease не используются.

Модель купона

В новую модель добавлены или явно разделены:

  • внутренний ID ставки events_data[].id;
  • potential_win и real_win;
  • original_coef и calculate_coef;
  • has_return;
  • raw_pointer, line_type, is_live;
  • main_game_id, is_sub_game, parent_game_id, sub_game_key;
  • счет на момент приема и счет расчета;
  • sport_name, tournament_id;
  • team1_id, team2_id;
  • opp_icon1, opp_icon2.
  • settlement_reason_code и settlement_reason для причины расчета или возврата.

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

coupon_code + events_data[].id

В callback этот ID ставки передается строкой в поле events_data[].uuid. Поле batchId имеет другое назначение: оно идентифицирует версию пакета callback и используется для дедупликации доставки.

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

До расчета купона или отдельной ставки поле calculate_date равно null. Значение 0 больше не используется.

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

Поле currency не входит в полную модель купона и callback. Если оно требуется для финансового учета, партнер должен сохранить переданное значение у себя вместе с coupon_code.

Для программной обработки причины расчета используйте settlement_reason_code. Поле settlement_reason является поясняющим текстом и может меняться; неизвестные коды нужно принимать и сохранять.

Статусы

Старый документ описывал только основные статусы купона 0, 2, 4 и ставки 0, 1, 2, 3, 21, 22.

Новый контракт дополнительно фиксирует:

  • купон 8 — возврат;
  • купон 15 — возвращен на перерасчет и ожидает нового результата;
  • ставка 4 — ожидает перерасчета;
  • ставка 23 — push;
  • расчетный множитель для возврата и половинных результатов;
  • отдельные исходный, рабочий и расчетный коэффициенты.

При возврате на перерасчет сразу отправляется callback со статусом купона 15 и статусом исхода 4. После перерасчета отправляется новый callback с актуальными статусами.

Если предыдущий результат купона уже был обработан, при первом получении статуса 15 партнер должен повторно списать сумму ставки amount. После нового финального статуса необходимо начислить новое значение real_win. Повтор callback с тем же batchId не должен повторно изменять баланс. Поле amount в callback отсутствует, поэтому его нужно сохранить при создании купона или получить через endpoint чтения.

Получение результатов

БылоСтало
Основной способ — периодический запрос рассчитанных купонов.Добавлен необязательный подписанный callback. Партнер может оставить polling основным способом либо использовать его как резервную сверку.
/coupons/list возвращал историю с ограниченной и не полностью определенной выборкой./api/partner/coupons/results имеет два точных режима: до 100 кодов или период создания до 24 часов.
Разница между временем создания и временем расчета была описана нечетко.results фильтрует по времени создания, calculated — по времени окончательного расчета.

Callback

Старый документ передавал callback_url, но не определял надежный публичный протокол доставки.

В новом API зафиксированы:

  • событие coupons.settled;
  • HMAC-SHA256 в X-Coupon-Signature;
  • подпись точных байтов тела;
  • пакетирование до 100 снимков;
  • идентификатор версии доставки batchId, который не является ID купона или ставки;
  • идемпотентная обработка;
  • прогрессивные обновления экспресса;
  • немедленное уведомление о первом проигрыше;
  • финальный снимок после расчета всех ставок;
  • повторы после временных ошибок через 1, 5, 15 и 60 минут;
  • обязательный HTTP 200 для подтверждения доставки.
  • settlement_reason_code и settlement_reason в каждой ставке расчетного снимка.

Callback подключается по желанию партнера. Партнер сообщает менеджеру, что хочет его использовать, после чего менеджер создает секретную фразу для подписи. URL задается самим партнером в callback_url при создании купона. В production следует использовать HTTPS; в тестовой среде допускается HTTP.

Публиковать постоянный IP отправителя в интеграционной документации не требуется. Если партнер дополнительно использует список разрешенных IP, актуальный адрес нужно получить у менеджера. Такая фильтрация является дополнительной мерой и не заменяет проверку HMAC.

Минимальный план миграции

  1. Начать хранить coupon_code строкой.
  2. Добавить поддержку новой оболочки ответа.
  3. Перейти на POST /api/partner/login.
  4. Перейти на POST /api/partner/coupons/place и читать body.coupons[].
  5. Перейти на body.changes[] и отдельные ошибки 501504.
  6. Добавить новые поля и статусы без удаления обработки старых.
  7. Выбрать получение результатов: polling, callback либо оба способа.
  8. Если выбран callback, согласовать его с менеджером, проверять HMAC и выполнять дедупликацию по batchId.
  9. Использовать calculated или results для получения результатов и сверки.
  10. Проверить обработку статусов купона 8, 15 и ставок 4, 23.
  11. Проверить, что calculate_date = null корректно обрабатывается до расчета.
  12. Учесть отдельное списание amount для каждого купона при multi = true.
  13. Запретить в корзине экспресса более 15 событий и связанные ставки одного матча.
  14. Сохранять нужные данные купона и ставок только после успешного ответа создания.
  15. Если нужна валюта купона, сохранять ее в своей системе при создании.
  16. Обработать 507 как атомарный отказ без созданных купонов и без списания клиентского баланса.
  17. Добавить хранение settlement_reason_code и не использовать текст settlement_reason как программный ключ.
  18. После проверки новой интеграции поэтапно отключить обращения к старым маршрутам.