Перейти к основному содержимому
🎉 GP CONF 2026: Конференция о рынке WEB-игр 👾 23 сентября | Подробнее

Игрок

Операции игрока выполняются в браузере витрины. Передавайте Content-Type и X-Game-Platform-ID, используйте настроенный домен площадки, чтобы браузерный Origin совпадал с ним, и указывайте credentials: 'include' в каждом запросе.

Не передавайте API-ключ площадки из браузера. После входа API устанавливает HttpOnly-cookie сессии: браузерный JavaScript не должен читать или создавать её.

Получение конфигурации авторизации

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

fragment PlatformAuthConfig on AuthConfig {
id
name
description
xsollaConfig {
loginProjectId
}
googleConfig {
clientID
}
yandexConfig {
clientID
}
vkIdConfig {
clientID
}
configs {
web {
implementation
activeService
}
}
}

query PlayerAuthConfiguration {
result: PlatformFetchGamePlatform {
__typename
... on Problem {
message
}
... on GamePlatform {
isMultipleAuthConfigUsed
authConfig {
...PlatformAuthConfig
}
allAuthConfigs {
...PlatformAuthConfig
}
}
}
}

Структура успешного ответа:

{
"data": {
"result": {
"__typename": "GamePlatform",
"isMultipleAuthConfigUsed": false,
"authConfig": {
"id": "configured-auth-id",
"name": "Вход через Google",
"description": "Войти с помощью Google",
"googleConfig": {
"clientID": "public-oauth-client-id"
},
"configs": {
"web": {
"implementation": "EXTERNAL",
"activeService": "GOOGLE"
}
}
},
"allAuthConfigs": []
}
}
}

Если isMultipleAuthConfigUsed равен true, предложите игроку выбрать конфигурацию из allAuthConfigs и передайте её id как authConfigId при входе. Иначе используйте authConfig.

Вход игрока

Завершите OAuth-сценарий одного из провайдеров авторизации, настроенных на площадке, а затем обменяйте полученный короткоживущий токен провайдера в GamePush.

Настройка провайдеров и требования к callback описаны в разделе «Сторонняя авторизация». На этой странице остаются специфичные для витрины обмен токена и работа с cookie сессии.

mutation LoginPlayer($input: LoginPlayerOnGamePlatformInput!) {
result: LoginPlayerOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on LoginPlayerOnGamePlatformResult {
isNewUser
}
}
}

Переменные:

{
"input": {
"gamePlatformID": 42,
"token": "SHORT_LIVED_PROVIDER_TOKEN",
"tokenType": "AccessToken",
"redirectUri": "https://games.example.com/auth/callback",
"authConfigId": "configured-auth-id"
}
}

Во время выполнения используйте настоящий короткоживущий токен провайдера, не записывайте его в логи и репозиторий. tokenType принимает AccessToken или ExchangeToken в зависимости от выбранного провайдера.

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

{
"data": {
"result": {
"__typename": "LoginPlayerOnGamePlatformResult",
"isNewUser": false
}
}
}

Чтобы завершить сессию, сохраните те же браузерные заголовки и настройки cookie:

mutation LogoutPlayer {
result: LogoutPlayerOnGamePlatform {
__typename
... on Problem {
message
}
... on Success {
success
}
}
}
{
"data": {
"result": {
"__typename": "Success",
"success": true
}
}
}

Получение и обновление профиля

query CurrentPlatformPlayer($input: GetGamePlatformPlayerInput!) {
result: GetGamePlatformPlayer(input: $input) {
__typename
... on Problem {
message
}
... on GamePlatformPlayer {
id
gamePlatformID
name
avatar
balance
autoSkipAds
credentials {
login
type
}
vip {
productTag
enabled
disableGameAds
disablePlatformAds
currencyAccrual
bonusCurrency
endTime
}
playedGames
}
}
}

Переменные:

{
"input": {}
}

Структура успешного ответа:

{
"data": {
"result": {
"__typename": "GamePlatformPlayer",
"id": 9001,
"gamePlatformID": 42,
"name": "Игрок",
"avatar": "https://cdn.example.com/avatar.webp",
"balance": "1200",
"autoSkipAds": false,
"credentials": {
"login": "player@example.com",
"type": "EMAIL"
},
"vip": {
"productTag": "vip-month",
"enabled": true,
"disableGameAds": true,
"disablePlatformAds": true,
"currencyAccrual": 100,
"bonusCurrency": 50,
"endTime": "2026-09-01T00:00:00Z"
},
"playedGames": [101, 102]
}
}
}

Передавайте projectId во входных данных только тогда, когда профиль нужно подготовить для конкретной игры.

mutation UpdatePlatformPlayer($input: UpdatePlayerProfileOnGamePlatformInput!) {
result: UpdatePlayerProfileOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on GamePlatformPlayer {
id
name
avatar
autoSkipAds
}
}
}

Переменные и успешный ответ:

{
"input": {
"name": "Новое имя",
"avatarURL": "https://cdn.example.com/new-avatar.webp",
"autoSkipAds": false
}
}
{
"data": {
"result": {
"__typename": "GamePlatformPlayer",
"id": 9001,
"name": "Новое имя",
"avatar": "https://cdn.example.com/new-avatar.webp",
"autoSkipAds": false
}
}
}

Формирование раздела «Мои игры»

Получите playedGames из профиля, а затем преобразуйте эти ID в карточки игр. Пустой список ID возвращает пустой список игр.

query MyGames($input: FetchGamesOnGamePlatformByIdsInput!, $lang: Lang) {
result: FetchGamesOnGamePlatformByIds(input: $input) {
__typename
... on Problem {
message
}
... on GameViewsList {
count
items {
id
name(lang: $lang)
icon(lang: $lang)
cover(lang: $lang)
platformUrl(lang: $lang)
rating
}
}
}
}
{
"lang": "RU",
"input": {
"gamePlatformId": 42,
"gameIds": [101, 102],
"targetOS": "Desktop"
}
}
{
"data": {
"result": {
"__typename": "GameViewsList",
"count": 2,
"items": [
{
"id": 101,
"name": "Пример игры",
"platformUrl": "https://games.example.com/game/example-game",
"rating": 8.4
}
]
}
}
}

Запишите игру после её запуска:

mutation AddPlayedGame($input: AddGameToPlayedOnGamePlatformInput!) {
result: AddGameToPlayedOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on Success {
success
}
}
}
{
"input": {
"gameViewId": 101
}
}
{
"data": {
"result": {
"__typename": "Success",
"success": true
}
}
}

Удалите одну игру или импортируйте локальный список в пустой профиль игрока с помощью следующих операций:

mutation RemovePlayedGame(
$input: RemoveGameFromPlayedOnGamePlatformInput!
) {
result: RemoveGameFromPlayedOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on Success {
success
}
}
}

mutation SyncPlayedGames($input: SyncPlayedGamesOnGamePlatformInput!) {
result: SyncPlayedGamesOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on Success {
success
}
}
}

Переменные для RemovePlayedGame:

{
"input": {
"gameViewId": 101
}
}

Переменные для SyncPlayedGames:

{
"input": {
"gameViewIds": [101, 102]
}
}

Обе успешные мутации возвращают {"__typename":"Success","success":true}. SyncPlayedGamesOnGamePlatform предназначена для импорта локально сохранённых игр гостя после первой регистрации игрока. Она сохраняет не более первых 25 опубликованных игр и только тогда, когда серверный список playedGames пуст. Если в нём уже есть игры, мутация возвращает успех без изменений. Она не заменяет существующий список; для последующих изменений используйте мутации добавления и удаления.

Покупка валюты или преимуществ площадки

Показывайте доступные пакеты из productsList запроса площадки. Начинайте покупку только после входа игрока.

Общие понятия товара и покупки описаны в разделе «Покупки». Запросы ниже покрывают специфичные для витрины покупку пакета, payload провайдера и проверку статуса.

mutation PurchasePlatformBundle($input: PurchaseGamePlatformCurrencyBundleInput!) {
result: PurchaseGamePlatformCurrencyBundle(input: $input) {
__typename
... on Problem {
message
}
... on PlayerPurchaseOutput {
product {
id
tag
type
price(platform: PARTNER)
currency
}
purchase {
_id
orderStatus
payload
}
}
}
}
{
"input": {
"productId": 15,
"lang": "RU"
}
}
{
"data": {
"result": {
"__typename": "PlayerPurchaseOutput",
"product": {
"id": 15,
"tag": "coins-1000",
"type": "CURRENCY_BUNDLE",
"price": 4.99,
"currency": "USD"
},
"purchase": {
"_id": "purchase-id",
"orderStatus": "NEW",
"payload": {
"token": "SHORT_LIVED_PAYMENT_TOKEN"
}
}
}
}
}

Получите paymentsConfig.configs.web.activeService из запроса площадки и обрабатывайте payload в зависимости от выбранного сервиса:

activeServiceПоля payloadДействие витрины
XSOLLA{ "token": "..." }Откройте Xsolla Pay Station по адресу https://secure.xsolla.com/paystation4/?token=<token>.
ROBOKASSA{ "url": "https://..." }Откройте полученный адрес оплаты в платёжном интерфейсе или перенаправьте на него игрока.
STRIPE{ "url": "https://..." }Откройте полученный адрес Stripe Checkout в платёжном интерфейсе или перенаправьте на него игрока.

Настройка стороны провайдера описана в разделах «Xsolla», «Robokassa» и «Stripe». Выбирайте интеграцию по activeService, а не по случайно найденному полю в payload. Считайте платёжные токены и адреса краткоживущими данными: не записывайте их в логи и не сохраняйте.

Браузер не должен самостоятельно отмечать покупку оплаченной. После завершения сценария провайдера опрашивайте покупку по ID и используйте orderStatus как источник истины:

query PlatformPurchase($input: GetGamePlatformPurchaseInput!) {
result: GetGamePlatformPurchase(input: $input) {
__typename
... on Problem {
message
}
... on PlayerPurchase {
_id
orderStatus
payload
product {
id
type
price(platform: PARTNER)
}
}
}
}
{
"input": {
"purchaseId": "purchase-id"
}
}
{
"data": {
"result": {
"__typename": "PlayerPurchase",
"_id": "purchase-id",
"orderStatus": "PAID",
"payload": {
"token": "SHORT_LIVED_PAYMENT_TOKEN"
},
"product": {
"id": 15,
"type": "CURRENCY_BUNDLE",
"price": 4.99
}
}
}
}

Для внутриигрового товара, оплачиваемого с баланса площадки, передайте товар, проект и провайдера из API игры:

mutation PurchaseGameProduct($input: PurchaseProductOnGamePlatformInput!) {
result: PurchaseProductOnGamePlatform(input: $input) {
__typename
... on Problem {
message
}
... on PlayerPurchase {
_id
projectId
productId
orderStatus
product {
id
name(lang: RU)
price(platform: PARTNER)
}
}
}
}
{
"input": {
"productId": 301,
"projectId": 501,
"provider": "GAMEPUSH"
}
}
{
"data": {
"result": {
"__typename": "PlayerPurchase",
"_id": "game-purchase-id",
"projectId": 501,
"productId": 301,
"orderStatus": "PAID",
"product": {
"id": 301,
"name": "Стартовый набор",
"price": 500
}
}
}
}

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