SDK Платежи in-app для Unreal (версия 10.0.0)
RuStore позволяет интегрировать платежи в мобильное приложение.
-
Если не знаете с чего начать, прочтите инструкцию в сценариях использования.
-
Если вы переходите на Pay SDK с billingClient SDK, ознакомьтесь с инструкцией по переходу. Подробности о Pay SDK можно узнать тут.
Подготовка к работе
Поддерживаются версии Unreal Engine 5.3 и выше.
- Скопируйте проекты плагина и приложения-примера из официального репозитория 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 — не ниже 34.
Инициализация SDK
Перед вызовом методов библиотеки необходимо выполнить её инициализацию.
URuStorePayClient::Instance()->Init();

Для работы SDK в вашем AndroidManifest.xml
плагин RuStorePay через файл RuStorePay_UPL_Android.xml
добавит в манифест приложения данные console_app_id_value
, internal_config_key
и sdk_pay_scheme_value
. Все значения располагаются внутри тэга <application>
.
<application>
...
<meta-data android:name="console_app_id_value" android:value="@string/rustore_PayClientSettings_consoleApplicationId" />
<meta-data android:name="internal_config_key" android:value="@string/rustore_PayClientSettings_internalConfigKey" />
<meta-data android:name="sdk_pay_scheme_value" android:value="@string/rustore_PayClientSettings_deeplinkScheme" />
</application>
-
console_app_id_key
— идентификатор приложения из RuStore консоли. internal_config_key
— всегда имеет значениеunreal
.sdk_pay_scheme_value
— схема deeplink.
Где в 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
).
Все значения должны быть заданы в файле ресурсов, например: rustore_pay_values.xml
.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rustore_PayClientSettings_consoleApplicationId">198332</string>
<string name="rustore_PayClientSettings_internalConfigKey" translatable="false">unreal</string>
<string name="rustore_PayClientSettings_deeplinkScheme" translatable="false">yourappscheme</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>
Деинициализация SDK
Вызов метода Init
для URuStorePayClient
привязывает объекты к корню сцены. Если дальнейшая работа с объектами больше не планируется, для освобождения памяти необходимо выполнить метод Dispose
. Вызов Dispose
отвяжет объект от корня и безопасно завершит все отправленные запросы.
bool isInitialized = URuStorePayClient::Instance()->Dispose();

Проверка инициализации SDK
Если вам нужно проверить факт инициализации библиотеки, используйте метод GetIsInitialized
. Метод вернет true
, если библиотека инициализирована, и false
, если Init
еще не был вызван.
bool isInitialized = URuStorePayClient::Instance()->GetIsIninialized();

Обработка deeplink
Deeplink в RuStore SDK платежей нужна для корректной работы со сторонними приложениями оплаты. Она помогает пользователям быстрее совершать покупки в стороннем приложении и возвращаться в ваше приложение.
Плагин RuStore Pay автоматически добавит в AndroidManifest.xml
дополнительную activity с необходимым intent-filter
(см. ниже). Изменить это поведение можно в файле RuStorePay_UPL_Android.xml
.
<?xml version="1.0" encoding="utf-8"?>
<activity android:name="com.Plugins.RuStorePay.RuStorePayIntentFilterActivity" android:exported="true" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/rustore_PayClientSettings_deeplinkScheme" />
</intent-filter>
</activity>
<meta-data android:name="sdk_pay_scheme_value" android:value="@string/rustore_PayClientSettings_deeplinkScheme" />
Реализация RuStorePayIntentFilterActivity
package com.Plugins.RuStorePay;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import java.util.List;
import ru.rustore.unrealsdk.payclient.RuStoreUnrealPayClient;
public class RuStorePayIntentFilterActivity extends Activity {
private static Class<?> gameActivityClass = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
RuStoreUnrealPayClient.INSTANCE.proceedIntent(getIntent());
startGameActivity(null);
}
}
@Override
public void onNewIntent(Intent newIntent) {
super.onNewIntent(newIntent);
setIntent(newIntent);
RuStoreUnrealPayClient.INSTANCE.proceedIntent(newIntent);
startGameActivity(newIntent);
}
private void startGameActivity(Intent intent) {
if (gameActivityClass == null) {
gameActivityClass = findMainActivityClass();
}
Intent newIntent = new Intent(this, gameActivityClass);
if (intent != null) newIntent.putExtras(intent.getExtras());
startActivity(newIntent);
}
private Class<?> findMainActivityClass() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setPackage(getPackageName());
List<ResolveInfo> resolveInfos = getPackageManager().queryIntentActivities(intent, 0);
if (resolveInfos.isEmpty()) {
return null;
}
String mainActivityName = resolveInfos.get(0).activityInfo.name;
try {
return Class.forName(mainActivityName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
}
Метод proceedIntent
имеет перегрузку с дополнительным параметром maxRetryTimeMs: Long
.
long maxRetryTimeMs = 5000L;
RuStoreUnityPayClient.INSTANCE.proceedIntent(intent, maxRetryTimeMs);
maxRetryTimeMs
— максимальное время (в миллисекундах) для повторных попыток инициализации платёжного клиента (по умолчанию 5000 мс).
Методы SDK
Проверка доступности работы с платежами
Для проверки доступности платежей, вызовите метод GetPurchaseAvailability
. При его вызове про веряются следующие условия.
- У компании подключена монетизация через консоль разработчика 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
}
);

Проверка статуса авторизации пользователя
Для проверки статуса авторизации пользователя, вызовите метод GetUserAuthorizationStatus
. Результатом выполнения метода является значение перечисления UserAuthorizationStatus
. Возможно только 2 значения:
AUTHORIZED
— пользователь авторизован в RuStore.UNAUTHORIZED
— пользователь неавторизован в RuStore. Данное значение также вернется если у пользователя нет установленного МП RuStore на девайсе.
RuStorePayClient.Instance.GetUserAuthorizationStatus(
onSuccess: (result) => {
if (result == UserAuthorizationStatus.AUTHORIZED) {
// Process result
}
});
onFailure: (error) => {
// Process error
},
