Перейти к основному содержимому
Unlisted page
This page is unlisted. Search engines will not index it, and only users having a direct link can access it.

7.0.0 (Beta)

RuStore позволяет интегрировать платежи в мобильное приложение.

подсказка
  • Если не знаете с чего начать, прочтите инструкцию в сценариях использования.

  • Если вы переходите на Pay SDK с billingClient SDK, ознакомьтесь с инструкцией по переходу. Подробности о Pay SDK можно узнать тут.

Условия работы платежей

  • Для приложения включена возможность покупок в RuStore Консоли.
  • Приложение не должно быть заблокировано в RuStore.
  • На устройстве пользователя установлена актуальная версия RuStore.
  • Пользователь авторизован в RuStore.
  • Пользователь не должен быть заблокирован в RuStore.

Подключение в проект

build.gradle
repositories {
maven {
url = uri("https://artifactory-external.vkpartner.ru/artifactory/maven")
}
}

Добавьте следующий код в свой конфигурационный файл для подключения зависимости.

build.gradle
dependencies {
implementation(platform("ru.rustore.sdk:bom:7.0.0"))
implementation("ru.rustore.sdk:pay")
}

Инициализация

Перед вызовом методов библиотеки необходимо выполнить её инициализацию. Сама инициализация происходит автоматически, но для работы SDK в вашем файле необходимо прописать . Значение необходимо указать в строковых ресурсах.

Сделать это можно следующим образом.

manifest.xml
<?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_key"
android:value="@string/CONSOLE_APPLICATION_ID" />

</application>
</manifest>
  • CONSOLE_APPLICATION_ID — идентификатор приложения из консоли RuStore.

    Пример: https://console.rustore.ru/apps/111111.
Где в RuStore Консоль отображаются идентификаторы приложений?
  1. Перейдите на вкладку Приложения и выберите нужное приложение.
  2. Скопируйте идентификатор из URL-адреса страницы приложения — это набор цифр между apps/ и /versions. Например, для URL-адреса https://console.rustore.ru/apps/123456/versions ID приложения — 123456.

Важно
  • ApplicationId, указанный в build.gradle, должен совпадать с applicationId APK-файла, который вы публиковали в RuStore Консоль.
  • Подпись keystore должна совпадать с подписью, которой было подписано приложение, опубликованное в RuStore Консоль. Убедитесь, что используемый buildType (пр. debug) использует такую же подпись, что и опубликованное приложение (пр. release).

Работа с SDK

Доступные публичные интеракторы:

  • PurchaseInteractor - интерактор, который позволяет работать с платежами и имеет несколько публичных методов.
    • getPurchase(purchaseId: PurchaseId): Task<Purchase> - позволяет получить информацию о покупке по её идентификатору.
    • getPurchases(productType: ProductType? = null): Task<List<Purchase>> - позволяет получить покупки пользователя. Данный метод поддерживает необязательную фильтрацию по типу товаров (потребляемые или непотреблямые товары). По умолчанию фильтр выключен и вернет все покупки пользователя (в не зависимости от типа товара) в статусах PAID и CONFIRMED.
    • PAID - статус, означающий успешное холдирование средств и ожидающих подтверждения или отмены покупки со стороны разработчика.
    • getPurchaseAvailability(): Task<PurchaseAvailabilityResult> - возвращает результат доступности работы с платежами.
    • purchaseOneStep(params: ProductPurchaseParams): Task<ProductPurchaseResult> - запускает сценарий одностадийной покупки товара. При использовании данного способа отсутствует холдирование денежных средств покупателя. При успешной покупке денежные средства сразу списываются со счета покупателя. Отмена покупки невозможна, возможен только возврат средств через консоль разработчика.
    • purchaseTwoStep(params: ProductPurchaseParams): Task<ProductPurchaseResult> - запускает сценарий двухстадийной покупки товара. При использовании данного способа осуществляется холдирование денежных средств покупателя. Т.е. при успешной покупке денежные средства списываются со счета покупателя только после подтверждения покупки со стороны разработчика.
    • confirmTwoStepPurchase(purchaseId: PurchaseId, developerPayload: DeveloperPayload? = null) - подтверждение покупки, совершенной по двухстадийной оплате.
    • cancelTwoStepPurchase(purchaseId: PurchaseId) - отмена покупки, совершенной по двухстадийной оплате.
  • ProductInteractor - интерактор, который позволяет работать с продуктами и имеет несколько публичных методов:
    • getProducts(productsId: List<ProductId>): Task<List<Product>> - позволяет получить информацию по активным продуктам, опубликованным в RuStore консоль.
    Важно

    Данный метод возвращает не более 1000 продуктов.

  • блок RuStoreUtils - набор публичных методов, таких как:
    • isRuStoreInstalled - проверки наличия приложения RuStore на девайсе пользователя.
    • openRuStoreDownloadInstruction - открывает веб-страницу для скачивания МП RuStore.
    • openRuStore - запускает МП RuStore.
    • openRuStoreAuthorization - запускает МП RuStore для авторизации. После успешной авторизации пользователя МП RuStore автоматически закроется.

Проверка доступности работы с платежами

Для проверки доступности платежей, вызовите метод getPurchaseAvailability у PurchaseInteractor. При его вызове проверяются следующие условия:

  • На устройстве пользователя установлена актуальная версия RuStore.
  • Пользователь авторизован в RuStore.
  • Пользователь и приложение не должны быть заблокированы в RuStore.
  • У компании подключена монетизация через консоль разработчика RuStore.

Если все условия выполняются, возвращается PurchaseAvailabilityResult.Available. Иначе возвращается PurchaseAvailabilityResult.Unavailable(val cause: Throwable), где cause — ошибка о невыполненном условии.

Чтобы понять причину ошибки, проверьте её тип на RuStoreException. См. Обработка ошибок.

Вызов метода getPurchaseAvailability
RuStorePayClient.instance.getPurchaseInteractor().getPurchaseAvailability()
.addOnSuccessListener { result ->
when (result) {
is PurchaseAvailabilityResult.Available -> {
// Process purchases available
}

is PurchaseAvailabilityResult.Unavailable -> {
// Process purchases unavailable
}
}
}.addOnFailureListener { throwable ->
// Process unknown error
}

Получение списка продуктов

Для получения продуктов, добавленных в ваше приложение через RuStore консоль, необходимо использовать метод getProducts.

Вызов метода getProducts
RuStorePayClient.instance.getProductInteractor().getProducts(productsId = listOf(ProductId("id1"), ProductId("id2")))
.addOnSuccessListener { products: List<Product> ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}

productsId: List<ProductId> — список идентификаторов продуктов (задаются при создании продукта в консоли разработчика). Список продуктов имеет ограничение в размере 1000 элементов.

Где в RuStore Консоль отображаются идентификаторы продуктов?
  1. Перейдите на вкладку Приложения и выберите нужное приложение.
  2. Выберите Монетизация в меню слева.
  3. Выберите тип товара: Подписки или Разовые покупки.
  4. Скопируйте идентификаторы нужных товаров.

Метод возвращает список продуктов. Ниже представлена модель продукта.

Структура продукта
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?,
)
  • productId — идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).
  • type — тип продукта. CONSUMABLE/NON-CONSUMABE (потребляемый/непотребляемый).
  • amountLabel — отформатированная цена покупки, включая валютный знак.
  • price — цена в минимальных единицах (в копейках).
  • currency — код валюты ISO 4217.
  • title — название продукта на языке language.
  • description — описание на языке language.
  • imageUrl — ссылка на картинку.

Примеры ответа

Пример модели Потребляемого продукта
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("Описание Непотребляемого продукта"),
)

Получение списка покупок

Для получения списка покупок пользователя используйте метод getPurchases.

Вызов метода получения списка покупок пользователя
RuStorePayClient.instance.getPurchaseInteractor().getPurchases()
.addOnSuccessListener { purchases: List<Purchase> ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}

Данный метод поддерживает опциональную фильтрацию по типу товаров (потребляемые или непотреблямые товары). По умолчанию фильтр выключен и вернет всё покупки пользователя (в не зависимости от типа товара) в статусах PAID и CONFIRMED. Покупка в статусе PAID - статус, означает холдирование средств и ожидает подтверждения покупки со стороны разработчика.

Вызов метода получения списка покупок пользователя с фильтрацией
RuStorePayClient.instance.getPurchaseInteractor().getPurchases(productType = ProductType.CONSUMABLE_PRODUCT)
.addOnSuccessListener { purchases: List<Purchase> ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}

Ниже представлена модель покупки.

Структура с информацией о покупке
public class Purchase internal constructor(
public val purchaseId: PurchaseId,
public val productId: ProductId,
public val invoiceId: InvoiceId,
public val orderId: OrderId?,
public val purchaseType: PurchaseType,
public val productType: ProductType,
public val description: Description,
public val purchaseTime: Date?,
public val price: Price,
public val amountLabel: AmountLabel,
public val currency: Currency,
public val quantity: Quantity,
public val status: PurchaseStatus,
public val subscriptionToken: SubscriptionToken?,
public val developerPayload: DeveloperPayload?,
)
  • purchaseId — идентификатор покупки.
  • productId — идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).
  • invoiceId — идентификатор счёта.
  • orderId — уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.
  • type — тип продукта (потребляемый / непотребляемый): CONSUMABLE/NON-CONSUMABE.
  • description — описание покупки.
  • purchaseTime — время покупки.
  • price — цена в минимальных единицах валюты.
  • amountLable — отформатированная цена покупки, включая валютный знак.
  • currency — код валюты ISO 4217.
  • quantity — количество продукта (необязательный параметр — если не указывать, будет подставлено значение 1).
  • purchaseState — состояние покупки.
  • developerPayload — строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки.
  • amountLabel — отформатированная цена покупки, включая валютный знак.
  • currency — код валюты ISO 4217.
  • description — описание на языке language.
  • developerPayload — строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки
  • invoiceId — идентификатор счёта.
  • orderId — уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.
  • price — цена в минимальных единицах (в копейках).
  • productId — идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).
  • productType — тип продукта.
  • purchaseId — идентификатор покупки.
  • purchaseTime — время покупки.
  • PurchaseType — тип покупки:
    • ONE_PHASE - одностадийная покупка;
    • TWO_PHASE - двухстадийная покупка.
  • quantity — количество продукта (необязательный параметр — если не указывать, будет подставлено значение 1).
  • status — состояние покупки:
    • INVOICE_CREATED — создан счёт на оплату, покупка ожидает оплаты;
    • CANCELLED — покупка отменена покупателем;
    • PROCESSING — запущена оплата;
    • REJECTED — покупка отклонена (например, ввиду недостатка средств);
    • PAID — только для двухстадийной оплаты, промежуточный статус, средства на счёте покупателя захолдированы, покупка ожидает подтверждения от разработчика;
    • CONFIRMED — покупка успешно оплачена;
    • REFUNDED — запрос на возврат средств за покупку совершён успешно;
    • REVERSED — только для двухстадийной оплаты, покупка была отменена разработчиком или не было произведено подтверждение покупки в течение 72 часов, холдирование средств отменено.

Получение сведений о покупке

Для получения информации о покупке, используйте метод getPurchase.
Вызов метода получения покупки пользователя
RuStorePayClient.instance.getPurchaseInteractor().getPurchase(PurchaseId("purchaseId"))
.addOnSuccessListener { purchase: Purchase ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}

Метод возвращает информацию о конкретной покупке в любом статусе. Ниже представлена модель покупки:

Структура с информацией о покупке
public class Purchase internal constructor(
public val purchaseId: PurchaseId,
public val productId: ProductId,
public val invoiceId: InvoiceId,
public val orderId: OrderId?,
public val purchaseType: PurchaseType,
public val productType: ProductType,
public val description: Description,
public val purchaseTime: Date?,
public val price: Price,
public val amountLabel: AmountLabel,
public val currency: Currency,
public val quantity: Quantity,
public val status: PurchaseStatus,
public val subscriptionToken: SubscriptionToken?,
public val developerPayload: DeveloperPayload?,
)
  • amountLabel — отформатированная цена покупки, включая валютный знак.
  • currency — код валюты ISO 4217.
  • description — описание на языке language.
  • developerPayload — строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки
  • invoiceId — идентификатор счёта.
  • orderId — уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.
  • price — цена в минимальных единицах (в копейках).
  • productId — идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).
  • productType — тип продукта.
  • purchaseId — идентификатор покупки.
  • purchaseTime — время покупки.
  • PurchaseType — тип покупки:
    • ONE_PHASE - одностадийная покупка;
    • TWO_PHASE - двухстадийная покупка.
  • quantity — количество продукта (необязательный параметр — если не указывать, будет подставлено значение 1).
  • status — состояние покупки:
    • INVOICE_CREATED — создан счёт на оплату, покупка ожидает оплаты;
    • CANCELLED — покупка отменена покупателем;
    • PROCESSING — запущена оплата;
    • REJECTED — покупка отклонена (например, ввиду недостатка средств);
    • PAID — только для двухстадийной оплаты, промежуточный статус, средства на счёте покупателя захолдированы, покупка ожидает подтверждения от разработчика;
    • CONFIRMED — покупка успешно оплачена;
    • REFUNDED — запрос на возврат средств за покупку совершён успешно;
    • REVERSED — только для двухстадийной оплаты, покупка была отменена разработчиком или не было произведено подтверждение покупки в течение 72 часов, холдирование средств отменено.

Пример ответа.

Пример модели покупки потребляемого продукта
Purchase(
purchaseId = PurchaseId("purchaseId"),
productId = ProductId("productId"),
invoiceId = InvoiceId("invoiceId"),
orderId = OrderId("orderId"),
purchaseType = PurchaseType.ONE_STEP,
productType = ProductType.CONSUMABLE_PRODUCT,
description = Description("description"),
purchaseTime = Date(123123123124),
price = Price(14100),
amountLabel = AmountLabel("141,00 ₽"),
currency = Currency("RUB"),
quantity = Quantity(1),
status = PurchaseStatus.CONFIRMED,
subscriptionToken = SubscriptionToken("subscriptionToken"),
developerPayload = DeveloperPayload("developerPayload"),
)

Статусная модель покупки

Статусная модель одностадийного платежа.



Статусная модель двухстадийного платежа.



Покупка продукта

Одностадийная оплата (без холдирования средств)

Для вызова покупки продукта используйте метод purchaseOneStep.

Вызов метода покупки продукта
RuStorePayClient.instance.getPurchaseInteractor().purchaseOneStep(
ProductPurchaseParams(
productId = ProductId("productId"),
orderId = null,
quantity = null,
developerPayload = null,
)
).addOnSuccessListener { paymentResult: PaymentResult ->
when (paymentResult) {
// Process PaymentResult
}
}.addOnFailureListener { throwable: Throwable ->
// Process error
}

Двухстадийная оплата (с холдированием средств)

Для вызова покупки продукта используйте метод purchaseTwoStep.

Вызов метода покупки продукта
RuStorePayClient.instance.getPurchaseInteractor().purchaseTwoStep(
ProductPurchaseParams(
productId = ProductId("productId"),
orderId = null,
quantity = null,
developerPayload = null,
)
).addOnSuccessListener { paymentResult: PaymentResult ->
when (paymentResult) {
// Process PaymentResult
}
}.addOnFailureListener { throwable: Throwable ->
// Process error
}

Структура параметров покупки

Структура параметров покупки
public class ProductPurchaseParams(
public val productId: ProductId,
public val quantity: Quantity? = null,
public val orderId: OrderId? = null,
public val developerPayload: DeveloperPayload? = null,
)
  • productId — идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).
  • quantity — количество продукта (необязательный параметр — если не указывать, будет подставлено значение 1).
  • orderId — уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.
  • developerPayload — строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки. Максимальная длина 250 символов.
Структура результата покупки
public sealed interface ProductPurchaseResult {

public class SuccessProductPurchaseResult(
public val orderId: OrderId?,
public val purchaseId: PurchaseId,
public val productId: ProductId,
public val invoiceId: InvoiceId,
public val subscriptionToken: SubscriptionToken?,
) : ProductPurchaseResult

public class CancelProductPurchaseResult(
public val purchaseId: PurchaseId?,
) : ProductPurchaseResult

public class FailureProductPurchaseResult(
public val orderId: OrderId?,
public val purchaseId: PurchaseId?,
public val productId: ProductId?,
public val invoiceId: InvoiceId?,
public val quantity: Quantity?,
public val subscriptionToken: SubscriptionToken?,
public val cause: Throwable,
) : ProductPurchaseResult
}
  • SuccessProductPurchaseResult - результат успешного завершения покупки цифрового товара.

  • FailureProductPurchaseResult - результат ошибки покупки цифрового товара.

  • CancelProductPurchaseResult - платёжный диалог закрыт до получения результата покупки. Состояние покупки неизвестно. Рекомендуем запросить статус покупки отдельно методом получения информации о покупке.

  • purchaseId - идентификатор покупки. Используется для получения информации о покупке в SDK методом получения информации о покупке

  • productId - идентификатор приобретенного продукта, указанный при создании в консоли разработчика RuStore.

  • invoiceId - идентификатор счета. Используется для серверной валидации платежа, поиска платежей в консоли разработчика, а также отображается покупателю в истории платежей в мобильном приложении RuStore

  • orderId - уникальный идентификатор оплаты, указанный разработчиком или сформированный автоматически (uuid).

  • subscriptionToken - токен для валидации покупки на сервере.

Серверная валидация покупки

Если вам необходимо произвести валидацию покупки на сервере RuStore, вы можете использовать subscriptionToken из модели ProductPurchaseResult.SuccessProductPurchaseResult, возвращаемой при успешной покупке продукта. Есть также методы для валидации платежей по их InvoiceId.

Получение subscriptionToken из результата покупки
val params = ProductPurchaseParams(ProductId("productId"))
RuStorePayClient.getProductInteractor().purchase(params)
.addOnSuccessListener { result ->
if (result is ProductPurchaseResult.SuccessProductPurchaseResult) {
val invoceId = result.invoceId.value
yourApi.validate(invoceId)
}
}

Также можно получить subscriptionToken в сущности Purchase. Сущность Purchase можно получить используя метод getPurchases().

Получение subscriptionToken из результата покупки
RuStorePayClient.getPurchaseInteractor().getPurchases()
.addOnSuccessListener { purchases ->
purchases.forEach { purchase ->
yourApi.validate(purchase.subscriptionToken)
}
}

Потребление (подтверждение) покупки

Подтверждения требуют только покупки, которые были запущены по двухстадийному сценарию оплаты, т.е. с холдированием средств. Такие покупки, после успешного холдирования будут находиться в статусе PurchaseStatus.PAID.

Для списания средств с карты покупателя требуется подтверждение покупки. Для этого вы должны использовать метод confirmTwoStepPurchase.

Вызов метода подтверждения
RuStorePayClient.getPurchaseInteractor().confirmTwoStepPurchase(
purchaseId = PurchaseId("purchaseId"),
developerPayload = null,
)
.addOnSuccessListener {
// Process success
}.addOnFailureListener { throwable: Throwable ->
// Process error
}
  • purchaseId — идентификатор покупки.
  • developerPayload — строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки. Максимум 250 символов. Если передан, заменяет значение, записанное при старте покупки методом purchase.

Отмена покупки

Через SDK можно отменять только те покупки, которые были запущены по двухстадийному сценарию оплаты, т.е. с холдированием средств. Такие покупки после успешного холдирования будут находиться в статусе PurchaseStatus.PAID. После отмены покупки будут переходить в статус PurchaseStatus.REVERSED.

подсказка

Используйте отмену покупки в случаях, если после оплаты (холдирования средств) вы не можете предоставить покупателю товар.

Для отмены покупки (холда) вы должны использовать метод cancelTwoStepPurchase.

RuStorePayClient.getPurchaseInteractor().cancelTwoStepPurchase(
purchaseId = PurchaseId("purchaseId"),
)
.addOnSuccessListener {
// Process success
}.addOnFailureListener { throwable: Throwable ->
// Process error
}
  • purchaseId — идентификатор покупки.

Обработка ошибок

  • RuStorePaymentNetworkException — ошибка сетевого взаимодействия SDK;
  • RuStorePaymentCommonException — общая ошибка SDK;
  • RuStorePayClientAlreadyExist — ошибка повторной инициализации SDK;
  • RuStorePayClientNotCreated — попытка обратиться к публичным интерфейсам SDK до момента её инициализации;
  • RuStorePayInvalidActivePurchase — запущен процесс оплаты неизвестного типа продукта;
  • RuStorePayInvalidConsoleAppId — не задан обязательный параметр сonsole_application_id для инициализации SDK;
  • RuStorePaySignatureException — неверная сигнатура ответа (возникает при попытке совершить мошеннические действия);
  • EmptyPaymentTokenException — ошибка получения платежного токена;
  • RuStoreNotInstalledException — на устройстве пользователя не установлен RuStore;
  • RuStoreOutdatedException — версия RuStore, установленная на устройстве пользователя, не поддерживает данный SDK;
  • RuStoreUserUnauthorizedException — пользователь не авторизован в RuStore;
  • RuStoreApplicationBannedException — приложение заблокировано в RuStore;
  • RuStoreUserBannedException — пользователь заблокирован в RuStore;
  • RuStoreException — базовая ошибка RuStore, от которой наследуются остальные ошибки.

Список зависимостей

  • androidx.core:core-ktx:1.7.0 — The Apache Software License, Version 2.0;
  • androidx.activity:activity-ktx:1.7.0 — The Apache Software License, Version 2.0;
  • androidx.fragment:fragment-ktx:1.4.0 — The Apache Software License, Version 2.0;
  • androidx.lifecycle:lifecycle-runtime-ktx:2.4.1 — The Apache Software License, Version 2.0;
  • androidx.lifecycle:lifecycle-common-java8:2.4.1 — The Apache Software License, Version 2.0;
  • androidx.recyclerview:recyclerview:1.2.1 — The Apache Software License, Version 2.0;
  • androidx.security:security-crypto:1.0.0 — The Apache Software License, Version 2.0;
  • com.google.android.material:material:1.3.0 — The Apache Software License, Version 2.0;
  • io.coil-kt:coil:2.6.0 — The Apache Software License, Version 2.0.