Maintaining a public-key based integration

Details and guidance on maintaining a legacy public_key based Link integration for older Plaid API versions.

Overview

In July 2020, Plaid introduced the link_token, which replaces the static public_key. While integrations using the public_key are still supported, it is recommended that you upgrade your integration to use a link_token instead, as future Plaid development and features will be based on the link_token infrastructure. To start upgrading, see the Link token migration guide.

Plaid Link for Web

This section provides instructions for maintaining Plaid integrations using the deprecated public_key parameter. These instructions cannot be used for new integrations or for adding OAuth support to existing integrations. For up-to-date content on this topic, see the Link Web SDK instead. For instructions on updating an existing legacy integration, see the Link token migration guide.

Installation

Include the Plaid Link initialize script on each page of your site. It should always be loaded directly from https://cdn.plaid.com, rather than included in a bundle or hosted yourself.

1
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>

Create

onSuccess

onExit

onEvent

open()

exit()

destroy()

Plaid Link for iOS

This section provides instructions for maintaining Plaid integrations using the deprecated public_key parameter. These instructions cannot be used for new integrations or for adding OAuth support to existing integrations. For up-to-date content on this topic, see the Link iOS SDK instead. For instructions on updating an existing legacy integration, see the Link token migration guide.

Overview

Here you find instructions on how to integrate and use Plaid Link for iOS. At the center of it lies LinkKit.framework: an embeddable framework managing the details of linking an account with Plaid.

To get up and running quickly with Plaid Link for iOS clone the Github repository and try out the example applications, which provide a reference implementation in Swift and Objective-C. Youʼll want to sign up for free API keys to get started.

Installation

Plaid Link for iOS is an embedabble framework that is bundled and distributed within your application. There are several ways to obtain the necessary files and keep them up-to-date; we recommend using CocoaPods or Carthage. Regardless of what you choose, submitting a new version of your application with the updated LinkKit.framework to the App Store is required.

Requirements

A new version of LinkKit.framework will be released around the 15th of every month. We recommend you keep up to date to provide the best Plaid Link experience in your application.

CocoaPods
  1. If you haven't already, install the latest version of CocoaPods.
  2. If you don't have an existing Podfile, run the following command to create one:
    1
    pod init
  3. Add this line to your Podfile:
    1
    pod 'Plaid'
  4. Run the following command:
    1
    pod install
  5. Add a custom Run Script build phase (we recommend naming it Prepare for Distribution ) with the script below, which prepares the LinkKit.framework for distribution through the App Store.
    1
    2
    3
    LINK_ROOT=${PODS_ROOT:+$PODS_ROOT/Plaid/ios}
    cp "${LINK_ROOT:-$PROJECT_DIR}"/LinkKit.framework/prepare_for_distribution.sh "${CODESIGNING_FOLDER_PATH}"/Frameworks/LinkKit.framework/prepare_for_distribution.sh
    "${CODESIGNING_FOLDER_PATH}"/Frameworks/LinkKit.framework/prepare_for_distribution.sh
  6. To update to newer releases in the future run:
    1
    pod install
Carthage
  1. If you haven't already, install the latest version of Carthage.
  2. If you don't have an existing Podfile, run the following command to create one:
    1
    pod init
  3. Add this line to your Podfile:
    1
    github "plaid/plaid-link-ios"
  4. Add a custom Run Script build phase (we recommend naming it Prepare for Distribution) with the script below, which prepares the LinkKit.framework for distribution through the App Store.
    1
    2
    3
    LINK_ROOT=${PODS_ROOT:+$PODS_ROOT/Plaid/ios}
    cp "${LINK_ROOT:-$PROJECT_DIR}"/LinkKit.framework/prepare_for_distribution.sh "${CODESIGNING_FOLDER_PATH}"/Frameworks/LinkKit.framework/prepare_for_distribution.sh
    "${CODESIGNING_FOLDER_PATH}"/Frameworks/LinkKit.framework/prepare_for_distribution.sh
  5. To update to newer releases in the future run:
    1
    carthage update plaid-ios --platform ios
Manual

Get the latest version of LinkKit.framework and embed it into your application.

Embed LinkKit.framework into your application, for example by dragging and dropping the file onto the Embed Frameworks build phase as shown below.

Depending on the location of the LinkKit.framework on the filesystem you may need to change the Framework Search Paths build setting to avoid the error: fatal error: 'LinkKit/LinkKit.h' file not found. For example, the LinkDemo Xcode projects have it set to FRAMEWORK_SEARCH_PATHS = $(PROJECT_DIR)/../ since the LinkKit.framework file is shared between them and is kept in the directory that also contains the demo project directories.

Finally, add a Run Script build phase (we recommend naming it Prepare for Distribution) with the script below. Be sure to run this build phase after the Embed Frameworks build phase or [CP] Embed Pods Frameworks build phase when integrating using CocoaPods, otherwise LinkKit.framework will not be properly prepared for distribution.

Failing to execute the run script build phase after the embed frameworks build phase very likely get your application rejected during App Store submission or review.

The script below removes from the framework any non-iOS device code that is included to support running LinkKit in the Simulator but that may not be distributed via the App Store.

Failing to run the script below will very likely get your application rejected during App Store submission or review.

Change the \${PROJECT_DIR\}/LinkKit.framework path in the example below according to your setup, and be sure to quote the filepaths when they contain whitespace.

1
2
3
LINK_ROOT=\${PODS_ROOT:+$PODS_ROOT/Plaid/ios\}
cp "\${LINK_ROOT:-$PROJECT_DIR\}"/LinkKit.framework/prepare_for_distribution.sh "\${CODESIGNING_FOLDER_PATH\}"/Frameworks/LinkKit.framework/prepare_for_distribution.sh
"\${CODESIGNING_FOLDER_PATH\}"/Frameworks/LinkKit.framework/prepare_for_distribution.sh

Implementation

To use Plaid Link for iOS import LinkKit and its symbols into your code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import LinkKit
extension ViewController : PLKPlaidLinkViewDelegate {
// call presentPlaidLink to create + initialize Link
func presentPlaidLink() {
let linkViewController = PLKPlaidLinkViewController(configuration: PLKConfiguration(...), delegate: self)
present(linkViewController, animated: true)
}
// handle didSucceedWithPublicToken delegate method
func linkViewController(
_ linkViewController: PLKPlaidLinkViewController,
didSucceedWithPublicToken publicToken: String,
metadata: [String : Any]?) { /* handle success */ }
// handle didExitWithError delegate method
func linkViewController(
_ linkViewController: PLKPlaidLinkViewController,
didExitWithError error: Error?,
metadata: [String : Any]?) { /* handle exit | error */ }
// handle didHandleEvent delegate method
func linkViewController(
_ linkViewController: PLKPlaidLinkViewController,
didHandleEvent event: String,
metadata: [String : Any]?) { /* handle exit | error */ }
}

Configure & present Link

didSucceedWithPublicToken

didExitWithError

didHandleEvent

Plaid Link for Android

This section provides instructions for maintaining Plaid integrations using the deprecated public_key parameter. These instructions cannot be used for new integrations or for adding OAuth support to existing integrations. For up-to-date content on this topic, see the Link Android SDK instead. For instructions on updating an existing legacy integration, see the Link token migration guide.

Overview

Here you find instructions on how to integrate and use Plaid Link for Android. At the center of it lies LinkSdk: an embeddable framework managing the details of linking an account with Plaid.

To get up and running quickly with Plaid Link for Android, clone the GitHub repository and try out the example applications, which provide a reference implementation in Java and Kotlin. Youʼll want to sign up for free API keys through the Plaid Developer Dashboard to get started.

Requirements

A new version of the Android SDK will be released around the 15th of every month. You should keep your version up-to-date to provide the best Plaid Link experience in your application.

Update your project plugins

In your root-level (project-level) Gradle file (build.gradle), add rules to include the Android Gradle plugin. Check that you have Google's Maven repository, as well.

1
2
3
4
5
6
7
8
9
10
11
buildscript {
repositories {
// Check that you have the following line (if not, add it):
google() // Google's Maven repository
mavenCentral() // Include to import Plaid Link Android SDK
jcenter() // Include to import Plaid Link transitive dependencies
}
dependencies {
// ...
}
}
Add the PlaidLink SDK to your app

In your module (app-level) Gradle file (usually app/build.gradle), add a line to the bottom of the file. The latest version of the PlaidLink SDK is Maven Central and can be found on Maven Central.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
android {
defaultConfig {
minSdkVersion 21 // or greater
}
// Enable Java 8 support for Link to work
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
// ...
implementation 'com.plaid.link:sdk-core:<insert latest version>'
}
Register your app ID

To register your Android app ID:

  1. Log in to the Plaid Dashboard
  2. Navigate to the API pane on the Team Settings page
  3. Configure one or more Android package names (e.g.com.plaid.example)
  4. Save your changes

Your Android app is now set up and ready to start integrating with the Plaid SDK.

Initialize Plaid Link Instance

Create an instance of Plaid Link by calling Plaid.initialize(application). Try to do this as early as possible to speed up opening Plaid Link.

1
2
3
4
5
6
7
8
9
import android.app.Application
import com.plaid.link.Plaid
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
Plaid.intialize(this)
}

Open Link

The Plaid object can be used to open Link with the given configuration. With Kotlin you can use the openPlaidLink extension function from an Activity or Fragment.

Handling Results and Events

The onActivityResult handler is called for the onSuccess and onExit events. Use PlaidLinkResultHandler to parse the result out of the returned intent.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import android.content.Intent
import com.plaid.link.LinkActivity
import com.plaid.link.Plaid
import com.plaid.linkbase.models.LinkEventListener
import com.plaid.linkbase.models.PlaidApiError
import com.plaid.linkbase.models.PlaidEnvironment
import com.plaid.linkbase.models.PlaidProduct
class MainActivity : AppCompatActivity() {
private val resultHandler = PlaidLinkResultHandler(
onSuccess = { it: LinkConnection -> /* handle onSuccess */ }
onExit = { it: PlaidError -> /* handle onExit */ }
)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (!resultHandler.onActivityResult(requestCode, resultCode, data)) {
Log.i(MainActivity.class.getSimpleName(), "Not handled");
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Plaid.setLinkEventListener { event -> Log.i("Event", event.toString()) }
...
}
}

onSuccess

onExit

onEvent

Plaid Link for React Native

This section provides instructions for maintaining Plaid integrations using the deprecated public_key parameter. These instructions cannot be used for new integrations or for adding OAuth support to existing integrations. For up-to-date content on this topic, see the Link React Native SDK instead. For instructions on updating an existing legacy integration, see the Link token migration guide.

To get started with Plaid Link for React Native youʼll want to sign up for free API keys through the Plaid Developer Dashboard.

Requirements

A new version of the React Native SDK will be released around the 20th of every month. You should keep your version up-to-date to provide the best Plaid Link experience in your application.

Version Compatibility
React Native SDKAndroid SDKiOS SDKStatus
7.x.x3.2.x>=2.0.7Active
6.x.x3.x.x>=2.0.1Active
5.x.x2.1.x>=1.1.34Active
4.x.x2.0.x<=1.1.33Active
3.x.x1.x.x<=1.1.33Deprecated
2.x.x0.3.x<=1.1.27Deprecated
1.x.x< 0.3.x<=1.1.24Deprecated

Getting Started

Installing the SDK

In your react-native project directory, run:

1
npm install --save react-native-plaid-link-sdk

Next Steps

PlaidLink

onSuccess

The onSuccess callback returns a LinkSuccess object.

onExit

onEvent

The React Native Plaid module emits onEvent events throughout the account linking process. To receive these events use the usePlaidEmitter hook.

OAuth

Using Plaid Link with an OAuth flow requires some additional setup instructions. For details, see the OAuth guide.

Upgrading

Plaid Link for Webviews

This section provides instructions for maintaining Plaid integrations using the deprecated public_key parameter. These instructions cannot be used for new integrations or for adding OAuth support to existing integrations. For up-to-date content on this topic, see the Link Webview SDK instead. For instructions on updating an existing legacy integration, see the Link token migration guide.

Here you will find instructions on how to integrate and use Plaid Link inside a Webview. We recommend starting with one of our sample Webview apps:

Each example app is runnable (on both simulators and devices) and includes code to initialize Link and process events sent from Link to your app via HTTP redirects.

Installation

Link is optimized to work within Webviews, including on iOS and Android. The Link initialization URL to use for Webviews is:

1
https://cdn.plaid.com/link/v2/stable/link.html

The Link configuration options for a Webview integration are passed via querystring rather than via a client-side JavaScript call. See the create section below for details on the available initialization parameters.

Communication between Link and your app

Communication between the Webview and your app is handled by HTTP redirects rather than client-side JavaScript callbacks. These redirects should be intercepted by your app. The example apps include sample code to do this.

All redirect URLs have the scheme plaidlink. The event type is communicated via the URL host and data is passed via the querystring.

1
plaidlink://

There are three supported events, connected, exit, and event, which are documented below.

Create

connected

exit

event

Update mode

When to use update mode

Over time, Items may need to refresh authentication information. This can happen if the user changes a password, if MFA requirements change, or if the login becomes locked. An Item can also require its authentication refreshed if it was only authorized for a limited amount of time and that authorization has expired or is about to expire. This can commonly happen to Items from European institutions that comply with the PSD2 regulation, which mandates that access to an Item can only be granted for 90 days at a time before it must be refreshed. Receiving an ITEM_LOGIN_REQUIRED error or a PENDING_EXPIRATION webhook indicates that the Item should be re-initialized via update mode.

Using update mode

To use update mode for an Item, initialize Link with a public_token for the Item that you wish to update. You can obtain the public_token using the /item/public_token/create endpoint:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Create a one-time use public_token for the Item.
// This public_token can be used to initialize Link
// in update mode for the user
app.get('/create_public_token', function(request, response, next) {
client.createPublicToken(ACCESS_TOKEN, function(err, res) {
if(error != null) {
console.log(msg + "\n" + JSON.stringify(err));
response.json({error: JSON.stringify(err)}):
} else {
// Use the public_token to initialize Link
var PUBLIC_TOKEN = res.public_token;
response.json({public_token: PUBLIC_TOKEN});
}
});
});

Link auto-detects the appropriate institution and handles the credential and multi-factor authentication process, if needed.

An Item's access_token does not change when using Link in update mode, so there is no need to repeat the exchange token process.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Initialize Link with the token parameter
// set to the generated public_token for the Item
const linkHandler = Plaid.create({
env: 'sandbox',
clientName: 'Client Name',
key: 'PUBLIC_KEY',
product: ['transactions'],
token: 'GENERATED_PUBLIC_TOKEN',
onSuccess: (public_token, metadata) => {
// You do not need to repeat the /item/public_token/exchange
// process when a user uses Link in update mode.
// The Item's access_token has not changed.
},
onExit: (err, metadata) => {
// The user exited the Link flow.
if (err != null) {
// The user encountered a Plaid API error prior
// to exiting.
}
// metadata contains the most recent API request ID and the
// Link session ID. Storing this information is helpful
// for support.
},
});

Link will automatically detect the institution ID associated with the public_token and present the appropriate credential view to your user.

Related errors

Below is a list of errors that you may encounter in update mode or that may cause you to launch the update mode flow:

  • ITEM_LOGIN_REQUIRED – The financial institution indicated that the user's password or MFA information has changed. They will need to reauthenticate via Link's update mode.
  • ITEM_NO_ERROR – Link was initialized in update mode for an Item that is in a good state. No further action is required.
  • INVALID_UPDATED_USERNAME – The username associated with an item is no longer valid.

OAuth Integration (Europe)

This section provides instructions for maintaining Plaid integrations using the deprecated public_key parameter. These instructions cannot be used for new integrations or for adding OAuth support to existing integrations. For instructions on updating an existing legacy integration, see the Link token migration guide.

Some European institutions use an OAuth authentication flow, in which Plaid Link redirects the end user to their bank’s website or mobile app to authenticate. If you are initializing Link with one or more European country codes, your integration may require changes in order to support OAuth authentication flows.

Integration TypeChanges Required
Desktop webNo
Mobile webYes
WebViewYes
Android SDKNo
iOS SDKYes
React Native for AndroidNo
React Native for iOSYes

If your integration requires changes, you will need to launch Link twice, once before and once after the OAuth redirect. The first time, you will need to provide two additional configuration parameters, oauthNonce and oauthRedirectUri. After the user completes the OAuth flow, Plaid will redirect back to your application via the oauthRedirectUri with a query parameter called oauth_state_id. To complete the Link flow, dismiss the first Link instance and re-initialize Link with two configuration parameters, the oauthNonce from the original Link initialization, as well as the oauthStateId from the oauth_state_id query parameter.

For security, the oauthNonce must be uniquely generated for each login and must be at least 16 characters long. We recommend using a UUID.

Before re-initializing Link, you should re-authenticate the end user to prevent a confused deputy problem. This can be accomplished by including one or more query parameters in your oauthRedirectUri. For example, you could include a parameter called user_id. Before re-initializing Link, you would check that the user_id in the redirect URI matches the user_id in your application state (e.g. a cookie).

Note that in mobile web browsers, if the end user has their bank’s mobile app installed, they will be redirected to the bank’s mobile app to authenticate, after which they will be redirected back to your web application in a new tab.

Allowed redirect URIs

To prevent open redirect attacks, your oauthRedirectUri must be configured through the developer dashboard. For security, the oauthRedirectUri cannot contain the oauthNonce.

App links

For mobile app integrations, the oauthRedirectUri must be registered as an app link to enable app-to-app authentication flows. You will need to configure an Android App Link or an Apple App Association File. Custom URI schemes are not supported; a proper universal link must be used.

Payment Initiation (UK and Europe)

This section provides instructions for maintaining Plaid integrations using the deprecated public_key parameter. These instructions cannot be used for new integrations or for adding OAuth support to existing integrations. For up-to-date content on this topic, see Payment Initiation instead. For instructions on updating an existing legacy integration, see the Link token migration guide.

The UK Payment Initiation API enables payment transfers within your app. Plaid supports both domestic payments denominated in pound sterling (typically via the Faster Payments network, although this is up to the institution) and international payments denominated in euro (typically via SEPA Credit Transfer). Each time a client wants to receive a payment, the end user must authorize the payment in Link before the payment can be initiated.

Note: The revised EU Directive on Payment Services ("PSD2") regulations require strong customer authentication ("SCA") for each payment order.

Initializing Link

To initialize Link for Payment Initiation, set payment_initiation as the only product and include the payment token. If an item has previously been created for the end user making the payment, a public_token can be included to initialize Link directly to the institution associated with the existing Item.

Creating a payment token

Create payment token

The /payment_initiation/payment/token/create endpoint has been deprecated. New Plaid customers will be unable to use this endpoint, and existing customers are encouraged to migrate to the newer, link_token-based flow. The recommended flow is to provide the payment_id to /link/token/create, which returns a link_token used to initialize Link.
The /payment_initiation/payment/token/create is used to create a payment_token, which can then be used in Link initialization to enter a payment initiation flow. You can only use a payment_token once. If this attempt fails, the end user aborts the flow, or the token expires, you will need to create a new payment token. Creating a new payment token does not require end user input.

payment_initiation/payment/token/create

Request fields and example

client_idstring
Your Plaid API client_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.
secretstring
Your Plaid API secret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.
payment_idrequiredstring
The payment_id returned from /payment_initiation/payment/create.
1
2
3
4
5
const response = await client.createPaymentToken(paymentID).catch((err) => {
// handle error
});
const paymentToken = response.payment_token;
const paymentTokenExpirationTime = response.payment_token_expiration_time;
payment_initiation/payment/token/create

Response fields and example

payment_tokenstring
A payment_token that can be provided to Link initialization to enter the payment initiation flow
payment_token_expiration_timestring
The date and time at which the token will expire, in ISO 8601 format. A payment_token expires after 15 minutes.
Format: date-time
request_idstring
A unique identifier for the request, which can be used for troubleshooting. This identifier, like all Plaid identifiers, is case sensitive.
1
2
3
4
5
{
"payment_token": "payment-token-sandbox-feca8a7a-5591-4aef-9297-f3062bb735d3",
"payment_token_expiration_time": "2020-01-01T00:00:00Z",
"request_id": "4ciYVmesrySiUAB"
}