Warning
As of August 2024, this app has been replaced by the Transfer Quickstart, a newer app that showcases more up to date Transfer functionality. The Plaid Pattern Transfer app is no longer maintained and contains deprecated patterns, such as the use of account funding ids instead of the Plaid Ledger.
This is a sample Transfer application demonstrating an end-to-end Plaid integration, focused on using the transfer endpoint to transfer funds.
The full Plaid Pattern collection of sample apps includes:
Plaid Pattern Personal Finance Manager - Demonstrates the Plaid Transactions API
Plaid Pattern Account Funding App - Demonstrates the Plaid Auth, Balance, and Identity APIs
Plaid Pattern Transfer App - Demonstrates the Transfer API
Plaid Pattern apps are provided for illustrative purposes and are not meant to be run as production applications.
- Docker Version 2.0.0.3 (31259) or higher, installed, running, and signed in. If you're on Windows, check out this link to get set up in WSL.
- Plaid API keys - sign up for a free Sandbox account if you don't already have one
- Sign up for a free ngrok account if you don't already have one. You will need the ngrok authtoken to configure the app.
Note: We recommend running these commands in a unix terminal. Windows users can use a WSL terminal to access libraries like make
.
-
Clone the repo.
git clone https://github.com/plaid/pattern-transfers.git cd pattern-transfers
-
Set up your link customization: To use Transfer UI, your Plaid integration must support Account Select v2 ("ASv2"). On the Plaid developer dashboard, create a new customization for Transfer UI with the view behavior set to "Enabled for one account". This is the only view behavior supported by Transfer UI.
-
Create the
.env
file.cp .env.template .env
-
Update the
.env
file with your Plaid API keys and, if you are testing OAuth, OAuth redirect uri (in sandbox this is 'http://localhost:3002/oauth-link') and link customization name. -
Update the
/ngrok/ngrok.yml
file with your ngrok authtoken. -
If you have entered an OAuth redirect uri in the .env file, you will also need to configure an allowed redirect URI for your client ID through the Plaid developer dashboard.
-
Finally, contact your Plaid Account Executive or Account Manager to make sure that your clientId is enabled for the Transfer product.
-
Start the services. The first run may take a few minutes as Docker images are pulled/built for the first time.
make start
-
Open http://localhost:3002 in a web browser.
-
View the logs
make logs
-
When you're finished, stop the services.
make stop
All available commands can be seen by calling make help
.
As a modern full-stack application, Pattern consists of multiple services handling different segments of the stack:
client
runs a React-based single-page web frontendserver
runs an application back-end server using NodeJS and Expressdatabase
runs a PostgreSQL databasengrok
exposes a ngrok tunnel from your local machine to the Internet to receive webhooks
We use Docker Compose to orchestrate these services. As such, each individual service has its own Dockerfile, which Docker Compose reads when bringing up the services.
More information about the individual services is given below.
The Pattern web client is written in JavaScript using React. It presents the Transfer UI workflow to the user, including an implementation of OAuth. The app runs on port 3002 by default, although you can modify this in docker-compose.yml. It includes an administration ledger view where you can simulate different transfer events.
For Transfer UI, the sandbox credentials are:
Username: user_good
Password: pass_good
Aside from websocket listeners (see below), all HTTP calls to the Pattern server are defined in src/services/api.js
.
The Pattern server is configured to send a message over a websocket whenever it receives a webhook from Plaid. On the client side websocket listeners are defined in src/components/Sockets.jsx
that wait for these messages and update data in real time accordingly.
The TRANSFER_EVENTS_UPDATE webhook is demonstrated in this sample app in the transfer webhook handler.
A view of all users is provided to developers on http://localhost:3002/userlist
. Developers have the ability to remove a user here.
The application server is written in JavaScript using Node.js and Express. It interacts with the Plaid API via the Plaid Node SDK, and with the database using node-postgres
. While we've used Node for the reference implementation, the concepts shown here will apply no matter what language your backend is written in.
Plaid uses webhooks to notify you whenever a new transfer event has occured. This sample app demonstrates the use of the sandbox transfer fire_webhook endpoint to test this webhook. For an example of this, see the transfer webhook handler. Upon receipt of this webhook, a call will be made to the transfer event sync endpoint to request the latest transfer events. For each event, the transfer get endpoint is called in order to get the current status of the transfer, and then the event is saved to the database.
For webhooks to work, the server must be publicly accessible on the internet. For development purposes, this application uses ngrok to accomplish that. The ngrok session is only valid for 2 hours and the server must be re-started after that.
A redirect_uri parameter is included in the linkTokenCreate call and set in this sample app to the PLAID_SANDBOX_REDIRECT_URI you have set in the .env file (http://localhost:3002/oauth-link
). This is the page that the user will be redirected to upon completion of the OAuth flow at their OAuth institution. You will also need to configure http://localhost:3002/oauth-link
as an allowed redirect URI for your client ID through the Plaid developer dashboard.
To test the OAuth flow in sandbox, choose 'Playtypus OAuth Bank' from the list of financial institutions in Plaid Link.
If you want to test OAuth in Production, you need to use https and set PLAID_REDIRECT_URI=https://localhost:3002/oauth-link
in .env
. In order to run your localhost on https, you will need to create a self-signed certificate and add it to the client root folder. MacOS users can use the following instructions to do this. Note that self-signed certificates should be used for testing purposes only, never for actual deployments. Windows users can use these instructions below.
If you are using MacOS, in your terminal, change to the client folder:
cd client
Use homebrew to install mkcert:
brew install mkcert
Then create your certificate for localhost:
mkcert -install
mkcert localhost
This will create a certificate file localhost.pem and a key file localhost-key.pem inside your client folder.
Then in the package.json file in the client folder, replace this line on line 26
"start": "PORT=3002 react-scripts start",
with this line instead:
"start": "PORT=3002 HTTPS=true SSL_CRT_FILE=localhost.pem SSL_KEY_FILE=localhost-key.pem react-scripts start",
Finally, in the wait-for-client.sh file in the server folder, replace this line on line 6
while [ "$(curl -s -o /dev/null -w "%{http_code}" -m 1 localhost:3002)" != "200" ]
with this line instead:
while [ "$(curl -s -o /dev/null -w "%{http_code}" -m 1 https://localhost:3002)" != "200" ]
After starting up the Pattern sample app, you can now view it at https://localhost:3002.
If you are on a Windows machine, in the package.json file in the client folder, replace this line on line 26
"start": "PORT=3002 react-scripts start",
with this line instead:
"start": "PORT=3002 HTTPS=true react-scripts start",
Then, in the wait-for-client.sh file in the server folder, replace this line on line 6
while [ "$(curl -s -o /dev/null -w "%{http_code}" -m 1 localhost:3002)" != "200" ]
with this line instead:
while [ "$(curl -s -o /dev/null -w "%{http_code}" -m 1 https://localhost:3002)" != "200" ]
After starting up the Pattern sample app, you can now view it at https://localhost:3002. Your browser will alert you with an invalid certificate warning; click on "advanced" and proceed.
The node debugging port (9229) is exposed locally on port 9229.
If you are using Visual Studio Code as your editor, you can use the Docker: Attach to Server
launch configuration to interactively debug the server while it's running. See the VS Code docs for more information.
The database is a PostgreSQL instance running inside a Docker container.
Port 5432 is exposed to the Docker host, so you can connect to the DB using the tool of your choice. Username and password can be found in docker-compose.yml.
To clear all the data in the database, enter into the terminal:
make clear-db
API and Link Identifiers are crucial for maintaining a scalable and stable integration. Occasionally, an Institution error may occur due to a bank issue, or a live product pull may fail on request. To resolve these types of issues, Plaid Identifiers are required to open a Support ticket in the Dashboard.
access_tokens
and item_ids
are the core identifiers that map end-users to their financial institutions.
As such, we are storing them in the database associated with our application users.
These identifiers should never be exposed client-side.
Plaid returns a unique request_id
in all server-side responses and Link callbacks.
A link_session_id
is also returned in Link callbacks.
These values can be used for identifying the specific network request or Link session for a user, and associating that request or session with other events in your application.
We store these identifiers in database tables used for logging Plaid API requests, as they can be useful for troubleshooting.
For more information, see the docs page on storing Plaid API identifiers.
The *.sql
scripts in the init
directory are used to initialize the database if the data directory is empty (i.e. on first run, after manually clearing the db by running make clear-db
, or after modifying the scripts in the init
directory).
See the create.sql initialization script to see some brief notes for and the schemas of the tables used in this application. While most of them are fairly self-explanitory, we've added some additional notes for some of the tables below.
This table stores all events received from the transfer/event/sync endpoint. It stores the plaid_event_id,related transfer_id, type of event, timestamp and sweep_amount and sweep_id, if applicable. Transfer events can be mapped to either their associated transfer or a specific userId.
This table stores responses from the Plaid API for client requests to the Plaid Link client.
User flows that this table captures (based on the client implementation, which hooks into the onExit
and onSuccess
Link callbacks):
- User opens Link, closes without trying to connect an account.
This will have type
exit
but no request_id, error_type, or error_code. - User tries to connect an account, fails, and closes link.
This will have type
exit
and will have a request_id, error_type, and error_code. - User successfully connects an account.
This will have type
success
but no request_id, error_type, or error_code.
This table stores responses from the Plaid API for server requests to the Plaid client. The server stores the responses for all of the requests it makes to the Plaid API. Where applicable, it also maps the response to an item and user. If the request returned an error, the error_type and error_code columns will be populated.
This demo includes ngrok, a utility that creates a secure tunnel between your local machine and the outside world. We're using it here to expose the local webhooks endpoint to the internet.
Browse to localhost:4040 to see the ngrok dashboard. This will show any traffic that gets routed through the ngrok URL.
Do NOT use ngrok in production! It's only included here as a convenience for local development and is not meant to be a production-quality solution.
Don’t want to use ngrok? As long as you serve the app with an endpoint that is publicly exposed, all the Plaid webhooks will work.
ngrok's free account has a session limit of 2 hours. To fully test out some of the transaction webhook workflows, you will need to get a more persistent endpoint as noted above when using the Production environment.
This image is a copy of the Docker Hub image wernight/ngrok. We've copied it here to allow us to more closely version it and to make changes as needed.
- https://hub.docker.com/r/wernight/ngrok/dockerfile
- https://github.com/wernight/docker-ngrok/tree/202c4692cbf1bbfd5059b6ac56bece42e90bfb82
- For an overview of the Plaid platform and products, refer to this Quickstart guide.
- Check out this introduction to Transfer.
- Find comprehensive information on Plaid API endpoints in the API documentation.
- Questions? Please head to the Help Center or open a Support ticket.
Plaid Pattern is a demo app that is intended to be used only for the purpose of demonstrating how you can integrate with Plaid. You are solely responsible for ensuring the correctness, legality, security, privacy, and compliance of your own app and Plaid integration. The Pattern code is licensed under the MIT License and is provided as-is and without warranty of any kind. Plaid Pattern is provided for demonstration purposes only and is not intended for use in production environments.