Authentication
This API is available only to merchants with standaloneWallet
access and walletSetup
scope to the config token.
Introduction
The Authentication service is responsible for issuing and managing access tokens.
Key Features:
- Provides a way to authenticate users through the login process.
- Supports handling Strong Customer Authentication (SCA) challenges to ensure secure transactions.
Prerequisites
Before integrating the Preferences Service, ensure you have:
- A valid Paysafe account with appropriate permissions.
- Set up instructions for Paysafe SDK Android or iOS.
To get started, initialize the AuthenticationService
instance in your app as shown below:
- Kotlin
- Swift
import com.paysafe.wallet.android.core.wallet.Wallet
val authenticationService = Wallet.getInstance().getAuthenticationService()
import PaysafeWallet
let authentication = Wallet.instance.authenticationService
Login Workflow Overview
Login steps
These operations might require Strong Customer Authentication (SCA). Please read Strong Customer Authentication for more information on the process.
Step 1.
Use loginWithPassword
or loginWithPin
to obtain an access token and then pass it to the authenticate method of the wallet. They requires two specific parameters clientIdentifier
and brandIdentity
, both of which are provided by Paysafe.
Step 2.
If SCA is required, Wallet.WalletError.scaRequired / ScaRequiredException will be thrown. Follow the steps outlined in the section Handle Strong Customer Authentication (SCA) Challenges to confirm the event.
Step 3.
After the SCA event is accepted, repeat the request providing the scaDetails
parameter.
Login with PIN
- Kotlin
- Swift
try {
// Login
val token = authentication.loginWithPin(
clientIdentifier = "C4JTpgmp3:XqIOmHdk",
brandIdentity = "finley",
request = PinTokenRequest(
username = "johnDoe123@example.com",
pin = "111222"
)
)
// Authenticate the wallet sdk
Wallet.getInstance().authenticate(AuthenticationConfiguration(token.accessToken))
// Your are done. Start using the wallet services
} catch (e: DataException) {
// Handle invalid credentials error
} catch (e: ScaRequiredException) {
// Solve Strong Customer Authentication challenge using e.authenticationEvent
// Call loginWithPin again, providing the scaDetails parameter
}
let pinTokenRequest = Wallet.PinTokenRequest(
username: "johnDoe123",
pin: "111222"
)
authentication.loginWithPin(clientIdentifier: "C4JTpgmp3:XqIOmHdk",
brandIdentity: "finley",
request: pinTokenRequest,
completion: { loginResult in
switch loginResult {
case .success(let authToken):
Wallet.instance.authenticate(with: .init(accessToken: authToken))
case .failure(let error):
if case .scaRequired(let authenticationEvent, _) = error as? Wallet.WalletError {
// Solve Strong Customer Authentication challenge using authenticationEvent
// Call loginWithPin again, providing the scaDetails parameter
} else {
// Handle other errors
}
}
})
Login with password
- Kotlin
- Swift
A PasswordTokenRequest object.
try {
// Login
val token = authentication.loginWithPassword(
clientIdentifier = "C4JTpgmp3:XqIOmHdk",
brandIdentity = "finley",
request = PasswordTokenRequest(
username = "johnDoe123@example.com",
password = "PaS#w0rd."
)
)
// Authenticate the wallet sdk
Wallet.getInstance().authenticate(AuthenticationConfiguration(token.accessToken))
// Your are done. Start using the wallet services
} catch (e: DataException) {
// Handle invalid credentials error
} catch (e: ScaRequiredException) {
// Solve Strong Customer Authentication challenge using e.authenticationEvent
// Call loginWithPassword again, providing the scaDetails parameter
}
A PasswordTokenRequest object.
let passwordTokenRequest = Wallet.PasswordTokenRequest(
username: "johnDoe123",
password: "Pa$$w0rd."
)
authentication.loginWithPassword(clientIdentifier: "C4JTpgmp3:XqIOmHdk",
brandIdentity: "finley",
request: passwordTokenRequest,
completion: { loginResult in
switch loginResult {
case .success(let authToken):
Wallet.instance.authenticate(with: .init(accessToken: authToken))
case .failure(let error):
if case .scaRequired(let authenticationEvent, _) = error as? Wallet.WalletError {
// Solve Strong Customer Authentication challenge using authenticationEvent
// Call loginWithPassword again, providing the scaDetails parameter
} else {
// Handle other errors
}
}
})
Handle Strong Customer Authentication (SCA) Challenges
Some wallet operations require Strong Customer Authentication and will trigger a process as described in Strong Customer Authentication.
Step 1.
Once the eventId
and walletOperationId
parameters are available, the first step is to initiate the SCA challenge with the method sendScaChallenge
, specifying
the preferred SCA method (e.g. One-time password - OTP) and channel (e.g. SMS or EMAIL) from the list of
availableVerifications
. Use the same method to resend the challenge if the customer does not receive the first one.
Step 2.
When the customer enters the requested SCA code, the second step is to use the method submitScaAttempt
to solve the SCA challenge. Provide
the same eventId
, walletOperationId
, method, and channel. The response from submitScaAttempt
is an object of type
ScaAuthenticationEventAttemptEmbeddedHybridResponse / ScaAuthenticationEventAttemptEmbeddedHybridResponse,
containing a status
and statusReason
fields. The status
will be Wallet.SCAAuthenticationEventAttemptStatus.verified / ScaAuthenticationEventAttemptStatus.VERIFIED for successful attempt and
Wallet.SCAAuthenticationEventAttemptStatus.failed / ScaAuthenticationEventAttemptStatus.FAILED for invalid value.
A WalletError.dataError / DataException will be
returned if the customer reaches the maximum number of unsuccessful attempts.
Step 3.
Once the SCA challenge is solved, repeat the requested wallet operation, providing the scaDetails
optional parameter.
Pass the same eventId
and walletOperationId
, that was used to solve the challenge.
- Kotlin
- Swift
// Obtain eventId and walletOperationId from the operation that requires SCA
val eventId = "..."
val walletOperationId = "..."
// 1. Instruct the system to send an one-time password (OTP) code via SMS
authenticationService.sendScaChallenge(
eventId = eventId,
request = ScaAuthenticationEventChallengeEmbeddedHybridRequest(
walletOperationId = walletOperationId,
verification = ScaAuthenticationEventAttemptVerification(
ScaAuthenticationEventAttemptVerificationMethod.OTP,
ScaAuthenticationEventAttemptVerificationChannel.SMS
)
)
)
// 2. Submit the one-time password entered by the customer
authenticationService.submitScaAttempt(
eventId = eventId,
request = ScaAuthenticationEventAttemptEmbeddedHybridRequest(
walletOperationId = walletOperationId,
verification = ScaAuthenticationEventAttemptVerification(
ScaAuthenticationEventAttemptVerificationMethod.OTP,
ScaAuthenticationEventAttemptVerificationChannel.SMS
),
value = "123456" // Replace with actual OTP value
)
)
// 3. Retry the wallet operation, providing the scaDetails parameter with the same eventId and walletOperationId.
// Obtain eventId and walletOperationId from the operation that requires SCA
let eventID = "..."
let walletOperationID = "..."
// 1. Instruct the system to send an one-time password (OTP) code via SMS
authenticationService.sendSCAChallenge(
eventID: eventID,
request: Wallet.SCAAuthenticationEventChallengeEmbeddedHybridRequest(
walletOperationID: walletOperationID,
verification: Wallet.SCAAuthenticationEventAttemptVerification(
method: .otp,
channel: .sms
)
),
completion: { result in
switch result {
case .success(let scaEventChallenge):
// Display information about scaEventChallenge
case .failure(let error):
// Handle error
}
}
)
// 2. Submit the one-time password entered by the customer
authenticationService.submitSCAAttempt(
eventID: eventID,
request: Wallet.SCAAuthenticationEventAttemptEmbeddedHybridRequest(
walletOperationID: walletOperationID,
verification: Wallet.SCAAuthenticationEventAttemptVerification(
method: .otp,
channel: .sms
),
value: "123456" // Replace with actual OTP value
),
completion: { result in
switch result {
case .success(let scaEventAttempt):
// Handle result of scaEventAttempt
case .failure(let error):
// Handle error
}
}
)
// 3. Retry the wallet operation, providing the scaDetails parameter with the same eventId and walletOperationId.