Поддержка BillingClient SDK прекращается 1 августа 2026 года. После 1 августа 2026 года платежи перестанут обрабатываться для всех покупок, включая подписки.
До этого времени BillingClient SDK продолжает свою работу, но устранение неисправностей, влияющих на работу платежей, может занимать больше времени. Новая функциональность добавляться не будет.
Рекомендуем использовать Pay SDK в проектах.
Для перехода на Pay SDK воспользуйтесь инструкцией по миграции.
SDK Платежи in-app и подписки для Unreal Engine (версия 6.0.0)
RuStore позволяет интегрировать платежи в мобильное приложение.
Если не знаете с чего начать, прочтите инструкцию в сценариях использования.
Подготовка к работе
- Скопируйте содержимое папки
Pluginsиз официального репозитория RuStore на GitFlic в папкуPluginsвнутри своего проекта. - Перезапустите Unreal Engine.
- В списке плагинов (Edit > Plugins > Project > Mobile) отметьте плагины RuStoreBilling и RuStoreCore.
- Подключите модули модули
RuStoreCoreиRuStoreBillingв файлеYourProject.Build.csв спискеPublicDependencyModuleNames. - В настройках проекта (Edit > Project Settings > Android) установите параметр Minimum SDK Version на уровень не ниже 24 и параметр Target SDK Version не ниже 31.
Обработка deeplink
Для корректной работы оплаты через сторонние приложения (СБП, SberPay и др.) необходимо правильно реализовать обработку deeplink. Плагин RuStore Billing автоматически добавит в AndroidManifest.xml дополнительную activity с необходимым intent-filter (см. ниже). Изменить это поведение можно в файле RuStoreBilling_UPL_Android.xml.
<activity android:name="com.Plugins.RuStoreBilling.RuStoreIntentFilterActivity" android:exported="true" android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Set your appscheme -->
<data android:scheme="@string/rustore_app_scheme" />
</intent-filter>
</activity>
Вашему проекту необходимо реализовать наличие строкового ресурса @string/rustore_app_scheme.
@string/rustore_app_scheme — схема вашего deeplink. Эта схема должна совпадать со схемой deeplink, указываемой при инициализации библиотеки billing-клиента.
Инициализация
Перед вызовом методов библиотеки необходимо выполнить ее инициализацию.
FURuStoreBillingClientConfig config;
config.consoleApplicationId = "123456";
config.deeplinkScheme = "yourscheme";
config.allowNativeErrorHandling = false;
config.enableLogs = false;
URuStoreBillingClient::Instance()->Init(config);
Все операции с клиентом также доступны из Blueprints. Ниже представлен пример инициализации.
-
consoleApplicationId— идентификатор приложения из RuStore консоли.
Где в RuStore Консоль отображаются идентификаторы приложений?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Скопируйте идентификатор из URL-адреса страницы приложения — это набор цифр между
apps/и/versions. Например, для URL-адресаhttps://console.rustore.ru/apps/123456/versionsID приложения —123456.

-
deeplinkSheme— URL-адрес для использования deeplink. В качестве названия может быть использовано любое уникальное имя (пример:yourappscheme). -
allowNativeErrorHandling— разрешить обработку ошибок в нативном SDK (см. подробнее в разделе Обработка ошибок). -
enableLogs— включить ведение журнала событий.
Вызов Init() привязывает объект к корню сцены, и если дальнейшая работа с объектом больше не планируется, для освобождения памяти необходимо выполнить метод Dispose().
Деинициализация
URuStoreBillingClient::Instance()->Dispose();
Проверка инициализации
Если вам нужно проверить факт инициализации библиотеки, используйте метод GetIsInitialized(). Метод вернет true, если библиотека инициализирована, и false, если Init еще не был вызван.
bool isInitialized = URuStoreBillingClient::Instance()->GetIsIninialized();
Как работают платежи
Проверка доступности работы с платежами
Во время проверки доступности платежей проверяются следующие условия.
- На устройстве пользователя установлена актуальная версия RuStore.
- Приложение RuStore поддерживает функциональность платежей.
- Пользователь авторизован в RuStore.
Пользователь и приложение не должны быть заблокированы в RuStore.
.Для приложения включена возможность покупок в RuStore Консоли.
.
Метод устарел и не реком ендуется к использованию.
Для проверки доступности платежей используйте метод
CheckPurchasesAvailability.
Каждый асинхронный запрос получает уникальный в рамках одного запуска приложения requestId. Каждое событие возвращает requestId запроса, породившего это событие.
long requestId = URuStoreBillingClient::Instance()->CheckPurchasesAvailability(
[]( long requestId, TSharedPtr<FURuStoreFeatureAvailabilityResult, ESPMode::ThreadSafe> response) {
// Process response
},
[]( long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);
Уведомление обратного вызова (callback) Success возвращает структуру FURuStoreFeatureAvailabilityResult в параметре Response (см. ниже).
USTRUCT(BlueprintType)
struct RUSTORECORE_API FURuStoreFeatureAvailabilityResult
{
GENERATED_USTRUCT_BODY()
FURuStoreFeatureAvailabilityResult()
{
isAvailable = false;
}
UPROPERTY(BlueprintReadWrite)
bool isAvailable;
UPROPERTY(BlueprintReadWrite)
FURuStoreError cause;
};
-
isAvailable— выполнение условий выполнения платежей (true/false). -
cause— информация об ошибке.
Все возможные ошибки cause описаны в разделе Обработка ошибок. Прочие ошибки возвращаются в Failure.
Уведомление обратного вызова (callback) Failure возвращает структуру FURuStoreError с информацией об ошибке в параметре Error. Структура ошибки FURuStoreError описана в разделе Обработка ошибок.
Методы SDK
Получение списка продуктов
Вы проверили, что платежи доступны и пользователи могут совершать покупки. Теперь можно получить список продуктов. Используйте метод GetProducts(), чтобы получить информацию о продуктах, добавленных в ваше приложение через RuStore Консоль.
long requestId = URuStoreBillingClient::Instance()->GetProducts(
productsId,
[]( long requestId, TSharedPtr<FURuStoreProductsResponse, ESPMode::ThreadSafe> response) {
// Process response
},
[]( long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);
TArray<FString> productIds — список идентификаторов продуктов. В нем не должно быть более 100 позиций.
Чтобы указать id продуктов, которые нужны для работы метода, выполните следующие действия.
- Откройте RuStore Консоль.
- Перейдите на вкладку Приложения.
- Выберите нужное приложение.
- В левом боковом меню выберите раздел Монетизация.
- Выберите тип товара: Подписки или Разовые покупки.
- Скопируйте идентификаторы нужных товаров. Это и есть
idпродуктов.

Уведомление обратного вызова (callback) Success возвращает структуру FURuStoreProductsResponse в параметре Response (см. ниже).
Ответ GetProducts
USTRUCT(BlueprintType)
struct FURuStoreProductsResponse
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
TArray<FURuStoreProduct> products;
};
products — список продуктов
Структура продукта
USTRUCT(BlueprintType)
struct FURuStoreProduct
{
GENERATED_USTRUCT_BODY()
FURuStoreProduct()
{
productId = "";
productType = EURuStoreProductType::NON_CONSUMABLE;
productStatus = EURuStoreProductStatus::INACTIVE;
priceLabel = "";
price = 0;
currency = "";
language = "";
title = "";
description = "";
imageUrl = "";
promoImageUrl = "";
}
UPROPERTY(BlueprintReadOnly)
FString productId;
UPROPERTY(BlueprintReadOnly)
EURuStoreProductType productType;
UPROPERTY(BlueprintReadOnly)
EURuStoreProductStatus productStatus;
UPROPERTY(BlueprintReadOnly)
FString priceLabel;
UPROPERTY(BlueprintReadOnly)
int price;
UPROPERTY(BlueprintReadOnly)
FString currency;
UPROPERTY(BlueprintReadOnly)
FString language;
UPROPERTY(BlueprintReadOnly)
FString title;
UPROPERTY(BlueprintReadOnly)
FString description;
UPROPERTY(BlueprintReadOnly)
FString imageUrl;
UPROPERTY(BlueprintReadOnly)
FString promoImageUrl;
UPROPERTY(BlueprintReadOnly)
FURuStoreProductSubscription subscription;
};
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).productType— тип продукта (потребляемый / непотребляемый / подписка):CONSUMABLE/NON-CONSUMABE/SUBSCRIPTION.productStatus— статус продукта.priceLable— отформатированная цена товара, включая валютный знак на языкеlanguage.price— цена в минимальных единицах (в копейках).currency— код валюты ISO 4217.language— язык, указанный с помощью BCP 47 кодирования.title— название продукта на языкеlanguage.description— описание на языкеlanguage.imageUrl— ссылка на картинку.promoImageUrl— ссылка на промокартинку.subscription— описание подписки, возвращается только для продуктов с типомsubscription.
Тип продукта
UENUM(BlueprintType)
enum class EURuStoreProductType : uint8
{
NON_CONSUMABLE UMETA(DisplayName = "NON_CONSUMABLE"),
CONSUMABLE UMETA(DisplayName = "CONSUMABLE"),
SUBSCRIPTION UMETA(DisplayName = "SUBSCRIPTION")
};
Статус продукта
UENUM(BlueprintType)
enum class EURuStoreProductStatus : uint8
{
ACTIVE UMETA(DisplayName = "ACTIVE"),
INACTIVE UMETA(DisplayName = "INACTIVE")
};
Структура подписки
USTRUCT(BlueprintType)
struct FURuStoreProductSubscription
{
GENERATED_USTRUCT_BODY()
FURuStoreProductSubscription()
{
introductoryPrice = "";
introductoryPriceAmount = "";
}
UPROPERTY(BlueprintReadOnly)
FURuStoreSubscriptionPeriod subscriptionPeriod;
UPROPERTY(BlueprintReadOnly)
FURuStoreSubscriptionPeriod freeTrialPeriod;
UPROPERTY(BlueprintReadOnly)
FURuStoreSubscriptionPeriod gracePeriod;
UPROPERTY(BlueprintReadOnly)
FString introductoryPrice;
UPROPERTY(BlueprintReadOnly)
FString introductoryPriceAmount;
UPROPERTY(BlueprintReadOnly)
FURuStoreSubscriptionPeriod introductoryPricePeriod;
};
subscriptionPeriod— период подписки.freeTrialPeriod— пробный период подписки.gracePeriod— льготный период подписки.introductoryPrice— отформатированная вступительная цена подписки, включая знак валюты, на языкеproduct:language.introductoryPriceAmount— вступительная цена в минимальных единицах валюты (в копейках).introductoryPricePeriod— расчетный период вступительной цены.
Структура для сроков периода подписки
USTRUCT(BlueprintType)
struct FURuStoreSubscriptionPeriod
{
GENERATED_USTRUCT_BODY()
FURuStoreSubscriptionPeriod()
{
years = 1970;
months = 1;
days = 1;
}
UPROPERTY(BlueprintReadOnly)
int years;
UPROPERTY(BlueprintReadOnly)
int months;
UPROPERTY(BlueprintReadOnly)
int days;
};
years— количество лет.months— количество месяцев.days— количество дней.
Уведомление обратного вызова (callback) Failure возвращает структуру FURuStoreError с информацией об ошибке в параметре Error.
Структура ошибки FURuStoreError описана в разделе Обработка ошибок.
Покупка продукта
Для вызова покупки продукта используйте метод PurchaseProduct().
Вызов метода покупки продукта
long requestId = URuStoreBillingClient::Instance()->PurchaseProduct(
productId,
orderId,
quantity,
developerPayload,
[]( long requestId, TShardPtr<FURuStorePaymentResult, ESPMode::ThreadSafe> response) {
// Process response
},
[]( long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).orderId: String— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых товаров.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации.
Уведомление обратного вызова (callback) Success возвращает умный потокобезопасный (ESPMode::ThreadSafe) указатель на объект наследника структуры FURuStorePaymentResult в параметре Response.
Тип объекта наследника можно получить используя метод GetTypeName(). Приведение типа можно выполнить через StaticCastSharedPtr<>.
// TShardPtr<FURuStorePaymentResult, ESPMode::ThreadSafe> response
FString typeName = response->GetTypeName();
if (typeName == "FURuStoreSuccess")
{
auto success = *StaticCastSharedPtr<FURuStoreSuccess>(response);
}
Возможные значения типов:
FURuStoreSuccess— результат успешного завершения покупки цифрового товара.FURuStoreFailure— при отправке запроса на оплату или получения статуса оплаты возникла проблема, невозможно установить статус покупки.FURuStoreCancelled— запрос на покупку отправлен, при этом пользователь закрыл «платежную шторку» на своем устройстве, и результат оплаты неизвестен.FURuStoreInvalidPaymentState— ошибка работы SDK платежей. Может возникнуть, в случае некорректного обратного deeplink.
В blueprint-реализаци уведомление обратного вызова (callback) Success возвращает объект наследника класса URuStorePaymentResultClass в параметре Response. Приведение к типу наследника можно выполнить через каскад вызовов Cast To.
Структура результата покупки
UCLASS(BlueprintType)
class RUSTOREBILLING_API URuStorePaymentResultClass : public UObject
{
GENERATED_BODY()
};
USTRUCT(BlueprintType)
struct RUSTOREBILLING_API FURuStorePaymentResult
{
GENERATED_USTRUCT_BODY()
virtual ~FURuStorePaymentResult() {}
virtual FString GetTypeName() { return "FURuStorePaymentResult"; }
};
Структура результата покупки Success
UCLASS(BlueprintType)
class RUSTOREBILLING_API URuStoreSuccess : public URuStorePaymentResultClass
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
FURuStoreSuccess value;
};
USTRUCT(BlueprintType)
struct RUSTOREBILLING_API FURuStoreSuccess : public FURuStorePaymentResult
{
GENERATED_USTRUCT_BODY()
FURuStoreSuccess()
{
orderId = "";
purchaseId = "";
productId = "";
invoiceId = "";
subscriptionToken = "";
sandbox = false;
}
UPROPERTY(BlueprintReadOnly)
FString orderId;
UPROPERTY(BlueprintReadOnly)
FString purchaseId;
UPROPERTY(BlueprintReadOnly)
FString productId;
UPROPERTY(BlueprintReadOnly)
FString invoiceId;
UPROPERTY(BlueprintReadOnly)
FString subscriptionToken;
UPROPERTY(BlueprintReadOnly)
bool sandbox;
virtual FString GetTypeName() override { return "FURuStoreSuccess"; }
};
Структура результата покупки Cancelled
UCLASS(BlueprintType)
class RUSTOREBILLING_API URuStoreCancelled : public URuStorePaymentResultClass
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
FURuStoreCancelled value;
};
USTRUCT(BlueprintType)
struct RUSTOREBILLING_API FURuStoreCancelled : public FURuStorePaymentResult
{
GENERATED_USTRUCT_BODY()
FURuStoreCancelled()
{
purchaseId = "";
sandbox = false;
}
UPROPERTY(BlueprintReadOnly)
FString purchaseId;
UPROPERTY(BlueprintReadOnly)
bool sandbox;
virtual FString GetTypeName() override { return "FURuStoreCancelled"; }
};
Структура результата покупки Failure
UCLASS(BlueprintType)
class RUSTOREBILLING_API URuStoreFailure : public URuStorePaymentResultClass
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
FURuStoreFailure value;
};
USTRUCT(BlueprintType)
struct RUSTOREBILLING_API FURuStoreFailure : public FURuStorePaymentResult
{
GENERATED_USTRUCT_BODY()
public:
FURuStoreFailure()
{
purchaseId = "";
invoiceId = "";
orderId = "";
quantity = 0;
productId = "";
errorCode = 0;
sandbox = false;
}
UPROPERTY(BlueprintReadOnly)
FString purchaseId;
UPROPERTY(BlueprintReadOnly)
FString invoiceId;
UPROPERTY(BlueprintReadOnly)
FString orderId;
UPROPERTY(BlueprintReadOnly)
int quantity;
UPROPERTY(BlueprintReadOnly)
FString productId;
UPROPERTY(BlueprintReadOnly)
int errorCode;
UPROPERTY(BlueprintReadOnly)
bool sandbox;
virtual FString GetTypeName() override { return "FURuStoreFailure"; }
};
Параметр sandbox определяет, является ли платеж тестовым. Значения могут быть true или false,
где true обозначает тестовый платеж, а false – реальный.
Структура результата покупки InvalidPaymentState
UCLASS(BlueprintType)
class RUSTOREBILLING_API URuStoreInvalidPaymentState : public URuStorePaymentResultBase
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly)
FURuStoreInvalidPaymentState value;
};
USTRUCT(BlueprintType)
struct RUSTOREBILLING_API FURuStoreInvalidPaymentState : public FURuStorePaymentResult
{
GENERATED_USTRUCT_BODY()
virtual FString GetTypeName() override { return "FURuStoreInvalidPaymentState"; }
};
Уведомление обратного вызова (callback) Failure возвращает структуру FURuStoreError с информацией об ошибке в параметре Error. Структура ошибки FURuStoreError описана в разделе Обработка ошибок.
Получение списка покупок
Метод возвращает только покупки со статусами из таблицы ниже. Подробнее о других возможных состояниях покупки смотрите в разделе Получение сведений о покупке.
| Тип/Статус | INVOICE_CREATED | CONFIRMED | PAID |
|---|---|---|---|
CONSUMABLE | + | + | |
NON-CONSUMABLE | + | + | |
SUBSCRIPTION | + | + |
Метод возвращает незавершенные состояния покупки и покупки потребляемых товаров, требующих обработки. Помимо этого, он показывает подтвержденные покупки для подписок и непотребляемых товаров — тех, которые нельзя купить повторно.
Для получения списка покупок пользователя используйте метод GetPurchases().
long requestId = URuStoreBillingClient::Instance()->GetPurchases(
[]( long requestId, TSharedPtr<FURuStorePurchasesResponse, ESPMode::ThreadSafe> response) {
// Process response
},
[]( long requestId, TSharedPtr<FURuStoreRuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);
Уведомление обратного вызова (callback) Success возвращает структуру FURuStorePurchasesResponse в параметре Response (см. ниже).
Ответ GetPurchases
USTRUCT(BlueprintType)
struct FURuStorePurchasesResponse: public FURuStoreResponseWithCode
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
TArray<FURuStorePurchase> purchases;
};
purchases — список запрошенных покупок
Структура покупки
USTRUCT(BlueprintType)
struct FURuStorePurchase
{
GENERATED_USTRUCT_BODY()
FURuStorePurchase()
{
purchaseId = "";
productId = "";
invoiceId = "";
language = "";
purchaseTime = FDateTime(0);
orderId = "";
amountLabel = "";
amount = 0;
currency = "";
quantity = 0;
purchaseState = EURuStorePurchaseState::CANCELLED;
developerPayload = "";
subscriptionToken = "";
}
UPROPERTY(BlueprintReadOnly)
FString purchaseId;
UPROPERTY(BlueprintReadOnly)
FString productId;
UPROPERTY(BlueprintReadOnly)
FString invoiceId;
UPROPERTY(BlueprintReadOnly)
FString language;
UPROPERTY(BlueprintReadOnly)
FDateTime purchaseTime;
UPROPERTY(BlueprintReadOnly)
FString purchaseTimeLabel;
UPROPERTY(BlueprintReadOnly)
FString orderId;
UPROPERTY(BlueprintReadOnly)
FString amountLabel;
UPROPERTY(BlueprintReadOnly)
int amount;
UPROPERTY(BlueprintReadOnly)
FString currency;
UPROPERTY(BlueprintReadOnly)
int quantity;
UPROPERTY(BlueprintReadOnly)
EURuStorePurchaseState purchaseState;
UPROPERTY(BlueprintReadOnly)
FString developerPayload;
UPROPERTY(BlueprintReadOnly)
FString subscriptionToken;
};
Состояние покупки
UENUM(BlueprintType)
enum class EURuStorePurchaseState : uint8
{
CREATED UMETA(DisplayName = "CREATED"),
INVOICE_CREATED UMETA(DisplayName = "INVOICE_CREATED"),
CONFIRMED UMETA(DisplayName = "CONFIRMED"),
PAID UMETA(DisplayName = "PAID UMETA"),
CANCELLED UMETA(DisplayName = "CANCELLED"),
CONSUMED UMETA(DisplayName = "CONSUMED"),
PAUSED UMETA(DisplayName = "PAUSED"),
CLOSED UMETA(DisplayName = "CLOSED")
};
-
purchaseId— идентификатор покупки. -
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр). -
invoiceId— идентификатор счета. -
language— язык, указанный с помощью BCP 47 кодирования. -
purchaseTime— время покупки. -
orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов. -
amountLable— отформатированная цена покупки, включая валютный знак. -
amount— цена в минимальных единицах валюты. -
currency— код валюты ISO 4217. -
quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых товаров. -
purchaseState— состояние покупки:CREATED— покупка создана;INVOICE_CREATED— создан счет на оплату, покупка ожидает оплаты;PAID— только для покупки потребляемого товара — промежуточный статус, средства на счете покупателя зарезервированы. Покупка ожидает подтверждения от разработчика;CONFIRMED— платеж за непотребляемый товар успешно совершен;CONSUMED— платеж за потребляемый товар успешно совершен;CANCELLED— покупка отменена — оплата не была произведена или был совершен возврат средств покупателю (для подписок после возврата средств покупка не переходит вCANCELLED);PAUSED— для подписок — подписка перешла в HOLD период;TERMINATED— подписка закрылась.
-
developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. -
subscriptionToken— токен для валидации покупки на сервере.
Обратный вызов (callback) Failure возвращает структуру FURuStoreError с информацией об ошибке в параметре Error.
Структура ошибки FURuStoreError описана в разделе Обработка ошибок.
Получение сведений о покупке
Для получения информации о покупке, используйте методGetPurchaseInfo.
long requestId = URuStoreBillingClient::Instance()->GetPurchaseInfo(
purchaseId,
[]( long requestId, TSharedPtr<FURuStorePurchaseInfoResponse, ESPMode::ThreadSafe> response) {
// Process response
},
[]( long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);
purchaseId — идентификатор покупки
Уведомление обратного вызова (callback) Success возвращает структуру FURuStorePurchase в параметре Response.
Уведомление обратного вызова (callback) Failure возвращает структуру FURuStoreError с информацией об ошибке. Структура ошибки FURuStoreError описана в разделе Обработка ошибок.
Статусная модель (purchaseState)
Статусная модель покупки потребляемых продуктов (CONSUMABLES)
Статусная модель покупки непотребляемых продуктов (NON-CONSUMABLES)
Статусная модель покупки подписок (SUBSCRIPTIONS)
Подтверждение (потребление) покупки
Продукты, требующие подтверждения (потребления)
Учитывайте тип покупки. Метод подтверждения (потребления) необходим, только если у вас потребляемый товар (CONSUMABLE), который можно купить много раз.
Чтобы такие товары начислились пользователям без ошибок, подтвердите подтверждение (потребление) продукта с помощью метода confirmPurchase.
При начислении товара в вашем приложении используйте серверную валидацию платежей. Начисляйте товар только когда платеж (счет) перейдет в финальный статус CONFIRMED.
Начисление продуктов пользователям надо делать в callback addOnSuccessListener метода confirmPurchase.
Статус PAID является промежуточным и означает, что средства пользователя захолдированы на карте и вам нужно подтвердить покупку.
Исключение — платежи через СБП или со счета телефона: при этих способах оплаты используется одностадийный платеж, но модель счета остается двухстадийной. Подробнее см. пояснения ниже.
При оплате потребляемых (CONSUMABLE) товаров через СБП или со счета телефона используется одностадийный платеж, при этом модель счета остается двухстадийной. Это значит, что при переходе счета в статус PAID при оплате через СБП или со счета мобильного телефона деньги уже списаны со счета покупателя, а с разработчика удержана комиссия. В этом случае при отмене покупки в состоянии PAID происходит возврат средств (refund), а не отмена холдирования — reverse. Удержанная комиссия разработчику не возвращается. При этом для завершения покупки все равно нужно выполнить метод подтверждения (потребления) — см. также таблицу ниже.
| Платежный метод | Тип платежа | Платеж в статусе PAID |
|---|---|---|
| Двухстадийный |
|
| Одностадийный |
|
Вызов метода подтверждения (потребления)
Для подтверждения (потребления) покупки используйте методConfirmPurchase. Запрос на подтверждение (потребление) покупки должен сопровождаться выдачей товара. После вызова подтверждения покупка перейдет в статус CONSUMED.
long requestId = RuStoreBillingClient::Instance()->ConfirmPurchase(
purchaseId,
[]( long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
},
[]( long requestId, TSharedPtr<FURuStoreConfirmPurchaseResponse, ESPMode::ThreadSafe> response) {
// Process response
}
);
purchaseId— идентификатор покупки.