Быстрый старт

Пример реализации

Ознакомьтесь с приложением-примером чтобы узнать, как правильно интегрировать платежи.

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

Для работы проведения платежей необходимо соблюдение всех условий:

  1. На устройстве пользователя установлено приложение RuStore. 
  2. Приложение RuStore поддерживает функциональность платежей.
  3. Пользователь авторизован в приложении RuStore.
  4. Пользователь и приложение не должны быть заблокированы в RuStore.
  5. Для приложения включена возможность покупок в системе RuStore Консоль.

Сервис имеет некоторые ограничения на работу за пределами РФ.

Добавление репозитория

Подключите репозиторий:

repositories {
    maven {
    }
}

Подключение зависимости

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

dependencies {
    implementation("ru.rustore.sdk:billingclient:1.1.1")
}

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

Инициализация библиотеки в проекте

Перед вызовом методов библиотеки необходимо выполнить ее инициализацию.

Создайте RuStoreBillingClient, используя RuStoreBillingClientFactory.create():

val billingClient: RuStoreBillingClient = RuStoreBillingClientFactory.create(
      context = app,
      consoleApplicationId = "111111",
      deeplinkScheme = "yourappscheme"
)

  • context — контекст Android. Может быть любым, в реализации используется applicationContext.

  • consoleApplicationId — код приложения из консоли разработчика RuStore (пример: https://console.rustore.ru/apps/111111).

  • deeplinkScheme — cхема deeplink, необходимая для возврата в ваше приложение после оплаты через стороннее приложение (например, SberPay или СБП). SDK генерирует свой хост к данной схеме.

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

Библиотека поддерживает логирование событий, которое подключается отдельно при инициализации библиотеки.

Чтобы узнать подробности инициализации библиотеки, ознакомьтесь с информацией.

Обработка deeplink

Для возвращения в ваше приложение после оплаты через сторонние приложения (СБП, SberPay и другие) необходимо правильно реализовать обработку deeplink. Укажите в AndroidManifest.xml intent-filter с scheme вашего проекта:

<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» — схема вашего deeplink, может быть изменена на другую. Эта схема должна совпадать с параметром deeplinkScheme, передаваемым в init().

Также для успешного возврата в приложение нужно добавить следующий код:

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, ознакомьтесь с информацией.

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

RuStore Billing SDK требует правильно обрабатывать состояния покупки, чтобы предоставить наилучший сценарий использования. Так, купленные потребляемые товары необходимо потребить, а незаконченные покупки — отменить, чтобы иметь возможность заново начать новую.

val purchasesUseCase = billingClient.purchases
val purchases = purchasesUseCase.getPurchases().await().purchases.orEmpty()
purchases.forEach { purchase ->
val purchaseId = purchase.purchaseId
    if (purchaseId != null) {
        when (purchase.purchaseState) {
                PurchaseState.CREATED, PurchaseState.INVOICE_CREATED -> {
                    RuStoreBillingClient.purchases.deletePurchase(purchaseId).await()
                }
                PurchaseState.PAID -> {
                    RuStoreBillingClient.purchases.confirmPurchase(purchaseId).await()
                }
                else -> Unit
        }
    }
}

Чтобы узнать подробности о обработке статусов покупок, ознакомьтесь с информацией

Чтобы узнать подробности получения списка покупок, ознакомьтесь с информацией.

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

Обработать результат покупки необходимо следующим образом:

private fun purchaseProduct(product: Product) {
    val purchasesUseCase = billingClient.purchases
    purchasesUseCase.purchaseProduct(product.productId)
        .addOnSuccessListener { paymentResult ->
            handlePaymentResult(paymentResult, product)
        }
        .addOnFailureListener {
            // Handle error
        }
}
 
private fun handlePaymentResult(paymentResult: PaymentResult, product: Product) {
    when (paymentResult) {
        is PaymentResult.InvalidPurchase -> {
            paymentResult.purchaseId?.let { deletePurchase(it) }
        }
 
        is PaymentResult.PurchaseResult -> {
            when (paymentResult.finishCode) {
                PaymentFinishCode.SUCCESSFUL_PAYMENT -> {
                    if (product.productType == ProductType.CONSUMABLE) {
                        confirmPurchase(paymentResult.purchaseId)
                    }
                }
                PaymentFinishCode.CLOSED_BY_USER,
                PaymentFinishCode.UNHANDLED_FORM_ERROR,
                PaymentFinishCode.PAYMENT_TIMEOUT,
                PaymentFinishCode.DECLINED_BY_SERVER,
                PaymentFinishCode.RESULT_UNKNOWN,
                -> {
                    deletePurchase(paymentResult.purchaseId)
                }
            }
        }
        else -> Unit
    }
}

Чтобы узнать подробности о покупке продукта, ознакомьтесь с информацией.

Чтобы узнать подробности о обработке статусов покупок, ознакомьтесь с информацией

Обновлено 3 мая 2023 г.
Was this information helpful?