SDK Платежи in-app для Kotlin/Java (версия 11.1.0)
RuStore позволяет интегрировать платежи в мобильное приложение.
-
Если не знаете с чего начать, прочтите инструкцию в сценариях использования.
-
Если вы переходите на Pay SDK с billingClient SDK, ознакомьтесь с инструкцией по переходу. Подробности о Pay SDK можно узнать тут.
Подготовка к работе
Добавление репозитория
repositories {
maven {
url = uri("https://nexus-external.vkteam.ru/repository/maven-rustore-exposed/")
}
}
Подключение зависимости
Добавьте следующий код в свой конфигурационный файл для подключения зависимости.
dependencies {
implementation(platform("ru.rustore.sdk:bom:2026.08.01"))
implementation("ru.rustore.sdk:pay")
}
Обработка deeplink
Обработка deeplink в RuStore SDK позволяет эффективно взаимодействовать со сторонними приложениями, при проведении платежей через банковские приложения (СБП, SberPay и др.). Это позволяет перевести пользователя на экран оплаты, а после завершения транзакции — вернуть в ваше приложение.
Для настройки работы с deeplink в вашем приложении и Pay SDK, укажите deeplinkScheme с помощью sdk_pay_scheme_value
в вашем AndroidManifest.xml файле и переопределите метод onNewIntent вашего Activity
- При использовании deeplinks указание схемы является обязательным.
- При попытке платежа без указания схемы будет возникать ошибка.
- Допускаются только символы в кодировке ASCII. Формат должен соответствовать спецификации RFC-3986.
Указание deeplinkScheme:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="your.app.package.name">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.App"
tools:targetApi="n">
<!-- ... -->
<activity
android:name=".YourPayActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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="yourappscheme" />
</intent-filter>
</activity>
<meta-data
android:name="sdk_pay_scheme_value"
android:value="yourappscheme" />
</application>
</manifest>
Замените yourappscheme на название своей схемы. Например, ru.package.name.rustore.scheme.
Затем, добавьте следующий код в Activity, в которую необходимо вернуться
после совершения оплаты (ваша страница приложения):
- Kotlin
- Java
class YourPayActivity : AppCompatActivity() {
private val intentInteractor: IntentInteractor by lazy {
RuStorePayClient.instance.getIntentInteractor()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
intentInteractor.proceedIntent(intent, sdkTheme = SdkTheme.LIGHT) // Опциональная тема
}
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
intentInteractor.proceedIntent(intent, sdkTheme = SdkTheme.LIGHT) // Опциональная тема
}
}
public class YourPayActivity extends AppCompatActivity {
private final IntentInteractor intentInteractor =
RuStorePayClient.Companion.getInstance().getIntentInteractor();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
intentInteractor.proceedIntent(getIntent(), SdkTheme.LIGHT); // Опциональная тема
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
intentInteractor.proceedIntent(intent, SdkTheme.LIGHT); // Опциональная тема
}
}
Для восстановления состояния вашего приложения при возврате с deeplink добавьте в
AndroidManifest.xml атрибут android:launchMode="singleTop".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="your.app.package.name">
<!-- ... -->
<application>
<!-- ... -->
<activity
android:name=".YourPayActivity"
android:launchMode="singleTop"
android:exported="true"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
<!-- ... -->
</activity>
<!-- ... -->
</application>
</manifest>
Инициализация SDK
Перед вызовом методов библиотеки необходимо выполнить ее инициализацию. Сама инициализац ия происходит автоматически, но для работы SDK в вашем файле Manifest.xml необходимо прописать console_app_id_value. Значение необходимо указать в строковых ресурсах.
Сделать это можно следующим образом.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="your.app.package.name">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.App"
tools:targetApi="n">
...
<meta-data
android:name="console_app_id_value"
android:value="@string/CONSOLE_APPLICATION_ID" />
<meta-data
android:name="sdk_pay_scheme_value"
android:value="@string/APP_SCHEME" />
</application>
</manifest>
-
Пример:CONSOLE_APPLICATION_ID— идентификатор приложения из RuStore консоли.https://console.rustore.ru/apps/111111.
Где в RuStore Консоль отображаются идентификаторы приложений?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Скопируйте идентификатор из URL-адреса страницы приложения — это набор цифр между
apps/и/versions. Например, для URL-адресаhttps://console.rustore.ru/apps/123456/versionsID приложения —123456.

ApplicationId, указанный вbuild.gradle, должен совпадать сapplicationIdAPK-файла, который вы публиковали в RuStore Консоль.- Для корректной работы с deeplink в AndroidManifest должен обязательно быть атрибут
<meta-data>с именем "sdk_pay_scheme_value". Значение - схема вашего приложения. -
Подпись
keystoreдолжна совпадать с подписью, которой было подписано приложение, опубликованное в RuStore Консоль. Убедитесь, что используемыйbuildType(пр.debug) использует такую же подпись, что и опубликованное приложение (пр.release).
Необходимые разрешения и параметры безопасности
Pay SDK автоматически добавляет в манифест приложения некоторые разрешения и параметры, необходимые для работы функциональности, связанной с безопасностью платежей.
Прочие разрешения
Также Pay SDK может потребовать другие стандартные разрешения, такие как:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Методы SDK
Доступные публичные интеракторы:
-
PurchaseInteractor- интерактор, который позволяет работать с платежами и имеет несколько публичных методов.getPurchase(purchaseId: PurchaseId): Task<Purchase>- позволяет получить информацию о покупке по её ID.getPurchases(productType: ProductType? = null, purchaseStatus: PurchaseStatus? = null, acknowledgementState: AcknowledgementState? = null): Task<List<Purchase>>— позволяет получить покупки пользователя. Данный метод поддерживает опциональную фильтрацию по типу товаров (потребляемые, непотребляемые товары или подписки), а также по статусу покупки (поддерживаются статусыPAID,CONFIRMEDACTIVEиPAUSED) и по состоянию выдачи товара (acknowledgementState). Возможные значения:PENDING,ACKNOWLEDGED,UNKNOWN. По умолчанию фильтры отключены, и вернутся все покупки пользователя (независимо от типа товара) в статусахPAID,CONFIRMEDACTIVEиPAUSED.getPurchaseAvailability(): Task<PurchaseAvailabilityResult>- возвращает результат проверки доступности работы с платежами.purchase(params: ProductPurchaseParams, preferredPurchaseType: PreferredPurchaseType = PreferredPurchaseType.ONE_STEP, sdkTheme: SdkTheme = SdkTheme.LIGHT, purchaseEventListener: PurchaseEventListener? = null): Task<ProductPurchaseResult>- позволяет совершить покупку продукта с указанием желаемого типа оплаты - одностадийной (ONE_STEP) или двухстадийной (TWO_STEP). Для данного метода оплаты на платёжной шторке доступны все способы оплаты. Если параметр не задан, по умолчанию запускается с оплатой в одну стадию.
Важно!Если указан тип оплаты
TWO_STEP, будет произведена попытка запустить двухстадийную оплату, но итоговый результат напрямую будет зависеть от того, какой способ оплаты (карта, СБП и др.) будет выбран пользователем.Обратите внимание, что тип оплаты
TWO_STEPнедоступен:- При выборе способа оплаты СБП.
- При покупке подписок.
Двухстадийная оплата доступна только для определенного набора способов оплаты (на текущий момент — только для карт и SberPay). Если выбран способ оплаты, который не поддерживает холдирование, то покупка будет запущена по сценарию с одной стадией.
purchaseTwoStep(params: ProductPurchaseParams, sdkTheme: SdkTheme = SdkTheme.LIGHT, purchaseEventListener: PurchaseEventListener? = null): Task<ProductPurchaseResult>- запускает сценарий гарантированной двухстадийной покупки товара. При использовании данного метода пользователю на платёжной шторке доступен ограниченный набор способов оплаты - только те, которые поддерживают двухстадийную оплату. В процессе платежа сначала осуществляется холдирование денежных средств покупателя, которые списываются только после подтверждения покупки методом confirmTwoStepPurchase.confirmTwoStepPurchase(purchaseId: PurchaseId, developerPayload: DeveloperPayload? = null)- подтверждение покупки, совершенной по двухстадийной оплате.cancelTwoStepPurchase(purchaseId: PurchaseId)- отмена покупки, совершённой по двухстадийной оплате.updateAcknowledgementState(purchaseId: PurchaseId, state: AcknowledgementState, developerPayload: DeveloperPayload? = null): Task<AcknowledgementState>- обновляет состояние выдачи товара.getBillingSubscriptions(): Task<List<BillingSubscription>>— возвращает список подписок, оформленных в SDK Billing Client.
-
ProductInteractor- интерактор, который позволяет работать с продуктами:getProducts(productsId: List<ProductId>): Task<List<Product>>- позволяет получить информацию по активным продуктам, опубликованным в RuStore консоль.
ВажноДанный метод возвращает не более 1000 продуктов и работает без авторизации и наличия установленного RuStore на устройстве пользователя.
-
UserInteractor- интерактор, который позволяет получить статус авторизации пользователяUserAuthorizationStatus. У данной модели может быть 2 состояния:AUTHORIZED- пользователь авторизован в RuStoreUNAUTHORIZED- пользователь неавторизован в RuStore.
-
IntentInteractor- интерактор, который позволяет обрабатывать intent-ы и deeplink-и. Необходим для корректного возвращения из приложения банка обратно в приложение и корректного восстановления состояния платежной шторки.proceedIntent(intent: Intent?, sdkTheme: SdkTheme = SdkTheme.LIGHT)- метод для обработки диплинков и восстановление состояния платежной шторки при возвращении в Ваше приложение из приложения банка. Вызов данного метода необходим для корректного отображения шторки оплаты при возвращении в приложение из приложения банка.
-
блок
RuStoreUtils- набор открытых методов, таких как:isRuStoreInstalled- проверки наличия приложения RuStore на устройстве пользователя.openRuStoreDownloadInstruction- открывает веб-страницу для скачивания приложения RuStore.openRuStore- запускает приложение RuStore.openRuStoreAuthorization- запускает приложение RuStore для авторизации. После успешной авторизации пользователя приложение RuStore автоматически закроется.
Получение списка продуктов
- Kotlin
- Java
Для получения продуктов, добавленных в ваше приложение через RuStore консоль, необходимо использовать метод getProducts.
RuStorePayClient.instance.getProductInteractor().getProducts(productsId = listOf(ProductId("id1"), ProductId("id2")))
.addOnSuccessListener { products: List<Product> ->
// Логика работы со списком продуктов
}
.addOnFailureListener { throwable: Throwable ->
// Обработка ошибки
}
productsId: List<ProductId> — список идентификаторов продуктов (задаются при создании продукта в консоли разработчика). Список продуктов имеет ограничение в размере 1000 элементов.
Где в RuStore Консоль отображаются идентификаторы продуктов?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Выберите Монетизация в меню слева.
- Выберите тип товара: Подписки или Разовые покупки.
- Скопируйте идентификаторы нужных товаров.

Метод возвращает список активных продуктов. Ниже представлена модель продукта.
public class Product internal constructor(
public val productId: ProductId,
public val type: ProductType,
public val amountLabel: AmountLabel,
public val price: Price?,
public val currency: Currency,
public val imageUrl: Url,
public val title: Title,
public val description: Description?,
public val subscriptionInfo: SubscriptionInfo?,
)
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).type— тип продукта.CONSUMABLE_PRODUCT/NON_CONSUMABLE_PRODUCT/SUBSCRIPTION(потребляемый/непотребляемый/подписка).amountLabel— отформатированная цена покупки, включая валютный знак.price— цена в минимальных единицах (в копейках).currency— код валюты ISO 4217.imageUrl— ссылка на картинку.title— название продукта на языкеlanguage.description— описание на языкеlanguage.subscriptionInfo— информация о подписке (будет неnull, если тип продуктаSUBSCRIPTION).
Модель subscriptionInfo содержит информацию о продукте подписки.
Наличие полей не означает, что пользователю по-прежнему доступен бесплатный или стартовый период: он мог ранее уже исчерпать эти периоды.
Ниже представлена сама модель.
public class SubscriptionInfo internal constructor(
public val periods: List<SubscriptionPeriod>,
)
public sealed interface SubscriptionPeriod
public class TrialPeriod internal constructor(
public val duration: String,
public val currency: String,
public val price: Int,
) : SubscriptionPeriod
public class PromoPeriod internal constructor(
public val duration: String,
public val currency: String,
public val price: Int,
) : SubscriptionPeriod
public class MainPeriod internal constructor(
public val duration: String,
public val currency: String,
public val price: Int,
) : SubscriptionPeriod
public class GracePeriod internal constructor(
public val duration: String,
) : SubscriptionPeriod
public class HoldPeriod internal constructor(
public val duration: String,
) : SubscriptionPeriod
duration- длительность периода в формате ISO 8601 (как в Public API)currency- код валюты ISO 4217price- цена в минимальных единицах (копейках).
Периоды подписки
-
TrialPeriod— бесплатный период -
PromoPeriod— стартовый период -
MainPeriod— стандартный период подписки -
GracePeriod— грэйс-период -
HoldPeriod— холд-период
Подробнее о работе периодов подписки описано в статье.
Пример работы с subscriptionInfo
RuStorePayClient.instance.getProductInteractor().getProducts(productsId = listOf(ProductId("id1"), ProductId("id2")))
.addOnSuccessListener { products: List<Product> ->
products.forEach { product ->
val periods = product.subscriptionInfo?.periods
when (period) {
is TrialPeriod -> {
println("Бесплатный период: ${period.duration} за ${period.price} ${period.currency}")
}
is PromoPeriod -> {
println("Стартовый период: ${period.duration} за ${period.price} ${period.currency}")
}
is MainPeriod -> {
println("Основной период: ${period.duration} за ${period.price} ${period.currency}")
}
is GracePeriod -> {
println("Период отсрочки: ${period.duration}")
}
is HoldPeriod -> {
println("Период удержания: ${period.duration}")
}
null -> {
println("subscriptionInfo is null")
}
}
}
}
.addOnFailureListener { throwable: Throwable ->
// Обработка ошибки
}
Примеры ответа
Иллюстрация структуры моделей в ответе (не компилируемый код — конструкторы моделей недоступны снаружи SDK).
Product(
productId = ProductId("conProduct1"),
type = ProductType.CONSUMABLE_PRODUCT,
amountLabel = AmountLabel("100.00 руб."),
price = Price(10000),
currency = Currency("RUB"),
imageUrl = Url("https://your_image_consumable_product.png"),
title = Title("Название Потребляемого продукта"),
description = Description("Описание потребляемого продукта"),
)
Product(
productId = ProductId("nonConProduct1"),
type = ProductType.NON_CONSUMABLE_PRODUCT,
amountLabel = AmountLabel("200.00 руб."),
price = Price(20000),
currency = Currency("RUB"),
imageUrl = Url("https://your_image_non_consumable_product.png"),
title = Title("Название Непотребляемого продукта"),
description = Description("Описание Непотребляемого продукта"),
)
Product(
productId = ProductId("sub_1"),
type = ProductType.SUBSCRIPTION,
amountLabel = AmountLabel("300.00 руб."),
price = Price(30000),
currency = Currency("RUB"),
imageUrl = Url("https://your_image_subscription.png"),
title = Title("Название вашей подписки"),
description = Description("Описание вашей подписки"),
subscriptionInfo = SubscriptionInfo(
periods = listOf(
TrialPeriod(
duration = "P1M",
currency = "RUB",
price = 0
),
PromoPeriod(
duration = "P5D",
currency = "RUB",
price = 149
),
MainPeriod(
duration = "P1Y",
currency = "RUB",
price = 299
),
GracePeriod(
duration = "P3D"
),
HoldPeriod(
duration = "P5D"
)
)
)
)
Для получения продуктов, добавленных в ваше приложение через RuStore консоль, необходимо использовать метод getProducts.
List<ProductId> productsId = Arrays.asList(new ProductId("id1"), new ProductId("id2"));
ProductInteractor productInteractor = RuStorePayClient.Companion.getInstance().getProductInteractor();
productInteractor.getProducts(productsId)
.addOnSuccessListener(products -> {
// Логика работы со списком продуктов
})
.addOnFailureListener(throwable -> {
// Обработка ошибки
});
productsId: List<ProductId> — список идентификаторов продуктов (задаются при создании продукта в консоли разработчика). Список продуктов имеет ограничение в размере 1000 элементов.
Где в RuStore Консоль отображаются идентификаторы продуктов?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Выберите Монетизация в меню слева.
- Выберите тип товара: Подписки или Разовые покупки.
- Скопируйте идентификаторы нужных товаров.

Метод возвращает список активных продуктов. Ниже представлена модель продукта:
public class Product {
private final ProductId productId;
private final ProductType type;
private final AmountLabel amountLabel;
private final Price price;
private final Currency currency;
private final Url imageUrl;
private final Title title;
private final Description description;
private final SubscriptionInfo subscriptionInfo;
public Product(ProductId productId, ProductType type, AmountLabel amountLabel, @Nullable Price price, Currency currency, Url imageUrl, Title title, @Nullable Description description, @Nullable SubscriptionInfo subscriptionInfo) {
this.productId = productId;
this.type = type;
this.amountLabel = amountLabel;
this.price = price;
this.currency = currency;
this.imageUrl = imageUrl;
this.title = title;
this.description = description;
this.subscriptionInfo = subscriptionInfo;
}
public ProductId getProductId() {
return productId;
}
public ProductType getType() {
return type;
}
public AmountLabel getAmountLabel() {
return amountLabel;
}
public @Nullable Price getPrice() {
return price;
}
public Currency getCurrency() {
return currency;
}
public Url getImageUrl() {
return imageUrl;
}
public Title getTitle() {
return title;
}
public @Nullable Description getDescription() {
return description;
}
public @Nullable SubscriptionInfo getSubscriptionInfo() {
return subscriptionInfo;
}
}
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).type— тип продукта.CONSUMABLE_PRODUCT/NON_CONSUMABLE_PRODUCT/SUBSCRIPTION(потребляемый/непотребляемый/подписка).amountLabel— отформатированная цена покупки, включая валютный знак.price— цена в минимальных единицах (в копейках).currency— код валюты ISO 4217.imageUrl— ссылка на картинку.title— название продукта на языкеlanguage.description— описание на языкеlanguage.subscriptionInfo— информация о подписке (будет неnull, если тип продуктаSUBSCRIPTION).
Модель subscriptionInfo содержит информацию о продукте подписки.
Наличие полей не означает, что пользователю по-прежнему доступен бесплатный или стартовый период: он мог ранее уже исчерпать эти периоды.
Ниже представлена сама модель.
public final class SubscriptionInfo {
private final List<SubscriptionPeriod> periods;
public SubscriptionInfo(List<SubscriptionPeriod> periods) {
this.periods = periods;
}
public List<SubscriptionPeriod> getPeriods() {
return periods;
}
}
public interface SubscriptionPeriod {
String getDuration();
}
public final class TrialPeriod implements SubscriptionPeriod {
private final String duration;
private final String currency;
private final int price;
public TrialPeriod(String duration, String currency, int price) {
this.duration = duration;
this.currency = currency;
this.price = price;
}
public String getDuration() { return duration; }
public String getCurrency() { return currency; }
public int getPrice() { return price; }
}
public final class PromoPeriod implements SubscriptionPeriod {
private final String duration;
private final String currency;
private final int price;
public PromoPeriod(String duration, String currency, int price) {
this.duration = duration;
this.currency = currency;
this.price = price;
}
public String getDuration() { return duration; }
public String getCurrency() { return currency; }
public int getPrice() { return price; }
}
public final class MainPeriod implements SubscriptionPeriod {
private final String duration;
private final String currency;
private final int price;
public MainPeriod(String duration, String currency, int price) {
this.duration = duration;
this.currency = currency;
this.price = price;
}
public String getDuration() { return duration; }
public String getCurrency() { return currency; }
public int getPrice() { return price; }
}
public final class GracePeriod implements SubscriptionPeriod {
private final String duration;
public GracePeriod(String duration) {
this.duration = duration;
}
public String getDuration() { return duration; }
}
public final class HoldPeriod implements SubscriptionPeriod {
private final String duration;
public HoldPeriod(String duration) {
this.duration = duration;
}
public String getDuration() { return duration; }
}
duration- длительность периода в формате ISO 8601 (как в Public API)currency- код валюты ISO 4217price- цена в минимальных единицах (копейках).
Периоды подписки
-
TrialPeriod— бесплатный период -
PromoPeriod— стартовый период -
MainPeriod— стандартный период подписки -
GracePeriod— грэйс-период -
HoldPeriod— холд-период
Подробнее о работе периодов подписки описано в статье.
Пример работы с subscriptionInfo
List<ProductId> productsId = Arrays.asList(new ProductId("id1"), new ProductId("id2"));
ProductInteractor productInteractor = RuStorePayClient.Companion.getInstance().getProductInteractor();
productInteractor.getProducts(productsId)
.addOnSuccessListener(products -> {
for (Product product : products) {
SubscriptionInfo subscriptionInfo = product.getSubscriptionInfo();
if (subscriptionInfo == null) {
println("SubscriptionInfo is null for product: " + product.getProductId());
continue;
}
List<SubscriptionPeriod> periods = subscriptionInfo.getPeriods();
if (periods == null || periods.isEmpty()) {
continue;
}
for (SubscriptionPeriod period : periods) {
switch (period) {
case TrialPeriod trialPeriod ->
println("Бесплатный период: " + trialPeriod.getDuration() +
" за " + trialPeriod.getPrice() + " " + trialPeriod.getCurrency());
case PromoPeriod promoPeriod ->
println("Стартовый период: " + promoPeriod.getDuration() +
" за " + promoPeriod.getPrice() + " " + promoPeriod.getCurrency());
case MainPeriod mainPeriod ->
println("Основной период: " + mainPeriod.getDuration() +
" за " + mainPeriod.getPrice() + " " + mainPeriod.getCurrency());
case GracePeriod gracePeriod ->
println("Период отсрочки: " + gracePeriod.getDuration());
case HoldPeriod holdPeriod ->
println("Период удержания: " + holdPeriod.getDuration());
default ->
println("Unknown period type: " + period.getClass().getSimpleName());
}
}
}
})
.addOnFailureListener(throwable -> {
// Обработка ошибки
});
Примеры ответа
Иллюстрация структуры моделей в ответе (не компилируемый код — конструкторы моделей недоступны снаружи SDK).
Product(
productId = ProductId("conProduct1"),
type = ProductType.CONSUMABLE_PRODUCT,
amountLabel = AmountLabel("100.00 руб."),
price = Price(10000),
currency = Currency("RUB"),
imageUrl = Url("https://your_image_consumable_product.png"),
title = Title("Название Потребляемого продукта"),
description = Description("Описание потребляемого продукта"),
)
Product(
productId = ProductId("nonConProduct1"),
type = ProductType.NON_CONSUMABLE_PRODUCT,
amountLabel = AmountLabel("200.00 руб."),
price = Price(20000),
currency = Currency("RUB"),
imageUrl = Url("https://your_image_non_consumable_product.png"),
title = Title("Название Непотребляемого продукта"),
description = Description("Описание Непотребляемого продукта"),
)
Product(
productId = ProductId("sub_1"),
type = ProductType.SUBSCRIPTION,
amountLabel = AmountLabel("300.00 руб."),
price = Price(30000),
currency = Currency("RUB"),
imageUrl = Url("https://your_image_subscription.png"),
title = Title("Название вашей подписки"),
description = Description("Описание вашей подписки"),
subscriptionInfo = SubscriptionInfo(
periods = listOf(
TrialPeriod(
duration = "P1M",
currency = "RUB",
price = 0
),
PromoPeriod(
duration = "P5D",
currency = "RUB",
price = 149
),
MainPeriod(
duration = "P1Y",
currency = "RUB",
price = 299
),
GracePeriod(
duration = "P3D"
),
HoldPeriod(
duration = "P5D"
)
)
)
)
Определение наличия авторизации у пользователя
Для проверки статуса авторизации пользователя, вызовите метод getUserAuthorizationStatus у UserInteractor.
Результатом выполнения метода является класс UserAuthorizationStatus.
Используйте метод getUserAuthorizationStatus только в тех сценариях, где вам важно заранее понять, авторизован ли пользователь в RuStore (или установлен ли RuStore на устройстве). Для запуска оплаты сам по себе этот метод не является обязательным.
Доступно 2 значения:
AUTHORIZED- пользователь авторизован в RuStore или через VK ID на платежной шторке.UNAUTHORIZED- пользователь не авторизован. Данное значение также вернется если у пользователя нет установленного RuStore на устройстве.
- Kotlin
- Java
RuStorePayClient.instance.getUserInteractor().getUserAuthorizationStatus()
.addOnSuccessListener { result ->
when (result) {
UserAuthorizationStatus.AUTHORIZED -> {
// Логика когда пользователь авторизован в RuStore или на платежной шторке
}
UserAuthorizationStatus.UNAUTHORIZED -> {
// Логика когда пользователь НЕ авторизован
}
}
}.addOnFailureListener { throwable ->
// Обработка ошибки
}
UserInteractor userInteractor = RuStorePayClient.Companion.getInstance().getUserInteractor();
userInteractor.getUserAuthorizationStatus()
.addOnSuccessListener(status -> {
switch (status) {
case AUTHORIZED:
// Логика когда пользователь авторизован в RuStore или на платежной шторке
break;
case UNAUTHORIZED:
// Логика когда пользователь НЕ авторизован
break;
}
})
.addOnFailureListener(throwable -> {
// Обработка ошибки
});
Проверка доступности работы с платежами
Для проверки доступности платежей, вызовите метод getPurchaseAvailability у PurchaseInteractor. При его вызове проверяются следующие условия.
- У компании подключена монетизация через консоль разработчика RuStore.
- Приложение не должно быть заблокировано в RuStore.
- Пользователь не должен быть заблокирован в RuStore.
Если все условия выполняются, возвращается результат Available. Иначе возвращается результат Unavailable с причиной — ошибкой о невыполненном условии. Возможные ошибки описаны в разделе Обработка ошибок.
- Kotlin
- Java
Причина недоступности платежей — в поле cause: Throwable результата PurchaseAvailabilityResult.Unavailable.
RuStorePayClient.instance.getPurchaseInteractor().getPurchaseAvailability()
.addOnSuccessListener { result ->
when (result) {
is PurchaseAvailabilityResult.Available -> {
// Обработка результата доступности платежей
}
is PurchaseAvailabilityResult.Unavailable -> {
// Обработка результата недоступности платежей
}
}
}.addOnFailureListener { throwable ->
// Обработка ошибки
}
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.getPurchaseAvailability()
.addOnSuccessListener(result -> {
if (result instanceof PurchaseAvailabilityResult.Available) {
// Обработка результата доступности платежей
} else if (result instanceof PurchaseAvailabilityResult.Unavailable) {
// Обработка результата недоступности платежей
}
})
.addOnFailureListener(throwable -> {
// Обработка ошибки
});
Покупка продукта
- При использовании одностадийного платежа покупка не требует подтверждения, денежные средства сразу списываются со счета покупателя, а с разработчика удерживается комиссия. В таком случае, если требуется вернуть денежные средства клиенту (например, по какой-то причине нет возможности поставить продукт), возможен только возврат средств через RuStore Консоль, денежные средства возвращаются покупателю через несколько дней. Возвращается полная стоимость покупки, при этом удержанная комиссия разработчику не возмещается.
- В случае использования двухстадийного платежа сначала производится холдирование средств на счете покупателя. Комиссия в этом случае не удерживается. После холдирования покупка требует подтверждения или отмены. Комиссия с разработчика удерживается при подтверждении покупки. Отмена покупки означает снятие холда - денежные средства мгновенно снова доступны покупателю.
На данный момент покупка подписки (SubscriptionPurchase) может быть совершена только с использованием одностадийного платежа (PurchaseType.ONE_STEP).
Двухстадийная оплата доступна только для определенного набора способов оплаты (на текущий момент — только для карт и SberPay). Технологии СБП не поддерживают двухстадийную оплату. Если выбран способ оплаты, который не поддерживает холдирование, то покупка будет запущена по сценарию с одной стадией.
- Kotlin
- Java
Оплата с выбором типа покупки
Для вызова покупки продукта с выбором стадийности оплаты используйте метод purchase.
val params = ProductPurchaseParams(
productId = ProductId("productId"),
orderId = null,
quantity = null,
developerPayload = null,
appUserId = null,
appUserEmail = null,
)
RuStorePayClient.instance.getPurchaseInteractor()
.purchase(params = params, preferredPurchaseType = PreferredPurchaseType.ONE_STEP, sdkTheme = SdkTheme.LIGHT, purchaseEventListener = null)
.addOnSuccessListener { result ->
// Логика обработки успешного результата покупки
}
.addOnFailureListener { throwable: Throwable ->
when(throwable){
is RuStorePaymentException.ProductPurchaseException -> // Обработка ошибки покупки продукта
is RuStorePaymentException.ProductPurchaseCancelled -> // Обработка отмены покупки продукта
else -> // Обработка ошибки
}
}
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых товаров.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются (при использовании кавычек требуется экранирование). Максимальная длина 250 символов. Символы не экранируются.-
appUserId— внутренний ID пользователя в вашем приложении (опциональный параметр). Строка с максимальной длиной в 128 символов.подсказкаНапример, данный параметр может использоваться для выявления случаев мошенничества в вашем приложении, что позволит повысить его безопасность.
appUserEmail— это необязательный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, его можно передать для автоматического заполнения поляemailпри отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользователя от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.preferredPurchaseType- желаемый тип покупки - одностадийная (ONE_STEP) или двухстадийная (TWO_STEP).sdkTheme- цветовая тема платежной шторки. Доступно 2 вариантаLIGHTиDARK(светлая и темная темы, соответственно). Данный параметр, для сохранения обратной совместимости между версиями SDK, реализован с параметром по умолчаниюLIGHT.purchaseEventListener- набор callback функций, позволяющий получать данные обinvoiceIdиpurchaseIdна разных этапах покупки - опционально.
preferredPurchaseType— желаемый тип покупки: одностадийная (ONE_STEP) или двухстадийная (TWO_STEP).
Данный метод по умолчанию запускается по одностадийному сценарию оплаты (preferredPurchaseType = PreferredPurchaseType.ONE_STEP), т.е. без холдирования средств.
Для двухстадийной оплаты нужно указать preferredPurchaseType = PreferredPurchaseType.TWO_STEP. Двухстадийная оплата (т.е. оплата с холдированием средств) для данного метода не гарантирована и напрямую зависит от того, какой способ оплаты (карта, СПБ и др.) выбрал пользователь.
При запуске данного метода (с предпочитаемым preferredPurchaseType = twoStep), до тех по р пока пользователь не выберет способ оплаты, стадийность покупки будет UNDEFINED. Учитывайте данное поведение при обработке результатов отмены (ProductPurchaseCancelled) или ошибки (ProductPurchaseException) покупки.
Двухстадийная оплата (с холдированием средств)
Для вызова покупки продукта по двухстадийному сценарию используйте метод purchaseTwoStep.
При вызове данного метода пользователю будет доступен ограниченный набор способов оплаты — только те, которые поддерживают двухстадийную оплату.
На данный момент покупка подписки (SubscriptionPurchase) может быть совершена только с использованием одностадийного платежа (PurchaseType.ONE_STEP).
val params = ProductPurchaseParams(
productId = ProductId("productId"),
orderId = null,
quantity = null,
developerPayload = null,
appUserId = null,
appUserEmail = null,
)
RuStorePayClient.instance.getPurchaseInteractor()
.purchaseTwoStep(params = params, sdkTheme = SdkTheme.LIGHT, purchaseEventListener = null)
.addOnSuccessListener { result ->
// Логика обработки успешного результата покупки
}
.addOnFailureListener { throwable: Throwable ->
when(throwable){
is RuStorePaymentException.ProductPurchaseException -> // Обработка ошибки покупки продукта
is RuStorePaymentException.ProductPurchaseCancelled -> // Обработка отмены покупки продукта
else -> // Обработка ошибки
}
}
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых товаров.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются (при использовании кавычек требуется экранирование). Максимальная длина 250 символов. Символы не экранируются.-
appUserId— внутренний ID пользователя в вашем приложении (опциональный параметр). Строка с максимальной длиной в 128 символов.подсказкаНапример, данный параметр может использоваться для выявления случаев мошенничества в вашем приложении, что позволит повысить его безопасность.
appUserEmail— это необязательный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, его можно передать для автоматического заполнения поляemailпри отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользователя от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.preferredPurchaseType- желаемый тип покупки - одностадийная (ONE_STEP) или двухстадийная (TWO_STEP).sdkTheme- цветовая тема платежной шторки. Доступно 2 вариантаLIGHTиDARK(светлая и темная темы, соответственно). Данный параметр, для сохранения обратной совместимости между версиями SDK, реализован с параметром по умолчаниюLIGHT.purchaseEventListener- набор callback функций, позволяющий получать данные обinvoiceIdиpurchaseIdна разных этапах покупки - опционально.
Структура параметров покупки
public class ProductPurchaseParams(
public val productId: ProductId,
public val quantity: Quantity? = null,
public val orderId: OrderId? = null,
public val developerPayload: DeveloperPayload? = null,
public val appUserId: AppUserId? = null,
public val appUserEmail: AppUserEmail? = null,
)
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых товаров.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются (при использовании кавычек требуется экранирование). Максимальная длина 250 символов. Символы не экранируются.-
appUserId— внутренний ID пользователя в вашем приложении (опциональный параметр). Строка с максимальной длиной в 128 символов.подсказкаНапример, данный параметр может использоваться для выявления случаев мошенничества в вашем приложении, что позволит повысить его безопасность.
appUserEmail— это необязательный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, его можно передать для автоматического заполнения поляemailпри отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользова теля от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.
Работа с PurchaseEventListener
Данный интерфейс представляет из себя набор callback функций событий покупки, которые вызываются в процессе покупки.
public interface PurchaseEventListener {
public fun onPurchaseCreated(purchaseId: PurchaseId, invoiceId: InvoiceId)
public fun onPaymentStarted(purchaseId: PurchaseId, invoiceId: InvoiceId)
public fun onPaymentCompleted(purchaseId: PurchaseId, invoiceId: InvoiceId)
public fun onPaymentFailed(purchaseId: PurchaseId?, invoiceId: InvoiceId?)
public fun onPurchaseCancelled(purchaseId: PurchaseId?, invoiceId: InvoiceId?)
}
Реализация передается в методы purchase() и purchaseTwoStep(). Благодаря данным уведомлениям можно получать данные о purchaseId и invoiceId на разных этапах покупки, чтобы взаимодействовать с этой информацией. Например, передать значение в аналитику или сделать запись в базу данных.
val params = ProductPurchaseParams(
productId = ProductId("productId"),
orderId = null,
quantity = null,
developerPayload = null,
appUserId = null,
appUserEmail = null,
)
val purchaseEventListener = object : PurchaseEventListener {
override fun onPurchaseCreated(purchaseId: PurchaseId, invoiceId: InvoiceId) {
// Реализация метода при создании покупки
}
override fun onPaymentStarted(purchaseId: PurchaseId, invoiceId: InvoiceId) {
// Реализация метода при старте покупки
}
override fun onPaymentCompleted(purchaseId: PurchaseId, invoiceId: InvoiceId) {
// Реализация метода при успешном завершении покупки
}
override fun onPaymentFailed(purchaseId: PurchaseId?, invoiceId: InvoiceId?) {
// Реализация метода при неуспешном завершении покупки
}
override fun onPurchaseCancelled(purchaseId: PurchaseId?, invoiceId: InvoiceId?) {
// Реализация метода при отмене покупки
}
}
RuStorePayClient.instance.getPurchaseInteractor()
.purchase(params = params, sdkTheme = SdkTheme.LIGHT, purchaseEventListener = purchaseEventListener)
.addOnSuccessListener { result ->
// Логика обработки успешного результата покупки
}
.addOnFailureListener { throwable: Throwable ->
when(throwable){
is RuStorePaymentException.ProductPurchaseException -> // Обработка ошибки покупки продукта
is RuStorePaymentException.ProductPurchaseCancelled -> // Обработка отмены покупки продукта
else -> // Обработка ошибки
}
}
Оплата с выбором типа покупки
Для вызова покупки продукта с выбором стадийности оплаты используйте метод purchase.
ProductPurchaseParams params = new ProductPurchaseParams(new ProductId("productId"), null, null, null, null, null);
RuStorePayClient ruStorePayClient = RuStorePayClient.Companion.getInstance();
PurchaseInteractor purchaseInteractor = ruStorePayClient.getPurchaseInteractor();
purchaseInteractor.purchase(params, PreferredPurchaseType.ONE_STEP, SdkTheme.LIGHT, null)
.addOnSuccessListener(result -> {
// Логика обработки успешного результата покупки
})
.addOnFailureListener(throwable -> {
if (throwable instanceof RuStorePaymentException.ProductPurchaseException) {
// Обработка ошибки покупки продукта
} else if (throwable instanceof RuStorePaymentException.ProductPurchaseCancelled) {
// Обработка отмены покупки продукта
} else {
// Обработка ошибки
}
});
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity— количество продукта. Необязательный параметр со стандарт ным значением1. Применим только к покупке потребляемых товаров.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются (при использовании кавычек требуется экранирование). Максимальная длина 250 символов. Символы не экранируются.-
appUserId— внутренний ID пользователя в вашем приложении (опциональный параметр). Строка с максимальной длиной в 128 символов.подсказкаНапример, данный параметр может использоваться для выявления случаев мошенничества в вашем приложении, что позволит повысить его безопасность.
appUserEmail— это необязательный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, его можно передать для автоматического заполнения поляemailпри отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользователя от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.preferredPurchaseType- желаемый тип покупки - одностадийная (ONE_STEP) или двухстадийная (TWO_STEP).sdkTheme- цветовая тема платежной шторки. Доступно 2 вариантаLIGHTиDARK(светлая и темная темы, соответственно). Данный параметр, для сохранения обратной совместимости между версиями SDK, реализован с параметром по умолчаниюLIGHT.purchaseEventListener- набор callback функций, позволяющий получать данные обinvoiceIdиpurchaseIdна разных этапах покупки - опционально.
Данный метод по умолчанию запускается по одностадийному сценарию оплаты (preferredPurchaseType = PreferredPurchaseType.ONE_STEP), т.е. без холдирования средств.
Для двухстадийной оплаты нужно указать preferredPurchaseType = PreferredPurchaseType.TWO_STEP. Двухстадийная оплата (т.е. оплата с холдированием средств) для данного метода не гарантирована и напрямую зависит от того, какой способ оплаты (карта, СПБ и др.) выбрал пользователь.
При запуске данного метода (с предпочитаемым preferredPurchaseType = twoStep), до тех пор пока пользователь не выберет способ оплаты, стадийность покупки будет UNDEFINED. Учитывайте данное поведение при обработке результатов отмены (ProductPurchaseCancelled) или ошибки (ProductPurchaseException) покупки.
Двухстадийная оплата (с холдированием средств)
Для вызова покупки продукта по двухстадийному сценарию используйте метод purchaseTwoStep.
При вызове данного метода пользователю будет доступен ограниченный набор способов оплаты — только те, которые поддерживают двухстадийную оплату.
На данный момент покупка подписки (SubscriptionPurchase) может быть совершена только с использованием одностадийного платежа (PurchaseType.ONE_STEP).
ProductPurchaseParams params = new ProductPurchaseParams(new ProductId("productId"), null, null, null, null, null);
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.purchaseTwoStep(params, SdkTheme.LIGHT)
.addOnSuccessListener(result -> {
// Логика обработки успешного результата покупки
})
.addOnFailureListener(throwable -> {
if (throwable instanceof RuStorePaymentException.ProductPurchaseException) {
// Обработка ошибки покупки продукта
} else if (throwable instanceof RuStorePaymentException.ProductPurchaseCancelled) {
// Обработка отмены покупки продукта
} else {
// Обработка ошибки
}
});
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых товаров.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются (при использовании кавычек требуется экранирование). Максимальная длина 250 символов. Символы не экранируются.-
appUserId— внутренний ID пользователя в вашем приложении (опциональный п араметр). Строка с максимальной длиной в 128 символов.подсказкаНапример, данный параметр может использоваться для выявления случаев мошенничества в вашем приложении, что позволит повысить его безопасность.
appUserEmail— это необязательный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, его можно передать для автоматического заполнения поляemailпри отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользователя от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.preferredPurchaseType- желаемый тип покупки - одностадийная (ONE_STEP) или двухстадийная (TWO_STEP).sdkTheme- цветовая тема платежной шторки. Доступно 2 вариантаLIGHTиDARK(светлая и темная темы, соответственно). Данный параметр, для сохранения обратной совместимости между версиями SDK, реализован с параметром по умолчаниюLIGHT.purchaseEventListener- набор callback функций, позволяющий получать данные обinvoiceIdиpurchaseIdна разных этапах покупки - опционально.
Структура параметров покупки
public class ProductPurchaseParams {
private final ProductId productId;
private final Quantity quantity;
private final OrderId orderId;
private final DeveloperPayload developerPayload;
private final AppUserId appUserId;
private final AppUserEmail appUserEmail;
public ProductPurchaseParams(ProductId productId, @Nullable Quantity quantity, @Nullable OrderId orderId, @Nullable DeveloperPayload developerPayload, @Nullable AppUserId appUserId, @Nullable AppUserEmail appUserEmail) {
this.productId = productId;
this.quantity = quantity;
this.orderId = orderId;
this.developerPayload = developerPayload;
this.appUserId = appUserId;
this.appUserEmail = appUserEmail;
}
public ProductId getProductId() {
return productId;
}
public @Nullable Quantity getQuantity() {
return quantity;
}
public @Nullable OrderId getOrderId() {
return orderId;
}
public @Nullable DeveloperPayload getDeveloperPayload() {
return developerPayload;
}
public @Nullable AppUserId getAppUserId() {
return appUserId;
}
public @Nullable AppUserEmail getAppUserEmail() {
return appUserEmail;
}
}
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых товаров.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются (при использовании кавычек требуется экранирование). Максимальная длина 250 символов. Символы не экранируются.-
appUserId— внутренний ID пользователя в вашем приложении (опци ональный параметр). Строка с максимальной длиной в 128 символов.подсказкаНапример, данный параметр может использоваться для выявления случаев мошенничества в вашем приложении, что позволит повысить его безопасность.
appUserEmail— это необязательный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, его можно передать для автоматического заполнения поляemailпри отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользователя от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.
Работа с PurchaseEventListener
Данный интерфейс представляет из себя набор callback функций событий покупки, которые вызываются в процессе покупки.
public interface PurchaseEventListener {
void onPurchaseCreated(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId);
void onPaymentStarted(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId);
void onPaymentCompleted(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId);
void onPaymentFailed(@Nullable PurchaseId purchaseId, @Nullable InvoiceId invoiceId);
void onPurchaseCancelled(@Nullable PurchaseId purchaseId, @Nullable InvoiceId invoiceId);
}
Реализация передается в методы purchase() и purchaseTwoStep(). Благодаря данным уведомлениям можно получать данные о purchaseId и invoiceId на разных этапах покупки, чтобы взаимодействовать с этой информацией. Например, передать значение в аналитику или сделать запись в базу данных.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
ProductPurchaseParams params = new ProductPurchaseParams(new ProductId("productId"), null, null, null, null, null);
PurchaseEventListener purchaseEventListener = new PurchaseEventListener() {
@Override
public void onPurchaseCreated(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId) {
// Реализация метода при создании покупки
}
@Override
public void onPaymentStarted(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId) {
// Реализация метода при старте покупки
}
@Override
public void onPaymentCompleted(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId) {
// Реализация метода при успешном завершении покупки
}
@Override
public void onPaymentFailed(@Nullable PurchaseId purchaseId, @Nullable InvoiceId invoiceId) {
// Реализация метода при неуспешном завершении покупки
}
@Override
public void onPurchaseCancelled(@Nullable PurchaseId purchaseId, @Nullable InvoiceId invoiceId) {
// Реализация метода при отмене покупки
}
};
purchaseInteractor.purchase(params, PreferredPurchaseType.ONE_STEP, SdkTheme.LIGHT, purchaseEventListener)
.addOnSuccessListener(result -> {
// Логика обработки успешного результата покупки
})
.addOnFailureListener(throwable -> {
if (throwable instanceof RuStorePaymentException.ProductPurchaseException) {
// Обработка ошибки покупки продукта
} else if (throwable instanceof RuStorePaymentException.ProductPurchaseCancelled) {
// Обработка отмены покупки продукта
} else {
// Обработка ошибки
}
});
Working with PurchaseEventListener
This interface is a set of purchase-event callbacks that are triggered during the purchase process.
public interface PurchaseEventListener {
void onPurchaseCreated(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId);
void onPaymentStarted(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId);
void onPaymentCompleted(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId);
void onPaymentFailed(@Nullable PurchaseId purchaseId, @Nullable InvoiceId invoiceId);
void onPurchaseCancelled(@Nullable PurchaseId purchaseId, @Nullable InvoiceId invoiceId);
}
The implementation is passed to the purchase() and purchaseTwoStep() methods. These notifications allow you to receive purchaseId and invoiceId at different stages of the purchase flow and use this information as needed. For example, you can send these values to analytics or store them in a database.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
ProductPurchaseParams params = new ProductPurchaseParams(new ProductId("productId"), null, null, null, null, null);
PurchaseEventListener purchaseEventListener = new PurchaseEventListener() {
@Override
public void onPurchaseCreated(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId) {
// Method implementation when a purchase is created
}
@Override
public void onPaymentStarted(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId) {
// Method implementation when the payment starts
}
@Override
public void onPaymentCompleted(@NotNull PurchaseId purchaseId, @NotNull InvoiceId invoiceId) {
// Method implementation when the payment is successfully completed
}
@Override
public void onPaymentFailed(@Nullable PurchaseId purchaseId, @Nullable InvoiceId invoiceId) {
// Method implementation when the payment fails
}
@Override
public void onPurchaseCancelled(@Nullable PurchaseId purchaseId, @Nullable InvoiceId invoiceId) {
// Method implementation when the purchase is cancelled
}
};
purchaseInteractor.purchase(params, PreferredPurchaseType.ONE_STEP, SdkTheme.LIGHT, purchaseEventListener)
.addOnSuccessListener(result -> {
// Logic for handling a successful purchase result
})
.addOnFailureListener(throwable -> {
if (throwable instanceof RuStorePaymentException.ProductPurchaseException) {
// Handle product purchase error
} else if (throwable instanceof RuStorePaymentException.ProductPurchaseCancelled) {
// Handle product purchase cancellation
} else {
// Handle error
}
});
Структура результата покупки
ProductPurchaseResult - результат успешной оплаты цифрового товара, подписки (для одностадийной оплаты)
или успешного холдирования средств (для двухстадийной оплаты).
- Kotlin
- Java
public class ProductPurchaseResult internal constructor(
public val orderId: OrderId?,
public val purchaseId: PurchaseId,
public val productId: ProductId,
public val invoiceId: InvoiceId,
public val purchaseType: PurchaseType,
public val productType: ProductType,
public val quantity: Quantity,
public val sandbox: Boolean,
)
public class ProductPurchaseResult {
private final OrderId orderId;
private final PurchaseId purchaseId;
private final ProductId productId;
private final InvoiceId invoiceId;
private final PurchaseType purchaseType;
private final ProductType productType;
private final Quantity quantity;
private final boolean sandbox;
public ProductPurchaseResult(OrderId orderId,
PurchaseId purchaseId,
ProductId productId,
InvoiceId invoiceId,
PurchaseType purchaseType,
ProductType productType,
Quantity quantity,
boolean sandbox) {
this.orderId = orderId;
this.purchaseId = purchaseId;
this.productId = productId;
this.invoiceId = invoiceId;
this.purchaseType = purchaseType;
this.productType = productType;
this.quantity = quantity;
this.sandbox = sandbox;
}
public OrderId getOrderId() {
return orderId;
}
public PurchaseId getPurchaseId() {
return purchaseId;
}
public ProductId getProductId() {
return productId;
}
public InvoiceId getInvoiceId() {
return invoiceId;
}
public PurchaseType getPurchaseType() {
return purchaseType;
}
public ProductType getProductType() {
return productType;
}
public Quantity getQuantity() {
return quantity;
}
public boolean isSandbox() {
return sandbox;
}
}
-
ProductPurchaseResult— результат успешной оплаты цифрового товара (для одностадийной оплаты) или успешного холдирования средств (для двухстадийной оплаты).purchaseId- идентификатор покупки. Используется для получения информации о покупке в SDK методом получения информации о покупке и серверной валидации подписки.productId- идентификатор приобретенного продукта, указанный при создании в консоли разработчика RuStore.invoiceId- идентификатор счета. Используется для серверной валидации платежа, поиска платежей в консоли разработчика, а также отображается покупателю в истории платежей в мобильном приложении RuStore.orderId- уникальный идентификатор оплаты, указанный разработчиком или сформированный автоматически (uuid).purchaseType- тип покупки (ONE_STEP/TWO_STEP/UNDEFINED- одностадийная/двухстадийная/стадийность не определена).productType- тип продукта (NON_CONSUMABLE_PRODUCT- непотребляемый товар,CONSUMABLE_PRODUCT- потребляемый товар,SUBSCRIPTION- подписка).quantity- количество товара, заданное при старте покупки.sandbox- флаг, указывающий признак тестового платежа в песочнице. ЕслиTRUE- покупка совершена в режиме тестирования.
Подтверждение покупки
- Kotlin
- Java
Подтверждения требуют только покупки, которые были запущены по двухстадийному сценарию оплаты, т.е. с холдированием средств. Такие покупки, после успешного холдирования будут находиться в статусе PurchaseStatus.PAID.
Для списания средств с карты покупателя требуется подтверждение покупки. Для этого вы должны использовать метод confirmTwoStepPurchase.
RuStorePayClient.instance.getPurchaseInteractor().confirmTwoStepPurchase(
purchaseId = PurchaseId("purchaseId"),
developerPayload = null,
)
.addOnSuccessListener {
// Логика успешного подтверждения покупки
}.addOnFailureListener { throwable: Throwable ->
// Обработка ошибки
}
purchaseId— идентификатор покупки.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются (при использовании кавычек требуется экранирование). Максимум 250 символов (символы не экранируются). Если передан, заменяет значение, записанное при старте покупки методомpurchase/purchaseTwoStep.
Подтверждения требуют только покупки, которые были запущены по двухстадийному сценарию оплаты, т.е. с холдированием средств. Такие покупки, после успешного холдирования будут находиться в статусе PurchaseStatus.PAID.
Для списания средств с карты по купателя требуется подтверждение покупки. Для этого вы должны использовать метод confirmTwoStepPurchase.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.confirmTwoStepPurchase(
new PurchaseId("purchaseId"),
null
).addOnSuccessListener( success -> {
// Логика успе шного подтверждения покупки
}).addOnFailureListener(throwable -> {
// Обработка ошибки
});
purchaseId— идентификатор покупки.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются (при использовании кавычек требуется экранирование). Максимум 250 символов (символы не экранируются). Если передан, заменяет значение, записанное при старте покупки методомpurchase/purchaseTwoStep.
Отмена покупки
Через SDK можно отменять только те покупки, которые были запущены по двухстадийному сценарию оплаты, т.е. с холдированием средств. Такие покупки после успешного холдирования будут находиться в статусе PurchaseStatus.PAID. После отмены покупки будут переходить в статус PurchaseStatus.REVERSED.
Используйте отмену покупки в случаях, если после оплаты (холдирования средств) вы не можете предоставить покупателю товар.
Для отмены покупки (холда) используйте метод cancelTwoStepPurchase.
- Kotlin
- Java
RuStorePayClient.instance.getPurchaseInteractor().cancelTwoStepPurchase(
purchaseId = PurchaseId("purchaseId"),
)
.addOnSuccessListener {
// Логика обработки успешной отмены покупки
}.addOnFailureListener { throwable: Throwable ->
// Обработка ошибки
}
purchaseId— идентификатор покупки.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.cancelTwoStepPurchase(
new PurchaseId("purchaseId")
).addOnSuccessListener(success -> {
// Process success
}).addOnFailureListener(throwable -> {
// Process error
});
purchaseId— идентификатор покупки.
Работа с подтверждением выдачи товара
Для обновления состояния подтверждения покупки используйте метод updateAcknowledgementState.
- Kotlin
- Java
RuStorePayClient.instance.getPurchaseInteractor()
.updateAcknowledgementState(
purchaseId = purchaseId,
state = AcknowledgementState.ACKNOWLEDGED,
developerPayload = null,
)
.addOnSuccessListener { state ->
// Состояние выдачи товара обновлено
}
.addOnFailureListener { throwable ->
// Обработка ошибки
}
Логика не является обязательной и не влияет на проведение платежей. Она позволяет хранить на стороне RuStore состояние обработки покупки, чтобы затем при получении списка покупок с отдельной фильтрацией выбирать только необработанные покупки и выполнять по ним выдачу товара.
После успешного проведения платежа статус выдачи товара по умолчанию имеет значение PENDING.
Для платежей, совершённых в более ранних версиях SDK, где эта логика ещё не поддерживалась, используется статус UNKNOWN. При необходимости такой статус можно изменить на любой другой.
Статус обработки можно изменять в обе стороны: например, переводить покупку из PENDING в ACKNOWLEDGED, а также возвращать её в предыдущий статус, если требуется отозвать ранее выданный товар, например после возврата платежа.
При вызове этого метода значение developerPayload можно обновить. Если параметр передан, текущее значение будет перезаписано. Если параметр не передан, сохранится текущее значение developerPayload.
purchaseInteractor.updateAcknowledgementState(
purchaseId,
AcknowledgementState.ACKNOWLEDGED,
null
)
.addOnSuccessListener(state -> {
// Состояние выдачи товара обновлено
})
.addOnFailureListener(throwable -> {
// Обработка ошибки
});
Логика не является обязательной и не влияет на проведение платежей. Она позволяет хранить на стороне RuStore состояние обработки покупки, чтобы затем при получении списка покупок с отдельной фильтрацией выбирать только необработанные покупки и выполнять по ним выдачу товара.
После успешного проведения платежа статус выдачи товара по умолчанию имеет значение PENDING.
Для платежей, совершённых в более ранних версиях SDK, где эта логика ещё не поддерживалась, используется статус UNKNOWN. При необходимости такой статус можно изменить на любой другой.
Статус обработки можно изменять в обе стороны: например, переводить покупку из PENDING в ACKNOWLEDGED, а также возвращать её в предыдущий статус, если требуется отозвать ранее выданный товар, например после возврата платежа.
При вызове этого метода значение developerPayload можно обновить. Если параметр передан, текущее значение будет перезаписано. Если параметр не передан, сохранится текущее значение developerPayload.
Получение сведений о покупке
- Kotlin
- Java
getPurchase.
RuStorePayClient.instance.getPurchaseInteractor().getPurchase(PurchaseId("purchaseId"))
.addOnSuccessListener { purchase: Purchase ->
when(purchase) {
is ProductPurchase -> {
// Логика обр аботки результата покупки продукта
}
is SubscriptionPurchase -> {
// Логика обработки результата покупки подписки
}
else -> {
// Логика обработки результата покупки c базовыми полями
}
}
}
.addOnFailureListener { throwable: Throwable ->
// Обработка ошибки
}
Метод возвращает информацию о конкретной покупке в любом статусе.
Детали моделей покупки ProductPurchase и SubscriptionPurchase представлены в соответствующих разделах.
Пример ответа — вывод toString() полученной модели (иллюстрация структуры, не компилируемый код).
ProductPurchase(
purchaseId=PurchaseId(value='purchaseId'),
productId=ProductId(value='game_coins_1000'),
invoiceId=InvoiceId(value='invoiceId'),
orderId=OrderId(value='orderId'),
purchaseType=ONE_STEP,
productType=CONSUMABLE_PRODUCT,
description=Description(value='description'),
purchaseTime=123123123124,
price=Price(value='14100'),
amountLabel=AmountLabel(value='141,00 ₽'),
currency=Currency(value='RUB'),
quantity=Quantity(value='1'),
status=CONFIRMED,
developerPayload='DeveloperPayload(value='developerPayload')',
sandbox=false,
acknowledgementState=PENDING
)
SubscriptionPurchase(
purchaseId=PurchaseId(value='sub_purchase_12345'),
invoiceId=InvoiceId(value='inv_sub_67890'),
orderId=OrderId(value='order_sub_abcde'),
purchaseType=ONE_STEP,
description=Description(value='Ежемесячная подписка на «Премиум»'),
purchaseTime=123123123124,
price=Price(value='29900'),
amountLabel=AmountLabel(value='299 ₽'),
currency=Currency(value='RUB'),
status=ACTIVE,
developerPayload='DeveloperPayload(value='user_id:123;source:profile')',
sandbox=false,
productId=ProductId(value='premium_monthly_v1'),
expirationDate='Sat Aug 01 12:00:00 GMT+03:00 2026',
gracePeriodEnabled='true',
acknowledgementState=ACKNOWLEDGED
)
getPurchase.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.getPurchase(new PurchaseId("purchaseId"))
.addOnSuccessListener(purchase -> {
if (purchase instanceof ProductPurchase productPurchase) {
// Логика обработки результата покупки продукта
} else if (purchase instanceof SubscriptionPurchase subscriptionPurchase) {
// Логика обработки результата покупки подписки
} else {
// Логика обработки результата покупки c базовыми полями
}
})
.addOnFailureListener(throwable -> {
// Обработка ошибки
});
Метод возвращает информацию о конкретной покупке в любом статусе.
Детали моделей покупки ProductPurchase и SubscriptionPurchase представлены в соответствующих разделах.
Получение списка покупок
- Kotlin
- Java
Для получения списка покупок пользователя используйте метод getPurchases.
RuStorePayClient.instance.getPurchaseInteractor().getPurchases()
.addOnSuccessListener { purchases: List<Purchase> ->
// Логика работы со списком покупок пользователя
}
.addOnFailureListener { throwable: Throwable ->
// Обработка ошибки
}
Данный метод позволяет фильтровать покупки по трем параметрам:
Тип товара (productType):
CONSUMABLE_PRODUCT— потребляемый товар;NON_CONSUMABLE_PRODUCT— непотребляемый товар;SUBSCRIPTION— подписка.
Статус покупки (purchaseStatus):
PAID— успешное холдирование средств, покупка ожидает подтверждения со стороны разработчика (для продуктов);CONFIRMED— покупка подтверждена, средства списаны (для продуктов);ACTIVE— подписка активна (для подписок);PAUSED— подписка в холд периоде: не удалось провести платеж (например, недостаточно средств на карте), но продолжаются попытки списания (для подписок).
Состояние выдачи товара (acknowledgementState):
PENDING— ожидает выдачи товара;ACKNOWLEDGED— товар выдан;UNKNOWN— логика не применима к платежу.
По умолчанию все фильтры выключены и возвращаются все покупки пользователя.
RuStorePayClient.instance.getPurchaseInteractor().getPurchases(
productType = ProductType.CONSUMABLE_PRODUCT,
purchaseStatus = ProductPurchaseStatus.PAID,
)
.addOnSuccessListener { purchases: List<Purchase> ->
// Логика работы со списком покупок пользователя
}
.addOnFailureListener { throwable: Throwable ->
// Обработка ошибки
}
Для получения списка покупок пользователя используйте метод getPurchases.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.getPurchases(null, null, null)
.addOnSuccessListener(purchases -> {
// Логика работы со списком покупок пользователя
})
.addOnFailureListener(error -> {
// Обработка ошибки
});
Данный метод позволяет фильтровать покупки по трем параметрам:
Тип товара (productType):
CONSUMABLE_PRODUCT— потребляемый товар;NON_CONSUMABLE_PRODUCT— непотребляемый товар;SUBSCRIPTION— подписка.
Статус покупки (purchaseStatus):
PAID— успешное холдирование средств, покупка ожидает подтверждения со стороны разработчика (для продуктов);CONFIRMED— покупка подтверждена, средства списаны (для продуктов);ACTIVE— подписка активна (для подписок);PAUSED— подписка в холд периоде: не удалось провести платеж (например, недостаточно средств на карте), но продолжаются попытки списания (для подписок).
Состояние выдачи товара (acknowledgementState):
PENDING— ожидает выдачи товара;ACKNOWLEDGED— товар выдан;UNKNOWN— логика не применима к платежу.
По умолчанию все фильтры выключены и возвращаются все покупки пользователя.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.getPurchases(ProductType.CONSUMABLE_PRODUCT, ProductPurchaseStatus.PAID, null)
.addOnSuccessListener(purchases -> {
// Логика работы со списком покупок пользователя
})
.addOnFailureListener(error -> {
// Обработка ошибки
});
Типы покупок
В SDK предусмотрен базовый интерфейс Purchase, который объединяет общие поля всех типов покупок.
На его основе созданы две реализации:
- ProductPurchase: для потребляемых и непотребляемых покупок.
- SubscriptionPurchase: для подписок.
Данное разделение позволяет каждому типу покупки иметь свои уникальные свойства и поведение.
- Kotlin
- Java
public interface Purchase {
public val purchaseId: PurchaseId
public val invoiceId: InvoiceId
public val orderId: OrderId?
public val purchaseType: PurchaseType
public val status: PurchaseStatus
public val description: Description
public val purchaseTime: Date?
public val price: Price
public val amountLabel: AmountLabel
public val currency: Currency
public val developerPayload: DeveloperPayload?
public val sandbox: Boolean
}
public interface Purchase {
PurchaseId getPurchaseId();
InvoiceId getInvoiceId();
@Nullable OrderId getOrderId();
PurchaseType getPurchaseType();
PurchaseStatus getStatus();
Description getDescription();
@Nullable Date getPurchaseTime();
Price getPrice();
AmountLabel getAmountLabel();
Currency getCurrency();
@Nullable DeveloperPayload getDeveloperPayload();
boolean isSandbox();
}
Модель разовой покупки ProductPurchase
- Kotlin
- Java
public class ProductPurchase internal constructor(
public override val purchaseId: PurchaseId,
public override val invoiceId: InvoiceId,
public override val orderId: OrderId?,
public override val purchaseType: PurchaseType,
public override val status: ProductPurchaseStatus,
public override val description: Description,
public override val purchaseTime: Date?,
public override val price: Price,
public override val amountLabel: AmountLabel,
public override val currency: Currency,
public override val developerPayload: DeveloperPayload?,
public override val sandbox: Boolean,
public val productId: ProductId,
public val quantity: Quantity,
public val productType: ProductType,
public val acknowledgementState: AcknowledgementState,
) : Purchase
public class ProductPurchase implements Purchase {
private final PurchaseId purchaseId;
private final InvoiceId invoiceId;
private final OrderId orderId;
private final PurchaseType purchaseType;
private final ProductPurchaseStatus status;
private final Description description;
private final Date purchaseTime;
private final Price price;
private final AmountLabel amountLabel;
private final Currency currency;
private final DeveloperPayload developerPayload;
private final boolean sandbox;
private final ProductId productId;
private final Quantity quantity;
private final ProductType productType;
private final AcknowledgementState acknowledgementState;
@Override
public PurchaseId getPurchaseId() { return purchaseId; }
@Override
public InvoiceId getInvoiceId() { return invoiceId; }
@Override
public @Nullable OrderId getOrderId() { return orderId; }
@Override
public PurchaseType getPurchaseType() { return purchaseType; }
@Override
public ProductPurchaseStatus getStatus() { return status; }
@Override
public Description getDescription() { return description; }
@Override
public @Nullable Date getPurchaseTime() { return purchaseTime; }
@Override
public Price getPrice() { return price; }
@Override
public AmountLabel getAmountLabel() { return amountLabel; }
@Override
public Currency getCurrency() { return currency; }
@Override
public @Nullable DeveloperPayload getDeveloperPayload() { return developerPayload; }
@Override
public boolean isSandbox() { return sandbox; }
public ProductId getProductId() { return productId; }
public Quantity getQuantity() { return quantity; }
public ProductType getProductType() { return productType; }
public AcknowledgementState getAcknowledgementState() { return acknowledgementState; }
}
purchaseId— идентификатор покупки. Идентификатор покупки. Используется для получения информации о покупке в SDK методом получения информации о покупке.invoiceId— идентификатор счета. Идентификатор счёта. Используется для серверной валидации платежа, поиска платежей в консоли разработчика, а также отображается покупателю в истории платежей в мобильном приложении RuStore.orderId- уникальный идентификатор оплаты, указанный разработчиком или сформированный автоматически (uuid).PurchaseType— тип покупки:ONE_STEP- одностадийная покупка;TWO_STEP- двухстадийная покупка;UNDEFINED- стадийность не определена.
status— состояние покупки:INVOICE_CREATED— создан счет на оплату, покупка ожидает оплаты;CANCELLED— покупка отменена покупателем;PROCESSING— запущена оплата;REJECTED— покупка отклонена (например, ввиду недостатка средств);EXPIRED— истекло время на оплату покупки;PAID— только для двухстадийной оплаты, промежуточный статус, средства на счете покупателя захолдированы, покупка ожидает подтверждения от разработчика;CONFIRMED— покупка успешно оплачена;REFUNDING— инициирован возврат средств, запрос отправлен в эквайер;REFUNDED— запрос на возврат средств за покупку совершен успешно. Деньги будут возвращены пользователю в течение 10 рабочих дней.;EXECUTING— покупка находится в процессе выполнения;REVERSED— только для двухстадийной оплаты, покупка была отменена разработчиком или не было произведено подтверждение покупки в течение 6 часов, холдирование средств отменено.
description- описание поку пки.purchaseTime— время покупки.price— цена в минимальных единицах (в копейках).amountLabel— отформатированная цена покупки, включая валютный знак.currency— код валюты ISO 4217.-
developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются (при использовании кавычек требуется экранирование) -
sandbox— флаг тестового платежа. Значениеtrue— тестовый платеж,false— реальный платеж. productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр). Идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity— количество продукта.productType— тип продукта. (CONSUMABLE_PRODUCT/NON_CONSUMABLE_PRODUCT/SUBSCRIPTION- потребляемый/непотребляемый/подписка.)acknowledgementState— состояние выдачи товара. Воз можные значения:PENDING(ожидает выдачи товара),ACKNOWLEDGED(товар выдан),UNKNOWN(логика не применима к платежу).
Статусная модель покупки
Статусная модель одностадийного платежа.
Статусная модель двухстадийного платежа.
Модель подписки
- Kotlin
- Java
public class SubscriptionPurchase internal constructor(
public override val purchaseId: PurchaseId,
public override val invoiceId: InvoiceId,
public override val orderId: OrderId?,
public override val purchaseType: PurchaseType,
public override val status: SubscriptionPurchaseStatus,
public override val description: Description,
public override val purchaseTime: Date?,
public override val price: Price,
public override val amountLabel: AmountLabel,
public override val currency: Currency,
public override val developerPayload: DeveloperPayload?,
public override val sandbox: Boolean,
public val productId: ProductId,
public val expirationDate: Date,
public val gracePeriodEnabled: Boolean,
public val acknowledgementState: AcknowledgementState,
) : Purchase
public class SubscriptionPurchase implements Purchase {
private final PurchaseId purchaseId;
private final InvoiceId invoiceId;
private final OrderId orderId;
private final PurchaseType purchaseType;
private final SubscriptionPurchaseStatus status;
private final Description description;
private final Date purchaseTime;
private final Price price;
private final AmountLabel amountLabel;
private final Currency currency;
private final DeveloperPayload developerPayload;
private final boolean sandbox;
private final ProductId productId;
private final Date expirationDate;
private final boolean gracePeriodEnabled;
private final AcknowledgementState acknowledgementState;
@Override
public PurchaseId getPurchaseId() { return purchaseId; }
@Override
public InvoiceId getInvoiceId() { return invoiceId; }
@Override
public @Nullable OrderId getOrderId() { return orderId; }
@Override
public PurchaseType getPurchaseType() { return purchaseType; }
@Override
public SubscriptionPurchaseStatus getStatus() { return status; }
@Override
public Description getDescription() { return description; }
@Override
public @Nullable Date getPurchaseTime() { return purchaseTime; }
@Override
public Price getPrice() { return price; }
@Override
public AmountLabel getAmountLabel() { return amountLabel; }
@Override
public Currency getCurrency() { return currency; }
@Override
public @Nullable DeveloperPayload getDeveloperPayload() { return developerPayload; }
@Override
public boolean isSandbox() { return sandbox; }
public ProductId getProductId() { return productId; }
public Date getExpirationDate() { return expirationDate; }
public boolean isGracePeriodEnabled() { return gracePeriodEnabled; }
public AcknowledgementState getAcknowledgementState() { return acknowledgementState; }
}
purchaseId— идентификатор покупки. Идентификатор покупки. Используется для получения информации о покупке в SDK методом получения информации о покупке.invoiceId— идентификатор счета. Идентификатор счёта. Используется для серверной валидации платежа, поиска платежей в консоли разработчика, а также отображается покупателю в истории платежей.orderId- уникальный идентификатор оплаты, указанный разработчиком или сформированный автоматически (uuid).PurchaseType— тип покупки:ONE_STEP- одностадийная покупка;TWO_STEP- двухстадийная покупка;UNDEFINED- стадийность не определена.
status- состояние подписки:INVOICE_CREATED- создан счет на оплату, подписка ожидает оплаты.CANCELLED- счет на оплату подписки отменен.EXPIRED- срок действия оплаты счета истек.PROCESSING- первый платеж по подписке в обработке.REJECTED- первый платеж по подписке отклонен. Подписка не оформлена.ACTIVE- п одписка активна.PAUSED- подписка приостановлена из-за проблем с оплатой.TERMINATED- закончились попытки списания по подписке (все были неуспешными). Подписка закрыта автоматически из-за проблем с оплатой.CLOSED- подписка была отменена пользователем или разработчиком. Истек срок оплаченного периода, подписка закрыта.
description- описание покупки.purchaseTime— время покупки.price— цена в минимальных единицах (в копейках).amountLabel— отформатированная цена покупки, включая валютный знак.currency— код валюты ISO 4217.-
developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются (при использовании кавычек требуется экранирование) -
sandbox— флаг тестового платежа. Значениеtrue— тестовый платеж,false— реальный платеж. productId— идентификатор продукта, который был присво ен продукту в RuStore Консоли (обязательный параметр). Идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).expirationDate- дата окончания действия подписки.gracePeriodEnabled- флаг, указывающий, активен ли Grace-период для подписки.acknowledgementState— состояние выдачи товара. Возможные значения:PENDING(ожидает выдачи товара),ACKNOWLEDGED(товар выдан),UNKNOWN(логика не применима к платежу).
Статусная модель подписки
Получение списка подписок, оформленных в SDK Billing Client
- Kotlin
- Java
RuStorePayClient.instance.getPurchaseInteractor().getBillingSubscriptions()
.addOnSuccessListener { subscriptions: List<BillingSubscription> ->
// Логика работы со списком подписок пользователя
}
.addOnFailureListener { throwable: Throwable ->
// Обработка ошибки
}
Метод возвращает список подписок, оформленных в SDK Billing Client.
Пример ответа.
BillingSubscription(
purchaseId = PurchaseId("sub_purchase_12345"),
invoiceId = InvoiceId("inv_sub_67890"),
orderId = OrderId("order_sub_abcde"),
purchaseType = PurchaseType.ONE_STEP,
status = SubscriptionPurchaseStatus.ACTIVE,
description = Description("Ежемесячная подписка на 'Премиум'"),
purchaseTime = Date(),
price = Price(29900), // Цена в копейках
amountLabel = AmountLabel("299 ₽"),
currency = Currency("RUB"),
developerPayload = DeveloperPayload("user_id:123;source:profile"),
sandbox = false,
productId = ProductId("premium_monthly_v1"),
expirationDate = Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(30)),
gracePeriodEnabled = true,
subscriptionToken = SubscriptionToken("special_validation_token"),
)
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.getBillingSubscriptions()
.addOnSuccessListener(subscriptions -> {
// Логика р аботы со списком подписок пользователя
})
.addOnFailureListener(error -> {
// Обработка ошибки
});
Метод возвращает список подписок, оформленных в SDK Billing Client.