Skip to main content

Connect a user

The Wealthica Connect process allows users to connect their financial institution accounts to your application. There are different ways to start the process and receive the connection result.

The easiest way to do that is using the Wealthica JS SDK to open the drop-in Wealthica Connect Widget right inside your web application, and receive the result via JS callbacks.

Or you can use an oAuth process where you redirect users to the Wealthica Connect URL to connect their account, and have them redirected back to your application with the result. This oAuth process can be used in web, mobile or desktop applications.

info

Throughout the documentation, we might use these terms interchangeably: financial institution account, account, connection, institution.

After user successfully connects a financial institution account to Wealthica, a "connection" will be created on the Wealthica side. This Wealthica connection is kept in sync with the user's financial institution account. In Wealthica API lingo, this connection is called "institution" (thus the /institutions endpoints).

Sometimes we might call it "account", but note that in this context it's different from a "user account".

Via drop-in Connect Widget

document.getElementById('#connect').addEventListener('click', () => {
user.connect().onConnection(async (institutionId, data) => {
console.log('provider', data.provider);

// Send the institution id to your server
sendToServer('/some-route', institutionId);
// Request institution data to display in the page
const institution = await user.institutions.getOne(institutionId);
displayAccount(institution);
});
}, false);

Start the connect process by calling user.connect() from your web application. It will open the Wealthica Connect Widget inside the page, and let the user select the financial institution they want to connect.

Receive via callbacks

user.connect().onConnection((institutionId, data) => {
console.log('provider', data.provider);
console.log('account connection success:', institutionId)
}).onError(error => {
console.error('account connection error:', error)
}).onEvent((name, data) => {
console.log('event:', name, data);
});

The drop-in Connect Widget sends data to the Wealthica Frontend SDK via 3 callbacks:

  • onConnection(institutionId, data)
  • onError(error)
  • onEvent(name, data)

onConnection(institutionId, data)

The onConnection() callback listens for successful connection from the Connect Widget. After user successfully connects their account, the Widget is automatically closed and the callback is called with an institutionId that belongs to a newly-created Wealthica connection. This Wealthica connection is kept in sync with the user's financial institution account.

It is recommended that you store this institutionId in your database for future updates.

onError(error)

The onError() callback listens for errors from the Connect Widget. During the process, if there is an error or if user clicks the close (X) button, the Widget is closed and the callback is called with an error object.

error object attributes

AttributeDescription
error_typeThe error code, e.g. 400.
messageThe error message.
institutionThe institution ID if it has been created.
providerType of institution (provider) if it has been created.

onEvent(name, data)

The onEvent() callback listens for events from the Connect Widget during the connection process.

NOTE: this is a WIP.

Customize Connect Widget

<html>
<head>
<style>
iframe[name='wealthica-connect-widget'] {
border: 1px solid gray;
width: 300px;
height: 500px;
display: none;
}
</style>
</head>
<body>
<nav>Nav bar</nav>
<section>
<h1>Connect your account</h1>

<button id="connect">Connect</button>
<iframe name='wealthica-connect-widget'></iframe>
</section>
</body>
</html>

Under the hood, the Connect Widget is loaded inside a <iframe name='wealthica-connect-widget'> element. By default, the .connect() method appends the iframe at the root of your page's <body>, with special styling so that it appears as an overlay inside the page.

You can customize the styling of the widget overlay via the wealthica-connect-widget.

If you need to control where the iframe is inside your page, you can pre-create the <iframe name='wealthica-connect-widget> anywhere in your page and the .connect() method will load the Connect Widget inside that element instead of creating a new one.

NOTE: the JS SDK will add display: block style to the iframe when opening the Connect Widget, and display: none when closing it.

Preselect a provider

document.getElementById('#connect_demo').addEventListener('click', () => {
user.connect({ provider: 'demo' }).onConnection((institutionId, data) => {
console.log('provider', data.provider);
console.log('Demo connection success:', institutionId)
});
}, false);

By default .connect() will open the Wealthica providers list for user to select from. Alternately you can pass in a provider to skip the selection step so that Wealthica Connect Widget go straight to the provider credentials form.

NOTE: Pass in the provider type that you get from the Provider object.

Reconnect an account

When an account's credentials expire or are revoked, Wealthica will no longer be able to synchronize its data from the provider. The account is put in a 'disconnected' state and will need to be reconnected.

To allow a user to reconnect a disconnected account, call user.reconnect(institutionId) from your web application. It will open the Wealthica Connect Widget inside the page, and let the user reconnect the account. The process is almost identical to connecting a new account, except that at the end of the process it would update the existing account instead of creating a new one.

Via Connect URL

Another way to connect an user is via the Wealthica Connect URL directly. You can load the Wealthica Connect URL using your own method (redirect from the current page or open in a new window, or inside a mobile WebView...).

You can customize various aspects of the Wealthica Connect process via the url params. A standard Wealthica Connect URL looks something like this:

POST https://connect.wealthica.com/connect?client_id=YOUR_CLIENT_ID

Form Data (x-www-form-urlencoded):
token=USER_TOKEN

Or with preselected provider:

POST https://connect.wealthica.com/connect/demo?client_id=YOUR_CLIENT_ID

Form Data (x-www-form-urlencoded):
token=USER_TOKEN

To reconnect account:

POST https://connect.wealthica.com/reconnect/INSTITUTION_ID?client_id=YOUR_CLIENT_ID

Form Data (x-www-form-urlencoded):
token=USER_TOKEN
info

The same Connect URL is loaded in the iframe when you connect via the drop-in Connect Widget using the JS SDK. The SDK just automatically encapsulates all handling logic in an easy-to-use interface to save you time.

Connect URL parameters

ParameterRequiredDescription
client_idYesYour team's Client ID.
tokenYesThe user token. See Authentication to see how to get the token.
redirect_uriNoThe URI to redirect to after the process is finished. This must match one of your team's registered Redirect URIs. More on this here.
originNoThe URL origin that triggers the process (e.g. https://some.domain). This is used mostly for when the Wealthica Connect is loaded inside an iframe, so it can pass data back to the parent page at the specified origin.
langNoThe content language. Currently only en, es, fr and it are accepted.
stateNoAn opaque string containing your application state, to maintain application state between redirects (in the oAuth process).
providersNoLimit the list of providers available for selection.
Example: questrade,tangerine,demo.
themeNoWealthica Connect widget theme. Available options: light, dark. Default: light.
providers_per_lineNoThe number of providers displayed per line on the select provider screen. Available options: 1, 2.
Default: 2.

Receive via URL params

The connection result is returned in the URL params at the end of the process. If you open the Connect URL inside an iframe, popup, or mobile WebView, you can expect the process to redirect to this URL when connection is successful:

https://connect.wealthica.com/connected?institution=INSTITUTION_ID&code=INSTITUTION_ID

And to this URL when connection failed or is interrupted:

https://connect.wealthica.com/exit?error_type=400&message=ERROR_MESSAGE

Custom Redirect URI

You can pass in the Wealthica Connect URL a custom redirect_uri so that it redirects to this uri at the end of the process.

For example, load the following Wealthica Connect URL:

POST https://connect.wealthica.com/connect?client_id=YOUR_CLIENT_ID&redirect_uri=https://myapp.test/wealthica/callback&state=APP_STATE_BEFORE_CONNECTION_IN_BASE64

Form Data (x-www-form-urlencoded):
token=USER_TOKEN

After user finishes connecting an account, it will redirect to:

https://myapp.test/wealthica/callback?institution=INSTITUTION_ID&code=INSTITUTION_ID&provider=PROVIDER&state=APP_STATE_BEFORE_CONNECTION_IN_BASE64

Or if the connection failed or user closes the process, it will redirect to:

After user finishes connecting an account, it will redirect to:

https://myapp.test/wealthica/callback?error_type=400&message=Invalid+credentials&state=APP_STATE_BEFORE_CONNECTION_IN_BASE64&provider=PROVIDER&institution=INSTITUTION_ID

In both cases, your page at https://myapp.test/wealthica/callback can look at the URL params and proceed accordingly. Optionally if you passed in a state, you will receive it back here to restore your application to the same state before the connection.

info
The Redirect URI must be registered first before it can be used. You can register multiple Redirect URIs for your team (for your development, staging or production urls). Contact us if you need to register your Redirect URIs.

All redirection URL params

ParameterTypeOnDescription
institutionStringBothThe Wealthica institution id corresponding to the newly-connected financial institution account.
Note that it's returned on Failure ONLY if it has been created before the error happens.
codeStringSuccessSame as institution. For oAuth compliance.
error_typeNumberFailureThe connection error code.
messageStringFailureThe connection error message.
forceBooleanFailuretrue means the process was explicitly closed by user.
stateStringBothThe application state passed to the Wealthica Connect URL at the start of the process (if available).

Via Direct API (advanced)

It's possible to implement your own Connect UI using the Wealthica Institutions API. But the process is complicated and thus not recommended.

Connect new account

  1. POST /institutions with the provider & credentials. If everything is valid, Wealthica should return 202 Accepted with the institution object. A new interactive sync should start and institution.sync_status should be syncing at this point.

  2. GET /institutions/:id/poll?v={institution.__v} to poll for an update and act according to sync_status

    • syncing: the institution is still syncing but there has been some progress. If institution.authorized is true, this means the sync has gotten past the login/authentication process, and is fetching new data. Your application may choose to stop polling at this point if you don't need to show the balances to your user right away.
    • ok: the sync has been successful.
    • error: there has been an authentication/authorization error, usually because of invalid credentials or 2FA verification. Detailed information on the error can be seen in institution.sync_error. Your application should first check sync_error.name and proceed accordingly.
      • LoginFailedError: Invalid credentials. You would need to update the credentials by calling PUT /institutions/:id with the new credentials. Similar to 1), you would receive a 202 Accepted status and "sync_status": "syncing". Then go back to polling.
      • SecurityQuestionError: 2FA / security question verification required. The question would be in sync_error.message, e.g. "sync_error.message": "Your one-time security code will be sent to number ending with XXX". Your application should send the answer (verification code in this case) by calling PUT /institutions/:id with { "security_answer": "thecode" } in the request body. Then go back to polling. If you wait too long to send the answer, then the answer or the interactive session might expire and you will need to start over by triggering a new sync.
    • retry: there has been an unexpected problem and the sync has been rescheduled in the next hour. It's advised to report to us the institution id so we can investigate the problem if sync_status stays in retry for an extended period of time.
    • If a 404 is returned on the poll, it means something wrong with the credentials, and the institution has been deleted from the Wealthica side. This is equivalent to LoginFailedError, but should happen only for new connections that have never synced, to minimize the number of abandoned connections. In this case, go back to 1) to create a new connection.

Each poll takes up to 30 seconds to return the latest institution object if there is an update. Otherwise, it would return 304 and your application is expected to poll again until there is a new sync_status. It might take from seconds to a couple of minutes to return a new status depending on the institution. If it takes too long to get a new sync_status, there's a chance there has been an error, in which case the application should stop polling.

info

The polling process above should be similar for when you connect a new account, sync or fix an existing connection.

Reconnect/fix a connection

Sometimes a connection might fail to sync because of changed/revoked credentials or 2FA verifications. In that case, when you fetch the connection by doing GET /institutions/:id, you should see "sync_status": "error" and the error type inside sync_error.name

LoginFailedError:

  1. Update the credentials by calling PUT /institutions/:id with the new credentials. A 202 Accepted should be returned and a new interactive sync should start. It's advised to have this triggered by the user, so they are around to handle any 2FA verification if needed.
  2. Poll for update and act accordingly.

SecurityQuestionError:

You might see the question under sync_error.message and be tempted to send an answer. However most of the time when you see this error, the 2FA session has already expired. You can confirm that by checking sync_status_details.date to see the date when the error is returned. If it's past 5 minutes since the error was set, then it's likely the session has expired. Some institutions have even shorter 2FA sessions (under 60s).

Even if it looks like the session is still active, it might not be possible to send an answer because the sync was likely started in non-interactive mode (i.e. daily syncs). So most of the time you would need to first trigger a new interactive sync:

  1. Call POST /institutions/:id/sync with { force: true, interactive: true } in the POST body.

    • Passing interactive enables interactive mode, which means the sync would accept 2FA answers. It's advised to have this triggered by the user, so they are around to handle any 2FA verification if needed.
    • Passing force allows starting a new sync even thought an existing sync is already in progress.
  2. Poll for update and act accordingly. If you get a new SecurityQuestionError, send the answer and poll again.

Sync a connection

  1. Trigger a sync by calling POST /institutions/:id/sync with { interactive: true } in the POST body.

    • Passing interactive enables interactive mode, which means the sync would accept 2FA answers. It's advised to have this triggered by the user, so they are around to handle any 2FA verification if needed.
  2. Poll for update and act accordingly.

Connecting with oAuth providers

OAuth providers (e.g. Questrade, Wealthsimple) require a specific workflow to connect. Some important notes:

  1. The oAuth process must be opened as Wealthica (using the oAuth Client Id provided under provider.client_id). Note: if you have a custom Client Id for the provider, use it instead (contact us for more info on this).
  2. At the end of the process, the oAuth result (code or errors) is always returned to the Wealthica OAuth Redirection service at https://api.wealthica.com/oauth/redirect. This redirection service will take care of returning the oAuth result back to your app. You will need to register your Redirect URI prior to the integration.

Detailed integration instructions

The process must be initiated for providers with oauth: true (from the /providers endpoint). The information needed to initiate the process is provided in the provider data, for example:

{
"name": "Questrade",
"oauth": true,
"client_id": "theclientid",
"authorize_url": "https://login.questrade.com/oauth2/authorize",
"scopes": ["read_acc"]
}

Upon registering your Redirect URI with Wealthica, you will be provided a sub string corresponding with the Redirect URI. You can register multilple Redirect URIs (for dev, staging and production environments), each with its own sub. For example:


// STEP 1: Build oAuth URL

const OAUTH_REDIRECT_URI = "https://api.wealthica.com/oauth/redirect";
const OAUTH_SUB = 'myappdev';

// If you have different receiving paths for different flows (e.g. connect vs reconnect), you can
// provide a path. It will be concatenated with your registered URI.
// E.g. https://dev.myapp.com/connect, https://dev.myapp.com/reconnect/someaccountid
const OAUTH_PATH = '/connect';

// Prepare oAuth state.
// The Wealthica OAuth Redirection service will redirect based on your `sub` and (optional) `path`.
// You can still pass your client state info here.
const oAuthState = {
sub: OAUTH_SUB,
path: OAUTH_PATH,
...additionalStateProps,
};
const state = encodeBase64(oAuthState);

// Build the URL
const url = new URL(provider.authorize_url);
url.searchParams.append("client_id", provider.client_id);
url.searchParams.append("response_type", "code");
url.searchParams.append("state", state);
url.searchParams.append("redirect_uri", OAUTH_REDIRECT_URI);
if (provider.scopes) url.searchParams.append("scope", provider.scopes.join(" "));

// STEP 2: Start the oAuth process
// User will be presented with the provider's oAuth page (Questrade in this example).
// E.g. https://login.questrade.com/oauth2/authorize?client_id=theclientid...
openURL(url.href);


// STEP 3: Handling oAuth result
// After user completes the process, the oAuth result will be passed to your Redirect URI.
// E.g. https://dev.myapp.com/connect?code=somecode&state=thestate...

// Your app will then be responsible to send the code to the Wealthica API. Either:

// Send a POST to `/institutions` endpoint to create a new connection
createInstitution({
name: "Questrade",
type: "questrade",
credentials: {
code: 'somecode',
client_id: 'your own OAuth Client Id', // optional, you should not need this in most cases.
}
});

// Or send a PUT to `/institutions/:id` to update the existing connection
updateInstitution({
id: 'existingconnectionid',
credentials: {
code: 'somecode',
client_id: 'your own OAuth Client Id', // optional, you should not need this in most cases.
}
})

The "Demo" institution

"Demo" is a dummy institution that can be used to test the API and simulate various scenarios by using different combinations of username/password:

  • username: wealthica, password: wealthica. Simulates a successful connection, without 2FA. Sync will succeed.
  • username: wealthica, password: anything. Simulates 2FA with multiple-choice question. Returns SecurityQuestionError.
    • answer: javascript. Simulates multi-step 2FA. Returns another SecurityQuestionError (whose answer is ruby).
    • answer: ruby. Simulates a successful answer. Sync will succeed.
    • answer: UserActionRequiredError. Simulates the UserActionRequiredError error.
    • answer: anything else. Returns LoginFailedError.
  • username: wealthica, password: crash. Simulates a crash during sync.
  • username: wealthica, password: error. Simulates an unknown error.
  • username: UserActionRequiredError, password: anything. Simulates the UserActionRequiredError error.
  • username: anything, password: anything. Simulates invalid credentials. Returns LoginFailedError.
  • username: TemporaryFailureError, password: anything. Simulates the TemporaryFailureError.
  • username: wealthica, password: wait-{step}-{timeout value in MS}. Simulates the syncing status for that particular step and the overall sync.
    • the valid steps that can be used are login, 2fa, investments, positions, transactions, documents.
    • password example: wait-login-120000.