Создание купона
Для регистрации выбранных пользователем ставок используйте:
POST /api/partner/coupons/place
Метод проверяет переданные исходы и создает один или несколько купонов.
В старом API использовался
POST /bet/place. Маршрут продолжает поддерживаться, но имеет другой формат ответа и другие коды некоторых ошибок. Для новой интеграции используйте/api/partner/coupons/place. Все необходимые изменения описаны в руководстве «Переход со старого API».
Авторизация
Метод требует клиентский JWT:
Authorization: Bearer <client_token>
Владелец созданных купонов определяется по JWT. Подробнее: «Авторизация».
Минимальный запрос
Для создания купона обязательно передать:
list_bets— массив указателей выбранных исходов;amount— положительную сумму ставки.
Пример ординара:
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
}'
Если mode и multi не переданы, используются безопасные значения по умолчанию:
{
"mode": "reject",
"multi": false
}
Полный пример запроса
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": "USD",
"callback_url": "https://partner.example.com/api/coupon-result",
"lang": "en",
"mode": "reject",
"mode_type": null,
"multi": false
}'
Поля запроса
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
list_bets | array[string] | Да | Один или несколько указателей выбранных исходов. Массив не может быть пустым. |
amount | number | Да | Положительная сумма ставки. |
currency | string/null | Нет | Произвольное строковое обозначение валюты, например USD, UAH, COIN или название внутренней валюты партнера. |
callback_url | string/null | Нет | URL указывает сам партнер. При использовании callback это адрес обработчика результатов; без callback можно передать основной домен сайта партнера. |
lang | string/null | Нет | Двухбуквенный код языка названий в данных купона. |
mode | string/null | Нет | Правило обработки изменившегося коэффициента: reject или accept. По умолчанию — reject. |
mode_type | integer/null | Для mode = "accept" | Дополнительное правило, определяющее, какие изменения коэффициента можно принять. Значения описаны в разделе «Изменение коэффициентов и доступности исхода». |
multi | boolean/null | Нет | false создает общий купон, true — отдельный ординар для каждого элемента list_bets. По умолчанию — false. Подробности описаны в разделе «Ординары, экспрессы и multi». |
list_bets
Каждый элемент массива представляет одну ставку и передается строкой:
{
"list_bets": [
"line#737779544#1#1#0#1.85",
"live#738917381#119#5869#0.5#3.6"
]
}
Готовые указатели нужно получать из выбранных исходов спортивной линии или iframe и передавать без изменений. Формат подробно описан на странице «Указатель ставки».
amount
amount — сумма одного создаваемого купона. Она передается как положительное десятичное число без фиксированного количества знаков после запятой:
{
"amount": 10.5
}
При multi = false это сумма общего ординара или экспресса. При multi = true эта сумма применяется отдельно к каждому созданному ординару. Подробный пример расчета общей суммы приведен в разделе «Ординары, экспрессы и multi».
При успешном создании API автоматически списывает эту сумму с баланса клиентского аккаунта SportAPI. Это отдельный баланс интеграции, а не баланс конечного пользователя в системе партнера.
currency
Передайте обозначение валюты, используемой партнером:
{
"currency": "USD"
}
Поле не ограничено официальными валютами и не требует кода ISO 4217. Можно использовать обычную, виртуальную, внутреннюю или вымышленную валюту.
Например:
{
"currency": "COIN"
}
API воспринимает currency как строковое обозначение. Чтобы партнер мог корректно сопоставлять купоны, рекомендуется использовать одно и то же значение для одной валюты во всех запросах создания.
callback_url
Значение callback_url партнер указывает самостоятельно. Если callback используется, передайте полный URL обработчика результатов:
{
"callback_url": "https://partner.example.com/api/coupon-result"
}
- в production используйте только
https://; - в тестовом окружении допускается
http://; null, пустая строка или отсутствие поля отключают callback для создаваемого купона;- при
multi = trueURL сохраняется для каждого созданного купона.
Если callback не используется, можно не передавать поле, передать null или пустую строку. Также допускается передать основной домен сайта партнера, например:
{
"callback_url": "https://partner.example.com"
}
Передавать основной домен вместо endpoint следует только тогда, когда callback для аккаунта не используется. Основной домен не считается URL обработчика callback. Если менеджер включит callback, в новых купонах необходимо указывать полный адрес endpoint, который принимает и обрабатывает запросы POST.
Callback необязателен: актуальные состояния можно получать обычными запросами API. Если партнер хочет использовать callback, об этом необходимо сообщить менеджеру. Менеджер включит доставку и создаст секретную фразу для проверки подписи.
Настройка получателя, подпись и повторы доставки описаны в разделе «Callback».
lang
Передавайте двухбуквенный код языка:
{
"lang": "en"
}
Этот язык используется для названий спорта, турнира, команд, группы ставок и исхода в данных купона. API поддерживает около 50 языков; полный перечень в документации не публикуется.
Язык фиксируется при создании купона. В дальнейшем купон можно получить только на языке, указанном в lang при его создании. Запросить тот же купон в другом переводе сейчас нельзя — поддержка нескольких языковых вариантов одного купона находится в разработке.
mode и mode_type
Кратко:
mode = "reject"— не создавать купон, если коэффициент изменился;mode = "accept"— разрешить прием изменившегося коэффициента по правилуmode_type.
Значения mode_type, ответы при изменении коэффициента и рекомендуемое поведение интерфейса описаны на отдельной странице «Изменение коэффициентов и доступности исхода».
multi
Кратко:
multi = false— все элементыlist_betsформируют один купон;multi = true— каждый элемент формирует отдельный ординар.
При multi = true будет создано несколько купонов, поэтому успешный ответ всегда содержит массив body.coupons. Финансовое поведение и примеры описаны на странице «Ординары, экспрессы и multi».
Что проверяет API
Перед созданием купона Система расчета купонов SportAPI проверяет:
- формат запроса и указателей;
- наличие исходов в текущей линии;
- блокировку исходов;
- актуальность коэффициентов;
- отсутствие в одном экспрессе нескольких исходов основного матча и связанных с ним саб-событий;
- положительное значение
amount; - достаточность баланса клиентского аккаунта для создания всех купонов.
Купон считается принятым только после успешного ответа API.
Важно. Не сохраняйте содержимое корзины партнера как принятый купон до получения подтверждения от API. Корзина содержит только предварительный выбор пользователя. Во время создания Система расчета повторно проверяет исходы: к этому моменту исход может исчезнуть из линии, быть заблокирован или изменить коэффициент. В таком случае API отклонит запрос, и купон не будет принят.
Создавайте в системе партнера запись принятого купона только при
code = 1и сохраняйте купоны, возвращенные вbody.coupons. Приcode = 0или отсутствии созданных купонов не сохраняйте предварительные данные корзины как принятый купон.
Списание баланса и атомарность
Создание выполняется по принципу «всё или ничего»:
- при
multi = falseс баланса клиентского аккаунта списывается одинamount; - при
multi = trueсписываетсяamount × количество создаваемых ординаров; - все купоны создаются вместе;
- если общей суммы недостаточно, баланс не изменяется и ни один купон не создается.
Успешный ответ с code = 1 означает, что купоны созданы и соответствующая сумма уже списана с клиентского баланса SportAPI.
Баланс конечного пользователя партнер ведет самостоятельно. Предварительное резервирование и окончательное списание в системе партнера не заменяют автоматическое списание клиентского баланса внутри SportAPI и не выполняются этим API.
Успешный ответ
Пример ответа при создании ординара:
{
"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": "Match result",
"bet_id": 1,
"bet_name": "First team to win",
"sport_id": 1,
"sport_name": "Football",
"tournament_id": 10001,
"tournament": "Test tournament",
"event_date": 1784977200000,
"status": 0,
"opp1": "Team 1",
"opp2": "Team 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,
"rate": "0"
}
]
}
]
},
"error_code": null,
"error_message": null,
"date": 1784970000015,
"time_ms": 45,
"path": "/api/partner/coupons/place"
}
Операция успешна, если одновременно:
- получен успешный HTTP-ответ;
code = 1;body.couponsсодержит созданные купоны.
Даже при создании одного купона поле body.coupons является массивом. При multi = true в нём будет отдельный объект для каждого созданного ординара.
Какие данные возвращаются
Каждый элемент body.coupons содержит:
- данные купона: код, сумму, коэффициенты, возможный и фактический выигрыш, статус и даты;
events_data— массив со всеми ставками этого купона;- по каждой ставке — исходный указатель, событие, рынок, названия, коэффициенты, статус расчета и другие доступные данные.
Партнер самостоятельно определяет, какие поля купона и ставок необходимо сохранять в своей системе. Однако coupon_code необходимо сохранить обязательно: это связующий ключ для последующего получения и обновления купона.
Храните coupon_code как строку, чтобы не потерять ведущие нули:
000000000272
Идентификатор ставки внутри купона
У купона есть собственный coupon_code, а у каждой ставки внутри events_data — внутренний идентификатор id:
{
"coupon_code": "000000000272",
"events_data": [
{
"id": 912,
"game_id": 737779544,
"status": 0
}
]
}
Если партнер хранит и обновляет ставки по отдельности, рекомендуется сохранять:
coupon_code + events_data[].id
Так можно однозначно найти конкретную ставку внутри конкретного купона.
В callback идентификатор ставки передается строкой в поле events_data[].uuid. Например, uuid = "912" соответствует ставке с id = 912 в полной модели купона.
Поля game_id и bet_id имеют другое назначение: они определяют спортивное событие и тип выбранного исхода, но не являются ID конкретной принятой ставки.
Не путайте идентификатор ставки с batchId: batchId идентифицирует доставку callback, а не купон и не отдельную ставку.
Полное описание возвращаемых полей приведено в разделе «Модель купона и ставки».
Начальное состояние купона
Сразу после создания:
- купон имеет статус
0; - его ставки имеют статус
0; real_winимеет значениеnull;calculate_coefимеет значениеnull;calculate_dateкупона и ставок имеет значениеnull.
Значение 0 вместо null для calculate_date не используется.
Статусы и последующий расчет описаны в разделе «Статусы и выплаты».
Ошибки создания
error_code | Причина |
|---|---|
10 | Тело запроса не передано. |
11 | Хотя бы один указатель ставки имеет неверный формат. |
12 | amount отсутствует или не является положительным числом. |
501 | Коэффициент изменился и не был принят по заданным правилам. |
502 | Исход отсутствует в текущей линии. |
503 | Исход заблокирован. |
504 | Во время проверки исхода произошла ошибка. |
506 | В один экспресс добавлено несколько исходов одного матча: основное событие и/или связанные саб-события. Подробнее: «Ставки одного матча в экспрессе». |
507 | На балансе клиентского аккаунта недостаточно средств для создания всех купонов. |
1002 | Передан неверный набор параметров. |
10000 | Внутренняя ошибка сервиса. |
Ошибки 501–504 возвращают сведения о проблемных исходах в body.changes. Не считайте такой ответ успешным только потому, что HTTP-код равен 200.
При недостаточном балансе API возвращает HTTP 200, code = 0:
{
"code": 0,
"error_code": 507,
"error_message": "Insufficient balance",
"date": 1753000000000,
"time_ms": 5,
"path": "/api/partner/coupons/place"
}
При 507 не сохраняйте ни один купон как принятый: операция полностью отклонена, а клиентский баланс не изменен.
При сетевой или серверной ошибке не повторяйте запрос автоматически, пока не исключена возможность, что первый запрос был обработан. Это защищает пользователя от случайного создания дублирующих купонов.
Следующий раздел: «Ординары, экспрессы и multi».