Игровая валюта
Игровая валюта оформляется как покупка с отдельным шагом расчёта. После входа игрок выбирает принадлежащий ему игровой аккаунт и оплачивает заказ балансом кабинета. Без входа доступны только предложения с доставкой предметом персонажу; для них покупатель выбирает способ оплаты.
Расчёт покупки фиксирует выбранное предложение, количество, скидки, итоговую сумму, получателя и срок действия. Это не отдельный платёж. Для подтверждения покупки передайте идентификатор действующего расчёта.
После входа используется выбранный игровой сервер и аккаунты текущего игрока. Для гостевой покупки передайте сервер, имя персонажа и email плательщика. Цену и скидку возвращает расчёт покупки.
Каталог, расчёт цены, заказ, списание и выдача выполняются сервером как одна согласованная цепочка. Клиент отображает только возвращённые значения и не пересчитывает сумму через float.
Список предложений
gameCurrencyOffers
Описание
Возвращает включённые предложения игровой валюты для текущего проекта и выбранного серверного контекста. Результат использует курсорную пагинацию; сервер не принимает gameServerId от клиента.
Входные данные
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
first | Int | нет | Размер страницы от 1 до 100. В схеме по умолчанию используется 50; в persisted operation передавайте значение явно |
after | ID | нет | Курсор из pageInfo.endCursor предыдущей страницы |
Результат
GameCurrencyOfferConnection содержит items и pageInfo. В каждом предложении:
| Поле | Тип | Описание |
|---|---|---|
id | ID! | Непрозрачный идентификатор предложения |
sku | String! | Уникальный код предложения |
name | String! | Локализованное название |
description | String! | Локализованное описание |
shortName | String! | Короткое название игровой валюты |
iconReference | String! | Ссылка на оформление предложения |
message | String! | Сообщение о выдаче |
deliveryType | GameCurrencyDeliveryType! | CHARACTER_ITEM или ACCOUNT_POINTS |
unitsPerPurchase | Int! | Количество игровых единиц в одном пакете |
unitPrice | GameCurrencyMoney! | Цена одного пакета в точном денежном формате |
pageInfo.hasNextPage показывает наличие следующей страницы. Если он равен true, передайте endCursor в after без изменения.
Пример обмена
{
"documentId": "gameCurrencyOffers",
"variables": {
"first": 50,
"after": null
}
}
{
"data": {
"gameCurrencyOffers": {
"items": [
{
"id": "01910000-0000-7000-8000-000000000101",
"sku": "adena-pack",
"name": "Набор адены",
"description": "Валюта для игрового аккаунта.",
"shortName": "ADENA",
"iconReference": "/assets/images/currency/adena.webp",
"message": "Валюта будет выдана после оплаты.",
"deliveryType": "ACCOUNT_POINTS",
"unitsPerPurchase": 100,
"unitPrice": {
"units": "250",
"code": "USD",
"scale": 2,
"decimal": "2.50"
}
},
{
"id": "01910000-0000-7000-8000-000000000201",
"sku": "soulshot-pack",
"name": "Набор Soulshot",
"description": "Предмет для выдачи выбранному персонажу.",
"shortName": "SOULSHOT",
"iconReference": "/assets/images/currency/soulshot.webp",
"message": "Выберите персонажа для выдачи.",
"deliveryType": "CHARACTER_ITEM",
"unitsPerPurchase": 1000,
"unitPrice": {
"units": "500",
"code": "USD",
"scale": 2,
"decimal": "5.00"
}
}
],
"pageInfo": {
"endCursor": null,
"hasNextPage": false
}
}
}
}
Ошибки
GAME_CURRENCY_SCOPE_UNAVAILABLE- серверный контекст игрока недоступен.GAME_CURRENCY_UNAVAILABLE- временно невозможно получить каталог.
Подготовка покупки
prepareGameCurrencyPurchase
Описание
Создаёт расчёт для выбранного предложения и получателя с ценой, скидками, количеством и сроком действия. Операция не списывает и не резервирует средства.
Входные данные
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
input.requestId | ID! | да | Новый UUIDv7 для попытки подготовки. Повтор с теми же данными идемпотентен |
input.offerId | ID! | да | Идентификатор предложения из gameCurrencyOffers |
input.quantity | Int! | да | Число пакетов от 1 до 1 000 000 |
input.accountName | String! | да | Логин принадлежащего игроку игрового аккаунта |
input.characterName | String | нет | Персонаж для CHARACTER_ITEM; для ACCOUNT_POINTS поле не передаётся |
Для доставки персонажу characterName обязателен. Для доставки на игровой аккаунт он должен отсутствовать.
Результат
GameCurrencyQuote (в тексте - «расчёт покупки») содержит зафиксированные до истечения срока данные:
| Поле | Тип | Описание |
|---|---|---|
id | ID! | Идентификатор расчёта |
offer | GameCurrencyOffer! | Снимок предложения |
quantity | Int! | Число пакетов |
deliveredUnits | Int! | Итоговое количество игровых единиц |
unitAmount | GameCurrencyMoney! | Цена одного пакета |
subtotal | GameCurrencyMoney! | Сумма до корректировок |
adjustments | [GameCurrencyPriceAdjustment!]! | Отдельные скидки и надбавки |
total | GameCurrencyMoney! | Итог к оплате |
hasSavings | Boolean! | Есть ли скидка в расчёте |
delivery | GameCurrencyDeliveryTarget! | Проверенный получатель |
expiresAt | DateTime! | Срок действия расчёта |
Суммы содержат атомарные units, код валюты code, точность scale и готовое представление decimal. adjustments.source позволяет отдельно показать скидку каталога, реферальную скидку, VIP или кампанию.
Пример обмена
{
"documentId": "prepareGameCurrencyPurchase",
"variables": {
"input": {
"requestId": "01910000-0000-7000-8000-000000000105",
"offerId": "01910000-0000-7000-8000-000000000101",
"quantity": 2,
"accountName": "account-one"
}
}
}
{
"data": {
"prepareGameCurrencyPurchase": {
"id": "01910000-0000-7000-8000-000000000102",
"offer": {
"id": "01910000-0000-7000-8000-000000000101",
"sku": "adena-pack",
"name": "Набор адены",
"description": "Валюта для игрового аккаунта.",
"shortName": "ADENA",
"iconReference": "/assets/images/currency/adena.webp",
"message": "Валюта будет выдана после оплаты.",
"deliveryType": "ACCOUNT_POINTS",
"unitsPerPurchase": 100,
"unitPrice": {
"units": "250",
"code": "USD",
"scale": 2,
"decimal": "2.50"
}
},
"quantity": 2,
"deliveredUnits": 200,
"unitAmount": {
"units": "250",
"code": "USD",
"scale": 2,
"decimal": "2.50"
},
"subtotal": {
"units": "500",
"code": "USD",
"scale": 2,
"decimal": "5.00"
},
"adjustments": [
{
"code": "vip-20",
"kind": "DISCOUNT",
"source": "VIP",
"amount": {
"units": "100",
"code": "USD",
"scale": 2,
"decimal": "1.00"
}
}
],
"total": {
"units": "400",
"code": "USD",
"scale": 2,
"decimal": "4.00"
},
"hasSavings": true,
"delivery": {
"type": "GAME_ACCOUNT",
"accountName": "account-one",
"characterName": null
},
"expiresAt": "2026-08-31T10:10:00.000000Z"
}
}
}
Ошибки
GAME_CURRENCY_INVALID_REQUEST- нарушен формат запроса или правило количества и получателя.GAME_CURRENCY_ACCOUNT_UNAVAILABLE- аккаунт или персонаж недоступен игроку.GAME_CURRENCY_OFFER_UNAVAILABLE- предложение выключено, удалено или не относится к текущему контексту.GAME_CURRENCY_SCOPE_UNAVAILABLE- невозможно определить допустимый проект, сервер или кошелёк.GAME_CURRENCY_CONFLICT- UUIDv7 уже использован с другими данными.GAME_CURRENCY_UNAVAILABLE- временная ошибка расчёта.
Покупка по расчёту
purchaseGameCurrency
Описание
Создаёт и оплачивает заказ по действующему расчёту. Сумма, скидка и получатель берутся из этого расчёта. Для изменения покупки сначала получите новый расчёт.
Входные данные
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
input.orderRequestId | ID! | да | Новый UUIDv7 для создания заказа |
input.paymentRequestId | ID! | да | Новый UUIDv7 для списания из кошелька |
input.quoteId | ID! | да | Идентификатор расчёта, полученный из подготовки |
orderRequestId и paymentRequestId являются разными ключами идемпотентности. Повтор каждого шага безопасен; повтор с другими данными возвращает конфликт, а не второе списание или вторую выдачу.
Результат
| Поле | Тип | Описание |
|---|---|---|
orderId | ID! | Заказ |
quoteId | ID! | Использованный расчёт |
orderStatus | GameCurrencyOrderStatus! | Состояние заказа |
paymentId | ID | Платёж из кошелька |
paymentStatus | GameCurrencyPaymentStatus! | Состояние списания или компенсации |
total | GameCurrencyMoney! | Зафиксированная сумма заказа |
createdAt | DateTime! | Время создания заказа |
Успешная выдача обычно заканчивается состояниями FULFILLED и PAID. Промежуточные состояния сообщают клиенту состояние обработки; повторно отправлять деньги или создавать заказ вручную не нужно.
Пример обмена
{
"documentId": "purchaseGameCurrency",
"variables": {
"input": {
"orderRequestId": "01910000-0000-7000-8000-000000000108",
"paymentRequestId": "01910000-0000-7000-8000-000000000109",
"quoteId": "01910000-0000-7000-8000-000000000102"
}
}
}
{
"data": {
"purchaseGameCurrency": {
"orderId": "01910000-0000-7000-8000-000000000103",
"quoteId": "01910000-0000-7000-8000-000000000102",
"orderStatus": "FULFILLED",
"paymentId": "01910000-0000-7000-8000-000000000104",
"paymentStatus": "PAID",
"total": {
"units": "400",
"code": "USD",
"scale": 2,
"decimal": "4.00"
},
"createdAt": "2026-08-31T10:01:00.000000Z"
}
}
}
При нулевом итоге покупка подтверждается без оплаты: paymentId равен null, paymentStatus равен NOT_REQUIRED. Заказ проходит состояния CONFIRMED, FULFILLING и FULFILLED; подтверждение ещё не означает завершённую выдачу.
Состояния
GameCurrencyOrderStatus: CONFIRMED, PENDING_PAYMENT, PAID, FULFILLING, FULFILLED, CANCELLED.
GameCurrencyPaymentStatus: NOT_REQUIRED, DEBIT_PENDING, PAID, REVERSAL_PENDING, REVERSED, REQUIRES_REVIEW.
Если расчёт истёк, повторите подготовку и покажите игроку новый результат. При отказе выдачи сервер запускает предусмотренную компенсацию; клиент не выполняет ручной возврат.
Ошибки
GAME_CURRENCY_REFRESH_REQUIRED- расчёт или заказ истёк либо больше не может быть оплачен; нужно повторить подготовку.GAME_CURRENCY_INSUFFICIENT_BALANCE- недостаточно средств в допустимом кошельке игрока.GAME_CURRENCY_PAYMENT_DEBT- погасите задолженность выбранного баланса, затем начните новую покупку.GAME_CURRENCY_CONFLICT- ключ идемпотентности использован с другим набором данных.GAME_CURRENCY_SCOPE_UNAVAILABLE- недоступно назначение баланса текущего проекта и сервера.GAME_CURRENCY_UNAVAILABLE- операция временно недоступна.
Гостевая покупка
Гостевой сценарий состоит из каталога, расчёта покупки, подготовки способов оплаты и запуска выбранного способа. Все операции публичны, но ограничены по частоте. Неизвестный и недоступный персонаж возвращают одинаковый код GAME_CURRENCY_RECIPIENT_UNAVAILABLE.
Каталог для гостя
guestGameCurrencyOffers
Возвращает только активные предложения CHARACTER_ITEM выбранного игрового сервера. Предложения ACCOUNT_POINTS требуют авторизации и в этот результат не входят.
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
gameServerId | Int! | да | Выбранный игровой сервер проекта |
first | Int | нет | Размер страницы от 1 до 100 |
after | ID | нет | Курсор следующей страницы |
{
"documentId": "guestGameCurrencyOffers",
"variables": {
"gameServerId": 1,
"first": 50,
"after": null
}
}
{
"data": {
"guestGameCurrencyOffers": {
"items": [
{
"id": "019c8a00-0000-7000-8000-000000000001",
"sku": "ADENA_250000",
"name": "Адена",
"description": "250 000 Adena для выбранного персонажа.",
"shortName": "Adena",
"iconReference": "/assets/images/currency/adena.webp",
"message": "Валюта будет доставлена после оплаты.",
"deliveryType": "CHARACTER_ITEM",
"unitsPerPurchase": 250000,
"unitPrice": {
"units": "199",
"code": "USD",
"scale": 2,
"decimal": "1.99"
}
}
],
"pageInfo": {
"endCursor": null,
"hasNextPage": false
}
}
}
}
Расчёт для персонажа
prepareGuestGameCurrencyPurchase
Проверяет персонажа и создаёт короткоживущий расчёт. Email относится к плательщику и не используется как получатель игровой валюты.
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
input.gameServerId | Int! | да | Игровой сервер из гостевого каталога |
input.requestId | ID! | да | UUIDv7 расчёта |
input.offerId | ID! | да | Предложение из гостевого каталога |
input.quantity | Int! | да | Число пакетов от 1 до 1 000 000 |
input.characterName | String! | да | Имя персонажа на выбранном сервере |
input.payerEmail | String! | да | Email плательщика |
{
"documentId": "prepareGuestGameCurrencyPurchase",
"variables": {
"input": {
"gameServerId": 1,
"requestId": "019c8a10-0000-7000-8000-000000000001",
"offerId": "019c8a00-0000-7000-8000-000000000001",
"quantity": 10,
"characterName": "Asterion",
}
}
}
{
"data": {
"prepareGuestGameCurrencyPurchase": {
"id": "019c8a10-0000-7000-8000-000000000002",
"offer": {
"id": "019c8a00-0000-7000-8000-000000000001",
"sku": "ADENA_250000",
"name": "Адена",
"description": "250 000 Adena для выбранного персонажа.",
"shortName": "Adena",
"iconReference": "/assets/images/currency/adena.webp",
"message": "Валюта будет доставлена после оплаты.",
"deliveryType": "CHARACTER_ITEM",
"unitsPerPurchase": 250000,
"unitPrice": {
"units": "199",
"code": "USD",
"scale": 2,
"decimal": "1.99"
}
},
"quantity": 10,
"deliveredUnits": 2500000,
"unitAmount": {
"units": "199",
"code": "USD",
"scale": 2,
"decimal": "1.99"
},
"subtotal": {
"units": "1990",
"code": "USD",
"scale": 2,
"decimal": "19.90"
},
"adjustments": [],
"total": {
"units": "1990",
"code": "USD",
"scale": 2,
"decimal": "19.90"
},
"hasSavings": false,
"delivery": {
"type": "CHARACTER",
"accountName": null,
"characterName": "Asterion"
},
"expiresAt": "2026-09-01T10:15:00.000000Z"
}
}
}
Ошибки
GAME_CURRENCY_RECIPIENT_UNAVAILABLE- получатель неизвестен или недоступен.GAME_CURRENCY_OFFER_UNAVAILABLE- предложение не поддерживает гостевую покупку или отключено.GAME_CURRENCY_RATE_LIMITED- превышена допустимая частота; повторите после указанной задержки.GAME_CURRENCY_CONFLICT- UUIDv7 повторно использован с другими данными.
Способы оплаты
prepareGuestGameCurrencyCheckout
Создаёт ожидающий оплаты заказ из действующего расчёта и возвращает подходящие способы с отдельным расчётом платежа для каждого.
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
input.gameServerId | Int! | да | Тот же игровой сервер |
input.orderRequestId | ID! | да | UUIDv7 создания заказа |
input.paymentRequestId | ID! | да | UUIDv7 подготовки оплаты |
input.quoteId | ID! | да | Действующий расчёт покупки |
input.characterName | String! | да | Тот же персонаж |
input.payerEmail | String! | да | Тот же email плательщика |
input.payerCountry | String | нет | Двухбуквенный код страны, если он известен |
{
"documentId": "prepareGuestGameCurrencyCheckout",
"variables": {
"input": {
"gameServerId": 1,
"orderRequestId": "019c8a10-0000-7000-8000-000000000003",
"paymentRequestId": "019c8a10-0000-7000-8000-000000000004",
"quoteId": "019c8a10-0000-7000-8000-000000000002",
"characterName": "Asterion",
"payerCountry": "DE"
}
}
}
{
"data": {
"prepareGuestGameCurrencyCheckout": {
"orderId": "019c8a10-0000-7000-8000-000000000005",
"quoteId": "019c8a10-0000-7000-8000-000000000002",
"orderStatus": "PENDING_PAYMENT",
"intent": {
"id": "019c8a10-0000-7000-8000-000000000006",
"status": "OPEN",
"expiresAt": "2026-09-01T10:20:00.000000Z"
},
"methods": [
{
"id": "019c8a10-0000-7000-8000-000000000007",
"code": "paygol",
"name": "PayGol",
"iconAssetId": "payment-method-paygol",
"paymentQuote": {
"id": "019c8a10-0000-7000-8000-000000000008",
"paymentAmount": {
"units": "1990",
"code": "EUR",
"scale": 2,
"decimal": "19.90"
},
"destinationAmount": {
"units": "1990",
"code": "USD",
"scale": 2,
"decimal": "19.90"
},
"payerFee": {
"units": "0",
"code": "EUR",
"scale": 2,
"decimal": "0.00"
},
"expiresAt": "2026-09-01T10:15:00.000000Z"
}
}
]
}
}
}
Если подходящих способов нет, операция возвращает GAME_CURRENCY_METHODS_UNAVAILABLE и не создаёт попытку оплаты.
Запуск оплаты
startGuestGameCurrencyCheckout
Запускает выбранный способ по его действующему расчёту. Все поля получателя должны совпадать с подготовленным заказом.
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
input.gameServerId | Int! | да | Игровой сервер заказа |
input.requestId | ID! | да | UUIDv7 запуска |
input.orderId | ID! | да | Подготовленный заказ |
input.quoteId | ID! | да | Расчёт покупки заказа |
input.characterName | String! | да | Проверенный персонаж |
input.payerEmail | String! | да | Email плательщика |
input.methodProfileId | ID! | да | methods[].id |
input.paymentQuoteId | ID! | да | methods[].paymentQuote.id |
{
"documentId": "startGuestGameCurrencyCheckout",
"variables": {
"input": {
"gameServerId": 1,
"requestId": "019c8a10-0000-7000-8000-000000000009",
"orderId": "019c8a10-0000-7000-8000-000000000005",
"quoteId": "019c8a10-0000-7000-8000-000000000002",
"characterName": "Asterion",
"methodProfileId": "019c8a10-0000-7000-8000-000000000007",
"paymentQuoteId": "019c8a10-0000-7000-8000-000000000008"
}
}
}
{
"data": {
"startGuestGameCurrencyCheckout": {
"orderId": "019c8a10-0000-7000-8000-000000000005",
"quoteId": "019c8a10-0000-7000-8000-000000000002",
"orderStatus": "PENDING_PAYMENT",
"intent": {
"id": "019c8a10-0000-7000-8000-000000000006",
"status": "PROCESSING",
"expiresAt": "2026-09-01T10:20:00.000000Z"
},
"attempt": {
"id": "019c8a10-0000-7000-8000-000000000010",
"status": "REQUIRES_CUSTOMER_ACTION",
"expiresAt": "2026-09-01T10:15:00.000000Z"
},
"action": {
"kind": "REDIRECT",
"expiresAt": "2026-09-01T10:15:00.000000Z",
"redirect": {
"url": "https://payments.example/checkout/019c8a10"
},
"formPost": null,
"qrCode": null,
"deepLink": null,
"wait": null
}
}
}
}
action.kind определяет единственное действие клиента: REDIRECT, FORM_POST, QR_CODE, DEEP_LINK или WAIT. URL и поля нужно использовать без изменения до action.expiresAt.
Повтор действия оплаты
retryGuestGameCurrencyCheckout
Продолжает тот же заказ после прерванного перехода или временной ошибки. Входные поля совпадают с startGuestGameCurrencyCheckout; для новой попытки используется новый requestId, а заказ, расчёт, получатель и выбранный способ не меняются.
{
"documentId": "retryGuestGameCurrencyCheckout",
"variables": {
"input": {
"gameServerId": 1,
"requestId": "019c8a10-0000-7000-8000-000000000011",
"orderId": "019c8a10-0000-7000-8000-000000000005",
"quoteId": "019c8a10-0000-7000-8000-000000000002",
"characterName": "Asterion",
"methodProfileId": "019c8a10-0000-7000-8000-000000000007",
"paymentQuoteId": "019c8a10-0000-7000-8000-000000000008"
}
}
}
{
"data": {
"retryGuestGameCurrencyCheckout": {
"orderId": "019c8a10-0000-7000-8000-000000000005",
"quoteId": "019c8a10-0000-7000-8000-000000000002",
"orderStatus": "PENDING_PAYMENT",
"intent": {
"id": "019c8a10-0000-7000-8000-000000000006",
"status": "PROCESSING",
"expiresAt": "2026-09-01T10:20:00.000000Z"
},
"attempt": {
"id": "019c8a10-0000-7000-8000-000000000012",
"status": "PENDING_PROVIDER",
"expiresAt": "2026-09-01T10:15:00.000000Z"
},
"action": {
"kind": "WAIT",
"expiresAt": "2026-09-01T10:15:00.000000Z",
"redirect": null,
"formPost": null,
"qrCode": null,
"deepLink": null,
"wait": {
"recommendedPollAfterSeconds": 3
}
}
}
}
}
Повтор с тем же UUIDv7 и теми же данными идемпотентен. Изменённые данные с уже использованным UUIDv7 возвращают GAME_CURRENCY_CONFLICT. Истёкший расчёт или способ оплаты возвращает GAME_CURRENCY_REFRESH_REQUIRED.
Типы и правила доставки
ACCOUNT_POINTSвыдаёт валюту на проверенный игровой аккаунт;characterNameне используется.CHARACTER_ITEMвыдаёт предмет выбранному персонажу. После входа выберите персонажа игрового аккаунта; для гостевой покупки укажите его имя на выбранном сервере.- Все предложения и получатели ограничены текущим проектом и сервером из сессии.
- Повтор запроса с тем же UUIDv7 не создаёт новый заказ, повторное списание или дублирующую выдачу.
Полные структуры GameCurrency* приведены в справочнике схем API. Обзор пополнения баланса находится в разделе Пополнение баланса игрока.
Бесплатная гостевая покупка
confirmFreeGuestGameCurrencyPurchase
Подтверждает выбранную покупку с нулевой итоговой суммой. Вызывайте после явного нажатия Купить, используя действующий расчёт из подготовки гостевой покупки. Получать способы оплаты и запускать платёж для неё не нужно.
Поле input | Тип | Значение |
|---|---|---|
gameServerId | Int! | Выбранный игровой сервер. |
orderRequestId | ID! | UUIDv7 создания заказа. |
confirmationRequestId | ID! | Другой UUIDv7 подтверждения. |
quoteId | ID! | ID действующего расчёта с нулевым итогом. |
characterName | String! | Получатель из расчёта, до 64 символов. |
payerEmail | String! | Email из расчёта, до 254 символов. |
{
"documentId": "confirmFreeGuestGameCurrencyPurchase",
"variables": {
"input": {
"gameServerId": 1,
"orderRequestId": "019bf3dd-b08b-7000-8000-000000000310",
"confirmationRequestId": "019bf3dd-b08b-7000-8000-000000000311",
"quoteId": "019bf3dd-b08b-7000-8000-000000000312",
"characterName": "Asterion",
}
}
}
{
"data": {
"confirmFreeGuestGameCurrencyPurchase": {
"orderId": "019bf3dd-b08b-7000-8000-000000000313",
"quoteId": "019bf3dd-b08b-7000-8000-000000000312",
"orderStatus": "CONFIRMED",
"paymentId": null,
"paymentStatus": "NOT_REQUIRED",
"total": {
"units": "0",
"code": "ELX",
"scale": 3,
"decimal": "0.000"
},
"createdAt": "2026-09-13T10:00:00Z"
}
}
}
При повторе сохраните оба идентификатора и остальные поля без изменений. Если расчёт истёк, подготовьте новый. Результат имеет тип GameCurrencyPurchase; paymentId равен null, а paymentStatus равен NOT_REQUIRED. CONFIRMED означает принятое подтверждение, но ещё не завершённую выдачу.