Connect Webhooks

Overview

Webhook events are sent at different points in the Finicity Connect process to allow partners to track status, get information about customer usage of Connect, and to be notified when the process is complete. This page specifically covers webhooks that originate from Connect. Use of webhooks in a call to Generate VOA Report or Generate VOI Report have a different format and do not include the X-Finicity-Signature mentioned below.

Webhooks are sent if the webhook parameter is specified in the API call body to Generate Finicity Connect URL.

Preventing Spoofing

If you are using the webhooks for sensitive or critical information it is recommended to verify the signature of the webhook. The X-Finicity-Signature header is added to all webhooks sent by Finicity Connect. To verify the signature, create a SHA-256 HMAC of the request body using your Partner Secret as the key. Then compare this to the signature included on the X-Finicity-Signature header. If the two are equal then the request is valid, otherwise it is spoofed.

It’s also suggested to store the eventId and ignore webhooks with an ID that has already been processed to prevent replay attacks.

Below is an example implementation of Signature Validation in Node.js.

Signature Validation
 const signature = req.header('X-Finicity-Signature');
const testSignature = crypto.createHmac('sha256', config.
FINICITY_PARTNER_AUTHENTICATION_TOKEN).update(req.rawBody).digest('hex'
);
if(!crypto.timingSafeEqual(Buffer.from(testSignature, 'ut
f8'), Buffer.from(signature, 'utf8'))){
throw new Error("Spoof detected. Rejecting webhook");
}

Below is a working example to use as a jumping off point for demo purposes only (please note that ‘HEX’ is used in the hash and validate):

Code Block Title
 const crypo = require('crypto');

const partnerSecret = '{{PARTNER_SECRET}}';

const rawWebhookBody = '{"eventType":"ping","payload":{}}';
const stringifiedWebhookBody = JSON.stringify(rawWebhookBody);

const signature = crypto
.createHmac('sha256', partnerSecret)
.update(stringifiedWebhookBody)
.digest('hex');

console.log(signature);

Event Body

All events include a wrapper that contains metadata about the event. The event data itself is housed in the payload key. Any custom data requested through the webhookData parameter on the Generate request will be included in this wrapper. The consumerId object will only be included for type=voi or type=voa. The eventType will match one of the Event Types listed in the next section.

The format of the event wrapper follows:

Event Body
 {
"customerId":"12345678",
"consumerId":"ed81281fcec7ec557aa7d292a3188b75",
"eventType":"started",
"eventId":"1495468585434-0e73d1719173766fe4dfe1a8",
"payload":{},
"webhookData": {}
}

Event Types

Every Connect webhook event type that the partner will receive is listed below in the order that they will be received. Reference this link to see an example of each.

Some events aren’t applicable for certain types of Finicity Connect.  The following table will direct you to which ones are applicable for the flow you are utilizing.

Event typeOAuthVOAVOA HISTORYVOIAGGREGATIONACHTRADESTREAMLITEFIXVOIE
pingXXXXXXXXXX
startedXXXXXXXXXX
institutionSupportedXXXXXXXXXX
institutionNotSupportedXXXXXXXXXX
institutionNotFoundXXXXXXXX
addingXXXXXXXXXX
unableToConnectXXXXX
invalidCredentialsXXXXXXXXX
credentialsUpdatedX
mfaXXXXXXXXX
mfaUpdatedX
processingx
discoveredXXXXXXX
addedXXXXXXXXXX
generatingXXXXX
doneXXXXXXXXXX
documentUploadX

Ping

The ping event is sent when the Generate Finicity Connect URL endpoint is called to verify that the webhook URL is accessible. This endpoint must return a 200 series or the Generate Finicity Connect URL call will fail.

Ping Event
 {
"eventType":ping
"Payload": []
}

Started

The started event is sent when the Finicity Connect is opened by the user. It is the first event sent after the ping event.

Started Event
 {
"customerId": "29272504",
"consumerId": "41d42ef0faef200e370208ad179a44cd",
"eventType": "started",
"eventId": "1543509164835-00bc130cfe79cecf9a025d70",
"payload": ""
}

institutionSupported

The InstitutionSupported event is sent when the user selects an FI. This indicates that the user has found the FI they were searching for and is currently certified for the product.

institutionSupported Event
 {
"customerId": "29272504",
"consumerId": "41d42ef0faef200e370208ad179a44cd",
"eventType": "institutionSupported",
"eventId": "1557155470294-f5e5273c2354e09670647e18",
"payload": {
"institutionId": "101732"
}
}

institutionNotSupported

The institutionNotSupported event is sent when the user selects an institution which is not certified. This applies for any call except for aggregation/lite/fix/voi-pp.

institutionNotSupported Event
 {
"customerId": "29272504",
"consumerId": "41d42ef0faef200e370208ad179a44cd",
"eventType": "institutionNotSupported",
"eventId": "1543535415162-6d06cbeed93533d612b4e255",
"payload": {
"institutionId": "15880"
}
}

institutionNotFound

The institutionNotFound event is sent when the user searches for an institution which is not in our list. We send the search query in the payload.

institutionNotFound Event
 {
"customerId": "29272504",
"eventType": "institutionNotFound",
"eventId": "1564677197519-4f47b664bd855275389e76c6",
"payload": {
"query": "not a real institution"
}
}

Adding

The adding event is sent when the Finicity Connect is discovering accounts accessible by set of entered credentials. If an institution is oAuth you will see additional data “oauth” which will be set to true.

Adding Event
 {
"customerId": "7065940",
"eventType": "adding",
"eventId": "1572413263805-b43cb6edb3254d4bebcfb4a0",
"payload": {
"institutionId": "102224",
"oauth": true
}
}

unableToConnect

The unableToConnect event is sent when there is a problem connecting to a given institution. This typically means that the institution itself is having availability problems. This maps to error codes 102, 900, 903, 904, 901, 910, 915, 916, and 920.

unableToConnect Event
 {
"customerId": "29272504",
"consumerId": "41d42ef0faef200e370208ad179a44cd",
"eventType": "unableToConnect",
"eventId": "1543535415162-6d06cbeed93533d612b4e255",
"payload": {
"institutionId": "15880"
"code": "error code"
}
}

invalidCredentials

Not supported for OAuth.

The invalidCredentials event is sent when the user enters incorrect credentials for the selected institution. This maps to error code 103 from the data services API.

invalidCredentials Event
 {
"customerId": "29272504",
"consumerId": "41d42ef0faef200e370208ad179a44cd",
"eventType": "invalidCredentials",
"eventId": "1543535972345-805ba937fdc4c6d3889b261c",
"payload": {
"institutionId": "101732"
}
}

credentialsUpdated

Not supported for OAuth.

The credentialsUpdated event is sent when the user enters correct credentials for the selected institution. This resolves error code 103 from the data services API. The mfa”: key indicates whether the credential challenge was followed by a sequential MFA challenge (“true”, or “false”).

credentialsUpdated Event
 {
"customerId": "29272504",
"consumerId": "41d42ef0faef200e370208ad179a44cd",
"eventType": "credentialsUpdated",
"eventId": "1559073542901-f2d2ebd11cf852a8114b54dc",
"payload": {
"institutionId": "101732",
"mfa": "false"
}
}

mfa

Not supported for OAuth.

The mfa event is sent when the user enters correct credentials for an institution and is then presented with a Multi-Factor Auth question (MFA).

mfa Event
 {
"customerId": "29272504",
"consumerId": "41d42ef0faef200e370208ad179a44cd",
"eventType": "mfa",
"eventId": "1543535689086-56219127a30d3f881436c0b2",
"payload": {
"institutionId": "101732"
}
}

mfaUpdated

Not supported for OAuth.

The mfaUpdated event is sent when the user completes the MFA challenge for an institution.

mfaUpdated Event
 {
"customerId": "29272504",
"eventType": "mfaUpdated",
"eventId": "1559073793752-914b6150eacc1d59fe444bf3",
"payload": {
"institutionId": "101732"
}
}

Processing

Only supported for OAuth

The processing event is sent when the user completes selecting their accounts on the Oauth flow and is being redirected back to Finicity Connect.

Processing Event
 {
"customerId":"7065940",
"eventType":"processing",
"eventId":"1567184715231-20b2b26125f0e7ada97395cb",
"Payload": {
"institutionId":"102224"
}
}

Discovered

Not supported for OAuth

The discovered event is sent after the user has successfully logged into an institution. This event includes all accounts found at the institution. This is a list of all of the accounts that the user is presented with to select from. The accounts in the payload of the subsequent added event will be a subset of the accounts in the discovered event.  If no accounts were discovered an empty array will be sent.

Discovered Event
 "customerId": "29272504",
"consumerId": "41d42ef0faef200e370208ad179a44cd",
"eventType": "discovered",
"eventId": "1543509870615-7db10ceac8b2f5fa9b7b078c",
"payload": {
"accounts": [
"...",
"..."
],
"mfa": ""
}
}

Added

The added event is sent after the user selects which of the discovered accounts they would like to add and saves them. These are the actual accounts that will be saved in the accounts resource associated with a customer. If an institution is oAuth you will see additional data “oauth” which will be set to true.

Added Event
 {
"customerId": "49369429",
"eventType": "added",
"eventId": "1569877463120-b69d33f580b26117b6139607",
"payload": {
"accounts": [
{
"id": "141383167",
"number": "1000001111",
"name": "Checking",
"balance": 930.04,
"type": "checking",
"status": "active",
"customerId": "49369429",
"institutionId": "101732",
"createdDate": 1569877453,
"lastUpdatedDate": 1569877462,
"currency": "USD",
"institutionLoginId": 32310612,
"displayPosition": 5
}
],
"institutionId": "101732",
"oauth": true
}
}

Generating

The generating event is sent after the user selects the Done button inside of connect when type is voi or voa. For type aggregation the generating event is not used.

Generating Event
 {
"customerId": "29272504",
"consumerId": "41d42ef0faef200e370208ad179a44cd",
"eventType": "generating",
"eventId": "1543510112988-61f34e0c5279666294094d9d",
"payload": {
"id": "ex3dz3iwvbe8",
"requestId": "5gw6dx2sj0",
"consumerId": "41d42ef0faef200e370208ad179a44cd",
"consumerSsn": "6789",
"type": "voa",
"status": "inProgress",
"source": "Finicity Connect",
"reportId": "ex3dz3iwvbe8"
}
}

Done

The done event is sent after the all pending items are completed.

Aggregation

For type aggregation this occurs as soon as the user clicks the Done button inside of Connect.

type=aggregation
Aggregation Done Event
 { } 

VOI or VOA

For type voi or voa then the done event is sent once the report has been generated and is ready for consumption.

type=voi or type=voa

Note that for voi or voa reports you can specify more than one report to be generated. As such the payload is an array containing the different report information. This event is only sent when all reports being generated cease being in the inProgress state.

Report Done Event
 {
"customerId":"50372071",
"eventType":"done",
"eventId":"1571149759962-bbf047aa3304f77dcbaf3e23",
"payload":[
{
"eventName":"done",
"id":"uq1scf3cvu9a",
"consumerId":"382abd9cea1df5745772171a24d6ea6d",
"consumerSsn":"3333",
"type":"voa",
"status":"success",
"portfolioId":"ixfmmzyasdc0-1-port"
}]
}

documentUpload

The documentUpload event is sent after the user uploads a document in Connect when the type is voietxverify.

documentUpload Event
 {
"consumerId":"9a6f18zzz219a49d7f198a5ea6d959371",
"customerId":"52906923",
"eventType":"documentUpload",
"eventId":"157652800zzz-5a1zzzzdb38df8a07915863305",
"payload":{
"assets":[
{
"assetId":"257zzzac-7712-45a6-b895-8132fc88011d",
"label":"lastPayPeriod"
},
{
"assetId":"c36zzz0f-6519-4185-aa9e-768461a7c776",
"label":"lastPayPeriodMinusOne"
}
]
}
}