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, the two login flows, reading session state, and logging out.

Most OnsideKit features require an authenticated user. A signed-in account securely stores payment methods and purchase history, and determines the correct product availability and pricing for the user's region.

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, delivered when the user cancels. 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.

The two login flows

Whichever way login starts, OnsideKit uses one of two flows:

  • 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).

You can force the in-SDK flow with OnsideDelegate.onsideShouldForceLocalLoginMethods(). Returning true always uses OnsideKit's own login screen and skips the app-to-app handoff. It is purely a UI-routing switch — it does not change which credentials are accepted. 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.

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?