BillingClient SDK помечён как устаревший. BillingClient SDK продолжает свою работу, но устранение неи справностей, влияющих на работу платежей, может занимать больше времени. Новая функциональность добавляться не будет.
Рекомендуем использовать Pay SDK в проектах. Для перехода на Pay SDK воспользуйтесь инструкцией по миграции
SDK Платежи in-app и подписки для Kotlin/Java (версия 6.0.0)
RuStore позволяет интегрировать платежи в мобильное приложение.
Если не знаете с чего начать, прочтите инструкцию в сценариях использования.
Подготовка к работе
- Kotlin
- Java
Добавление репозитория
Подключите репозиторий, как показано в примере ниже.
repositories {
maven {
url = uri("https://artifactory-external.vkpartner.ru/artifactory/maven")
}
}
Подключение зависимости
Добавьте следующий код в свой конфигурационный файл для подключения зависимости.
- Подключение BOM
- Подключение версии напрямую
Преимущества использования BOM-файла для конфигурации.
-
Единое управление версиями:
- С BOM вы можете управлять версиями всех зависимостей из одного файла. Это особенно полезно, если вы используете несколько библиотек, которые должны быть совместимы друг с другом.
- Например, если у вас есть несколько библиотек от RuStore, таких как
ru.rustore.sdk:billingclientиru.rustore.sdk:pushclient, вы можете использовать BOM, чтобы гарантировать, что все они будут совместимы друг с другом.
-
Упрощение обновлений:
- Обновление зависимостей становится проще, так как вам нужно изменить версию только в одном месте — в BOM-файле. Это снижает риск пропустить обновление какой-либо зависимости и избежать конфликтов версий.
- Например, если новая версия BOM-файла содержит обновленные версии всех библиотек, вам достаточно обновить только BOM-файл, а не каждую зависимость по отдельности.
-
Повышение совместимости:
- Использование BOM помогает избежать конфликтов версий между различными библиотеками. Это особенно важно, когда библиотеки имеют зависимости друг от друга.
- Например, если две библиотеки зависят от разных версий одной и той же библиотеки, это может вызвать конфликты. BOM помогает избежать таких ситуаций, гарантируя, что все зависимости совместимы.
dependencies {
implementation(platform("ru.rustore.sdk:bom:6.0.0"))
implementation("ru.rustore.sdk:billingclient")
}
dependencies {
implementation("ru.rustore.sdk:billingclient:6.0.0")
}
Добавление репозитория
Подключите репозиторий, как показано в примере ниже.
repositories {
maven {
url "https://artifactory-external.vkpartner.ru/artifactory/maven"
}
}
Подключение зависимости
Добавьте следующий код в свой конфигурационный файл для подключения зависимости.
- Подключение BOM
- Подключение версии напрямую
Преимущества использования BOM-файла для конфигурации.
-
Единое управление версиями:
- С BOM вы можете управлять версиями всех зависимостей из одного файла. Это особенно полезно, если вы используете несколько библиотек, которые должны быть совместимы друг с другом.
- Например, если у вас есть несколько библиотек от RuStore, таких как
ru.rustore.sdk:billingclientиru.rustore.sdk:pushclient, вы можете использовать BOM, чтобы гарантировать, что все они будут совместимы друг с другом.
-
Упрощение обновлений:
- Обновление зависимостей становится проще, так как вам нужно изменить версию только в одном месте — в BOM-файле. Это снижает риск пропустить обновление какой-либо зависимости и избежать конфликтов версий.
- Например, если новая версия BOM-файла содержит обновленные версии всех библиотек, вам достаточно обновить только BOM-файл, а не каждую зависимость по отдельности.
-
Повышение совместимости:
- Использование BOM помогает избежать конфликтов версий между различными библиотеками. Это особенно важно, когда библиотеки имеют зависимости друг от друга.
- Например, если две библиотеки зависят от разных версий одной и той же библиотеки, это может вызвать конфликты. BOM помогает избежать таких ситуаций, гарантируя, что все зависимости совместимы.
dependencies {
implementation platform("ru.rustore.sdk:bom:6.0.0")
implementation "ru.rustore.sdk:billingclient"
}
dependencies {
implementation "ru.rustore.sdk:billingclient:6.0.0"
}
Обработка deeplink
- Kotlin
- Java
class YourBillingActivity: AppCompatActivity() {
// Previously created with RuStoreBillingClientFactory.create()
private val billingClient: RuStoreBillingClient = YourDependencyInjection.getBillingClient()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
billingClient.onNewIntent(intent)
}
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
billingClient.onNewIntent(intent)
}
}
Для восстановления состояния вашего приложения при возврате с deeplink добавьте в
AndroidManifest.xml android:launchMode="singleTask".
<activity
android:name=".YourBillingActivity"
android:launchMode="singleTask"
android:exported="true"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
public class YourBillingActivity extends AppCompatActivity {
// Previously created with RuStoreBillingClientFactory.create();
RuStoreBillingClient billingClient = YourDependencyInjection.getBillingClient();
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
billingClient.onNewIntent(getIntent());
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
billingClient.onNewIntent(intent);
}
}
Для восстановления состояния вашего приложения при возврате с deeplink добавьте в
AndroidManifest.xml android:launchMode="singleTask".
<activity
android:name=".YourBillingActivity"
android:launchMode="singleTask"
android:exported="true"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
Инициализация SDK
Перед вызовом методов библиотеки необходимо выполнить её инициализацию.
- Kotlin
- Java
Создайте RuStoreBillingClient, используя RuStoreBillingClientFactory.create().
val billingClient: RuStoreBillingClient = RuStoreBillingClientFactory.create(
context = app,
consoleApplicationId = "111111",
deeplinkScheme = "yourappscheme",
// Опциональные параметры
themeProvider = null,
debugLogs = false,
externalPaymentLoggerFactory = null,
)
-
context— это ключевой элемент, который предоставляет информацию о текущем состоянии приложения или объекта.к сведениюВ Android существует несколько типов контекста:
- Контекст приложения — это singleton-экземпляр, доступный через
getApplicationContext(). - Контекст
Activity— доступен внутриActivityи привязан к её жизненному циклу. - Контекст в
ContentProvider— доступен через методgetContext()и аналогичен контексту приложения.
Для создания
RuStoreBillingClientпредпочтительнее использоватьapplicationContext. - Контекст приложения — это singleton-экземпляр, доступный через
-
consoleApplicationId— идентификатор приложения из RuStore консоли.
Где в RuStore Консоль отображаются идентификаторы приложений?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Скопируйте идентификатор из URL-адреса страницы приложения — это набор цифр между
apps/и/versions. Например, для URL-адресаhttps://console.rustore.ru/apps/123456/versionsID приложения —123456.

ApplicationId, указанный в build.gradle, должен совпадать с applicationId APK-файла, который вы публиковали в RuStore Консоль.
-
deeplinkScheme— схема deeplink, необходимая для возврата в ваше приложение после оплаты через стороннее приложение (например, SberPay или СБП). SDK генерирует свой хост к данной схеме.
yourappscheme, должна совпадать со схемой, указанной в AndroidManifest.xml (подробнее см. Обработка deeplink).-
themeProvider— интерфейс, кото рый предоставляет темуBillingClientTheme. Возможны 2 реализации темыBillingClientTheme: светлая (Light) и тёмная (Dark). Необязательный интерфейс, по умолчанию применяется светлая тема.
примечаниеПо умолчанию тема будет светлой (
Light), но вы можете настроить и тёмную (Dark). -
externalPaymentLoggerFactory— интерфейс, позволяющий вести журнал событий.подсказкаЖурнал событий полезен для версий, которые ещё не опубликованы на пользователей. С его помощью можно отследить возникающие ошибки.
-
debugLogs— флаг, регулирующий ведение журнала событий. Укажите значениеtrue, если хотите, чтобы события попадали в журнал. В ином случае укажитеfalse.
Подпись keystore должна совпадать с подписью, которой было подписано приложение, опубликованно е в RuStore Консоль. Убедитесь, что используемый buildType (пр. debug) использует такую же подпись, что и опубликованное приложение (пр. release).
Создайте RuStoreBillingClient, используя RuStoreBillingClientFactory.create().
final Context context = getContext();
final String consoleApplicationId = "111111";
final String deeplinkScheme = "yourappscheme";
// Опциональные параметры
final BillingClientThemeProvider themeProvider = null;
final boolean debugLogs = false;
final ExternalPaymentLoggerFactory externalPaymentLoggerFactory = null;
final SuperAppTokenProvider superAppTokenProvider = null;
RuStoreBillingClient billingClient = RuStoreBillingClientFactory.INSTANCE.create(
context,
consoleApplicationId,
deeplinkScheme,
// Опциональные параметры
themeProvider,
superAppTokenProvider,
externalPaymentLoggerFactory
debugLogs,
);
-
context— это ключевой элемент, который предоставляет информацию о текущем состоянии приложения или объекта.к сведениюВ Android существует несколько типов контекста:
- Контекст приложения — это singleton-экземпляр, доступный через
getApplicationContext(). - Контекст
Activity— доступен внутриActivityи привязан к её жизненному циклу. - Контекст в
ContentProvider— доступен через методgetContext()и аналогичен контексту приложения.
Для создания
RuStoreBillingClientпредпочтительнее использоватьapplicationContext. - Контекст приложения — это singleton-экземпляр, доступный через
-
consoleApplicationId— идентификатор приложения из RuStore консоли.
Где в RuStore Консоль отображаются идентифика торы приложений?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Скопируйте идентификатор из URL-адреса страницы приложения — это набор цифр между
apps/и/versions. Например, для URL-адресаhttps://console.rustore.ru/apps/123456/versionsID приложения —123456.

ApplicationId, указанный в build.gradle, должен совпадать с applicationId APK-файла, который вы публиковали в RuStore Консоль.
-
deeplinkScheme— схема deeplink, необходимая для возврата в ва ше приложение после оплаты через стороннее приложение (например, SberPay или СБП). SDK генерирует свой хост к данной схеме.
yourappscheme, должна совпадать со схемой, указанной в AndroidManifest.xml (подробнее см. Обработка deeplink).-
themeProvider— интерфейс, который предоставляет темуBillingClientTheme. Возможны 2 реализации темыBillingClientTheme: светлая (Light) и тёмная (Dark). Необязательный интерфейс, по умолчанию применяется светлая тема.
примечаниеПо умолчанию тема будет светлой (
Light), но вы можете настроить и тёмную (Dark). -
externalPaymentLoggerFactory— интерфейс, позволяющий вести журнал событий.подсказкаЖурнал событий полезен для версий, которые ещё не опубликованы на пользователей. С его помощью можн о отследить возникающие ошибки.
-
debugLogs— флаг, регулирующий ведение журнала событий. Укажите значениеtrue, если хотите, чтобы события попадали в журнал. В ином случае укажитеfalse.
Подпись keystore должна совпадать с подписью, которой было подписано приложение, опубликованное в RuStore Консоль. Убедитесь, что используемый buildType (пр. debug) использует такую же подпись, что и опубликованное приложение (пр. release).
Методы SDK
Получение списка продуктов
- Kotlin
- Java
getProducts, чтобы получить информацию о продуктах, добавленных в ваше приложение через RuStore Консоль.
val productsUseCase: ProductsUseCase = billingClient.products
productsUseCase.getProducts(productIds = listOf("id1", "id2"))
.addOnSuccessListener { products: List<Product> ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}
productIds — список идентификаторов продуктов. В нём не должно быть более 100 позиций.
Чтобы указать id продуктов, которые нужны для работы метода, выполните следующие действия.
- Откройте RuStore Консоль.
- Перейдите на вкладку Приложения.
- Выберите нужное приложение.
- В левом боковом меню выберите раздел Монетизация.
- Выберите тип товара: Подписки или Разовые покупки.
- Скопируйте идентификаторы нужных товаров. Это и есть
idпродуктов.

Метод возвращает
data class Product(
val productId: String,
val productType: ProductType?,
val productStatus: ProductStatus,
val priceLabel: String?,
val price: Int?,
val currency: String?,
val language: String?,
val title: String?,
val description: String?,
val imageUrl: Uri?,
val promoImageUrl: Uri?,
val subscription: ProductSubscription?,
)
Структура продукта
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).productType— тип продукта (потребляемый / непотребляемый / подписка):CONSUMABLE/NON-CONSUMABE/SUBSCRIPTION.productStatus— статус продукта.priceLable— отформатированная цена товара, включая валютный знак на языкеlanguage.price— цена в минимальных единицах (в копейках).currency— код валюты ISO 4217.language— язык, указанный с помощью BCP 47 кодирования.title— название продукта на языкеlanguage.description— описание на языкеlanguage.imageUrl— ссылка на картинку.promoImageUrl— ссылка на промокартинку.subscription— описание подписки, возвращается только для продуктов с типомsubscription.
Структура подписки
data class ProductSubscription(
val subscriptionPeriod: SubscriptionPeriod?,
val freeTrialPeriod: SubscriptionPeriod?,
val gracePeriod: SubscriptionPeriod?,
val introductoryPrice: String?,
val introductoryPriceAmount: String?,
val introductoryPricePeriod: SubscriptionPeriod?
)
subscriptionPeriod— период подписки.freeTrialPeriod— пробный период подписки.gracePeriod— льготный период подписки.introductoryPrice— отформатированная вступительная цена подписки, включая знак валюты, на языкеproduct:language.introductoryPriceAmount— вступительная цена в минимальных единицах валюты (в копейках).introductoryPricePeriod— расчётный период вступительной цены.
Структура периода подписки
data class SubscriptionPeriod(
val years: Int,
val months: Int,
val days: Int,
)
years— количество лет.months— количество месяцев.days— количество дней.
getProducts, чтобы получить информацию о продуктах, добавленных в ваше приложение через RuStore Консоль.
ProductsUseCase productsUseCase = billingClient.getProducts();
productsUseCase.getProducts(Arrays.asList("id1", "id2"))
.addOnSuccessListener(products ->
// Process success
)
.addOnFailureListener(throwable ->
// Process error
);
productIds: List<String> — список идентификаторов продуктов. В нём не должно быть более 100 позиций.
Чтобы указать id продуктов, которые нужны для работы метода, выполните следующие действия.
- Откройте RuStore Консоль.
- Перейдите на вкладку Приложения.
- Выберите нужное приложение.
- В левом боковом меню выберите раздел Монетизация.
- Выберите тип товара: Подписки или Разовые покупки.
- Скопируйте идентификаторы нужных товаров. Это и есть
idпродуктов.

Структура продукта
public Product(
String productId,
@Nullable
ProductType productType,
ProductStatus productStatus,
@Nullable
String priceLabel,
@Nullable
Integer price,
@Nullable
String currency,
@Nullable
String language,
@Nullable
String title,
@Nullable
String description,
@Nullable
Uri imageUrl,
@Nullable
Uri promoImageUrl,
@Nullable
ProductSubscription subscription
) {
this.productId = productId;
this.productType = productType;
this.productStatus = productStatus;
this.priceLabel = priceLabel;
this.price = price;
this.currency = currency;
this.language = language;
this.title = title;
this.description = description;
this.imageUrl = imageUrl;
this.promoImageUrl = promoImageUrl;
this.subscription = subscription;
}
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).productType— тип продукта (потребляемый / непотребляемый / подписка):CONSUMABLE/NON-CONSUMABE/SUBSCRIPTION.productStatus— статус продукта.priceLabel— отформатированная цена товара, включая валютный знак на языкеlanguage.price— цена в минимальных единицах (в копейках).currency— код валюты ISO 4217.language— язык, указанный с помощью BCP 47 кодирования.title— название продукта на языкеlanguage.description— описание на язык еlanguage.imageUrl— ссылка на картинку.promoimageurl— ссылка на промокартинку.subscription— описание подписки, возвращается только для продуктов с типомsubscription.
Структура подписки
public ProductSubscription(
@Nullable
SubscriptionPeriod subscriptionPeriod,
@Nullable
SubscriptionPeriod freeTrialPeriod,
@Nullable
SubscriptionPeriod gracePeriod,
@Nullable
String introductoryPrice,
@Nullable
String introductoryPriceAmount,
@Nullable
SubscriptionPeriod introductoryPricePeriod
) {
this.subscriptionPeriod = subscriptionPeriod;
this.freeTrialPeriod = freeTrialPeriod;
this.gracePeriod = gracePeriod;
this.introductoryPrice = introductoryPrice;
this.introductoryPriceAmount = introductoryPriceAmount;
this.introductoryPricePeriod = introductoryPricePeriod;
}
subscriptionPeriod— период подписки.freeTrialPeriod— пробный период подписки.gracePeriod— льготный период подписки.introductoryPrice— отформатированная вступительная цена подписки, включая знак валюты, на языкеproduct:language.introductoryPriceAmount— вступительная цена в минимальных единицах валюты (в копейках).introductoryPricePeriod— расчётный период вступительной цены.
Структура периода подписки
public SubscriptionPeriod(
int years,
int months,
int days
) {
this.years = years;
this.months = months;
this.days = days;
}
years— количество лет.months— количество месяцев.days— количество дней.