7.0.0 (Beta)
RuStore позволяет интегрировать платежи в мобильное приложение.
-
Если не знаете с чего начать, прочтите инструкцию в сценариях использования.
-
Если вы переходите на Pay SDK с billingClient SDK, озн акомьтесь с инструкцией по переходу. Подробности о Pay SDK можно узнать тут.
Пример реализации
Ознакомьтесь с приложением-примером чтобы узнать, как правильно интегрировать 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
Инициализация
Перед вызовом методов библиотеки необходимо выполнить её инициализацию. Сама инициализация происходит автоматически, но для работы SDK в вашем файле необходимо прописать
. Значение необходимо указать в строковых ресурсах.
Сделать это можно следующим образом.
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 = URuStorePayClient::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)
URuStorePayAmountLabel* amountLabel;
UPROPERTY(BlueprintReadOnly)
URuStorePayCurrency* currency;
UPROPERTY(BlueprintReadOnly)
URuStorePayDescription* description; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayUrl* imageUrl;
UPROPERTY(BlueprintReadOnly)
URuStorePayPrice* price; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayProductId* productId;
UPROPERTY(BlueprintReadOnly)
URuStorePayTitle* title;
UPROPERTY(BlueprintReadOnly)
EURuStorePayProductType type;
FURuStorePayProduct()
{
amountLabel = NewObject<URuStorePayAmountLabel>();
currency = NewObject<URuStorePayCurrency>();
description = nullptr;
imageUrl = NewObject<URuStorePayUrl>();
price = nullptr;
productId = NewObject<URuStorePayProductId>();
title = NewObject<URuStorePayTitle>();
type = static_cast<EURuStorePayProductType>(0);
}
};
productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).type
— тип продукта.CONSUMABLE/NON-CONSUMABE
(потребляемый/непотребляемый).amountLabel
— отформатированная цена покупки, включая валютный знак.price
— цена в минимальных единицах (в копейках).currency
— код валюты ISO 4217.title
— название продукта на языкеlanguage
.description
— описание на языкеlanguage
.imageUrl
— ссылка на картинку.
Покупка продук та
Одностадийна оплата (без холдирования средств)
Для вызова покупки продукта используйте методPurchaseOneStep
.
FURuStorePayProductPurchaseParams productPurchaseParams;
...
long requestId = URuStorePayClient::Instance()->PurchaseOneStep(
productPurchaseParams,
[](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 символов.
Двустадийна оплата (с холдированием средств)
FURuStorePayProductPurchaseParams productPurchaseParams;
...
long requestId = URuStorePushClient::Instance()->PurchaseTwoStep(
productPurchaseParams,
[](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
}
);

Структура параметров покупки:
USTRUCT(BlueprintType)
struct FURuStorePayProductPurchaseParams
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
URuStorePayProductId* productId;
UPROPERTY(BlueprintReadOnly)
URuStorePayDeveloperPayload* developerPayload; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayOrderId* orderId; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayQuantity* quantity; // nullable
FURuStorePayProductPurchaseParams()
{
productId = NewObject<URuStorePayProductId>();
developerPayload = nullptr;
orderId = nullptr;
quantity = nullptr;
}
};
productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки (опционально).orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов (опционально).quantity
— количество продукта (необязательный параметр — если не указывать, будет использоваться значение1
) (опционально).
Структура результата покупки:
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)
URuStorePayInvoiceId* invoiceId;
UPROPERTY(BlueprintReadOnly)
URuStorePayOrderId* orderId; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayProductId* productId;
UPROPERTY(BlueprintReadOnly)
URuStorePayPurchaseId* purchaseId;
UPROPERTY(BlueprintReadOnly)
URuStorePaySubscriptionToken* subscriptionToken; // nullable
virtual FString GetTypeName() override { return "FURuStorePaySuccessProductPurchaseResult"; }
FURuStorePaySuccessProductPurchaseResult()
{
invoiceId = NewObject<URuStorePayInvoiceId>(GetTransientPackage());
orderId = nullptr;
productId = NewObject<URuStorePayProductId>(GetTransientPackage());
purchaseId = NewObject<URuStorePayPurchaseId>(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)
FURuStoreError cause;
UPROPERTY(BlueprintReadOnly)
URuStorePayInvoiceId* invoiceId;
UPROPERTY(BlueprintReadOnly)
URuStorePayOrderId* orderId;
UPROPERTY(BlueprintReadOnly)
URuStorePayProductId* productId;
UPROPERTY(BlueprintReadOnly)
URuStorePayPurchaseId* purchaseId;
UPROPERTY(BlueprintReadOnly)
URuStorePayQuantity* quantity;
UPROPERTY(BlueprintReadOnly)
URuStorePaySubscriptionToken* subscriptionToken;
virtual FString GetTypeName() override { return "FURuStorePayFailureProductPurchaseResult"; }
FURuStorePayFailureProductPurchaseResult()
{
invoiceId = nullptr;
orderId = nullptr;
productId = nullptr;
purchaseId = nullptr;
quantity = nullptr;
subscriptionToken = nullptr;
}
};
FURuStorePaySuccessProductPurchaseResult
— результат успешного завершения покупки цифрового товара.FURuStorePayCancelProductPurchaseResult
— запрос на покупку отправлен, при этом пользователь закрыл «платёжную шторку» на своём устройстве, и результат оплаты неизвестен.FURuStorePayFailureProductPurchaseResult
— при отправке запроса на оплату или получения статуса оплаты возникла проблема, невозможно установить статус покупки.
Получение списка покупок
Для получения списка покупок пользователя используйте метод GetPurchases
.
long requestId = URuStorePayClient::Instance()->GetPurchases(
[](long requestId, TSharedPtr<TArray<FURuStorePayPurchase>, ESPMode::ThreadSafe> response) {
// Process response
},
[](long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);

Метод возвращает список покупок в статусах CONFIRMED
(для непотребляемых товаров) и PAID
(для потребляемых товаров). Ниже представлена модель покупки.
USTRUCT(BlueprintType)
struct FURuStorePayPurchase
{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
URuStorePayAmountLabel* amountLabel;
UPROPERTY(BlueprintReadOnly)
URuStorePayCurrency* currency;
UPROPERTY(BlueprintReadOnly)
URuStorePayDescription* description;
UPROPERTY(BlueprintReadOnly)
URuStorePayDeveloperPayload* developerPayload; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayInvoiceId* invoiceId;
UPROPERTY(BlueprintReadOnly)
URuStorePayOrderId* orderId; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayPrice* price;
UPROPERTY(BlueprintReadOnly)
URuStorePayProductId* productId;
UPROPERTY(BlueprintReadOnly)
EURuStorePayProductType productType;
UPROPERTY(BlueprintReadOnly)
URuStorePayPurchaseId* purchaseId;
UPROPERTY(BlueprintReadOnly)
URuStorePayDate* purchaseTime; // nullable
UPROPERTY(BlueprintReadOnly)
EURuStorePayPurchaseType purchaseType;
UPROPERTY(BlueprintReadOnly)
URuStorePayQuantity* quantity;
UPROPERTY(BlueprintReadOnly)
EURuStorePayPurchaseStatus status;
UPROPERTY(BlueprintReadOnly)
URuStorePaySubscriptionToken* subscriptionToken; // nullable
FURuStorePayPurchase()
{
amountLabel = NewObject<URuStorePayAmountLabel>(GetTransientPackage());
currency = NewObject<URuStorePayCurrency>(GetTransientPackage());
description = NewObject<URuStorePayDescription>(GetTransientPackage());
developerPayload = nullptr;
invoiceId = NewObject<URuStorePayInvoiceId>(GetTransientPackage());
orderId = nullptr;
price = NewObject<URuStorePayPrice>();
productId = NewObject<URuStorePayProductId>(GetTransientPackage());
productType = static_cast<EURuStorePayProductType>(0);
purchaseId = NewObject<URuStorePayPurchaseId>(GetTransientPackage());
purchaseTime = nullptr;
purchaseType = static_cast<EURuStorePayPurchaseType>(0);
quantity = NewObject<URuStorePayQuantity>(GetTransientPackage());
status = static_cast<EURuStorePayPurchaseStatus>(0);
subscriptionToken = nullptr;
}
};
amountLabel
— отформатированная цена покупки, включая валютный знак.currency
— код валюты ISO 4217.description
— описание на языкеlanguage
.-
developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки invoiceId
— идентификатор счёта.orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.price
— цена в минимальных единицах (в копейках).productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).productType
— тип продукта.
purchaseId
— идентификатор покупки.purchaseTime
— время покупки.PurchaseType
— тип покупки:ONE_PHASE
- одностадийная покупка;TWO_PHASE
- двухстадийная покупка.
quantity
— количество продукта (необязательный параметр — если не указывать, будет использоваться значение1
).status
— состояние покупки:INVOICE_CREATED
— создан счёт на оплату, покупка ожидает оплаты;CANCELLED
— покупка отменена покупателем;PROCESSING
— запущена оплата;REJECTED
— покупка отклонена (например, ввиду недостатка средств);PAID
— только для двухстадийной оплаты, промежуточный статус, средства на счёте покупателя захолдированы, покупка ожидает подтверждения от разработчика;CONFIRMED
— покупка успешно оплачена;REFUNDED
— запрос на возврат средств за покупку совершён успешно;REVERSED
— только для двухстадийной оплаты, покупка была отменена разработчиком или не было произведено подтверждение покупки в течение 72 часов, холдирование средств отменено.
Получение сведений о покупке
Для получения информации о покупке, используйте метод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)
URuStorePayAmountLabel* amountLabel;
UPROPERTY(BlueprintReadOnly)
URuStorePayCurrency* currency;
UPROPERTY(BlueprintReadOnly)
URuStorePayDescription* description;
UPROPERTY(BlueprintReadOnly)
URuStorePayDeveloperPayload* developerPayload; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayInvoiceId* invoiceId;
UPROPERTY(BlueprintReadOnly)
URuStorePayOrderId* orderId; // nullable
UPROPERTY(BlueprintReadOnly)
URuStorePayPrice* price;
UPROPERTY(BlueprintReadOnly)
URuStorePayProductId* productId;
UPROPERTY(BlueprintReadOnly)
EURuStorePayProductType productType;
UPROPERTY(BlueprintReadOnly)
URuStorePayPurchaseId* purchaseId;
UPROPERTY(BlueprintReadOnly)
URuStorePayDate* purchaseTime; // nullable
UPROPERTY(BlueprintReadOnly)
EURuStorePayPurchaseType purchaseType;
UPROPERTY(BlueprintReadOnly)
URuStorePayQuantity* quantity;
UPROPERTY(BlueprintReadOnly)
EURuStorePayPurchaseStatus status;
UPROPERTY(BlueprintReadOnly)
URuStorePaySubscriptionToken* subscriptionToken; // nullable
FURuStorePayPurchase()
{
amountLabel = NewObject<URuStorePayAmountLabel>(GetTransientPackage());
currency = NewObject<URuStorePayCurrency>(GetTransientPackage());
description = NewObject<URuStorePayDescription>(GetTransientPackage());
developerPayload = nullptr;
invoiceId = NewObject<URuStorePayInvoiceId>(GetTransientPackage());
orderId = nullptr;
price = NewObject<URuStorePayPrice>();
productId = NewObject<URuStorePayProductId>(GetTransientPackage());
productType = static_cast<EURuStorePayProductType>(0);
purchaseId = NewObject<URuStorePayPurchaseId>(GetTransientPackage());
purchaseTime = nullptr;
purchaseType = static_cast<EURuStorePayPurchaseType>(0);
quantity = NewObject<URuStorePayQuantity>(GetTransientPackage());
status = static_cast<EURuStorePayPurchaseStatus>(0);
subscriptionToken = nullptr;
}
};
amountLabel
— отформатированная цена покупки, включая валютный знак.currency
— код валюты ISO 4217.description
— описание на языкеlanguage
.-
developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки invoiceId
— идентификатор счёта.orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.price
— цена в минимальных единицах (в копейках).productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).productType
— тип продукта.
purchaseId
— идентификатор покупки.purchaseTime
— время покупки.PurchaseType
— тип покупки:ONE_PHASE
- одностадийная покупка;TWO_PHASE
- двухстадийная покупка.
quantity
— количество продукта (необязательный параметр — если не указывать, будет использоваться значение1
).status
— состояние покупки:INVOICE_CREATED
— создан счёт на оплату, покупка ожидает оплаты;CANCELLED
— покупка отменена покупателем;PROCESSING
— запущена оплата;REJECTED
— покупка отклонена (например, ввиду недостатка средств);PAID
— только для двухстадийной оплаты, промежуточный статус, средства на счёте покупателя захолдированы, покупка ожидает подтверждения от разработчика;CONFIRMED
— покупка успешно оплачена;REFUNDED
— запрос на возврат средств за покупку совершён успешно;REVERSED
— только для двухстадийной оплаты, покупка была отменена разработчиком или не было произведено подтверждение покупки в течение 72 часов, холдирование средств отменено.
Статусная модель покупки
Статусная модель одностадийного платежа.
Статусная модель двухстадийного платежа.
Валидация покупки на сервере
Если вам необходимо произвести валидацию успешной покупки на сервере RuStore, вы можете использовать subscriptionToken
из модели SuccessProductPurchaseResult
, возвращаемой при успешной покупке продукта.
long requestId = URuStorePushClient::Instance()->PurchaseTwoStep(
productPurchaseParams,
[](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
или GetPurchase
.
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
}
);
Подтверждение (потребление) покупки
Вызов метода подтверждения (потребления)
Для подтверждения (потребления) покупки используйте методConfirmTwoStepPurchase
. Запрос на подтверждение (потребление) покупки должен сопровождаться выдачей товара. После вызова подтверждения покупка перейдёт в статус CONSUMED
.
URuStorePayPurchaseId* purchaseId = ...
URuStorePayDeveloperPayload* developerPayload = ...
long requestId = URuStoreBillingClient::Instance()->ConfirmTwoStepPurchase(
purchaseId,
developerPayload,
[](long requestId) {
// Process response
},
[](long requestId, TSharedPtr<FURuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);

purchaseId
— идентификатор покупки.-
developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки
Отмена покупки
Для отмены покупки используйте метод CancelTwoStepPurchase
.
Вызов метода отмены покупки
URuStorePayPurchaseId* purchaseId = ...
long requestId = URuStoreBillingClient::Instance()->CancelTwoStepPurchase(
purchaseId,
[]( long requestId) {
// Process response
},
[]( long requestId, TSharedPtr<FURuStoreRuStoreError, ESPMode::ThreadSafe> error) {
// Process error
}
);

purchaseId
— идентификатор покупки.
Используйте этот метод, если у вас есть логика, завязанная на удалении покупки. Покупка отменяется автоматически через таймаут в 20 минут, либо при повторной покупке от того же клиента.
Обратный вызов (callback) Failure
возвращает структуру FURuStoreError
с информацией об ошибке в параметре Error
. Структура ошибки FURuStoreError
описана в разделе Обработка ошибок.
Обработка ошибок
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, от которой наследуются остальные ошибки.