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

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

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

QuickPayAuthState

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

public enum QuickPayAuthState: Equatable {
    case notAuthorized
    case authorizationInProgress
    case accountAuthorized
    case securityCheckInProgress
    case securityCheckFailed(reason: SecurityCheckFailReason)
    case securityCheckRequired
    case securityCheckCompleted
}
Состояние Описание Вход в Яндекс Проверка безопасности
.notAuthorized Пользователь не авторизован через Яндекс ID Нет Нет
.authorizationInProgress Идёт OAuth-авторизация Нет Нет
.accountAuthorized Пользователь авторизован через Яндекс ID, но проверка безопасности ещё не выполнена Да Нет
.securityCheckInProgress Пользователь авторизован, идёт проверка безопасности (Face ID / Touch ID / passcode). Запрос может не появиться, если сессия ещё активна Да Нет
.securityCheckFailed(reason:) Проверка безопасности не пройдена. Причина доступна в поле reason Да Нет
.securityCheckRequired Пользователь авторизован, но сессия проверки безопасности истекла Да Нет
.securityCheckCompleted Пользователь полностью авторизован, проверка безопасности пройдена, SDK готов к платежам Да Да

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

Сценарий Переход
Первый вход .notAuthorized.authorizationInProgress.accountAuthorized.securityCheckInProgress.securityCheckCompleted
Холодный старт .accountAuthorized.securityCheckInProgress.securityCheckCompleted
Истечение сессии проверки безопасности .securityCheckCompleted.securityCheckRequired.securityCheckInProgress.securityCheckCompleted
Отмена проверки безопасности пользователем .securityCheckInProgress.securityCheckFailed(.userCancelled)
Биометрия недоступна на устройстве .accountAuthorized.securityCheckFailed(.biometryNotAvailable)
Выход из аккаунта любое состояние → .notAuthorized

SecurityCheckFailReason

Причина неудачной проверки безопасности. Передаётся в .securityCheckFailed(reason:).

public enum QuickPayAuthState.SecurityCheckFailReason: Equatable {
    case userCancelled
    case biometryNotAvailable
    case unknownError
}
Причина Описание
.userCancelled Пользователь отменил или закрыл запрос проверки безопасности
.biometryNotAvailable Устройство не поддерживает биометрию или она не настроена
.unknownError Другая ошибка

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

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

let state = await YandexQuickPay.instance.getAuthState()

switch state {
case .securityCheckCompleted:
    // Проверка безопасности пройдена — показать кнопку логаута, скрыть баннер
case .accountAuthorized:
    // Авторизован через Яндекс ID, но проверка безопасности не выполнена
case .notAuthorized:
    // Не авторизован — показать свой баннер, скрыть кнопку логаута
case .securityCheckRequired:
    // Авторизован, но потребуется проверка безопасности при следующей операции
case .securityCheckFailed(let reason):
    // Проверка безопасности не пройдена — обработать reason
case .authorizationInProgress, .securityCheckInProgress:
    // Идёт авторизация или проверка безопасности — показать индикатор загрузки
}

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

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

let isRequired = try await YandexQuickPay.instance.isSecurityCheckRequired()

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

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

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

final class QuickPayListener: QuickPaymentStateListener {

    func onPaymentEnabledStateChanged(isEnabled: Bool) { /* ... */ }
    func onSessionExpired() { /* ... */ }
    func onPaymentResult(quickpayResult: QuickPayResult) { /* ... */ }

    func onAuthStateChanged(_ state: QuickPayAuthState) {
        DispatchQueue.main.async {
            switch state {
            case .securityCheckCompleted:
                self.showLogoutButton()
            case .notAuthorized:
                self.hideLogoutButton()
            case .securityCheckFailed(let reason):
                self.handleSecurityCheckFailure(reason)
            default:
                break
            }
        }
    }
}