For the complete documentation index, see llms.txt. This page is also available as Markdown.

Authentication & User Account

How OnsideKit handles authentication: explicit and on-demand login, standard and external login flows, reading session state, and logging out.

Most OnsideKit features require an authenticated user. The account determines product availability, pricing, and purchase history. Regular Onside accounts also support saved bank cards; external accounts have a smaller set of purchase capabilities.

You rarely have to manage login by hand — OnsideKit logs the user in on demand when an action needs it.

How login is triggered

There are two ways the login flow starts.

Explicit login

Call Onside.requestLogin(completion:) — for example, behind a dedicated "Log in" button.

@MainActor static func requestLogin(
    completion: (@MainActor (Result<Void, OnsideLoginError>) -> Void)? = nil
)
Onside.requestLogin { result in
    switch result {
    case .success:
        // The user is now logged in.
        updateUI()
    case .failure(.loginDiscarded):
        // The user dismissed the login screen.
        break
    }
}

OnsideLoginError has a single case, .loginDiscarded. It is delivered when the user cancels the flow — and also when the login screen could not be presented at all, because no active UIWindowScene was available. Treat it as "this login attempt did not complete" rather than strictly "user said no". Read the storefront to determine the current session state. The completion is optional — call Onside.requestLogin() to log in without handling the result.

Implicit (on-demand) login

You usually don't need to call requestLogin first. When the user is not authenticated and performs an action that needs an account, OnsideKit presents the login flow automatically and then resumes the original action.

On-demand login is triggered by:

  • Starting a purchase — Onside.defaultPaymentQueue().add(_:completion:)

  • Restoring purchases — Onside.defaultPaymentQueue().restoreCompletedTransactions(completion:)

  • Presenting the payment methods manager — Onside.presentPaymentMethodsManager(completion:)

If the user dismisses the login screen, the corresponding call reports .loginDiscarded through its completion handler.

Not every account-related call logs the user in. Onside.makeSignedInAppsHistoryRequest() does not present login — it returns .failure(.notLoggedIn) when there is no active session. See Signed In-App Purchase History.

Choosing a login flow

If Onside.externalLoginDelegate is assigned, the SDK first requests your app’s account identifier and attempts external login. A missing identifier or session-creation failure falls back to the regular login method. See External Login.

Without an external delegate, or after that fallback, OnsideDelegate.onsideLoginMethod() selects the regular flow:

  • App-to-app login (preferred). If the Onside store app is installed and you set Onside.callbackScheme, OnsideKit hands off to the Onside app for a seamless login and returns the user to your app. This requires the URL-scheme setup and Onside.handle(url:) forwarding from Initializing the SDK.

  • In-SDK login (fallback). Otherwise OnsideKit presents its own phone-number login screen. This is used when the Onside app isn't installed, when callbackScheme isn't set, or when you force it via the delegate (see below).

Implement OnsideDelegate.onsideLoginMethod() and return .local to use the in-SDK phone login instead of the app-to-app handoff. The default is .auto. An assigned external delegate takes priority over either value; .local does not disable external login. See The Onside Delegate.

Reading the session state

The session is represented by the storefront on the payment queue. A non-nil storefront means there is an authenticated session.

Check the current status

Observe changes

To react to login and logout in real time, add an observer conforming to OnsidePaymentTransactionObserver. OnsideKit calls onsidePaymentQueueDidChangeStorefront(_:) whenever the storefront changes (including nil → value on login and value → nil on logout).

Logging out

Onside.logout() ends the current session and clears the user's local authentication state (tokens and cached profile).

After logout, Onside.defaultPaymentQueue().storefront becomes nil, and the next action that requires an account triggers the login flow again. Logout does not remove Onside.externalLoginDelegate; if it still returns an account identifier, the next login can create an external session again.

OnsideKit may also log the user out automatically if the server invalidates the session (for example, the cached profile can no longer be refreshed). Observe the storefront, as shown above, to keep your UI in sync.

Authentication, region, and pricing

The signed-in account also determines the user's region, which drives product availability and pricing. You can fetch products before login using a best-guess region, then re-fetch once the storefront is known. See Regions & Storefronts.

Last updated

Was this helpful?