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

6.1.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:6.1.0"))
implementation("ru.rustore.sdk:pay")
}

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

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

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

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(): Task<List<Purchase>> — позволяет получить покупки пользователя. В списке возвращаются покупки в статусе CONFIRMED для непотребляемых товаров и PAID для потребляемых товаров. PAID — статус, означающий успешное холдирование средств. Такая покупка ожидает подтверждения со стороны разработчика.
    • getPurchaseAvailability(): Task<PurchaseAvailabilityResult> — возвращает результат доступности работы с платежами.
    • consumePurchase(purchaseId: PurchaseId, developerPayload: DeveloperPayload? = null) — позволяет совершить потребление (подтверждение) покупки. Подходит только для потребляемых товаров.
  • ProductInteractor — интерактор, который позволяет работать с продуктами и имеет несколько публичных методов:
    • getProducts(productsId: List<ProductId>): Task<List<Product>> — позволяет получить информацию о продуктах по их ID. В списке продуктов можно указать до 1000 элементов.
    • purchase(params: ProductPurchaseParams): Task<ProductPurchaseResult> — позволяет совершить покупку продукта.
  • Блок 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. См. Обработка ошибок.

Например, если вы получили RuStoreUserUnauthorizedException, это означает, что пользователь не авторизован в RuStore. В этом случае вы можете вызвать метод openRuStoreAuthorization, который запускает мобильное приложение RuStore для авторизации. Другие доступные методы см. в разделе Работа с SDK.

Вызов метода getPurchaseAvailability
RuStorePayClient.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.getPurchaseInteractor().getPurchases()
.addOnSuccessListener { purchases: List<Purchase> ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}

Метод возвращает список покупок в статусах CONFIRMED для непотребляемых товаров и PAID для потребляемых товаров. Ниже представлена модель покупки:

Структура с информацией о покупке
public class Purchase internal constructor(
public val purchaseId: PurchaseId,
public val productId: ProductId,
public val invoiceId: InvoiceId,
public val orderId: OrderId?,
public val type: PurchaseType,
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 — строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки.

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

Для получения информации о покупке, используйте метод getPurchase.
Вызов метода получения покупки пользователя
RuStorePayClient.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 type: PurchaseType,
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 — состояние покупки.

    Промежуточные статусы:

    • INVOICE_CREATED — создан счёт на оплату, покупка ожидает оплаты.
    • PROCESSING — запущена оплата.
    • PAID — только покупки потребляемого товара — промежуточный статус, средства на счёте покупателя зарезервированы. Покупка ожидает подтверждения от разработчика.

    Финальные статусы:

    • CONSUMED — платеж за потребляемый товар успешно совершен.
    • CONFIRMED — платеж за непотребляемый товар успешно совершен.
    • CANCELLED— покупка отменена, оплата не была произведена.
    • EXPIRED — истекло время на оплату покупки.
    • REJECTED — покупка отклонена (например, ввиду недостатка средств).
    • REVERSED — покупка была отменена, т. к. не было произведено подтверждение в течение 72 часов (только для потребляемых товаров).
    • REFUNDED — запрос на возврат средств за покупку совершён успешно.

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

  • developerPayload — строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки.

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

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

Статусная модель покупки потребляемых продуктов (CONSUMABLES)

Покупка отменена

CANCELLED

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

EXPIRED


INVOICE_CREATED
Создан счёт на оплату покупки. Покупка не оплачена


PROCESSING
Запущен процесс оплаты счёта


REJECTED
Покупка не может быть оплачена выбранным способом (например, недостаточно средств на карте)


CONSUMED
Для покупок потребляемых товаров. Покупка подтверждена и оплачена. Денежные средства списаны у покупателя и отправлены разработчику. Доступна повторная покупка товара
Время на оплату
счёта истекло
Покупка отменена
пользователем
Пользователь
начал оплату
Операция оплаты
отклонена
Покупка оплачена


REFUNDED
Запрос на возврат средств за покупку совершён успешно. Доступна повторная покупка товара
Совершён возврат
средств за покупку


PAID
Для покупок потребляемых товаров. Средства на карте пользователя захолдированы успешно. Покупка ожидает подтверждения. Повторная покупка товара заблокирована


REVERSED
Не было произведено подтверждение покупки в течение 72 часов
Отмена покупки

Статусная модель покупки непотребляемых продуктов (NON-CONSUMABLES)

Покупка отменена

CANCELLED

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

EXPIRED


INVOICE_CREATED
Создан счёт на оплату покупки. Покупка не оплачена


PROCESSING
Запущен процесс оплаты счёта


REJECTED
Покупка не может быть оплачена выбранным способом (например, недостаточно средств на карте)


CONFIRMED
Для покупок непотребляемых товаров. Покупка оплачена. Повторная покупка товара запрещена
Время на оплату
счёта истекло
Покупка отменена
пользователем
Пользователь
начал оплату
Операция оплаты отклонена
Покупка оплачена


REFUNDED
Запрос на возврат средств за покупку совершён успешно. Доступна повторная покупка товара
Совершён возврат
средств за покупку

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

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

Вызов метода покупки продукта
RuStorePayClient.getProductInteractor().purchase(
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 — платёжный диалог закрыт до получения результата покупки. Состояние покупки неизвестно. Рекомендуем запросить статус покупки отдельно методом получения информации о покупке.

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

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

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

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

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

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

RuStore содержит продукты следующих типов:

  • CONSUMABLE (потребляемый) — можно купить много раз, например кристаллы в приложении.
  • NON_CONSUMABLE (непотребляемый) — можно купить один раз, например отключение рекламы в приложении.

Подтверждения требуют только продукты типа CONSUMABLE, если они находятся в состоянии PurchaseState.PAID.

Для потребления покупки используйте метод consumePurchase:

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

Обработка незавершённых платежей

Обработка незавершённых платежей производится разработчиком.

Чтобы подтвердить покупку типа CONSUMABLE и в статусе PAID вызовите метод потребления (подтверждения) покупки (см. Получение сведений о покупке).

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

  • 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, от которой наследуются остальные ошибки.