Account Linking
Overview
Users must link their third party bank account with Productfy before performing any ACH money movement with the account. Linking bank accounts serves the following purposes:
- Verifies that the user owns the account being linked
- Obtains the bank account number and routing number, which are required for initiating subsequent ACH transactions
There are two ways to link an account:
- Instant Account Verification - Productfy supports its own account linking service in partnership with Yodlee, as well as other third party account linking providers you may have a direct relationship with.
- Micro-deposit Verification (MDV) - Productfy provides services that can initiate two small micro-deposits to an account, which then need to be verified by the customer to ensure they have access to the account.
We recommend you use a combination of # 1 and 2 above to ensure your customers can always link their bank accounts.
Using third party account linking providers
If you have your own relationship with a non-Yodlee account linking provider (ex. Plaid, MX, etc.), you can use it for account linking and send the Productfy system the account and routing number for the linked account. Work with your Productfy representative to have your environment configured for a non-Yodlee account linking provider. There are two technical steps to follow:
-
Call the Save External Account API to save the account and routing number and associate it with the correct Person ID or Organization ID. Note, this API only supports accounts of the following types: checking, savings, money market, loan.
-
Call Verify External Link API to set the account to Verified
Yodlee security standards
Clients using Yodlee for account linking or data aggregation must adhere to their security standards outlined here: www.productfy.io/data-source-policy.
Prerequisites for Yodlee account linking
Before account linking can occur, verify the following requirements are met:
- You have created a person or organization on the Productfy system. Person must be created with
linkWithYodlee
parameter astrue
. - The person or organization has completed KYC verification.
- If linking an organization you must register the organization in Yodlee first using the Register Organization With Yodlee api
Account linking workflow
Start the account linking workflow by displaying the account linking widget, which allows the user to log in to their bank account and instantly link that account to Productfy. If the link can’t be made, the user can manually link their bank account by providing the bank account number and routing number, which triggers the Micro-Deposit Verification (MDV) process using ACH transactions to prove account ownership.
Step 1 - Get configuration
Use the Get Yodlee FastLink Configuration API to retrieve the data needed to initialize the Yodlee Fastlink widget directly.
The accessToken
returned by this Yodlee API expires after 30 minutes.
Step 2 - Integrate widget
As shown in the following image, Yodlee's widget enables the user to search for their bank and create a connection to that bank’s online system. Follow Yodlee’s integration requirements to initialize the Fastlink Widget. In Yodlee's fastlink.open() method, please be sure to set params.configName
to Verification to use the widget to link an account to be used for money movement (ACH).
Step 3 - Display the widget
Note - it may take between 1-15 minutes for Yodlee to fully link an account once the user submits their information through the widget.
Productfy recommends the following best practices to integrate the web widget:
- Display a link for users to choose not to use the account linking widget and manually link their accounts. For example, if the user’s bank is not one of the supported banks, they will not be able to use the widget and must perform the traditional micro-deposit verification.
- Pass in an event handler for errors from the widget to improve customer experience and aid in troubleshooting errors. See Productfy recommended code below:
// Let's keep track of how many times the user failed to log into their bank siteconst failedLoginCounter = 0;const otherErrorsCounter = 0;const onError = (data) => {console.error(data); // If you want to log the error to the browser console/*** Example of "data"* additionalStatus: "INCORRECT_CREDENTIALS"* fnToCall: "accountStatus"* isMFAError: true* providerAccountId: 11810284* providerId: 2852* providerName: "Bank of America"* reason: "The credentials you've entered are incorrect. Verify that CAPS LOCK is not on* and that the desired financial institution was selected."* requestId: "M+HOk5ylDDDBDTZnaApg2E9VSqI="* status: "FAILED"*/if (data && data.status === 'FAILED' && data.additionalStatus === 'INCORRECT_CREDENTIALS') {failedLoginCounter++;} else {otherErrorsCounter++;}// It would be good to log the error to our backend so that we can investigate possible bugs// or system downtime.const payload = {apiUrl: 'API_URL', // Optional. If you are accessing Productfy's API from the web app.pageUrl: window.location.href,eventBody: data,callbackType: 'onError',isError: true,fastlinkConfiguration: { // Essentially the values you're passing into the FastLink widgetfastLinkURL: 'FASTLINK_URL',accessToken: 'Bearer YOUR_ACCESS_TOKEN',params: {configName : 'Aggregation' // Whichever mode you're running FastLink in},},// In this section, if you keep track of the IDs in your web app, passing them to the logs// would be helpful.session: {companyId: 'COMPANY_ID', // OptionalloginId: 'LOGIN_ID', // OptionalpersonId: 'PERSON_ID', // OptionalsessionKey: 'SESSION_KEY', // Optional. If you are accessing Productfy's API from the web app.},};try {fetch('https://logger.productfy.io/', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify(payload),});} catch (e) {console.error('Could not log error', e);}// If the user attempted and failed several times (you can tweak the values and logic// to your liking)if (failedLoginCounter > 2 || otherErrorsCounter > 2) {// Hide FastLink and show a dialog asking if they want to try adding their account// using the routing and account numbers. Or redirect them to a support page.}};
Step 4 - Save Yodlee FastLink Result
After a user completes the Yodlee FastLink widget flow, it may take up to 15 minutes for Yodlee to respond back with confirmation that the account is linked. In the meantime, you can temporarily save the account information to Productfy's PersonKVPData object by passing in the Yodlee Provider ID and Yodlee Provider Account ID to one of the APIs below. This will store the Account Name, Account Type, Estimate Balance, and Bank Name from Yodlee, which you can use to display to your customer.
For Person:
For Organization:
Step 5 - Get Productfy Account ID
After the user gets through the Yodlee FastLink widget, Productfy will wait to hear back from Yodlee before creating an account on the system.
Note - it may take up to 15 minutes for Yodlee to fully link an account once the user submits their information through the widget.
You will need the Account ID for subsequent API calls below. There are two ways to obtain the Account ID:
- Listen to Productfy's Account Linked webhook. The webhook will trigger after the account is confirmed on the Productfy system and its payload will include the Account ID.
- Call the Get Multiple Accounts API with the user's Person ID to retrieve the Account ID once it's available.
- You can find this field under the returns section field
yodlee.accountId
- In the event support is needed from Yodlee, Productfy will also need the field
yodlee.providerAccountId
for troubleshooting
- You can find this field under the returns section field
The
yodlee.accountId
field represents the ID of the account (i.e. checking/savings/credit card) linked to Yodlee. While the yodlee.providerAccountId
represents the user's ID on the Yodlee platform.
Step 6 - Verify account linking status
Use the Account Linking Status API to check on the status of an attempted account link. The status of the link will guide the next steps for the user as indicated below:
- If the Account Linking Status API returns an accountID and has needAccountNumber and needRoutingNumber as false, the user’s account is successfully linked.
- If the Account Linking Status API returns an accountID but has needAccountNumber and needRoutingNumber as true, then the account has been partially added. You will need to ask the user to input the Routing Number and Account Number for their bank account and save it to Productfy with the Add Routing & Account Numbers API.
- If needVerifyMicroDeposits is true, the user was not able to authenticate, and the traditional micro-deposit verification flow must be completed. Go to Step 7 - Traditional Micro-Deposit Verification.
Step 7 - Traditional micro-deposit verification
If the user was unable to authenticate using the account linking widget, use MDV to verify that micro deposits make it to the user’s bank account. This takes 1 business day or less. After the deposit is verified, the user must return to your app to verify the amounts of the micro deposits, which do not expire. Also, we will automatically initiate withdrawals for the micro-deposit amounts to take the money back.
Ask for account number and routing number
The API you use for this depends on whether you're using the Yodlee integration described above, or not. If you are using the Yodlee integration above, then the account ID has already been created and associated with the Person or Organization ID and you can use the Sensitive Financial Information API to get the account and routing number:
If you are choosing not to use the Yodlee integration above and just build a micro-deposits flow only for linking accounts, then you need to call the Save External Account API to save the account and routing number and associate it with the correct Person ID or Organization ID:
Initiate micro-deposits
Use the Initiate Micro-Deposits API to initiate two micro-deposit verifications (MDV) to the account ID that was created. It will take 1 business day or less for the two amounts to show up in the bank account.
Verify micro-deposits
After you've initiated micro-deposit transfers, use this API to verify the amounts. You must wait 3 hours before you can verify the micro-deposits. The micro-deposit verification is invalidated after 5 failures. Micro-deposits do not expire.
Micro-deposit verifications in test environments are valid for any amount less than $0.10.
Step 8 - Optional support for removing linked accounts
You can support deletion of a Yodlee-linked financial account using the removeFinancialAccount API. This will remove the account and all associated transactions from Yodlee. This is a permanent operation that cannot be reversed. NOTE: Do not use this to delete virtual accounts.
Step 9 - Test Your Yodlee Integration
Below is a preset list of test credentials from Yodlee to make sure your integration works as planned. Use it for testing purposes in your development and production environments. Note that IQ Bank shows up in production but is a mock bank with fake transactions to be used for testing purposes only.
Disclaimer About Using Yodlee DAG Accounts:
- Yodlee DAG is a simulation tool that Yodlee offers as a testing aid. The site is a Yodlee hosted site.
- Any Yodlee DAG account's performance issues and DAG site issues are completely unique and do not in any way reflect on our real production site's behavior.
- There are no SLAs for Yodlee DAG. Yodlee supports this testing aid on a best effort basis.
- Yodlee DAG can be used to simulate a good selection of scenarios but does not offer the nuances and variety of actual accounts.
- We highly recommend that Yodlee DAG is only used for development and integration testing and that actual accounts are procured and used for User Acceptance Testing.
Name | Username | Password | Description |
---|---|---|---|
IQ Bank | test_860190 | test@iqb | Transactions date back to August 31, 2021 |
IQ Bank | test_072854 | test@iqb | Transactions date back to August 31, 2021 |
IQ Bank | test_mfa_token_110136 | test@iqb; Token: 1234 | Transactions date back to August 31, 2021 |
IQ Bank | test_mfa_qa_717510 | test@iqb; What is the name of your best friend? Alex; Which city is your high school? Texas | Transactions date back to August 31, 2021 |
DAG Site | stmttest.site16441.2 | site16441.2 | Transactions are in 2016 |
DAG Site | DagTest365Txn.site16441.2 | site16441.2 | Transactions are in 2018 |
DAG OAuth | GOAuth.site19335.1 | site19335.1 | --- |