6.1.0 (Beta)
RuStore позволяет интегрировать платежи в мобильное приложение.
Если не знаете с чего начать, прочтите инструкцию в сценариях использования.
Пример реализации
Ознакомьтесь с приложением-примером чтобы узнать, как правильно интегрировать SDK платежей.
Условия работы платежей
- Для приложения включена возможность покупок в RuStore Консоли.
- Приложение не должно быть заблокировано в RuStore.
- На устройстве пользователя установлена актуальная версия RuStore.
- Пользователь авторизован в RuStore.
- Пользователь не должен быть заблокирован в RuStore.
Подготовка к работе
- Скопируйте проекты плагина и приложения-примера из официального репозитория RuStore на GitFlic.
- Скопируйте содержимое папки
unreal_example/Plugins
в папкуPlugins
внутри своего проекта. Перезапустите Unreal Engine. - В списке плагинов (Edit > Plugins > Mobile) отметьте плагины RuStorePay и RuStoreCore.
- В файле
YourProject.Build.cs
в спискеPublicDependencyModuleNames
подключите модулиRuStoreCore
иRuStorePay
. - В настройках проекта (Edit > Project Settings > Android) установите параметры:
- Minimum SDK Version — не ниже 24;
- Target SDK Version — не ниже 31.
Настройка Unreal Engine
Для версий Unreal Engine младше 5.4 должно быть выполнено обновление gradle и gradle-wrapper.
- Перейдите в корневую директорию установки Unreal Engine (например:
C:\Program Files\Epic Games\UE_4.26
). - В файле
\Engine\Build\Android\Java\gradle\build.gradle
задайте версию пакетаcom.android.tools.build:gradle
не ниже4.2.2
. - В файле
\Engine\Build\Android\Java\gradle\gradle\wrapper\gradle-wrapper.properties
задайте версию пакетаgradle
не ниже7.5-all
.
buildscript {
repositories {
google()
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
apply from: 'buildscriptAdditions.gradle', to: buildscript
}
apply from: 'baseBuildAdditions.gradle'
allprojects {
repositories {
google()
mavenCentral()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
Инициализация
Перед вызовом методов библиотеки необходимо выполнить её инициализацию.
URuStorePayClient::Instance()->Init();
Для работы SDK в вашем AndroidManifest.xml
плагин RuStorePay через файл RuStorePay_UPL_Android.xml
добавит в манифест приложения данные console_app_id_key
и internal_config_key
. Оба значения располагаются внутри тэга <application>
.
<application>
...
<meta-data android:name="console_app_id_key" android:value="@string/rustore_PayClientSettings_consoleApplicationId" />
<meta-data android:name="internal_config_key" android:value="unreal" />
</application>
internal_config_key
– всегда имеет значениеunreal
.-
console_app_id_key
— идентификатор приложения из консоли RuStore.
Где в RuStore Консоль отображаются идентификаторы приложений?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Скопируйте идентификатор из URL-адреса страницы приложения — это набор цифр между
apps/
и/versions
. Например, для URL-адресаhttps://console.rustore.ru/apps/123456/versions
ID приложения —123456
.
Package Name приложения, указанный в Edit ➝ Project Settings... ➝ Player ➝ Android ➝ Other Settings ➝ Package Name, должен совпадать с Package Name APK-файла, который вы публиковали в системе RuStore Консоль.
Подпись keystore
должна совпадать с подписью, которой было подписано приложение, опубликованное в системе RuStore Консоль. Убедитесь, что используемый buildType
(пр. debug
) использует такую же подпись, что и опубликованное приложение (пр. release
).
Значение console_app_id_key
должно быть задано в файле ресурсов, например: rustore_pay_values.xml
.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rustore_PayClientSettings_consoleApplicationId">198332</string>
</resources>
Файл ресурсов может быть вкл ючен в проект через UPL-файл вашего проекта, в следующем примере копирование файла rustore_pay_values.xml
будет выполняться из директории Source/YOUUR_PROJECT_NAME
.
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:android="http://schemas.android.com/apk/res/android">
<resourceCopies>
<copyFile src="$S(PluginDir)/rustore_pay_values.xml" dst="$S(BuildDir)/res/values/rustore_pay_values.xml" />
</resourceCopies>
</root>
Не задавайте значения console_app_id_key
и internal_config_key
напрямую в манифесте. Строки должны располагаться в файле ресурсов.
Деинициализация
Вызов метода Init
для URuStorePayClient
привязывает объекты к корню сцены. Если дальнейшая работа с объектами больше не планируется, для освобождения памяти необходимо выполнить метод Dispose
. Вызов Dispose
отвяжет объект от корня и безопасно завершит все отправленные запросы.
bool isInitialized = URuStorePayClient::Instance()->Dispose();
Проверка инициализации
Если вам нужно проверить факт инициализации библиотеки, используйте метод GetIsInitialized
. Метод вернет true
, если библиотека инициализирована, и false
, если Init
еще не был вызван.
bool isInitialized = URuStorePayClient::Instance()->GetIsIninialized();
Работа с SDK
Проверка доступности работы с платежами
Для проверки доступности платежей, вызовите метод GetPurchaseAvailability
. При его вызове проверяются следующие условия.
- На устройстве пользователя установлена актуальная версия RuStore.
- Приложение RuStore поддерживает функциональность платежей.
- Пользователь авторизован в RuStore.
- Пользователь и приложение не должны быть заблокированы в RuStore.
- Для приложения включена возможность покупок в RuStore Консоли.
PurchaseAvailabilityResult.Available
.
В противном случае возвращается PurchaseAvailabilityResult.Unavailable(val cause: Throwable)
, где cause
— это ошибка о невыполне нном условии. Для проверки причины возвращения такого результата нужно проверить тип ошибки на RuStoreException
(данные ошибки описаны в разделе Обработка ошибок).
long requestId = URuStorePayClient::Instance()->GetPurchaseAvailability(
[](long requestId, TSharedPtr<FURuStorePayPurchaseAvailabilityResult, ESPMode::ThreadSafe> response) {
// Process response
},
[](long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);
Проверка установки приложения RuStore
Чтобы проверить установлен ли на устройстве пользователя RuStore необходимо вызвать метод IsRuStoreInstalled
.
bool bIsRuStoreInstalled = URuStorePayClient::Instance()->IsRuStoreInstalled();
-
true
– RuStore установлен. -
false
– RuStore не установлен.
Получение списка продуктов
Для получения продуктов, добавленных в ваше приложение через RuStore консоль, необходимо использовать метод GetProducts
.
TArray<URuStorePayProductId*> productIds;
long requestId = URuStorePushClient::Instance()->GetProducts(
productsId,
[](long requestId, TSharedPtr<TArray<FURuStorePayProduct>, ESPMode::ThreadSafe> response) {
// Process response
},
[](long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);
TArray<URuStorePayProductId*> productIds
— список идентификаторов продуктов (задаются при создании продукта в консоли разработчика). Список продуктов имеет ограничение в размере 1000 элементов.
Где в RuStore Консоль отображаются идентификаторы продуктов?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Выберите Монетизация в меню слева.
- Выберите тип товара: Подписки или Разовые покупки.
- Скопируйте идентификаторы нужных товаров.
Метод возвращает список продуктов. Ниже представлена модель продукта.
USTRUCT(BlueprintType)
struct FURuStorePayProduct
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
URuStorePayProductId* productId;
UPROPERTY(BlueprintReadOnly)
EURuStorePayProductType type;
UPROPERTY(BlueprintReadOnly)
URuStorePayAmountLabel* amountLabel;
UPROPERTY(BlueprintReadOnly)
URuStorePayPrice* price; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayCurrency* currency;
UPROPERTY(BlueprintReadOnly)
URuStorePayUrl* imageUrl; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayTitle* title;
UPROPERTY(BlueprintReadOnly)
URuStorePayDescription* description; // nullable
FURuStorePayProduct()
{
productId = NewObject<URuStorePayProductId>();
type = static_cast<EURuStorePayProductType>(0);
amountLabel = NewObject<URuStorePayAmountLabel>();
price = nullptr;
currency = NewObject<URuStorePayCurrency>();
imageUrl = nullptr;
title = NewObject<URuStorePayTitle>();
description = nullptr;
}
};
productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).type
— тип продукта (потребляемый / непотребляемый):CONSUMABLE
/NON-CONSUMABE
.-
amountLabel
— отформатированная цена покупки, включая валютный знак price
— цена в минимальных единицах (в копейках).currency
— код валюты ISO 4217.title
— название продукта на языкеlanguage
.description
— описание на языкеlanguage
.imageUrl
— ссылка на картинку.
Покупка продукта
Для вызова покупки продукта используйте методPurchase
.
URuStorePayProductId* productId = ...
URuStorePayQuantity* quantity = ...
URuStorePayOrderId* orderId = ...
URuStorePayDeveloperPayload* developerPayload = ...
long requestId = URuStorePushClient::Instance()->Purchase(
productId,
quantity,
orderId,
developerPayload,
[](long requestId, TSharedPtr<FURuStorePayProductPurchaseResult, ESPMode::ThreadSafe> response) {
auto type = response->GetTypeName();
if (type.Equals("FURuStorePaySuccessProductPurchaseResult"))
{
auto success = *StaticCastSharedPtr<FURuStorePaySuccessProductPurchaseResult>(response);
// Process success
}
else
if (type.Equals("FURuStorePayCancelledProductPurchaseResult"))
{
auto cancelled = *StaticCastSharedPtr<FURuStorePayCancelledProductPurchaseResult>(response);
// Process cancelled
}
else
if (type.Equals("FURuStorePayFailureProductPurchaseResult"))
{
auto failure = *StaticCastSharedPtr<FURuStorePayFailureProductPurchaseResult>(response);
// Process failure
}
else
{
// Process invalid state
}
},
[](long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);
productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity
— количество продукта (необязательный параметр — если не указывать, будет подставлено значение1
).orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки. Максимальная длина 250 символов.
Структура результата покупки.
USTRUCT(BlueprintType)
struct RUSTOREPAY_API FURuStorePayProductPurchaseResult
{
GENERATED_USTRUCT_BODY()
virtual ~FURuStorePayProductPurchaseResult() {}
virtual FString GetTypeName() { return "FURuStorePayProductPurchaseResult"; }
};
USTRUCT(BlueprintType)
struct RUSTOREPAY_API FURuStorePaySuccessProductPurchaseResult : public FURuStorePayProductPurchaseResult
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
URuStorePayOrderId* orderId; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayPurchaseId* purchaseId;
UPROPERTY(BlueprintReadOnly)
URuStorePayProductId* productId;
UPROPERTY(BlueprintReadOnly)
URuStorePayInvoiceId* invoiceId;
UPROPERTY(BlueprintReadOnly)
URuStorePaySubscriptionToken* subscriptionToken; // nullable
virtual FString GetTypeName() override { return "FURuStorePaySuccessProductPurchaseResult"; }
FURuStorePaySuccessProductPurchaseResult()
{
orderId = nullptr;
purchaseId = NewObject<URuStorePayPurchaseId>(GetTransientPackage());
productId = NewObject<URuStorePayProductId>(GetTransientPackage());
invoiceId = NewObject<URuStorePayInvoiceId>(GetTransientPackage());
subscriptionToken = nullptr;
}
};
USTRUCT(BlueprintType)
struct RUSTOREPAY_API FURuStorePayCancelledProductPurchaseResult : public FURuStorePayProductPurchaseResult
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
URuStorePayPurchaseId* purchaseId; // nullable
virtual FString GetTypeName() override { return "FURuStorePayCancelledProductPurchaseResult"; }
FURuStorePayCancelledProductPurchaseResult()
{
purchaseId = nullptr;
}
};
USTRUCT(BlueprintType)
struct RUSTOREPAY_API FURuStorePayFailureProductPurchaseResult : public FURuStorePayProductPurchaseResult
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
URuStorePayOrderId* orderId;
UPROPERTY(BlueprintReadOnly)
URuStorePayPurchaseId* purchaseId;
UPROPERTY(BlueprintReadOnly)
URuStorePayProductId* productId;
UPROPERTY(BlueprintReadOnly)
URuStorePayInvoiceId* invoiceId;
UPROPERTY(BlueprintReadOnly)
URuStorePayQuantity* quantity;
UPROPERTY(BlueprintReadOnly)
URuStorePaySubscriptionToken* subscriptionToken;
UPROPERTY(BlueprintReadOnly)
FURuStoreError cause;
virtual FString GetTypeName() override { return "FURuStorePayFailureProductPurchaseResult"; }
FURuStorePayFailureProductPurchaseResult()
{
orderId = nullptr;
purchaseId = nullptr;
productId = nullptr;
invoiceId = nullptr;
quantity = nullptr;
subscriptionToken = nullptr;
}
};
FURuStorePaySuccessProductPurchaseResult
— результат успешного завершения покупки цифрового товара.FURuStorePayCancelProductPurchaseResult
— запрос на покупку отправлен, при этом пользователь закрыл «платёжную шторку» на своём устройстве, и результат оплаты неизвестен.FURuStorePayFailureProductPurchaseResult
— при отправке запроса на оплату или получения статуса оплаты возникла проблема, невозможно установить статус покупки.
Получение списка покупок
Для получения списка покупок пользователя используйте метод GetPurchases
.
RuStorePayClient.Instance.GetPurchases(
onFailure: (error) => {
// Process error
},
onSuccess: (result) => {
// Process success
});
Метод возвращает список покупок в статусах CONFIRMED
(для непотребляемых товаров) и PAID
(для потребляемых товаров). Ниже представлена модель покупки.
USTRUCT(BlueprintType)
struct FURuStorePayPurchase
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
URuStorePayPurchaseId* purchaseId;
UPROPERTY(BlueprintReadOnly)
URuStorePayProductId* productId;
UPROPERTY(BlueprintReadOnly)
URuStorePayInvoiceId* invoiceId;
UPROPERTY(BlueprintReadOnly)
URuStorePayOrderId* orderId; // nullable
UPROPERTY(BlueprintReadOnly)
EURuStorePayPurchaseType type;
UPROPERTY(BlueprintReadOnly)
URuStorePayDescription* description;
UPROPERTY(BlueprintReadOnly)
URuStorePayDate* purchaseTime; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayPrice* price;
UPROPERTY(BlueprintReadOnly)
URuStorePayAmountLabel* amountLabel;
UPROPERTY(BlueprintReadOnly)
URuStorePayCurrency* currency;
UPROPERTY(BlueprintReadOnly)
URuStorePayQuantity* quantity;
UPROPERTY(BlueprintReadOnly)
EURuStorePayPurchaseStatus status;
UPROPERTY(BlueprintReadOnly)
URuStorePaySubscriptionToken* subscriptionToken; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayDeveloperPayload* developerPayload; // nullable
FURuStorePayPurchase()
{
purchaseId = NewObject<URuStorePayPurchaseId>(GetTransientPackage());
productId = NewObject<URuStorePayProductId>(GetTransientPackage());
invoiceId = NewObject<URuStorePayInvoiceId>(GetTransientPackage());
orderId = nullptr;
type = static_cast<EURuStorePayPurchaseType>(0);
description = NewObject<URuStorePayDescription>(GetTransientPackage());
purchaseTime = nullptr;
price = NewObject<URuStorePayPrice>();
amountLabel = NewObject<URuStorePayAmountLabel>(GetTransientPackage());
currency = NewObject<URuStorePayCurrency>(GetTransientPackage());
quantity = NewObject<URuStorePayQuantity>(GetTransientPackage());
status = static_cast<EURuStorePayPurchaseStatus>(0);
subscriptionToken = nullptr;
developerPayload = nullptr;
}
};
purchaseId
— идентификатор покупки.productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).invoiceId
— идентификатор счёта.orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.type
— тип покупки:-
APPLICATION
-
NON_CONSUMABLE_PRODUCT
-
CONSUMABLE_PRODUCT
-
SUBSCRIPTION
-
-
description
— описание на языкеlanguage
purchaseTime
— время покупки:-
price
— цена в минимальных единицах (в копейках) amountLable
— отформатированная цена покупки, включая валютный знак.currency
— код валюты ISO 4217.quantity
— количество продукта (необязательный параметр — если не указывать, будет подставлено значение1
).status
— состояние покупки:-
INVOICE_CREATED
— создан счёт на оплату, покупка ожидает оплаты -
CANCELLED
— покупка отменена покупателем -
PROCESSING
— запущена оплата -
REJECTED
— покупка отклонена (например, ввиду недостатка средств) -
PAID
— только для двухстадийной оплаты, промежуточный статус, средства на счёте покупателя захолдированы, покупка ожидает подтверждения от разработчика -
CONFIRMED
— покупка успешно оплачена -
REFUNDED
— запрос на возврат средств за покупку совершён успешно -
REVERSED
— только для двухстадийной оплаты, покупка была отменена разработчиком или не было произведено подтверждение покупки в течение 72 часов, холдирование средств отменено
-
-
developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки -
subscriptionToken
— токен для валидации покупки на сервере
Получение сведений о покупке
Для получения информации о покупке, используйте методGetPurchase
.
URuStorePayPurchaseId* purchaseId = ...
long requestId = URuStorePushClient::Instance()->GetPurchase(
purchaseId,
[](long requestId, TSharedPtr<FURuStorePayPurchase, ESPMode::ThreadSafe> response) {
// Process response
},
[](long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);
Метод возвращает информацию о конкретной покупке в любом статусе. Ниже представлена модель покупки.
USTRUCT(BlueprintType)
struct FURuStorePayPurchase
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
URuStorePayPurchaseId* purchaseId;
UPROPERTY(BlueprintReadOnly)
URuStorePayProductId* productId;
UPROPERTY(BlueprintReadOnly)
URuStorePayInvoiceId* invoiceId;
UPROPERTY(BlueprintReadOnly)
URuStorePayOrderId* orderId; // nullable
UPROPERTY(BlueprintReadOnly)
EURuStorePayPurchaseType type;
UPROPERTY(BlueprintReadOnly)
URuStorePayDescription* description;
UPROPERTY(BlueprintReadOnly)
URuStorePayDate* purchaseTime; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayPrice* price;
UPROPERTY(BlueprintReadOnly)
URuStorePayAmountLabel* amountLabel;
UPROPERTY(BlueprintReadOnly)
URuStorePayCurrency* currency;
UPROPERTY(BlueprintReadOnly)
URuStorePayQuantity* quantity;
UPROPERTY(BlueprintReadOnly)
EURuStorePayPurchaseStatus status;
UPROPERTY(BlueprintReadOnly)
URuStorePaySubscriptionToken* subscriptionToken; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayDeveloperPayload* developerPayload; // nullable
FURuStorePayPurchase()
{
purchaseId = NewObject<URuStorePayPurchaseId>(GetTransientPackage());
productId = NewObject<URuStorePayProductId>(GetTransientPackage());
invoiceId = NewObject<URuStorePayInvoiceId>(GetTransientPackage());
orderId = nullptr;
type = static_cast<EURuStorePayPurchaseType>(0);
description = NewObject<URuStorePayDescription>(GetTransientPackage());
purchaseTime = nullptr;
price = NewObject<URuStorePayPrice>();
amountLabel = NewObject<URuStorePayAmountLabel>(GetTransientPackage());
currency = NewObject<URuStorePayCurrency>(GetTransientPackage());
quantity = NewObject<URuStorePayQuantity>(GetTransientPackage());
status = static_cast<EURuStorePayPurchaseStatus>(0);
subscriptionToken = nullptr;
developerPayload = nullptr;
}
};
purchaseId
— идентификатор покупки.productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).invoiceId
— идентификатор счёта.orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгене рирован автоматически (uuid). Максимальная длина 150 символов.type
— тип покупки:-
APPLICATION
-
NON_CONSUMABLE_PRODUCT
-
CONSUMABLE_PRODUCT
-
SUBSCRIPTION
-
-
description
— описание на языкеlanguage
purchaseTime
— время покупки:-
price
— цена в минимальных единицах (в копейках) amountLable
— отформатированная цена покупки, включая валютный знак.currency
— код валюты ISO 4217.quantity
— количество продукта (необязательный параметр — если не указывать, будет подставлено значение1
).status
— состояние покупки:-
INVOICE_CREATED
— создан счёт на оплату, покупка ожидает оплаты -
CANCELLED
— покупка отменена покупателем -
PROCESSING
— запущена оплата -
REJECTED
— покупка отклонена (например, ввиду недостатка средств) -
PAID
— только для двухстадийной оплаты, промежуточный статус, средства на счёте покупателя захолдированы, покупка ожидает подтверждения от разработчика -
CONFIRMED
— покупка успешно оплачена -
REFUNDED
— запрос на возврат средств за покупку совершён успешно -
REVERSED
— только для двухстадийной оплаты, покупка была отменена разработчиком или не было произведено подтверждение покупки в течение 72 часов, холдирование средств отменено
-
-
developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки -
subscriptionToken
— токен для валидации покупки на сервере
Валидация покупки на сервере
Если вам необходимо произвести валидацию успешной покупки на сервере RuStore, вы можете использовать subscriptionToken
из модели SuccessProductPurchaseResult
, возвращаемой при успешной покупке продукта.
long requestId = URuStorePushClient::Instance()->Purchase(
productId,
quantity,
orderId,
developerPayload,
[](long requestId, TSharedPtr<FURuStorePayProductPurchaseResult, ESPMode::ThreadSafe> response) {
auto type = response->GetTypeName();
if (type.Equals("FURuStorePaySuccessProductPurchaseResult")) {
auto success = *StaticCastSharedPtr<FURuStorePaySuccessProductPurchaseResult>(response);
FString subscriptionToken = success.subscriptionToken->value;
yourApi.validate(subscriptionToken);
}
},
[](long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);
Также можно получить subscriptionToken
в модели Purchase
. Модель Purchase
можно получить используя метод GetPurchases
.
long requestId = URuStorePushClient::Instance()->GetPurchases(
[](long requestId, TSharedPtr<TArray<FURuStorePayPurchase>, ESPMode::ThreadSafe> response) {
for (const auto& item : *response) {
yourApi.validate(item.subscriptionToken);
}
},
[](long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);
Потребление (подтверждение) покупки
RuStore содержит продукты следующих типов:
CONSUMABLE
(потребляемый) — можно купить много раз, например кристаллы в приложении.NON_CONSUMABLE
(непотребляемый) — можно купить один раз, например отключение рекламы в приложении.
Подтверждения требуют только продукты ти па CONSUMABLE
, если они находятся в состоянии PAID
.
ConsumePurchase
. Запрос на потребление (подтверждение) покупки должен сопровождаться выдачей товара. После вызова подтверждения покупка перейдёт в статус CONSUMED
.
PurchaseId id = ...
DeveloperPayload payload = ...
RuStorePayClient.Instance.ConsumePurchase(
purchaseId: id,
developerPayload: payload,
onFailure: (error) => {
// Process error
},
onSuccess: () => {
// Process success
});
purchaseId
— идентификатор покупки.-
developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки
Обработка ошибок
RuStorePaymentNetworkException
— ошибка сетевого взаимодействия SDK;RuStorePaymentCommonException
— общая ошибка SDK;RuStorePayClientAlreadyExist
— ошибка повторной инициализации SDK;RuStorePayClientNotCreated
— попытка обратиться к публичным интерфейсам SDK до момента её инициализации;RuStorePayInvalidActivePurchase
— запущен процесс оплаты неизвестного типа продукта;RuStorePayInvalidConsoleAppId
— не задан обязательный параметрсonsole_application_id
для инициализации SDK;RuStorePaySignatureException
— неверная сигнатура ответа (возникает при попытке совершить мошеннические действия);EmptyPaymentTokenException
— ошибка получения платежного токена;RuStoreNotInstalledException
— на устройстве пользователя не установлен RuStore;RuStoreOutdatedException
— версия RuStore, установленная на устройстве пользователя, не поддерживает данный SDK;RuStoreUserUnauthorizedException
— пользователь не авторизован в RuStore;RuStoreApplicationBannedException
— приложение заблокировано в RuStore;RuStoreUserBannedException
— пользователь заблокирован в RuStore;RuStoreException
— базовая ошибка RuStore, от которой наследуются остальные ошибки.