Skip to main content

Login (Web SDK)

Before your customers can access their cards and managed accounts, they must be onboarded and authenticated on our platform. The login components capture credentials securely and convert them into one-time-use tokens that you can safely send to our API.

Weavr identities and your app's users

A Weavr identity is separate from the account a customer signs in to in your own app. The Weavr identity is the regulated record that holds accounts, cards, and payment permissions, and the end user authenticates against it directly - Strong Customer Authentication can't be delegated to your app. Even so, your customer should experience a single app and a single set of credentials. See Weavr identities and your app's users for how the two relate.

We support two login factors:

  • Password - see complexity requirements
  • Passcode - 4 digits, suitable when your app already authenticates the user with another factor

Each factor has a paired confirm component that validates the value entered in a second field matches the first. Use confirm components during sign-up and password change flows.

Choosing a login approach

There are two ways to submit a password to POST /login_with_password, and the approach you choose determines whether you use our secure components.

Tokenised login (preferred)

Capture the password with our secure login component and convert it into a one-time-use token. The password is encrypted inside a view your app cannot read, so your code and servers never see the plaintext. You exchange the token - not the password - for a session.

Use this approach for the standard Weavr security model. Because the plaintext never touches your app, you stay out of PCI DSS scope and qualify for the lightest Self-Assessment Questionnaire. This is the approach the rest of this page documents.

Non-tokenised login

If you don't use our tokenisationTokenize Replace a card's primary account number (PAN) with a unique digital token that stands in for the real card during a transaction. When a cardholder adds a card to Apple Pay or Google Pay via push provisioning, the wallet provider stores a device-specific token rather than the underlying PAN, so the real card number isn't exposed on the device or shared with merchants. for the password - for example, you already operate a PCI DSS-compliant environment that handles the plaintext securely - capture the password in your own native field, validate it there, then submit the plaintext value to POST /login_with_password from your server.

Contact us first

Accepting a plaintext password at POST /login_with_password requires configuration by our team and isn't something you can turn on yourself in the Weavr portal. Reach out to our support team to enable it before you build this flow.

In this case, don't use our secure login component. The component exists to tokeniseTokenize Replace a card's primary account number (PAN) with a unique digital token that stands in for the real card during a transaction. When a cardholder adds a card to Apple Pay or Google Pay via push provisioning, the wallet provider stores a device-specific token rather than the underlying PAN, so the real card number isn't exposed on the device or shared with merchants. the value inside a sandboxed view; it deliberately gives your code no way to read or validate the plaintext a user types, so it can't back a flow that needs the raw password.

Prefer tokenised login

TokenisedTokenize Replace a card's primary account number (PAN) with a unique digital token that stands in for the real card during a transaction. When a cardholder adds a card to Apple Pay or Google Pay via push provisioning, the wallet provider stores a device-specific token rather than the underlying PAN, so the real card number isn't exposed on the device or shared with merchants. login is preferred for every integration that doesn't already carry its own PCI DSS obligations, because it keeps the plaintext password out of your systems entirely.

Where each component fits in your login screen

The login components each render one credential field inside a tokenizedTokenize Replace a card's primary account number (PAN) with a unique digital token that stands in for the real card during a transaction. When a cardholder adds a card to Apple Pay or Google Pay via push provisioning, the wallet provider stores a device-specific token rather than the underlying PAN, so the real card number isn't exposed on the device or shared with merchants. iframe. The mockup below shows where they typically appear in your app - hover the numbered hotspots for the underlying API calls.

Password and passcode are alternatives - pick one for your app. Each is paired with its confirm component, which validates the value entered in the second field matches the first. Hover or focus a numbered hotspot to see the underlying API call.

Set up the SDK first

To use our UI components, you must first set up the SDK in your app.


Password

Use it for: login screens, sign-up password creation, and change-password flows.

The Password component collects your customer's password securely and converts it into a token, which you can safely send to Weavr using the API.

Password complexity

Customer passwords must satisfy all of the following:

  • 8 to 30 characters
  • at least one uppercase letter
  • at least one lowercase letter
  • at least one number
  • at least one special character
  • different from the user's last 5 passwords

Validate password

Surface these rules in your sign-up and change-password screens before the user submits.

To check a candidate password against the same rules without committing it, call POST /passwords/validate from your server. The endpoint returns success if the password meets the policy and a conflict response if it doesn't.

Submit password

The API rejects passwords that don't meet these requirements with AUTH_009 PASSWORD_POLICY_VIOLATION.

Step-up required to update an existing password

Due to requirements related to strong customer authentication, your authentication token must be stepped-up when calling this component to update an existing password.

<form onSubmit="onSubmit(); return false;">
Username: <input type="input" name="u" /><br />
Password:
<div id="password"></div>
<br />
<input type="submit" value="Login" />
</form>

<script type="text/javascript">
window.OpcUxSecureClient.init("YOUR_UI_KEY");

var form = window.OpcUxSecureClient.form();

// The first argument is the field name used as the token key when tokenize() is called.
var input = form.input("password", "password", {
placeholder: "Password",
maxlength: 30,
});
input.mount(document.getElementById("password"));

// Pressing the enter key in the password input triggers the submit handler
input.on("submit", () => {
console.log("submit password input");
});

function onSubmit() {
form.tokenize(function (tokens) {
console.log(tokens);
});
}
</script>

Authenticate the user

With the tokenizedTokenize Replace a card's primary account number (PAN) with a unique digital token that stands in for the real card during a transaction. When a cardholder adds a card to Apple Pay or Google Pay via push provisioning, the wallet provider stores a device-specific token rather than the underlying PAN, so the real card number isn't exposed on the device or shared with merchants. password, authenticate the user from your server.

Server-side only

You must perform this step on the server side of your app.

POST/login_with_passwordTry it
{
"email": "[email protected]",
"password": {
"value": "pa$$word"
}
}

After a successful login, the response includes a token field. Use this token to authenticate the user in subsequent API calls.

Confirm password

Use it for: sign-up and change-password screens, alongside the Password component.

The Confirm password component pairs with the Password component to validate that two entered passwords match.

Pair the components in one form

The confirm password component requires the password component to be mounted in the same form.

<form onSubmit="onSubmit(); return false;">
<label>Password Confirmation</label>
<div id="input-password"></div>
<br />
<div id="input-password-confirm"></div>
<br />
<input type="submit" value="confirm" />
</form>
<div id="inputPasswordConfirmResponse"></div>

<script type="text/javascript">
window.OpcUxSecureClient.init("YOUR_UI_KEY");

const form = window.OpcUxSecureClient.form();

const password = form.input("password", "password", {
placeholder: "Password",
});
const confirmPassword = form.input("confirmPassword", "confirmPassword", {
placeholder: "Confirm Password",
});

password.mount("#input-password");
confirmPassword.mount("#input-password-confirm");

function onSubmit() {
// tokenize checks the passwords match before tokenizing
form.tokenize(
(res) => {
document.getElementById("inputPasswordConfirmResponse").innerText =
JSON.stringify(res);
},
(err) => {
console.error("Error:", err.message);
document.getElementById("inputPasswordConfirmResponse").innerText =
"ERROR: " + JSON.stringify(err);
}
);
}
</script>

Passcode

Use it for: login screens when your app authenticates the user with a 4-digit passcode instead of a password.

If your app already authenticates the user with another factor, you can use a 4-digit passcode in place of a password.

Passcode mode is opt-in

Contact our support team if you're interested in setting up your app to use passcodes instead of passwords.

Step-up required to update an existing passcode

Due to requirements related to strong customer authentication, your authentication token must be stepped-up when calling this component to update an existing passcode. Step-up isn't required for initial passcode creation during onboarding.

<form onSubmit="onSubmit(); return false;">
Username: <input type="input" name="u" /><br />
Passcode:
<div id="passcode"></div>
<br />
<input type="submit" value="Login" />
</form>

<script type="text/javascript">
window.OpcUxSecureClient.init("YOUR_UI_KEY");

var form = window.OpcUxSecureClient.form();

var input = form.input("passcode", "passCode", {
placeholder: "Pass Code",
});
input.on("submit", () => {
onSubmit();
});

input.mount(document.getElementById("passcode"));

function onSubmit() {
form.tokenize(function (tokens) {
console.log(tokens);
});
}
</script>

Authenticate the user

The login API endpoint is the same for password and passcode - you exchange the tokenizedTokenize Replace a card's primary account number (PAN) with a unique digital token that stands in for the real card during a transaction. When a cardholder adds a card to Apple Pay or Google Pay via push provisioning, the wallet provider stores a device-specific token rather than the underlying PAN, so the real card number isn't exposed on the device or shared with merchants. credential for a session token from your server.

Server-side only

You must perform this step on the server side of your app.

POST/login_with_passwordTry it
{
"email": "[email protected]",
"password": {
"value": "pa$$word"
}
}

Confirm passcode

Use it for: passcode-setup screens during sign-up and change-passcode flows, alongside the Passcode component.

The Confirm passcode component pairs with the Passcode component to validate that two entered passcodes match.

Pair the components in one form

The confirm passcode component requires the passcode component to be mounted in the same form.

<form onSubmit="onSubmit(); return false;">
<label>Passcode Confirmation</label>
<div id="input-passcode"></div>
<br />
<div id="input-passcode-confirm"></div>
<br />
<input type="submit" value="confirm" />
</form>
<div id="inputPasscodeConfirmResponse"></div>

<script type="text/javascript">
window.OpcUxSecureClient.init("YOUR_UI_KEY");

const form = window.OpcUxSecureClient.form();

const passcode = form.input("passcode", "passCode", {
placeholder: "Passcode",
});
const confirmPasscode = form.input("confirmPasscode", "confirmPassCode", {
placeholder: "Confirm Passcode",
});

passcode.mount("#input-passcode");
confirmPasscode.mount("#input-passcode-confirm");

function onSubmit() {
// tokenize checks the passcodes match before tokenizing
form.tokenize(
(res) => {
document.getElementById("inputPasscodeConfirmResponse").innerText =
JSON.stringify(res);
},
(err) => {
console.error("Error:", err.message);
document.getElementById("inputPasscodeConfirmResponse").innerText =
"ERROR: " + JSON.stringify(err);
}
);
}
</script>