Skip to main content

Wallet SDK (Android)

Overview

The Wallet SDK for Android enables secure identity verification and transaction authorization during checkout. It is optimized for native Kotlin apps and leverages multi-factor authentication (MFA) with passkeys.

This SDK allows your wallet app to:

  • Initiate an MFA session tied to a transaction.
  • Guide users through passkey authentication, passkey creation, or fallback login.
  • Streamline checkout flows directly within a native Android experience.

Use this SDK when building wallet apps that require frictionless and secure checkout with passkeys.

Requirements

  • Android 9+ (API level 28+)
  • Android Studio
  • Kotlin

Prerequisites

  • Create an application to obtain a base URL. The SDK uses this base URL to interact with the LoginID authentication service.
  • Create an API key with at least the external:verify scope. You’ll need this to request authorization tokens from your backend.

Before installing the SDK, configure the association between your Android application and your website using a Digital Asset Links file.

Android uses a Digital Asset Links file named assetlinks.json to verify the association between your application and your website.

Find Your Package Name

You can find your application's package name in the app module's build.gradle.kts file under defaultConfig:

android {
defaultConfig {
applicationId = "<PACKAGE_NAME>"
}
}

Generate the SHA-256 Certificate Fingerprint

Use the keytool utility included with the Java Development Kit to retrieve the SHA-256 fingerprint of your application's signing certificate:

keytool -list -v \
-keystore KEYSTORE_PATH \
-alias KEYSTORE_ALIAS \
-storepass KEYSTORE_PASSWORD \
-keypass KEY_PASSWORD

Replace the following values:

  • KEYSTORE_PATH with the path to your keystore
  • KEYSTORE_ALIAS with the signing-key alias
  • KEYSTORE_PASSWORD with the keystore password
  • KEY_PASSWORD with the signing-key password

The command output includes the certificate's SHA-256 fingerprint.

Local Development

For local development, you can use the default Android debug keystore with the following values:

  • KEYSTORE_ALIAS: androiddebugkey
  • KEYSTORE_PASSWORD: android
  • KEY_PASSWORD: android

Use a dedicated signing key for production applications. For applications distributed through Google Play, you can find the app-signing certificate fingerprint in the Google Play Console.

Register the Fingerprint

Register your application's SHA-256 certificate fingerprint in your LoginID application's FIDO2 section before continuing. For instructions, see Adding Android Fingerprint.

Host the assetlinks.json File

Create an assetlinks.json file containing your application's package name and SHA-256 certificate fingerprint:

[
{
"relation": [
"delegate_permission/common.get_login_creds"
],
"target": {
"namespace": "android_app",
"package_name": "<PACKAGE_NAME>",
"sha256_cert_fingerprints": [
"<SHA256_FINGERPRINT>"
]
}
}
]

Replace <PACKAGE_NAME> and <SHA256_FINGERPRINT> with your application's values.

Host the file at the following location:

https://<WEBSITE_DOMAIN>/.well-known/assetlinks.json

The file must be publicly accessible over HTTPS.

Declare the Association in Your Android Application

Add an asset_statements resource to res/values/strings.xml:

<resources>
<string name="asset_statements" translatable="false">
[{
\"include\": \"https://<WEBSITE_DOMAIN>/.well-known/assetlinks.json\"
}]
</string>
</resources>

Then add the corresponding <meta-data> element inside the <application> element of your AndroidManifest.xml file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data
android:name="asset_statements"
android:resource="@string/asset_statements" />
</application>
</manifest>

Set Up the SDK

Download the SDK

After creating your LoginID application, open the Android section of the Get Started guide and download the latest version of the SDK.

The SDK is distributed as Android Archive (.aar) files.

Add the SDK to Your Project

Copy the LoginID SDK artifacts into your app module's libs directory:

app/
└── libs/
├── api.jar
├── core-release.aar
└── mfa-release.aar

Add the SDK artifacts and required dependencies to your app module's build.gradle.kts:

dependencies {
// LoginID SDK
implementation(files("libs/api.jar"))
implementation(files("libs/core-release.aar"))
implementation(files("libs/mfa-release.aar"))

// Required dependencies
implementation("com.squareup.okhttp3:okhttp:5.1.0")
implementation("com.squareup.moshi:moshi:1.15.2")
implementation("com.squareup.moshi:moshi-adapters:1.15.2")
ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.2")

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")

implementation("androidx.credentials:credentials-play-services-auth:1.6.0")
implementation("androidx.security:security-crypto:1.1.0")
}

Initialize the SDK

import com.loginid.core.models.LoginIDConfig
import com.loginid.mfa.LoginIDCheckoutMFA

class MyApplication : Application() {
val lid = LoginIDCheckoutMFA(<LOGINID_BASE_URL>)

override fun onCreate() {
super.onCreate()

// Additional setup...
}
}

Class LoginIDCheckoutMFA

A specialized authentication helper built on top of LoginID's MFA flow, designed for checkout scenarios where you need both authentication and identity trust.

This helps orchestrate the MFA flow tied to a transaction (e.g., confirming a purchase) using passkeys.

constructor

Initializes a new instance of the LoginIDCheckoutMFA.

class LoginIDCheckoutMFA

constructor(context: Context, baseUrl: String)

Creates a new wallet authentication helper using a base URL.

Use this initializer when you only have the environment base URL and want sensible defaults for the underlying SDK configuration.

ParameterTypeRequiredDescription
contextContextYesThe Android application context.
baseUrlStringYesThe LoginID environment base URL (e.g., from your environment configuration).

LoginIDCheckoutMFA

constructor(config: LoginIDConfig)

Creates a new wallet authentication helper with an explicit LoginIDConfig.

Use this when you already have a fully-formed LoginIDConfig and want more control.

ParameterTypeRequiredDescription
configLoginIDConfigYesThe complete configuration used to initialize the underlying LoginID SDK.
config.contextContextYesThe Android application context.
config.baseUrlStringYesThe base URL of the LoginID service. This value is used to resolve the App ID and make API calls.
config.appIdStringNoThe application ID. If not provided, it will be extracted from the baseUrl.
config.useTrustIdBooleanNoA flag to enable or disable the use of Trust ID. Defaults to false.

LoginIDCheckoutMFA

beginFlow

beginFlow(txPayload: String, username: String, options: BeginFlowOptions?)

Begins the MFA authentication flow for a checkout session.

This starts an MFA session bound to a specific transaction payload and optional identifiers such as merchant checkoutId.

beginFlow(txPayload: String, username: String, options: BeginFlowOptions?)

ParameterTypeRequiredDescription
txPayloadStringYesThe transaction payload to be confirmed/authorized.
usernameStringNoThe username of the user initiating MFA. Defaults to an empty string.
optionsBeginFlowOptions?NoOptional parameters for beginning the flow. If options.txPayload is provided, it takes precedence over the txPayload parameter.
options.displayNameString?NoA human-palatable name for the user account, intended only for display on your passkeys and modals.
options.usernameTypeUsernameTypeNoThe type of username validation to be used. Defaults to [UsernameType.OTHER].
options.txPayloadString?NoA string representing transaction details for confirmation during MFA.
This can be plain text or a JSON-formatted string for structured details.
options.merchantTrustIdString?NoMerchant-generated identifier for the current checkout session. Used as a key to retrieve associated trust information and link the session with wallet-issued identity data.
options.traceIdString?NoA unique identifier used to trace and correlate all events associated with a single MFA interaction. If you don’t provide this, the server may generate one automatically.
options.deviceIdString?NoAn identifier for the device used in the authentication process. This property helps determine if
supported authentications can be proceeded, allowing future authentications to identify the device
correctly.
Overrides the stored device identifier. If not provided, the SDK uses the stored value.

data class MFASessionResult(
val flow: MfaNext.Flow?
val remainingFactors: List<RemainingAction>
val username: String?
val isComplete: Boolean
val session: String?
val idToken: String?
val accessToken: String?
val refreshToken: String?
val payloadSignature: String?
val merchantTrustId: String?
val walletTrustId: String?
val passkeyInfo: PasskeyInfo?
val deviceId: String?
val nextAction: ActionName?
)

performAction

performAction(action: ActionName, options: PerformActionOptions?)

Performs an MFA action using the provided factor and optional payload.

In a checkout context, this method commonly covers:

  • Passkey Registration (PASSKEY_REG): Register a new passkey.
  • Passkey Authentication (PASSKEY_AUTH): Sign into a wallet account using a passkey.
  • Passkey Transaction Confirmation (PASSKEY_TX): Confirm a specific transaction using a passkey.
  • External Authentication (EXTERNAL): Sign in with a third-party authenticator.
performAction(action: ActionName, options: PerformActionOptions?)

ParameterTypeRequiredDescription
actionPASSKEY_REG
PASSKEY_AUTH
PASSKEY_TX
OTP_SMS
OTP_EMAIL
OTP_VERIFY
EXTERNAL
YesThe MFA factor/action to execute.
optionsPerformActionOptions?NoAction options such as payload, displayName, or an updated txPayload.
options.sessionString?NoThe MFA state session. This should be obtained from a previous MFA request or initiation step.
options.payloadString?NoThe payload required for completing the authentication factor. This typically contains user input or challenge-response data.
options.displayNameString?NoA human-palatable name for the user account, intended only for display on your passkeys.
options.txPayloadString?NoAn updated transaction payload generated by the merchant to represent the purchase or operation being confirmed. This updates the initial txPayload used in the beginFlow method.
options.activityActivity?NoAn optional Activity required for passkey operations.
options.usernameAnchorViewView?NoAn optional View to anchor the credential manager UI for passkey autofill.

data class MFASessionResult(
val flow: MfaNext.Flow?
val remainingFactors: List<RemainingAction>
val username: String?
val isComplete: Boolean
val session: String?
val idToken: String?
val accessToken: String?
val refreshToken: String?
val payloadSignature: String?
val merchantTrustId: String?
val walletTrustId: String?
val passkeyInfo: PasskeyInfo?
val deviceId: String?
val nextAction: ActionName?
)

performAction(action: ActionName, activity: Activity, options: PerformActionOptions?)

Performs a passkey-based MFA action.

This is a convenience method for passkey operations that require an Activity.

performAction(action: ActionName, activity: Activity, options: PerformActionOptions?)

ParameterTypeRequiredDescription
actionPASSKEY_REG
PASSKEY_AUTH
PASSKEY_TX
OTP_SMS
OTP_EMAIL
OTP_VERIFY
EXTERNAL
YesThe MFA factor to perform. Must be one of PASSKEY_REG, PASSKEY_AUTH, or PASSKEY_TX.
activityActivityYesThe Activity required for passkey operations.
optionsPerformActionOptions?NoOptional parameters for the action.
options.sessionString?NoThe MFA state session. This should be obtained from a previous MFA request or initiation step.
options.payloadString?NoThe payload required for completing the authentication factor. This typically contains user input or challenge-response data.
options.displayNameString?NoA human-palatable name for the user account, intended only for display on your passkeys.
options.txPayloadString?NoAn updated transaction payload generated by the merchant to represent the purchase or operation being confirmed. This updates the initial txPayload used in the beginFlow method.
options.activityActivity?NoAn optional Activity required for passkey operations.
options.usernameAnchorViewView?NoAn optional View to anchor the credential manager UI for passkey autofill.

data class MFASessionResult(
val flow: MfaNext.Flow?
val remainingFactors: List<RemainingAction>
val username: String?
val isComplete: Boolean
val session: String?
val idToken: String?
val accessToken: String?
val refreshToken: String?
val payloadSignature: String?
val merchantTrustId: String?
val walletTrustId: String?
val passkeyInfo: PasskeyInfo?
val deviceId: String?
val nextAction: ActionName?
)

Errors

LoginIDError

Can occur during the authentication process. It is designed to encapsulate detailed information about login-related errors, making it easier to handle and debug issues related to user authentication.

FieldTypeDetails
msgCodestringThe error code associated with the login error. Defaults to unknown_error.
msgstringThe detailed message or description of the error. Defaults to unknown error.
messgagestringThe detailed message or description of the error. Defaults to unknown error.

...
...

} catch (error: Exception) {
if (error is LoginIDError) {
print("Failed with error: ${error.msg}")
print("Failed with error code: ${error.msgCode}")
}
}