6.0.0
RuStore позволяет интегрировать платежи в мобильное приложение.
Если не знаете с чего начать, прочтите инструкцию в сценариях использования.
Пример реализации
Ознакомьтесь с приложением-примером чтобы узнать, как правильно интегрировать SDK платежей.
Подробнее о приёме платежей без установки RuStore читайте здесь.
Условия работы платежей
- Kotlin
- Java
- Пользователь и приложение не должны быть заблокированы в RuStore.
- Для приложения включена возможность покупок в RuStore Консоли.
Сервис имеет некоторые ограничения на работу за пределами России.
- Пользователь и приложение не должны быть заблокированы в RuStore.
- Для приложения включена возможность покупок в 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
Deeplink в RuStore SDK платежей нужна для корректной работы со сторонними приложениями оплаты. Она помогает пользователям быстрее совершать покупки в стороннем приложении и возвращаться в ваше приложение.
Для настройки работы с deeplink в вашем приложении и RuStore SDK, укажите deeplinkScheme
внутри вашего AndroidManifest
файла и переопределите метод onNewIntent
вашего Activity
.
<activity
android:name=".YourBillingActivity">
<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>
Вместо yourappscheme
из примера выше укажите название своей схемы. Например, ru.package.name.rustore.scheme
.
Схема, указанная в AndroidManifest
файле должна совпадать со схемой, которую вы указываете в методе create
RuStore SDK платежей.
Далее в Activity
, в которую необходимо вернуться после совершения оплаты (ваша страница магазина), нужно добавить следующий код.
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">
Deeplink в RuStore SDK платежей нужна для корректной работы со сторонними приложениями оплаты. Она помогает пользователям быстрее совершать покупки в стороннем приложении и возвращаться в ваше приложение.
Для настройки работы с deeplink в вашем приложении и RuStore SDK, укажите deeplinkScheme
внутри вашего AndroidManifest
файла и переопределите метод onNewIntent
вашего Activity
.
<activity
android:name=".YourBillingActivity">
<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>
Вместо yourappscheme
из примера выше укажите название своей схемы. Например, ru.package.name.rustore.scheme
.
Схема, указанная в AndroidManifest
файле должна совпадать со схемой, которую вы указываете в методе create
RuStore SDK платежей.
Далее в Activity
, в которую необходимо вернуться после совершения оплаты (ваша страница магазина), нужно добавить следующий код.
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">
Инициализация
Перед вызовом методов библиотеки необходимо выполнить её инициализацию.
- 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 (пример:https://console.rustore.ru/apps/123456
).Чтобы получить ID приложения, скопируйте цифры из URL-адреса страницы приложения в RuStore Консоли после
apps/
.
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 (пример:https://console.rustore.ru/apps/123456
).Чтобы получить ID приложения, скопируйте цифры из URL-адреса страницы приложения в RuStore Консоли после
apps/
.
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
).
Как работают платежи
На схеме ниже показан примерный алгоритм настройки и подключения платежей, на который вы можете ориентироваться. Учитывайте особенности вашего проекта в работе.
Проверка доступности работы с платежами
- Kotlin
- Java
Для проверки доступности платежей используйте метод checkPurchasesAvailability
.
Проверка доступности платежей зависит от наличия RuStore на устройстве пользователя. Начиная с 6.0.0 версии если у пользователя не установлено приложение RuStore, метод вернёт FeatureAvailabilityResult.Available
. Это возможно благодаря запуску приёма платежей без установки RuStore.
В зависимости от того, есть ли на устройстве пользователя RuStore, проверяются следующие условия:
Не установлен RuStore
Если RuStore не установлен на устройстве, метод вернёт FeatureAvailabilityResult.Available
.
Установлен RuStore
- На устройстве пользователя установлена актуальная версия RuStore.
- Приложение RuStore поддерживает функциональность платежей.
- Пользователь авторизован в RuStore.
- Пользователь и приложение не должны быть заблокированы в RuStore.
- Для приложения включена возможность покупок в RuStore Консоли.
При выполнении всех указанных выше условий метод вернёт FeatureAvailabilityResult.Available
.
В противном случае возвращается FeatureAvailabilityResult.Unavailable(val cause: RuStoreException)
, где cause
— это ошибка о невыполненном условии.
Все возможные ошибки RuStoreException
описаны в разделе Обработка ошибок. Прочие ошибки возвращаются в onFailure
. (См. Task API).
RuStoreBillingClient.checkPurchasesAvailability(context)
.addOnSuccessListener { result ->
when (result) {
FeatureAvailabilityResult.Available -> {
// Process purchases available
}
is FeatureAvailabilityResult.Unavailable -> {
// Process purchases unavailable
}
}
}
.addOnFailureListener { throwable ->
// Process unknown error
}
context
— контекст Android.
Для проверки доступности платежей используйте метод checkPurchasesAvailability
.
Проверка доступности платежей зависит от наличия RuStore на устройстве пользователя. Начиная с 6.0.0 версии если у пользователя не установлено приложение RuStore, метод вернёт FeatureAvailabilityResult.Available
. Это возможно благодаря запуску приёма платежей без установки RuStore.
В зависимости от того, есть ли на устройстве пользователя RuStore, проверяются следующие условия:
Не установлен RuStore
Если RuStore не установлен на устройстве, метод вернёт FeatureAvailabilityResult.Available
.
Установлен RuStore
- На устройстве пользователя установлена актуальная версия RuStore.
- Приложение RuStore поддерживает функциональность платежей.
- Пользователь авторизован в RuStore.
- Пользователь и приложение не должны быть заблокированы в RuStore.
- Для приложения включена возможность покупок в RuStore Консоли.
При выполнении всех указанных выше условий метод вернёт FeatureAvailabilityResult.Available
.
В противном случае возвращается FeatureAvailabilityResult.Unavailable(val cause: RuStoreException)
, где cause
— это ошибка о невыполненном условии.
Все возможные ошибки RuStoreException
описаны в разделе Обработка ошибок. Прочие ошибки возвращаются в onFailure
. (См. Task API).
RuStoreBillingClientExtKt.checkPurchasesAvailability(RuStoreBillingClient.Companion, getContext())
.addOnSuccessListener(result -> {
if (result instanceof FeatureAvailabilityResult.Available) {
// Hanlde purchases available
} else {
RuStoreException exception = ((FeatureAvailabilityResult.Unavailable) result).getCause();
// Hanlde purchases unavailable
}
})
.addOnFailureListener(error -> {
// Handle error
});
В данной версии SDK метод будет возвращать сообщение о доступности платежа.
Работа с 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
— тип продукта.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
— тип п родукта.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
— количество дней.
Покупка продукта
- Kotlin
- Java
Для вызова покупки продукта используйте метод purchaseProduct
.
val purchasesUseCase: PurchasesUseCase = billingClient.purchases
purchasesUseCase.purchaseProduct(
productId = productId,
orderId = UUID.randomUUID().toString(),
quantity = 1,
developerPayload = null,
).addOnSuccessListener { paymentResult: PaymentResult ->
when (paymentResult) {
// Process PaymentResult
}
}.addOnFailureListener { throwable: Throwable ->
// Process error
}
productId: String
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).orderId: String
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически.quantity: Int
— количество продукта (опциональный параметр).developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки.
Структура результата покупки
public sealed interface PaymentResult {
public data class Success(
val orderId: String?,
val purchaseId: String,
val productId: String,
val invoiceId: String,
val sandbox: Boolean,
val subscriptionToken: String? = null,
) : PaymentResult
public data class Cancelled(
val purchaseId: String,
val sandbox: Boolean,
) : PaymentResult
public data class Failure(
val purchaseId: String?,
val invoiceId: String?,
val orderId: String?,
val quantity: Int?,
val productId: String?,
val sandbox: Boolean,
val errorCode: Int?,
) : PaymentResult
public object InvalidPaymentState : PaymentResult()
}
Параметр sandbox
определяет, является ли платёж тестовым. Значения могут быть true
или false
,
где true
обозначает тестовый платёж, а false
– реальный.
Success
— результат успешного завершения покупки цифрового товара.Failure
— при отправке запроса на оплату или получения статуса оплаты возникла проблема, невозможно установить статус покупки.Cancelled
— запрос на покупку отправлен, при этом пользователь закрыл «платёжную шторку» на своём устройстве, и результат оплаты неизвестен.InvalidPaymentState
— ошибка работы SDK платежей. Может возникнуть, в случае некорректного обратного deeplink.
Для вызова покупки продукта используйте метод purchaseProduct
.
purchasesUseCase.purchaseProduct(productId, null, 1, developerPayload)
.addOnSuccessListener(result ->
// Process PaymentResult
)
.addOnFailureListener(throwable ->
// Process error
);
productId: String
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).orderId: String
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически.quantity: Int
— количество продукта (опциональный параметр).developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки.
Структура результата покупки
public interface PaymentResult {
class Success implements PaymentResult {
@Nullable
String orderId;
String purchaseId;
String productId;
String invoiceId;
boolean sandbox;
@Nullable
String subscriptionToken;
public Success(@Nullable String orderId, String purchaseId, String productId, String invoiceId,
boolean sandbox, @Nullable String subscriptionToken) {
this.orderId = orderId;
this.purchaseId = purchaseId;
this.productId = productId;
this.invoiceId = invoiceId;
this.sandbox = sandbox;
this.subscriptionToken = subscriptionToken;
}
}
class Failure implements PaymentResult {
@Nullable
String purchaseId;
@Nullable
String invoiceId;
@Nullable
String orderId;
@Nullable
Integer quantity;
@Nullable
String productId;
boolean sandbox;
@Nullable
Integer errorCode;
public Failure(@Nullable String purchaseId, @Nullable String invoiceId, @Nullable String orderId,
@Nullable Integer quantity, @Nullable String productId, boolean sandbox, @Nullable Integer errorCode) {
this.purchaseId = purchaseId;
this.invoiceId = invoiceId;
this.orderId = orderId;
this.quantity = quantity;
this.productId = productId;
this.sandbox = sandbox;
this.errorCode = errorCode;
}
}
class Cancelled implements PaymentResult {
String purchaseId;
boolean sandbox;
public Cancelled(String purchaseId, boolean sandbox) {
this.purchaseId = purchaseId;
this.sandbox = sandbox;
}
}
class InvalidPaymentState implements PaymentResult {}
}
Параметр sandbox
определяет, является ли платёж тестовым. Значения могут быть true
или false
,
где true
обозначает тестовый платёж, а false
– реальный.
Success
— результат успешного завершения покупки цифрового товара.Failure
— при отправке запроса на оплату или получения статуса оплаты возникла проблема, невозможно установить статус покупки.Cancelled
— запрос на покупку отправлен, при этом пользователь закрыл «платёжную шторку» на своём устройстве, и результат оплаты неизвестен.InvalidPaymentState
— ошибка работы SDK платежей. Может возникнуть, в случае некорректного обратного deeplink.
Получение сведений о покупке
- Kotlin
- Java
getPurchaseInfo
.
val purchasesUseCase: PurchasesUseCase = billingClient.purchases
purchasesUseCase.getPurchaseInfo("purchaseId")
.addOnSuccessListener { purchase: Purchase ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}
Структура покупки
data class Purchase(
val purchaseId: String?,
val productId: String,
val productType: ProductType?,
val invoiceId: String?,
val language: String?,
val purchaseTime: Date?,
val orderId: String?,
val amountLabel: String?,
val amount: Int?,
val currency: String?,
val quantity: Int?,
val purchaseState: PurchaseState?,
val developerPayload: String?,
val subscriptionToken: String?
)
-
purchaseId
— идентификатор покупки. -
productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр). -
invoiceId
— идентификатор счёта. -
language
— язык, указанный с помощью BCP 47 кодирования. -
purchaseTime
— врем я покупки. -
orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически. -
amountLable
— отформатированная цена покупки, включая валютный знак на языкеlanguage
. -
amount
— цена в минимальных единицах валюты. -
currency
— код валюты ISO 4217. -
quantity
— количество продукта (опциональный параметр). -
purchaseState
— состояние покупки:CREATED
— покупка создана;INVOICE_CREATED
— по покупке создан счёт, ожидает оплаты;PAID
— только покупки потребляемого товара — промежуточный статус, средства на счёте покупателя зарезервированы. Покупка ожидает подтверждения от разработчика;CONFIRMED
— финальный статус, покупка подтверждена (для подписок и непотребляемых товаров). Средства отправлены разработчику. Повторная покупка товара блокируется магазином;CONSUMED
— для потребляемых товаров — конечный статус, потребление покупки подтверждено. Можно производить повторную покупку товара;CANCELLED
— покупка отменена — оплата не была произведена или был совершен возврат средств покупателю (для подписок после возврата средств покупка не переходит вCANCELLED
);PAUSED
— для подписок — подписка перешла в HOLD период;TERMINATED
— подписка закрылась.
-
developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки. -
subscriptionToken
— токен для валидации покупки на сервере.
Статусная модель (purchaseState
)
Статусная модель покупки потребляемых продуктов (CONSUMABLES
)
Статусная модель покупки непотребляемых продуктов (NON-CONSUMABLES
)
Статусная модель покупки подписок (SUBSCRIPTIONS
)
getPurchaseInfo
.
PurchasesUseCase purchasesUseCase = billingClient.getPurchases();
purchasesUseCase.getPurchaseInfo("purchaseId")
.addOnSuccessListener(purchase ->
// Process success
)
.addOnFailureListener(throwable ->
// Process error
);
Структура покупки
public Purchase(
@Nullable
String purchaseId,
String productId,
@Nullable
ProductType productType,
@Nullable
String invoiceId,
@Nullable
String language,
@Nullable
Date purchaseTime,
@Nullable
String orderId,
@Nullable
String amountLabel,
@Nullable
Integer amount,
@Nullable
String currency,
@Nullable
Integer quantity,
@Nullable
PurchaseState purchaseState,
@Nullable
String developerPayload,
@Nullable
String subscriptionToken
) {
this.purchaseId = purchaseId;
this.productId = productId;
this.productType = productType;
this.invoiceId = invoiceId;
this.language = language;
this.purchaseTime = purchaseTime;
this.orderId = orderId;
this.amountLabel = amountLabel;
this.amount = amount;
this.currency = currency;
this.quantity = quantity;
this.purchaseState = purchaseState;
this.developerPayload = developerPayload;
this.subscriptionToken = subscriptionToken;
}
-
purchaseId
— идентификатор покупки. -
productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр). -
invoiceId
— идентификатор счёта. -
language
— язык, указанный с помощью BCP 47 кодирования. -
purchaseTime
— время покупки. -
orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически. -
amountLable
— отформатированная цена покупки, включая валютный знак на языкеlanguage
. -
amount
— цена в минимальных единицах валюты. -
currency
— код валюты ISO 4217. -
quantity
— количество продукта (опциональный параметр). -
purchaseState
— состояние покупки:CREATED
— покупка создана;INVOICE_CREATED
— по покупке создан счёт, ожидает оплаты;PAID
— только покупки потребляемого товара — промежуточный статус, средства на счёте покупателя зарезервированы. Покупка ожидает подтверждения от разработчика;CONFIRMED
— финальный статус, покупка подтверждена (для подписок и непотребляемых товаров). Ср едства отправлены разработчику. Повторная покупка товара блокируется магазином;CONSUMED
— для потребляемых товаров — конечный статус, потребление покупки подтверждено. Можно производить повторную покупку товара;CANCELLED
— покупка отменена — оплата не была произведена или был совершен возврат средств покупателю (для подписок после возврата средств покупка не переходит вCANCELLED
);PAUSED
— для подписок — подписка перешла в HOLD период.TERMINATED
— подписка закрылась.
-
developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки. -
subscriptionToken
— токен для валидации покупки на сервере.
Статусная модель (purchaseState
)
Статусная модель покупки потребляемых продуктов (CONSUMABLES
)
Статусная модель покупки непотребляемых продуктов (NON-CONSUMABLES
)
Статусная модель покупки подписок (SUBSCRIPTIONS
)
Получение списка покупок
- Kotlin
- Java
Метод возвращает только покупки со статусами из таблицы ниже. Подробнее о других возможных состояниях покупки смотрите в разделе Получение сведений о покупке.
Тип/Статус | INVOICE_CREATED | CONFIRMED | PAID | PAUSED |
---|---|---|---|---|
CONSUMABLE | + | + | ||
NON-CONSUMABLE | + | + | ||
SUBSCRIPTION | + | + | + |
Метод возвращает незавершённые состояния покупки и покупки потребляемых товаров, требующих обработки. Помимо этого, он показывает подтверждённые покупки для подписок и непотребляемых товаров — тех, которые нельзя купить повторно.
Для получения списка покупок пользователя используйте метод getPurchases
.
val purchasesUseCase: PurchasesUseCase = billingClient.purchases
purchasesUseCase.getPurchases()
.addOnSuccessListener { purchases: List<Purchase> ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}
Структура покупки
data class Purchase(
val purchaseId: String?,
val productId: String,
val productType: ProductType?,
val invoiceId: String?,
val language: String?,
val purchaseTime: Date?,
val orderId: String?,
val amountLabel: String?,
val amount: Int?,
val currency: String?,
val quantity: Int?,
val purchaseState: PurchaseState?,
val developerPayload: String?,
val subscriptionToken: String?
)
purchaseId
— идентификатор покупки.productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).productType
— тип продукта.invoiceId
— идентификатор счёта.language
— язык, указанный с помощью BCP 47 кодирования.purchaseTime
— время покупки.orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически.amountLable
— отформатированная цена покупки, включая валютный знак на языкеlanguage
.amount
— цена в минимальных единицах валюты.currency
— код валюты ISO 4217.quantity
— количество продукта (опциональный параметр).purchaseState
— состояние покупки.
Структура ответа сервера на запрос покупок
data class PurchasesResponse(
override val meta: RequestMeta?,
override val code: Int,
override val errorMessage: String?,
override val errorDescription: String?,
override val errors: List<DigitalShopGeneralError>?,
val purchases: List<Purchase>?,
) : ResponseWithCode
meta
— дополнительная информация о запросе.code
— код ответа.errorMessage
— сообщение об ошибке для пользователя.errorDescription
— расшифровка сообщения об ошибке.errors
— список ошибок для запрошенных продуктов.purchases
— список запрошенных покупок.
Метод возвращает только покупки со статусами из таблицы ниже. Подробнее о других возможных состояниях покупки смотрите в разделе Получение сведений о покупке.
Тип/Статус | INVOICE_CREATED | CONFIRMED | PAID | PAUSED |
---|---|---|---|---|
CONSUMABLE | + | + | ||
NON-CONSUMABLE | + | + | ||
SUBSCRIPTION | + | + | + |
Метод возвращает незавершённые состояния покупки и покупки потребляемых товаров, требующих обработки. Помимо этого, он показывает подтверждённые покупки для подписок и непотребляемых товаров — тех, которые нельзя купить повторно.
Для получения списка покупок пользователя используйте метод getPurchases
.
PurchasesUseCase purchasesUseCase = billingClient.getPurchases();
purchasesUseCase.getPurchases()
.addOnSuccessListener(purchases -> {
// Process PaymentResult
})
.addOnFailureListener(throwable ->
// Process error
);
Структура покупки
public Purchase(
@Nullable
String purchaseId,
String productId,
@Nullable
ProductType productType,
@Nullable
String invoiceId,
@Nullable
String language,
@Nullable
Date purchaseTime,
@Nullable
String orderId,
@Nullable
String amountLabel,
@Nullable
Integer amount,
@Nullable
String currency,
@Nullable
Integer quantity,
@Nullable
PurchaseState purchaseState,
@Nullable
String developerPayload,
@Nullable
String subscriptionToken
) {
this.purchaseId = purchaseId;
this.productId = productId;
this.productType = productType;
this.invoiceId = invoiceId;
this.language = language;
this.purchaseTime = purchaseTime;
this.orderId = orderId;
this.amountLabel = amountLabel;
this.amount = amount;
this.currency = currency;
this.quantity = quantity;
this.purchaseState = purchaseState;
this.developerPayload = developerPayload;
this.subscriptionToken = subscriptionToken;
}
purchaseId
— идентификатор покупки.productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).productType
— тип продукта.invoiceId
— идентификатор счёта.language
— язык, указанный с помощью BCP 47 кодирования.purchaseTime
— время покупки.orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически.AmountLabel
— отформатированная цена покупки, включая валютный знак на языкеlanguage
.amount
— цена в минимальных единицах валюты.currency
— код валюты ISO 4217.quantity
— количество продукта (опциональный параметр).purchaseState
— состояние покупки.developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки.subscriptionToken
— токен для валидации покупки на сервере.
Валидация покупки на сервере
- Kotlin
- Java
Есл и вам необходимо произвести валидацию успешной покупки на сервере методами API RuStore, вы можете использовать subscriptionToken
в PurchaseResult
, возвращаемой purchaseProduct
при успешной покупке продукта.
SubscriptionToken
состоит из invoiceId
покупки и userId
, записанных через точку: $invoiceId.$userId
.
Также можно получить subscriptionToken
в сущности Purchase
. Сущность Purchase
можно получить используя метод getPurchases
.
val purchasesUseCase: PurchasesUseCase = billingClient.purchases
purchasesUseCase.purchaseProduct(productId).addOnSuccessListener { paymentResult ->
if (paymentResult is PaymentResult.Success) {
val subscriptionToken = paymentResult.subscriptionToken
yourApi.validate(subscriptionToken)
}
}
Также можно получить subscriptionToken
в сущности Purchase
. Сущность Purchase
можно получить используя метод getPurchases
.
val purchasesUseCase: PurchasesUseCase = billingClient.purchases
purchasesUseCase.getPurchases().addOnSuccessListener { purchases ->
purchases.forEach { purchase ->
yourApi.validate(purchase.subscriptionToken)
}
}
Если вам необходимо произвести валидацию успешной покупки на сервере методами API RuStore, вы можете использовать subscriptionToken
в PurchaseResult
, возвращаемой purchaseProduct
при успешной покупке продукта.
SubscriptionToken
состоит из invoiceId
покупк и и userId
, записанных через точку: $invoiceId.$userId
.
Также можно получить subscriptionToken
в сущности Purchase
. Сущность Purchase
можно получить используя метод getPurchases
.
PurchasesUseCase purchasesUseCase = billingClient.getPurchases();
purchasesUseCase.purchaseProduct(productId).addOnSuccessListener(paymentResult -> {
if (paymentResult instanceof PaymentResult.Success) {
String subscriptionToken = ((PaymentResult.Success) paymentResult).getSubscriptionToken();
yourApi.validate(subscriptionToken);
}
});
Также можно получить subscriptionToken
в сущности Purchase
. Сущность Purchase
можно получить используя метод getPurchases
.
PurchasesUseCase purchasesUseCase = billingClient.getPurchases();
purchasesUseCase.getPurchases().addOnSuccessListener(purchases -> {
for (Purchase purchase : purchases) {
yourApi.validate(purchase.getSubscriptionToken());
}
});