Состояние авторизации

SDK позволяет отслеживать состояние авторизации пользователя. Это полезно, чтобы:

  • Показать или скрыть кнопку логаута
  • Сменить баннер Яндекса на свой на части экранов
  • Отличить состояние «не авторизован» от «авторизован, но проверка безопасности не пройдена»

QuickPayAuthorizationState

Описывает текущий уровень авторизации пользователя в SDK.

interface QuickPayAuthorizationState {
    data object Initial : QuickPayAuthorizationState
    class DeviceNotSecured(val reason: QuickPayDeviceNotSecurityReason) : QuickPayAuthorizationState
    data object NotAuthorized : QuickPayAuthorizationState
    data object AuthInProgress : QuickPayAuthorizationState
    data object AccountAuthorized : QuickPayAuthorizationState
    data object SecurityCheckInProgress : QuickPayAuthorizationState
    class SecurityCheckFailed(val reason: QuickPaySecurityCheckFailureReason) : QuickPayAuthorizationState
    data object SecurityCheckRequired : QuickPayAuthorizationState
    data object SecurityCheckCompleted : QuickPayAuthorizationState
}
Состояние Описание Вход в Яндекс Проверка безопасности
Initial Состояние по умолчанию до загрузки авторизации Неизвестно Неизвестно
DeviceNotSecured На устройстве отсутствует блокировка экрана (PIN, графический ключ, пароль) или биометрия. Причина доступна в поле reason Нет Нет
NotAuthorized Пользователь не авторизован через Яндекс ID Нет Нет
AuthInProgress Идёт OAuth-авторизация через Login SDK Нет Нет
AccountAuthorized Пользователь авторизован через Яндекс ID, но проверка безопасности ещё не начата. BST-сессия не запрошена Да Нет
SecurityCheckInProgress Пользователь авторизован, идёт проверка безопасности (биометрия или ввод PIN/пароля устройства) Да Нет
SecurityCheckFailed Проверка безопасности не пройдена. Причина доступна в поле reason Да Нет
SecurityCheckRequired Пользователь авторизован, но истёк таймаут аутентификации в Keystore (300 с). Возвращается только при явном вызове getAuthorizationState(). В остальных случаях запрос проверки безопасности показывается пользователю автоматически Да Нет
SecurityCheckCompleted Проверка безопасности пройдена, SDK готов к платежам Да Да

Переходы между состояниями

Сценарий Переход
Первый вход NotAuthorizedAuthInProgressAccountAuthorizedSecurityCheckInProgressSecurityCheckCompleted
Холодный старт InitialAccountAuthorizedSecurityCheckInProgressSecurityCheckCompleted
Истечение таймаута проверки безопасности (300 с)* SecurityCheckCompletedSecurityCheckRequiredSecurityCheckInProgressSecurityCheckCompleted
Отмена проверки безопасности пользователем SecurityCheckInProgressSecurityCheckFailed(UserCancelled)
Изменение биометрических данных на устройстве SecurityCheckInProgressSecurityCheckFailed(KeyInvalidated)
Устройство без блокировки экрана или биометрии InitialDeviceNotSecured
Выход из аккаунта любое состояние → NotAuthorized

QuickPaySecurityCheckFailureReason

Причина неудачной проверки безопасности. Передаётся в QuickPayAuthorizationState.SecurityCheckFailed.

interface QuickPaySecurityCheckFailureReason {
    data object UserCancelled : QuickPaySecurityCheckFailureReason
    data object Lockout : QuickPaySecurityCheckFailureReason
    data object LockoutPermanent : QuickPaySecurityCheckFailureReason
    data object KeyInvalidated : QuickPaySecurityCheckFailureReason
    data object NoHardware : QuickPaySecurityCheckFailureReason
    data object NotEnrolled : QuickPaySecurityCheckFailureReason
    data object NetworkError : QuickPaySecurityCheckFailureReason
    data object Unknown : QuickPaySecurityCheckFailureReason
}
Причина Описание
UserCancelled Пользователь отменил или закрыл запрос проверки безопасности
Lockout Слишком много неудачных попыток, временная блокировка
LockoutPermanent Биометрия заблокирована до разблокировки устройства
KeyInvalidated Биометрические данные изменены или снята блокировка экрана
NoHardware На устройстве нет биометрического оборудования
NotEnrolled Биометрия или блокировка экрана не настроена
NetworkError Ошибка сети
Unknown Другая ошибка

QuickPayDeviceNotSecurityReason

Причина, по которой устройство не защищено. Передаётся в QuickPayAuthorizationState.DeviceNotSecured.

interface QuickPayDeviceNotSecurityReason {
    data object NoHardware : QuickPayDeviceNotSecurityReason
    data object NotEnrolled : QuickPayDeviceNotSecurityReason
    data object Unavailable : QuickPayDeviceNotSecurityReason
}
Причина Описание
NoHardware На устройстве нет биометрического оборудования
NotEnrolled Биометрия или блокировка экрана (PIN/графический ключ/пароль) не настроена
Unavailable Аутентификация на устройстве недоступна по неизвестной причине

Получение текущего состояния

Метод getAuthorizationState() возвращает текущее состояние синхронно:

val state = YandexQuickPay.getAuthorizationState()

when (state) {
    is QuickPayAuthorizationState.SecurityCheckCompleted -> {
        // Проверка безопасности пройдена — показать кнопку логаута, скрыть баннер
    }
    is QuickPayAuthorizationState.AccountAuthorized -> {
        // Авторизован через Яндекс ID, но проверка безопасности не начата
    }
    is QuickPayAuthorizationState.NotAuthorized -> {
        // Не авторизован — показать свой баннер, скрыть кнопку логаута
    }
    is QuickPayAuthorizationState.DeviceNotSecured -> {
        // Устройство не защищено — обработать state.reason
    }
    is QuickPayAuthorizationState.SecurityCheckRequired -> {
        // Авторизован, но потребуется проверка безопасности при следующей операции
    }
    is QuickPayAuthorizationState.SecurityCheckFailed -> {
        // Проверка безопасности не пройдена — обработать state.reason
    }
    is QuickPayAuthorizationState.AuthInProgress,
    is QuickPayAuthorizationState.SecurityCheckInProgress -> {
        // Идёт авторизация или проверка безопасности — показать индикатор загрузки
    }
    is QuickPayAuthorizationState.Initial -> {
        // Состояние по умолчанию до загрузки авторизации
    }
}

Проверка необходимости security check

Метод isSecurityCheckRequired() позволяет явно проверить, потребуется ли проверка безопасности при следующей операции:

val isRequired = YandexQuickPay.isSecurityCheckRequired()

if (isRequired) {
    // Следующая операция потребует проверку безопасности
}

Подписка на изменения

Переопределите onAuthorizationStateChanged в QuickPaymentStateListener. Метод имеет реализацию по умолчанию (no-op), поэтому переопределение опционально.

val quickPayListener = object : QuickPaymentStateListener {
    override fun onPaymentEnabledStateChanged(isEnabled: IsPaymentEnabled) { /* ... */ }
    override fun onSessionExpired() { /* ... */ }
    override fun onPaymentResult(result: QuickPayResult) { /* ... */ }

    override fun onAuthorizationStateChanged(state: QuickPayAuthorizationState) {
        when (state) {
            is QuickPayAuthorizationState.SecurityCheckCompleted -> showLogoutButton()
            is QuickPayAuthorizationState.NotAuthorized -> hideLogoutButton()
            is QuickPayAuthorizationState.DeviceNotSecured -> handleDeviceNotSecured(state.reason)
            is QuickPayAuthorizationState.SecurityCheckFailed -> handleSecurityCheckFailure(state.reason)
            else -> { /* обработать остальные состояния при необходимости */ }
        }
    }
}