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

Быстрый старт

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

Для первого запуска callback не требуется. Результат купона можно получить обычным запросом к API.

Что понадобится

До начала интеграции получите у менеджера:

  • базовый URL API;
  • логин;
  • пароль.

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

line#737779544#1#1#0#1.85

Замените его актуальным указателем из вашей интеграции со Sport Line API.

Сохраните полученный адрес без завершающего / в переменной:

BASE_URL="https://coupon-api.example.com"

Это только пример. Замените https://coupon-api.example.com адресом, который предоставил менеджер.

Шаг 1. Проверьте доступность API

Метод проверки не требует авторизации:

curl --request GET \
  --url "$BASE_URL/api/partner/health" \
  --header "Accept: application/json"

Успешный ответ:

{
  "code": 1,
  "body": "ok",
  "error_code": null,
  "error_message": null,
  "date": 1784970000000,
  "time_ms": 1,
  "path": "/api/partner/health"
}

Если запрос не выполняется, проверьте базовый URL, доступ к сети и настройки firewall.

Шаг 2. Получите JWT

Передайте логин и пароль:

curl --request POST \
  --url "$BASE_URL/api/partner/login" \
  --header "Accept: application/json" \
  --header "Content-Type: application/json" \
  --data '{
    "username": "{username}",
    "password": "{password}"
  }'

Успешный ответ:

{
  "code": 1,
  "body": {
    "token": "eyJhbGciOiJIUzI1NiJ9...",
    "username": "partner-demo"
  },
  "error_code": null,
  "error_message": null,
  "date": 1784970000000,
  "time_ms": 35,
  "path": "/api/partner/login"
}

Сохраните значение body.token. Во всех следующих запросах передавайте его в заголовке:

Authorization: Bearer <client_token>

JWT администратора для клиентских методов не подходит.

Подробнее: «Авторизация».

Шаг 3. Создайте ординар

Ординар — это купон с одной ставкой.

Замените:

  • <client_token> — токеном из предыдущего шага;
  • значение в list_bets — актуальным указателем выбранного исхода;
  • amount и currency — суммой и валютой вашей ставки;
  • lang — нужным двухбуквенным кодом языка.

Запрос:

curl --request POST \
  --url "$BASE_URL/api/partner/coupons/place" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer <client_token>" \
  --header "Content-Type: application/json" \
  --data '{
    "list_bets": [
      "line#737779544#1#1#0#1.85"
    ],
    "amount": 10,
    "currency": "UAH",
    "lang": "ru",
    "mode": "reject",
    "multi": false
  }'

Здесь:

  • mode: "reject" отклоняет купон, если коэффициент изменился;
  • mode: "accept" позволяет принять изменившийся коэффициент; разные значения mode_type и их поведение описаны в разделе «Изменение коэффициентов»;
  • multi: false объединяет все элементы list_bets в один купон;
  • multi: true создает отдельный ординар для каждого элемента list_bets; сумма amount применяется к каждому купону, поэтому общую сумму нужно учитывать в корзине;
  • один элемент list_bets создает ординар.

В этом примере используются безопасные значения по умолчанию: mode: "reject" и multi: false.

Пример успешного ответа:

{
  "code": 1,
  "body": {
    "coupons": [
      {
        "coupon_code": "000000000272",
        "amount": 10,
        "win": 18.5,
        "potential_win": 18.5,
        "real_win": null,
        "coef": 1.85,
        "original_coef": 1.85,
        "calculate_coef": null,
        "has_return": false,
        "date": 1784970000000,
        "status": 0,
        "asian": false,
        "calculate_date": null,
        "coupon_type": 1,
        "events_count": 1,
        "events_data": [
          {
            "id": 912,
            "game_id": 737779544,
            "main_game_id": 737779544,
            "is_sub_game": false,
            "parent_game_id": null,
            "raw_pointer": "line#737779544#1#1#0#1.85",
            "line_type": "line",
            "is_live": false,
            "bet_group_id": 1,
            "bet_group_name": "Исход матча",
            "bet_id": 1,
            "bet_name": "Победа первой команды",
            "sport_id": 1,
            "sport_name": "Футбол",
            "tournament_id": 10001,
            "tournament": "Тестовый турнир",
            "event_date": 1784977200000,
            "status": 0,
            "opp1": "Команда 1",
            "opp2": "Команда 2",
            "team1_id": 101,
            "team2_id": 102,
            "opp_icon1": 101,
            "opp_icon2": 102,
            "coef": 1.85,
            "calc_coef": null,
            "bet_score": "line#737779544#1#1#0#1.85",
            "calculate_date": null,
            "calculate_score": null,
            "settlement_reason_code": null,
            "settlement_reason": null,
            "rate": "0"
          }
        ]
      }
    ]
  },
  "error_code": null,
  "error_message": null,
  "date": 1784970000015,
  "time_ms": 45,
  "path": "/api/partner/coupons/place"
}

Операция успешна, если code = 1.

При таком ответе API уже списал amount с баланса клиентского аккаунта SportAPI. При multi = true списывается amount за каждый созданный купон. Если общей суммы недостаточно, API возвращает 507, Insufficient balance, не создает купоны и не изменяет клиентский баланс.

Баланс конечного пользователя находится в системе партнера и обрабатывается отдельно.

Важно. До получения code = 1 содержимое корзины является только предварительным выбором пользователя, а не принятым купоном. Не сохраняйте его в системе партнера как принятый купон: при проверке исход уже может отсутствовать в линии, быть заблокирован или иметь другой коэффициент. После подтверждения сохраняйте данные купонов, которые API вернул в body.coupons.

В body.coupons API возвращает созданные купоны. Даже если создан только один купон, coupons остается массивом.

Каждый купон содержит:

  • общие данные купона: код, сумму, потенциальную выплату, коэффициент, тип и статус;
  • events_count — количество ставок;
  • events_data — массив с подробной информацией по каждой ставке: идентификаторами события и исхода, названиями, участниками, коэффициентом, указателем и расчетными полями.

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

coupon_code необходимо сохранить обязательно: это основной ключ связи между купоном в Системе расчета купонов SportAPI и записью в системе партнера. Храните его как строку, чтобы не потерять ведущие нули.

Если партнер отслеживает результат каждой ставки отдельно, следует сохранять events_data[].id и другие необходимые поля. Рекомендуемый ключ конкретной ставки — сочетание coupon_code и events_data[].id.

Подробнее:

Шаг 4. Проверьте текущее состояние

Передайте сохраненный coupon_code:

curl --request GET \
  --url "$BASE_URL/api/partner/coupons/get?coupon_code=000000000272" \
  --header "Accept: application/json" \
  --header "Authorization: Bearer <client_token>"

Пока купон не рассчитан, в ответе будут:

{
  "code": 1,
  "body": {
    "coupon_code": "000000000272",
    "real_win": null,
    "calculate_coef": null,
    "status": 0,
    "calculate_date": null
  },
  "error_code": null,
  "error_message": null,
  "date": 1784970000000,
  "time_ms": 5,
  "path": "/api/partner/coupons/get"
}

status = 0 означает, что расчет еще не завершен.

После расчета купона ответ будет содержать итоговый статус, фактическую выплату и расчетные данные. Сокращенный пример выигравшего ординара:

{
  "code": 1,
  "body": {
    "coupon_code": "000000000272",
    "amount": 10,
    "potential_win": 18.5,
    "real_win": 18.5,
    "original_coef": 1.85,
    "calculate_coef": 1.85,
    "status": 2,
    "calculate_date": 1784973600000,
    "coupon_type": 1,
    "events_count": 1,
    "events_data": [
      {
        "status": 1,
        "coef": 1.85,
        "calc_coef": 1.85,
        "calculate_date": 1784973600000,
        "calculate_score": "2:1"
      }
    ]
  },
  "error_code": null,
  "error_message": null,
  "date": 1784973600100,
  "time_ms": 6,
  "path": "/api/partner/coupons/get"
}

В этом примере:

  • статус купона 2 означает выигрыш;
  • статус ставки 1 означает выигрыш;
  • real_win содержит фактическую выплату;
  • calculate_coef содержит итоговый расчетный коэффициент.

Подробнее:

Обязательно проверяйте code

HTTP 200 не всегда означает, что операция выполнена. Бизнес-ошибки обычно также возвращаются с HTTP 200, но содержат:

{
  "code": 0,
  "error_code": 501,
  "error_message": "Coefficient is change"
}

Минимальная логика обработки ответа:

HTTP 2xx и code = 1 → операция успешна
HTTP 2xx и code = 0 → обработать error_code и error_message
HTTP 401 → получить новый JWT
HTTP 403 → проверить доступ клиента и тип токена
HTTP 5xx → временная серверная ошибка

Подробнее:

Как получать результаты автоматически

После первого успешного купона выберите подходящий способ:

  1. Периодически запрашивать купоны через клиентский API.
  2. Подключить callback через менеджера и получать подписанные обновления автоматически.
  3. Использовать callback как основной способ, а запросы API — для резервной сверки.

Callback необязателен. Для его подключения менеджер включает функцию и создает секретную фразу для проверки HMAC-подписи.

Подробнее:

Готово

Базовая интеграция работает, если ваша система:

  • получает JWT;
  • создает купон с code = 1;
  • сохраняет coupon_code как строку;
  • получает состояние купона по его коду;
  • различает транспортные и бизнес-ошибки.

Следующий шаг: разобраться с авторизацией и обработкой JWT.