Returning users

Learn how to preserve sessions for Link users and avoid duplicate account connections with user tokens.

The user token is a necessary tool to create a seamless returning user experience and prevent duplicate account connections. User tokens are temporary access keys that allow you to take users to the correct spot within the Argyle flow. Whenever you need a user to return to Argyle Link, you have to utilize user tokens in the Link configuration.


Users

Users flowUsers flow

Argyle refers to your customers (loan applicants, potential bank account holders, etc.) as users. Users interface with Argyle Link to connect their payroll accounts or update their direct deposit.

Users log in to Argyle Link using their payroll account credentials. If they cannot remember their password for the account, they can select the Forgot password? option. This brings them to the payroll provider's platform, where they should follow the platform's password recovery flow.


Use cases

User tokens are required to:

Direct users to reconnect accounts

Direct users to reconnectDirect users to reconnect

Some payroll providers have connection timeouts or force log out if users log in on another device. If your customers have previously connected a payroll account, Link enables them to re-authenticate without entering their credentials again. They can simply select the Reconnect button to continue sharing their account data with you.

Direct users to confirm a direct deposit update

Pay distributionPay distribution

You can have users connect their payroll accounts, return to your app for additional steps, and then return to Argyle to confirm a direct deposit update. This use case is relevant if you are utilizing Argyle for paycheck-linked lending or similar solutions.

Direct users to manage their connected accounts

Manage connected account screenManage connected account screen

Likewise, you can direct users to manage their account connections, where they can revoke the access, connect more accounts (for example, when a user has more than one job), and update their direct deposit.

Direct users to complete MFA

Additional MFAAdditional MFA

An additional multi-factor authentication (MFA) step can be required when users are confirming their pay allocation/distribution or removing allocations directly via API. In such cases, you can send the user directly to the MFA screen.

User tokens prevent duplicate account connections

If the user token is absent, Link does not recognize the previously connected user and creates a duplicate account for them. The data is identical in the two accounts but they are treated as two separate connected accounts, as Argyle treats all the accounts agnostically.

Check how the single charge upon account connection works.


When to utilize user tokens

Argyle strongly recommends user tokens as the best practice for all cases, especially if you expect your users to return to Link. Unless you are performing a specific one-time connection or want to prevent a user from returning to Link, you should utilize user tokens.


Suggested flow for user token usage

Link generates a userId and userToken when a user connects an account. Tokens are short-lived, and it is recommended to generate a new token from a user’s userId via the API every time you initialize Argyle Link for a returning user.

When connecting a new user:

  1. Initialize Link with your configuration.
  2. Include the onUserCreated callback.
  3. Save the userId that is sent by the callback.

📘

In Q1 of 2023, user tokens will be transitioned to being required for all Link initializations, including for new users.

To prepare for this change, we recommend the following process when initializing Link for new users programmatically going forward:

Link initialization for a new user

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
</head>

<body>
    <script src="https://plugin.argyle.com/argyle.web.v3.js"></script>
    <script type="text/javascript">
        const argyle = Argyle.create({
        linkKey: 'YOUR_LINK_KEY', // insert your Link key here. It can be found in the Argyle Console.
        apiHost: 'https://api-sandbox.argyle.com/v1', // sandbox environment is used in this example. Change to production environment before launching.
        onUserCreated: ({ userId, userToken }) => {
          console.log('User created: ', userId, 'User token:', userToken)
        } // save the userId and userToken
      })
      argyle.open()
    </script>
</body>

</html>
class ViewController: UIViewController {

 override func viewDidLoad() {
    _ = Argyle.shared
      .loginWith(
        linkKey: "YOUR_LINK_KEY", // insert your Link key here. It can be found in the Argyle Console.
        apiHost: "https://api-sandbox.argyle.com/v1") // sandbox environment is used in this example. Change to production environment before launching.
      .resultListener(self)
  }

  @IBAction func argyleNewUser(_ sender: Any) {
    let argyle = Argyle.shared.controller
    argyle.modalPresentationStyle = .fullScreen
    self.present(argyle, animated: true, completion: nil)
  }
}

extension ViewController: ArgyleResultListener {

    func onUserCreated(token: String, userId: String) {
        // save userId and userToken
        print("APP: onUserCreated((token: \(token), userId: \(userId))")
    }
        // rest of callbacks (all callbacks must be implemented)
}
val config = ArgyleConfig.Builder()
  .loginWith(
        "YOUR_LINK_KEY", // insert your Link key here. It can be found in the Argyle Console.
        "https://api-sandbox.argyle.com/v1", // sandbox environment is used in this example. Change to production environment before launching.  
        "") 
  .setCallbackListener(object : Argyle.ArgyleResultListener {

    override fun onUserCreated(userToken: String, userId: String) {
      // save userId and userToken
      Log.d("Result", "onUserCreated:  userId: $userId, userToken: $userToken")
    }
  })
  .build()

Argyle.instance.init(config)
Argyle.instance.startSDK(this)
import ArgyleSdk from '@argyleio/argyle-plugin-react-native'

ArgyleSdk.loginWith(
    "YOUR_LINK_KEY", // insert your Link key here. It can be found in the Argyle Console.
    "https://api-sandbox.argyle.com/v1", // sandbox environment is used in this example. Change to production environment before launching. 
    "")
ArgyleSdk.start()

Recommended user tokens flow for returning users:

  • Create a new user token by calling the /user-tokens endpoint with their userId.
  • Provide the userToken in your Link Initialization. Make sure user tokens are requested on your server-side and your client_id and client_secret are never exposed on the front-end.

Link initialization for a returning user

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
</head>

<body>
    <script src="https://plugin.argyle.com/argyle.web.v3.js"></script>
    <script type="text/javascript">
        const argyle = Argyle.create({
        linkKey: 'YOUR_LINK_KEY', // insert your Link key here. It can be found in the Argyle Console.
        apiHost: 'https://api-sandbox.argyle.com/v1', // sandbox environment is used in this example. Change to production environment before launching.
        userToken: 'USER_TOKEN', // insert the new user token here
        linkItems: [] // add Link item IDs (e.g. ‘Starbox’) if you want to constrain the Link item list in the Search screen.
      })
      argyle.open()
    </script>
</body>

</html>
_ = Argyle.shared
        .loginWith(
            linkKey: "YOUR_LINK_KEY", // insert your Link key here. It can be found in the Argyle Console.
            apiHost: "https://api-sandbox.argyle.com/v1") // sandbox environment is used in this example. Change to production environment before launching.
        .linkItems([]) // add Link item IDs (e.g. "Starbox") if you want to constrain the Link item list in the search screen.
        .resultListener(self)

let argyle = Argyle.shared.updateToken("USER_TOKEN").controller // insert the new user token here
argyle.modalPresentationStyle = .fullScreen
self.present(argyle, animated: true, completion: nil)
val config = ArgyleConfig.Builder()
    .loginWith(
        "YOUR_LINK_KEY", // insert your Link key here. It can be found in the Argyle Console.
        "https://api-sandbox.argyle.com/v1", // sandbox environment is used in this example. Change to production environment before launching.
        "USER_TOKEN") // insert the new user token here
    .linkItems(arrayOf()) // add Link item IDs (e.g. "Starbox") if you want to constrain the Link item list in the search screen.
    .setCallbackListener(object : Argyle.ArgyleResultListener {
        // callbacks    
    })
    .build()

Argyle.instance.init(config)
Argyle.instance.startSDK(this)
import ArgyleSdk from '@argyleio/argyle-plugin-react-native'

ArgyleSdk.loginWith(
        "YOUR_LINK_KEY", // insert your Link key here. It can be found in the Argyle Console.
        "https://api-sandbox.argyle.com/v1", // sandbox environment is used in this example. Change to production environment before launching.
        "USER_TOKEN") // insert the new user token here
ArgyleSdk.linkItems([]) // add Link item IDs (e.g. "Starbox") if you want to constrain the Link item list in the search screen.
ArgyleSdk.start()

If userToken is absent, every time a user tries to connect an account (successfully or not), Link emits a new userToken (via onUserCreated).

However, the most important information here is the userId. With userId, you can associate the user on Argyle's side to the user on your platform.

If you know userId, you can follow the suggested flow for user token usage and generate a new userToken when initiating a Link session for returning users.

Creating users on the back-end via API

Because a userToken is short-lived, if your system requires that you create users in advance on the back-end via the API, we recommend following the same suggested flow for user tokens for returning users:

  • Create a new user token by calling the /user-tokens endpoint with their userId.
  • Provide the userToken in your Link Initialization. Make sure user tokens are requested on your server-side and your client_id and client_secret are never exposed on the front-end.

User tokens expiration

User tokens are JWT tokens that contain an expiration date. You can always decode the token to discover the exact expiration date (check exp field).

As mentioned in the suggested flow section, we recommend generating a new userToken from a user’s userId each time Link is initialized, rather than saving a userToken, checking for expiration, and updating if expired.

Decoded JWT token payload:

{
    "client_id": "0d9b5bf3-97fa-4757-a136-b2a03d171414",
    "exp": 1652481485,
    "iat": 1649889485,
    "iss": "argyle-core-auth-prod",
    "jti": "00097a26-2f2a-4aa0-8eca-95ebe56d57a8",
    "sub": "017f8978-bbfd-ff64-18ce-d59f99bf51c2",
    "user_id": "017f8978-bbfd-ff64-18ce-d59f99bf51c2"
}
  • client_id - client’s unique identifier
  • exp - expiry date in seconds Unix time
  • iat - issue date in seconds Unix time
  • iss - issuer of the token
  • jti - unique token id
  • sub - subject of the token: user_id
  • user_id - user_id of the user