
В какой-то момент всё становится серьёзным — даже в приложениях про любовь. Команда Redspell, создатели игры Senses (интерактивные романтические истории), решили стать одними из первых, кто интегрировал новую платёжку от RuStore — Pay SDK. И встроили — с нуля, но в итоге с ростом метрик.
Вот честный рассказ о том, как ребята внедряли RuStore Pay SDK, что пошло не так, как с этим справились и какие результаты в итоге получили. Если вы тоже раздумываете, стоит ли связываться — читайте до конца. Там есть приятные цифры.
Зачем вообще этот Pay SDK
Если коротко: Pay SDK — это способ встроить в приложение платежи, которые работают быстро, выглядят нативно и не заставляют пользователя вводить свой email в 2025 году (серьёзно, хватит уже). Разработан специально в RuStore, адаптируется под вашу архитектуру и не требует танцев с дебагером в полнолуние.
Что внутри:
Простая интеграция без лишних зависимостей;
Одно- и двухстадийная оплата (на любой вкус);
Вся логика платежей — у вас под контролем;
VK ID — всё быстро и удобно;
Работает даже если у пользователя нет RuStore.

И да, вскоре он станет достойной альтернативой BillingClient SDK. Но уже сейчас умеет больше:
Купоны, возвраты, список продуктов без авторизации;
И даже чеки в мессенджер или почту, если вы по олдскулу.
Как всё начиналось
Когда Senses появился в RuStore, перед Redspell встал вполне логичный вопрос: как получить максимальную выгоду от монетизации. Всё-таки 85% дохода с приложения — это внутриигровые покупки, а значит, платёжка должна быть быстрой, нативной и не раздражать пользователя (ну, и разработчика, конечно).
И тут на горизонте — Pay SDK: всё ещё в beta, но уже с полноценной функциональностью, официальной поддержкой и гибкостью под разные сценарии. Раньше Redspell использовали сторонние веб-интерфейсы для монетизации — решение не самое удобное, не нативное и не всегда стабильное. Поэтому переход на Pay SDK стал логичным шагом: хотелось, чтобы весь процесс оплаты проходил прямо внутри приложения — быстро, аккуратно и под контролем.
Выбирая между BillingClient SDK и новым Pay SDK, команда Redspell сразу сделала ставку на второй вариант — он уже закрывал нужные задачи и, что важно, активно развивается RuStore.
В итоге ребята не растерялись — и пошли в пилот.
Технический квест на Unity
Платформа у Redspell — Unity. SDK нужно было аккуратно прикрутить, не развалив игру.
Вкратце, что было не так:
Вызовы Pay SDK встроили через стандартный Unity Purchase Module — без лома кода.
Код
class RuStoreModule: AbstractPurchasingModule
{
public const string STORE_NAME = "RuStore";
private static RuStoreModule _instance;
public static IPurchasingModule Instance()
{
_instance ??= new RuStoreModule();
return _instance;
}
public override void Configure()
{
RegisterStore(STORE_NAME,new RuStore());
}
}
internal class RuStore : IStore
{
private IStoreCallback _storeCallback;
public void Initialize(IStoreCallback callback)
{
_storeCallback = callback;
bool isRuStoreInstalled = RuStorePayClient.Instance.IsRuStoreInstalled();
if (!isRuStoreInstalled)
{
_storeCallback.OnSetupFailed(InitializationFailureReason.PurchasingUnavailable, "RuStore is not installed");
return;
}
var settings = BlackMagicSettings.Instance;
RuStorePayClient.Instance.GetPurchaseAvailability(
onFailure: (error) =>
{
// Process error
_storeCallback.OnSetupFailed(InitializationFailureReason.PurchasingUnavailable,$"{error.name}:{error.description}");
},
onSuccess: (response) =>
{
if (response.isAvailable)
{
RuStorePayClient.Instance.GetPurchases(OnGetPurchasesFailure,onGetPurchasesSuccess);
}
else
{
var error = response.cause;
_storeCallback.OnSetupFailed(InitializationFailureReason.PurchasingUnavailable, $"{error.name}:{error.description}");
}
}
);
}
Но не обошлось без затыков: нужно было переопределить стандартный Unity Activity, добавить Java-файл и всё это собрать на CI под Android.
Ещё и уведомления с этим не дружили — конфликтовали.
Код
#if UNITY_ANDROID // && !UNITY_EDITOR
public class RuStorePostProcessor : IPostGenerateGradleAndroidProject
{
public int callbackOrder => 100;
public void OnPostGenerateGradleAndroidProject(string path)
{
var gradleDir = path;
#if RUSTORE
PatchAndroidManifest(gradleDir);
GenerateJavaHandler(gradleDir);
#else
Debug.Log("RuStore disabled");
RemoveJavaHandler(gradleDir);
#endif
}
#if RUSTORE
void PatchAndroidManifest(string gradleDir)
{
string manifestPath = Path.Combine(
gradleDir, "src", "main", "AndroidManifest.xml");
var doc = XDocument.Load(manifestPath);
XNamespace androidNs = "http://schemas.android.com/apk/res/android";
var application = doc.Root.Element("application");
// e.g. add an <activity> or <meta-data> entry:
var activity = new XElement("activity",
new XAttribute(androidNs + "name", "games.extras.blackmagic.RuStoreDeeplinkActivity"),
new XAttribute(androidNs + "exported", "true")
);
activity.Add(
new XElement("intent-filter",
new XElement("action", new XAttribute(androidNs + "name", "android.intent.action.VIEW")),
new XElement("category", new XAttribute(androidNs + "name", "android.intent.category.DEFAULT")),
new XElement("category", new XAttribute(androidNs + "name", "android.intent.category.BROWSABLE")),
new XElement("data", new XAttribute(androidNs + "scheme", "@string/rustore_PayClientSettings_deeplinkScheme"))
)
);
application.Add(activity);
....
}
void GenerateJavaHandler(string gradleDir)
{
string javaDir = Path.Combine(
gradleDir, "src", "main", "java", "games", "extras", "blackmagic");
Directory.CreateDirectory(javaDir);
string javaFile = Path.Combine(javaDir, "RuStoreDeeplinkActivity.java");
string code = @"
package games.extras.blackmagic;
import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import ru.rustore.unitysdk.payclient.RuStoreUnityPayClient;
import com.unity3d.player.UnityPlayerActivity;
import android.util.Log;
public class RuStoreDeeplinkActivity extends Activity {
@Override protected void onCreate(Bundle savedInstanceState) {
.....
Как выкрутились:
Сделали дополнительный Activity, который ловит Intent и запускает SDK. Код генерируется через Unity Post-Processor — только когда надо. Гибко, красиво, работает.
Что в итоге?
Через пару месяцев стало ясно: SDK живёт, платежи идут, пользователи довольны. А главное — метрики сказали «да»:
Процент платящих пользователей в RuStore более чем в 3 раза превышает аналогичный показатель на Google Play.
Прирост APRU (Average Revenue Per User, средняя выручка на одного пользователя) составил +207 % по сравнению с Google Play и +63 % по отношению к App Store.
ARPPU (Average revenue per paying user, средняя выручка на одного платящего пользователя) на 29 % выше, чем в Google Play.
RuStore демонстрирует самый высокий средний чек среди всех платформ, опережая App Store на 28,4 %.
Huawei-пользователи остались в игре — отсутствие GMS больше не препятствует стабильным платежам.
А вам зачем это знать?
Если вы тоже публикуетесь в RuStore и вам нужна платёжка, которая:
быстро ставится;
не ломает архитектуру;
дружит с VK ID;
и в целом работает как надо —
то Pay SDK — рабочий инструмент, с которым можно запускать монетизацию уже сейчас. Redspell интегрировал его без драмы, метрики пошли вверх, пользователи не убежали — разве что в очередной виртуальный роман с новым пиксельным красавчиком или красавицей.
Плюс, если что-то не клеится — команда поддержки действительно отвечает, а не «мы передали вашу заявку в параллельную вселенную».
А ещё у нас есть телеграм-канал — подписывайтесь, там регулярно появляется всякое полезное (и местами весёлое) для разработчиков.