Название библиотеки: Bimos Billing Library, язык: kotlin, среда разработки: Android Studio.

1. Регистрация в ЮKassa, получение ключей магазина.

Первое, что необходимо сделать, это зарегистрироваться в ЮКассе. Для регистрации вам необходим статус самозанятого, ИП или ЮЛ. Всю информацию по регистрации вы найдете на соответствующих ресурсах.
После регистрации личного кабинета в ЮКассе по умолчанию будет создан тестовый магазин (создание реального магазина занимает около недели). Как только у вас появится тестовый магазин, вы можете приступить к интеграции покупок в свое приложение. В магазине вы найдете ключи необходимые для работы с Bimos Billing Library: shopId, секретный ключ и ключ для мобильного SDK. Для этого в меню слева перейдите в раздел Интеграция -> Ключи API:
shopId (shopId) - это шестизначный номер магазина. Секретный ключ (secretKey) и ключ для мобильного SDK (clientApplicationKey) находятся в соответствующих разделах. В тестовом магазине ключи выглядят так: "test_YeX1KZVv_Mfc758yIlVYDjYKgtjaTRwOQkPh6Wk586E", когда у вас появится реальный магазин ключи будут выглядеть так же, только вместо слова "test" будет "live".
Вы получили первые три ключа, необходимые для интеграции.

2. Создание продуктов приложения.

2.1. Скачайте приложение Bimos Admin.

2.2. При открытии приложения необходимо войти в аккаунт, если его нет, то зарегистрироваться. Зарегистрироваться можно только по почте (стандартная процедура с верификацией).

2.3. После регистрации вы попадете в личный кабинет, где будут находится ваши приложения, в которые вы будете интегрировать покупки. Нажмите "Добавить приложение". Вы попадете на активити создания приложения, необходимо ввести название, выбрать иконку и нажать "Создать". Рекомендуется давать название и выбирать иконку, как у приложения, для которого вы это делаете, чтобы потом не путаться. Созданное приложение удалить нельзя (только редактировать). Далее откройте созданное приложение. Вверху экрана вы увидите applicationId - четвертый ключ, необходимый для интеграции.

2.4. В созданном приложении нажмите "Добавить продукт". Вы попадете на активити создания продукта. Там необходимо будет заполнить поля (обязательные помечены звездочкой). Каждое поле является параметром вашего продукта:
____1) Тип (type) - покупка или подписка. Обязательный, не изменяемый параметр (вы не сможете его отредактировать после создания продукта). Покупка - однократный платеж. Подписка - продукт, который пользователь оплачивает регулярно через определенный период.
____2) Период (subscriptionPeriod) - интервал времени подписки. Обязательный, не изменяемый параметр. Есть 4 варианта - 1 месяц, 3 месяца, 6 месяцев, 12 месяцев.
____3) Идентификатор продукта (id). Обязательный, не изменяемый параметр. Рекомендуется писать его в стиле snake_case.
____4) Название продукта (name). Обязательный, изменяемый параметр.
____5) Стоимость продукта (price). Обязательный, изменяемый параметр.
____6) Описание продукта (description). Не обязательный, изменяемый параметр.
____7) Стоимость продукта в месяц (pricePerMonth). Не обязательный, изменяемый параметр. Только для подписок.
____8) Порядковый номер (number). Не обязательный, изменяемый параметр. Дополнительное поле для сортировки продуктов в вашем приложении.
____9) Бесплатный пробный период (trialPeriod). Не обязательный, изменяемый параметр (по умолчанию равен 0). Деньги "замораживаются" на счете и списываются только по окончании этого периода, если пользователь за это время не отменит покупку. При отмене пользователем покупки комиссия за платеж не списывается.
____10) Полная стоимость (fullPrice). Не обязательный, изменяемый параметр. Для использования в маркетинговых целях.
____11) Скидка (discount). Не обязательный, изменяемый параметр. Для использования в маркетинговых целях.
____12) Применение новой стоимости к действующим подписчикам (applyNewPrice). Не обязательный, изменяемый параметр (по умолчанию равен false). Только для подписок. Говорит серверу о сумме очередного списания по подписке при изменении её стоимости. Если галочка не поставлена, значит списывается сумма по которой пользователь изначально подписался на продукт, если галочка стоит, то списывается текущая стоимость.
____13) Промо (promo). Не обязательный, изменяемый параметр. Для использования в маркетинговых целях.
____14) Тэг (tag). Не обязательный, изменяемый параметр. Параметр, который можно использовать по своему усмотрению.

Все эти параметры являются свойствами класса:
data class Product(val id: String, val applicationId: String, val type: String, val subscriptionPeriod: Int, val name: String, val description: String, val price: Int, val pricePerMonth: Int, val number: Int, val currency: String, val discount: String, val fullPrice: Int, val applyNewPrice: Boolean, val trialPeriod: Int, val promo: String, val tag: String).
Все свойства non nullable (по умолчанию значения 0 или "").

Когда вы открываете страницу вашего приложения, то Bimos Admin делает запрос на сервер и получает в ответе все продукты вашего приложения в виде списка List<Product>. То же самое происходит в вашем реальном приложении, когда вы делаете запрос продуктов.

Созданный продукт удалить нельзя, всего можно создать до 10 продуктов для одного приложения.

3. Интеграция библиотеки Bimos Billing Library.

3.1. Настройка проекта.

3.1.1. Подключение библиотек.

Добавить зависимости в build.gradle файл:

dependencies {

        ...
        implementation 'com.squareup.retrofit2:retrofit:2.9.0'
        implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
        implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0'
        implementation 'com.squareup.okhttp3:okhttp:4.11.0'
        implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1'
        implementation 'ru.yoomoney.sdk.kassa.payments:yookassa-android-sdk:6.10.0'

        ...

}
Скачайте библиотеку Bimos Billing Library. Распакуйте архив, у вас должен получится файл bimos-billing-ktx-v1.aar
Измените вид своего проекта в Android Studio на Project (вверху слева выпадающее меню). Откройте папку модуля вашего приложения, найдите в нем папку libs (если её нет, то создайте), поместите в эту папку скачанный файл bimos-billing-ktx-v1.aar
Добавить зависимость этой библиотеки в build.gradle файл:
____- если у вас последняя версия Android Studio:

dependencies {

        ...
        implementation(files('libs/bimos-billing-ktx-v1.aar'))

        ...

}
____- если у вас старая версия Android Studio:

dependencies {

        ...
        implementation files('libs/bimos-billing-ktx-v1.aar')

        ...

}
3.1.2. Настройка доступа к сети.

Добавить атрибут networkSecurityConfig внутрь тэга application AndroidManifest файла:

<application
        ...
        android:networkSecurityConfig="@xml/ym_network_security_config"
        ...
</application>

Создать файл конфигурации ym_network_security_config.xml в директории xml ресурсов и прописать там:

<network-security-config>

        ...
        <domain-config cleartextTrafficPermitted="true">
                <domain includeSubdomains="true">certs.yoomoney.ru</domain>
        </domain-config>

        ...
</network-security-config>

Если у вас уже есть атрибут networkSecurityConfig, то добавьте этот код ваш существующий файл конфигурации.
3.1.3. Добавление уникальной схемы диплинка.

Добавить в блок android.defaultConfig файла build.gradle строку:

android {
        defaultConfig {
                ...
                resValue "string", "ym_app_scheme", "example_app"
                ...
        }
}

Вместо "example_app" нужно придумать свою уникальную схему (любые слова из латинских букв, например my_premium_app, mypremiumapp, superapp, btryilmsrnkdxj и т.п.)

3.2. Создание экземпляра класса Bimos.

В активити или фрагменте создайте переменную bimos:

class MainActivity : AppCompatActivity() {
        private lateinit var bimos: Bimos

        ...
}

Если у вас активити, инициализируйте эту переменную в функции onCreate(), в конструктор необходимо передать активити:

override fun onCreate(savedInstanceState: Bundle?) {

        ...

        bimos = Bimos(activity = this)

        ...

}

Если у вас фрагмент, инициализируйте эту переменную в функции onViewCreated(), в конструктор необходимо передать активити:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        ...

        bimos = Bimos(activity = requireActivity() as AppCompatActivity)

        ...

}

Далее необходимо инициализировать свойства созданного экземпляра класса, которые будут использоваться библиотекой в запросах:

bimos.init(
        shopId = 654730,
        secretKey = "live_YeX1KZVv_Mfc758yIlVYDjYKgtjaTRwOQkPh6Wk586E",
        clientApplicationKey = "live_MjU0ODIwYhyrIkmGV8IdJ1W176FkpUPDfnfkCG1FEGE",
        applicationId = "ae7b4e96-b318-73aр0-a8f9-ef09798af86",
        colorScheme = "#8573B6",
        applicationName = "AppExample"
)

shopId, secretKey и clientApplicationKey вы берете из магазина в личном кабинете ЮКассы (см. п 1), applicationId вы берете со страницы вашего приложения в Bimos Admin (см. п 2), colorScheme это цвет, в который будут окрашены элементы виджетов Bimos Library и SDK ЮКассы (рекомендуется использовать основной цвет вашего приложения - primary color), applicationName название вашего приложения.

3.3. Запросы на сервер Bimos.

С помощью библиотеки вы можете сделать следующие запросы на сервер Bimos:

Так же вы можете получить списки продуктов и платежей:
____getProductList() - список List продуктов приложения;
____getProductMap() - список Map продуктов приложения;
____getPaymentList() - список платежей пользователя;
3.3.1. Запрос всех продуктов приложения:

bimos.getApplicationProducts(object : GetApplicationProductsCallback {
        override fun onSuccessfulResponse(products: List<Product>) {
                // Успешный ответ
        }

        override fun onErrorResponse(statusCode: Int, statusMessage: String, errorBody: String?) {
                // Ошибка в ответе
        }

        override fun onFailure(call: Call<List<Product>>, t: Throwable) {
                // Нет соединения с сервером
        }
})

Параметры у функции getApplicationProducts() отсутствуют, библиотека берет applicationId, который вы передали при инициализации свойств (см. п 3.2).
В ответе придет список products: List<Product>. Это тот же data class Product, что и в Bimos Admin, а список products это список продуктов, которые вы там создали для этого приложения.
3.3.2. Запрос всех активных платежей пользователя:

bimos.getUserPayments(userUid, object : GetUserPaymentsCallback {
        override fun onSuccessfulResponse(payments: List<Payment>) {
                // Успешный ответ
        }

        override fun onErrorResponse(statusCode: Int, statusMessage: String, errorBody: String?) {
                // Ошибка в ответе
        }

        override fun onFailure(call: Call<List<Payment>>, t: Throwable) {
                // Нет соединения с сервером
        }
})

В качестве аргумента в функцию getUserPayments() необходимо передать userUid - идентификатор пользователя, на который вы сохраняете его покупки (например, почта или какой-то рандомный uid), по этому идентификатору вы будете искать платежи пользователя в админпанели Bimos Admin. Другой параметр - applicationId библиотека берет из свойств, которые вы передали при инициализации (см. п 3.2).
В ответе придет список payments: List<Payment>.
data class Payment(val paymentId: String, val userUid: String, val productId: String, val applicationId: String, val status: String, val confirmationUrl: String, val cancellationReason: String, val initialPrice: String, val currentPrice: String, val currency: String, val paymentTime: Long, val activationTime: Long, val renewalTime: Long, val endOfTermTime: Long, val type: String, val subscriptionPeriod: Int, val paymentConfirmed: Boolean, val trialPeriod: Int,val test: Boolean)

Свойства данного класса:
____1) paymentId - идентификатор платежа, присваивается ЮКассой при создании данного платежа.
____2) userUid - идентификатор пользователя, к которому относится этот платеж.
____3) productId - идентификатор продукта, к которому относится этот платеж (свойство id класса Product).
____4) applicationId - идентификатор приложения, к которому относится этот платеж.
____5) status - статус платежа. Может быть пять вариантов:
________- "succeeded" - успешный;
________- "waiting_for_capture" - бесплатный пробный период;
________- "pending" - ожидает подтверждения;
________- "canceled" - отменен;
________- "forbidden" - подписка отменена пользователем (пользователь запретил очередное списание);
____6) cancellationReason - причина отмены платежа (статус платежа "canceled"). Могут быть следующие варианты:
________- "3d_secure_failed" - не пройдена аутентификация по 3-D Secure (подтверждение платежа);
________- "call_issuer" - оплата данным платежным средством отклонена по неизвестным причинам;
________- "canceled_by_merchant" - платеж отменен при оплате в две стадии (платеж был в статусе "pending" и пользователь отменил подтверждение);
________- "card_expired" - истек срок действия банковской карты;
________- "country_forbidden" - нельзя заплатить банковской картой, выпущенной в этой стране;
________- "expired_on_capture" - истек срок списания оплаты у двухстадийного платежа (платеж был в статусе "waiting_for_capture" и не был вовремя подтвержден);
________- "expired_on_confirmation" - истек срок оплаты: пользователь не подтвердил платеж за время, отведенное на оплату выбранным способом;
________- "fraud_suspected" - платеж заблокирован из-за подозрения в мошенничестве;
________- "general_decline" - причина не детализирована;
________- "insufficient_funds" - не хватает денег для оплаты;
________- "internal_timeout" - технические неполадки на стороне ЮKassa: не удалось обработать запрос в течение 30 секунд;
________- "invalid_card_number" - неправильно указан номер карты;
________- "invalid_csc" - неправильно указан код CVV2 (CVC2, CID);
________- "issuer_unavailable" - организация, выпустившая платежное средство, недоступна;
________- "payment_method_limit_exceeded" - исчерпан лимит платежей для данного платежного средства или вашего магазина;
________- "payment_method_restricted" - запрещены операции данным платежным средством (например, карта заблокирована из-за утери, кошелек — из-за взлома мошенниками);
____7) initialPrice - цена, по которой пользователь изначально купил продукт.
____8) currentPrice - текущая цена продукта (указывается последнее установленное вами значение).
____9) paymentTime - время совершения покупки.
____10) activationTime - время списания оплаты с пользователя после окончания бесплатного пробного периода. Если пробный период отсутствует, то значение равно 0.
____11) renewalTime - время очередного списания по подписке. Для покупок это значение равно 0.
____12) endOfTermTime - время окончания периода подписки. Для покупок это значение равно 0.
____13) type - тип купленного продукта. Может быть два варианта:
________- "purchase" - покупка;
________- "subscription" - подписка;
____14) subscriptionPeriod - период подписки. Может быть пять вариантов:
________- 0 - значение по умолчанию для покупок;
________- 1 - 1 месяц;
________- 3 - 3 месяца;
________- 6 - 6 месяцев;
________- 12 - 12 месяцев;
____15) trialPeriod - бесплатный пробный период. Может быть три варианта:
________- 3 - 3 дня;
________- 5 - 5 дней (бывает только при проведении платежа через Sber Pay);
________- 7 - 7 дней;
____16) test - тестовый платеж или нет. Может быть два варианта:
________- true - тестовый;
________- false - реальный;

Все свойства non nullable.
3.3.3. Запрос всех продуктов приложения и активных платежей пользователя:

bimos.getProductsAndPayments(userUid, object : ProductsAndPaymentsCallback {
        override fun onSuccessfulResponse(productsAndPayments: ProductsAndPayments) {
                // Успешный ответ
        }

        override fun onErrorResponse(statusCode: Int, statusMessage: String, errorBody: String?) {
                // Ошибка в ответе
        }

        override fun onFailure(call: Call<ProductsAndPayments>, t: Throwable) {
                // Нет соединения с сервером
        }
})

Запрос getPaymentsAndProducts() представляет из себя совокупность предыдущих двух запросов, в ответе придет объект productsAndPayments: ProductsAndPayments.
data class ProductsAndPayments(val products: List<Product>, val payments: List<Payment>)

3.3.4. Списки продуктов и платежей.

У класса Bimos есть методы, которые предоставляют доступ к трем спискам:
____1) Список List продуктов приложения - List<Product>. Чтобы в этом списке появились данные необходимо сделать успешный запрос getApplicationProducts() либо getPaymentsAndProducts();
____2) Список Map продуктов приложения - Map<String, Product>, ключом является id продукта, по которому вы можете получить сам продукт (объект Product). Чтобы в этом списке появились данные необходимо сделать успешный запрос getApplicationProducts() либо getPaymentsAndProducts();
____3) Список активных платежей пользователя - List<Payment>. Чтобы в этом списке появились данные необходимо сделать успешный запрос getUserPayments() либо getPaymentsAndProducts();

Обновление этих списков происходит каждый раз, когда вы получаете соответствующие данные с сервера. То есть, в них всегда будет актуальная информация с последнего успешного запроса. Обратите внимание, что эти списки являются свойствами вашего экземпляра класса Bimos и хранятся во временной памяти.

Получить сами списки можно с помощью методов:
val productList: List<Product> = bimos.getProductList()
val productMap: Map<String, Product> = bimos.getProductMap()
val paymentList: List<Payment> = bimos.getPaymentList()

Из этих списков можно получить необходимый продукт или платеж для использования их в запросах:
val product = productMap["идентификатор_вашего_продукта"] - получение продукта по идентификатору
val product = productList[индекс] - получение продукта по индексу
val payment = paymentList[индекс] - получение платежа по индексу
3.3.5. Создание платежа:

bimos.createPayment(userUid, customerId, product, object : CreatePaymentCallback {
        override fun onCreatingPayment() {
                // Отправлен запрос на создание платежа
        }

        override fun onSuccessfulResponse(payment: Payment) {
                // Платеж успешно создан

                when(payment.status) {
                        "succeeded" -> {

                        }
                        "waiting_for_capture" -> {

                        }
                        "canceled" -> {
                                val cancellationReason = payment.cancellationReason

                        }
                }
        }

        override fun onYookassaErrorResponse(yookassaError: YookassaError) {
                // Ошибка создания платежа
        }

        override fun onErrorResponse(statusCode: Int, statusMessage: String, errorBody: String?) {
                // Ошибка в ответе
        }

        override fun onFailure(call: Call<PaymentResponse>, t: Throwable) {
                // Нет соединения с сервером
        }

}, object : ConfirmationPaymentCallback {
        override fun onCanceledConfirmationResult() {
                // Подтверждение отменено
        }

        override fun onErrorConfirmationResult(code: Int?, description: String?, url: String?) {
                // Ошибка подтверждения
        }

}, object : GetPaymentStatusCallback {
        override fun onSuccessfulResponse(payment: Payment) {
                // Статус платежа успешно подтвержден

                when(payment.status) {
                        "succeeded" -> {

                        }
                        "waiting_for_capture" -> {

                        }
                        "canceled" -> {
                                val cancellationReason = payment.cancellationReason

                        }

                        "pending" -> {

                        }
                }
        }

        override fun onYookassaErrorResponse(yookassaError: YookassaError) {
                // Ошибка подтверждения статуса платежа
        }

        override fun onErrorResponse(statusCode: Int, statusMessage: String, errorBody: String?) {
                // Ошибка в ответе
        }

        override fun onFailure(call: Call<PaymentResponse>, t: Throwable) {
                // Нет соединения с сервером
        }
})

В качестве аргументов в функцию createPayment() необходимо передать userUid, customerId и product:
- userUid - идентификатор пользователя, на который вы сохраняете его покупки (например, почта или какой-то рандомный uid), по этому идентификатору вы будете искать платежи пользователя в админпанели Bimos Admin.
- customerId - идентификатор аналогичный userUid, нужен для поиска платежей пользователя в вашем магазине ЮКассы. Оба параметра можно сделать одинаковыми, например, почта пользователя.
- product - продукт, который необходимо купить, его можно взять из списка продуктов (см. п 3.3.4).

Процесс создания платежа состоит из трех этапов:

1) Отправка запроса на создание платежа

колбэк object : CreatePaymentCallback {}

onCreatingPayment() - срабатывает после того как библиотека отправит запрос на сервер Bimos. Это нужно для того, чтобы вы могли как-то показать пользователю на экране начало процесса платежа, так как он может быть относительно длительным по времени.

onSuccessfulResponse(payment: Payment) - срабатывает при успешном создании платежа и его сохранении на сервере Bimos. Приходит созданный платеж payment: Payment.
Платежная система ЮКасса создает платеж с одним из четырех статусов:
____1) "succeeded" - плетеж прошел, денежные средства списаны;
____2) "waiting_for_capture" - плетеж ожидает списания, денежные средства "заморожены" (бесплатный пробный период);
____3) "canceled" - плетеж отменен;
____4) "pending" - плетеж ожидает подтверждения, пользователь должен подтвердить списание денежных средств (код по СМС или приложение Сбербанк);
Функция срабатывает только если у созданного платежа статусы "succeeded", "waiting_for_capture" или "canceled". Если платеж приходит в статусе "pending", то библиотека сразу отправляет его на второй этап - подтверждение платежа пользователем, это обязательная процедура, от вас никаких действий не требуется.

В реальных платежах созданный платеж придет в статусе "pending" либо "canceled". Все реальные платежи проходят процедуру подтверждения пользователем, это требование любого банка (код в СМС вам присылает ваш банк, чтобы убедится в отсутствии мошеннических действий). Если по каким-то причинам платежной системе не удалось списать денежные средства, то платеж будет отменен с указанием причины отмены.
В тестовых платежах статус платежа зависит от используемой тестовой карты:
____5555555555554444 - статус "succeeded";
____5555555555554477 - статус "pending";
____5555555555554592 - статус "canceled", причина отмены "3d_secure_failed";
____5555555555554535 - статус "canceled", причина отмены "call_issuer";
____5555555555554543 - статус "canceled", причина отмены "card_expired";
____5555555555554527 - статус "canceled", причина отмены "general_decline";
____5555555555554600 - статус "canceled", причина отмены "insufficient_funds";
____5555555555554584 - статус "canceled", причина отмены "country_forbidden";
Полный список тестовых карт можно посмотреть в документации ЮКасса - тестирование платежей.

onYookassaErrorResponse(yookassaError: YookassaError) - срабатывает, если в платежной системе ЮКасса произошла ошибка при создании платежа. Приходит ошибка yookassaError: YookassaError.
data class YookassaError(val type: String, val id: String, val code: String, val description: String, val parameter: String)
Свойства данного класса:
____type - фиксированное значение - "error", обязательный параметр;
____id - идентификатор ошибки, обязательный параметр;
____code - код ошибки, обязательный параметр;
____description - описание ошибки, необязательный параметр;
____parameter - название заголовка или параметра тела ответа, из-за которого произошла ошибка, необязательный параметр;

2) Подтверждение платежа пользователем

колбэк object : ConfirmationPaymentCallback {}

onCanceledConfirmationResult() - срабатывает, если пользователь отменяет подтверждение (нажимает кнопку "назад" либо закрывает форму подтверждения платежа.

onErrorConfirmationResult() - срабатывает, если при подтверждении платежа возникла какая-то ошибка, данный этой ошибки можно посмотреть в пришедших параметрах.

Если пользователь подтвердил платеж, то библиотека автоматически отправляет запрос на проверку статуса платежа, это обязательная процедура, от вас никаких действий не требуется.
Проверка статуса необходима, так как подтверждение платежа пользователем не является гарантией того, что денежные средства будут списаны.

3) Проверка статуса платежа

колбэк object : GetPaymentStatusCallback {}

onSuccessfulResponse(payment: Payment) - срабатывает, при успешной проверке статуса платежа и его сохранении на сервере Bimos. Приходит созданный платеж payment: Payment.
Платеж придет в одном из четырех статусов:
____1) "succeeded" - плетеж подтвержден, денежные средства списаны;
____2) "waiting_for_capture" - плетеж подтвержден и ожидает списания, денежные средства "заморожены" (бесплатный пробный период);
____3) "canceled" - плетеж отменен;
____4) "pending" - платеж не подтвержден по одной из трех причин:
________- информация о подтверждении платежа ещё не поступила в ЮКассу (иногда бывают задержки 1-2 минуты, особенно при подтверждении через приложение Сбербанк);
________- какие-то сбои в платежной системе;
________- при подтверждении через приложение Сбербанк пользователь нажал "Отмена". В таком случае mSDK ЮКассы почему-то всё равно считает этот платеж подтвержденным.

onYookassaErrorResponse(yookassaError: YookassaError) - срабатывает, если в платежной системе ЮКасса произошла ошибка при проверке статуса платежа.
3.3.6. Отмена платежа (во время бесплатного пробного периода):

bimos.cancelPayment(payment, object : CancelPaymentCallback {
        override fun onCancellationPayment() {
                // Отправлен запрос на отмену платежа
        }

        override fun onSuccessfulResponse(productsAndPayments: ProductsAndPayments) {

                // Платеж успешно отменен
        }

        override fun onYookassaErrorResponse(yookassaError: YookassaError) {
                // Ошибка отмены платежа
        }

        override fun onErrorResponse(statusCode: Int, statusMessage: String, errorBody: String?) {
                // Ошибка в ответе
        }

        override fun onFailure(call: Call<CancelPaymentResponse>, t: Throwable) {

                // Нет соединения с сервером
        }
})

Отменить платеж можно только когда он находится в статусе "waiting_for_capture" (бесплатный пробный период). Пользователь должен иметь возможность сделать это самостоятельно.
По окончании пробного периода денежные средства списываются и платеж переходит в статус "succeeded".

В качестве аргумента в функцию cancelPayment() необходимо передать payment - платеж, который необходимо отменить, его можно взять из списка платежей (см. п 3.3.4).
onCancellationPayment() - срабатывает после того как библиотека отправит запрос на сервер Bimos.

onSuccessfulResponse(productsAndPayments: ProductsAndPayments) - срабатывает при успешной отмене платежа и сохранении изменений на сервере Bimos. Приходит объект productsAndPayments: ProductsAndPayments (см. п 3.3.3).

onYookassaErrorResponse(yookassaError: YookassaError) - срабатывает, если в платежной системе ЮКасса произошла ошибка при отмене платежа.
3.3.7. Отмена подписки:

bimos.cancelSubscription(payment, object : CancelSubscriptionCallback {
        override fun onSuccessfulResponse(productsAndPayments: ProductsAndPayments) {
                // Подписка успешно отменена
        }

        override fun onErrorResponse(statusCode: Int, statusMessage: String, errorBody: String?) {
                // Ошибка в ответе
        }

        override fun onFailure(call: Call<ProductsAndPayments>, t: Throwable) {
                // Нет соединения с сервером
        }
})

Отменить можно только действующую подписку - статус платежа "succeeded", тип платежа "subscription". Пользователь должен иметь возможность сделать это самостоятельно.
После отмены подписки платеж переходит в статус "forbidden". Далее вы можете дать возможность пользователю восстановить эту подписку (см. п 3.3.8).

В качестве аргумента в функцию cancelSubscription() необходимо передать payment - платеж, который необходимо отменить, его можно взять из списка платежей (см. п 3.3.4).

onSuccessfulResponse(productsAndPayments: ProductsAndPayments) - срабатывает при успешной отмене подписки и сохранении изменений на сервере Bimos. Приходит объект productsAndPayments: ProductsAndPayments (см. п 3.3.3).
3.3.8. Восстановление подписки:

bimos.recoverSubscription(payment, object : RecoverSubscriptionCallback {
        override fun onSuccessfulResponse(productsAndPayments: ProductsAndPayments) {
                // Подписка успешно восстановлена
        }

        override fun onErrorResponse(statusCode: Int, statusMessage: String, errorBody: String?) {
                // Ошибка в ответе
        }

        override fun onFailure(call: Call<ProductsAndPayments>, t: Throwable) {
                // Нет соединения с сервером
        }
})

Восстановить можно только отмененную подписку - статус платежа "forbidden", тип платежа "subscription".
После восстановления подписки платеж переходит в статус "succeeded". Далее пользователь должен иметь возможность отменить эту восстановленную подписку самостоятельно (см. п 3.3.7).
Функции cancelSubscription() и recoverSubscription() противоположные по действию, они меняют статус платежа (подписки) с "succeeded" на "forbidden" и наоборот, что дает серверу Bimos понимание, нужно совершать очередной платеж по этой подписке или нет.

В качестве аргумента в функцию recoverSubscription() необходимо передать payment - платеж, который необходимо восстановить, его можно взять из списка платежей (см. п 3.3.4).

onSuccessfulResponse(productsAndPayments: ProductsAndPayments) - срабатывает при успешной отмене подписки и сохранении изменений на сервере Bimos. Приходит объект productsAndPayments: ProductsAndPayments (см. п 3.3.3).