Dwolla + Plaid ACH

This guide walks you through how to set up ACH payments using Dwolla with instant bank account verification using Plaid.

Dwolla allows you to send ACH payments from any US bank account to any other, so it works for user-to-user, user-to-app, or app-to-user payments.

Security requirements

As part of Dwolla security check, the client will have to fill out a questionnaire similar to this. One thing to note is that as of June 2020 the way that Bubble hashes passwords isn't acceptable by Dwolla standards, so their integration will require using Google/Facebook/other Oauth service, combined with a separate two factor verification built into the Bubble app.

Demo

You can see the demo of the functionality on this page and the read-only editor here

High-level app flow

  1. User creates an account in Bubble - either verified or unverified

  2. User creates an account in Dwolla and stores the account ID on their Bubble account

  3. User uses Plaid to add their bank account to Dwolla and stores the bank account details in Bubble

  4. User initiates a transfer from one bank account to another bank account in Dwolla

  5. Dwolla notifies Bubble of various status updates through webhooks and Bubble sends notification emails based on those webhooks

Preliminary set-up

Dwolla account

Create a sandbox account here.

Plaid account

Create an account here. Then go to Account > Integrations and turn on the Dwolla integration.

API calls

Copy in the API Connector configurations from here to your app. The 3 configurations are:

  1. Dwolla Authentication - used to generate a temporary token that's used to perform Dwolla API calls

    1. You should update the [token] value in the Authorization: Basic [token] header. The value is "[client_id]:[client_secret]" with base 64 encoding applied to it - you can use this tool to encode it

  2. Dwolla - used to make Dwolla API calls

  3. Plaid - used to make Plaid API calls

    1. You should update the client id and client secret with yours

Plaid Link is Plaid's tool that is used to easily connect user's bank account to Dwolla. To initialize it you'll need to place an HTML element with the following code somewhere on the page on which you want to start the Plaid flow. You can place it in a reuseable element (like the header) if you want to be able to start this flow from multiple pages.

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

User flows set-up

User registration

Before Dwolla transfers can occur, the user should be registered in Dwolla's system. Assuming a personal account, there are 2 types of registration: verified and unverified. Unverified registration requires only a few pieces of information while verified registration requires more information (and can get rejected). In any transaction, at least 1 user (either sender or recipient) should be verified, the other can be unverified.

To register the user with Dwolla, just run one of the two Dwolla registration API calls - either verified or unverified. A few notes about this:

  • The base URL will likely be either https://api-sandbox.dwolla.com or https://api.dwolla.com. Best practice is to create a field on the Website object and link this input to that field, so that the base URL can easily be updated and can vary across version-test and version-live

  • For Authorization, the format should be "Bearer [token]" where [token] is the result of running the Dwolla Authentication API call

  • Dwolla results are returned in the header of the request (instead of the body, like usual). The "location" field will return the ID/URL of the user, which should be stored on the User Object in Bubble.

Adding a bank account

After the user is registered, you can use Plaid to add a bank account to their Dwolla account. To start, you'll need to open Plaid Link by running the following code using Toolbox Run Javascript action:

var linkHandler = Plaid.create({
env: 'sandbox',
apiVersion: 'v2',
clientName: 'Stripe/Plaid Test',
key: '4a56d2de92db147dc4505db7167dcf',
product: 'auth',
selectAccount: true,
onSuccess: function(public_token, metadata) {
// Send the public_token and account ID to your app server.
bubble_fn_account_id(metadata.accounts[0].id);
bubble_fn_account_name(metadata.accounts[0].name);
bubble_fn_account_mask(metadata.accounts[0].mask);
bubble_fn_account_type(metadata.accounts[0].type);
bubble_fn_account_subtype(metadata.accounts[0].subtype);
bubble_fn_institution_name(metadata.institution.name);
bubble_fn_token(public_token);
},
onExit: function(err, metadata) {
// The user exited the Link flow.
if (err != null) {
// The user encountered a Plaid API error prior to exiting.
}
},
});
linkHandler.open();

Here are the changes you should make in the code above:

  • Make the environment variable be whatever environment you're using in Plaid. Just like with the Dwolla base URL it's a good practice to make this dynamic and store it on the Website object, so it's easy to update later

  • Update the key with your key from Plaid

  • Update all of the bubble_fn.... names with the names of the Javascript to Bubble elements that you place on the page (or in a reuseable)

    • This is how Plaid Link will pass information for the connected bank account back to Bubble

When using Plaid Link in Sandbox mode you can use "user_good" and "pass_good" to connect to a bank account in any bank.

When Plaid Link is finished running, it will pass the bank account values to the JavaScript to Bubble elements, as shown above.

Linking the account to Dwolla

Once Plaid Link has passed the above information to Bubble, it's time to send it to Dwolla. Here's the process for doing that:

  1. Make an API call to Plaid to exchange the Public Token for an Access Token

  2. Make an API call to Plaid to exchange the Access token for Dwolla tokken

  3. Make an API call to Dwolla to send the Dwolla token to the Dwolla account, this will return the new "funding-source" created in Dwolla

  4. Save the Dwolla funding source ID in Bubble, along with a few other fields originally returned by Plaid (institution name, account type, etc.)

Note that if the user has previously added a bank account to Dwolla, you should remove it first before adding a new one.

Initiating a payment

One of the API calls included allows you to initiate a payment from one funding source to another funding source. Just like the other calls, it will return the ID of the created payment in the "location" field of the response's headers.

When running the call the "Idempotency-Key" header should be set to a unique value, such as the Bubble unique ID of the Payment object for which this payment is being executed. This prevents the transaction from accidentally being executed twice as Dwolla will block it if the key is not unique.

Email notifications

Dwolla used to require setting up webhooks and email notifications for various actions that happen within the system. However their new set up takes care of those for us automatically.

Dwolla customer verification process

Each transaction in Dwolla needs to have at least one "verified" user. There are a few different types of users in Dwolla (here), and they have different transfer limits and onboarding processes. Business accounts are more onerous since you need to verify both the business and the business owner.

Here is a doc that covers how to use the API to run the user authentication process. Note: this involves a process for handling errors/retries if the information provided doesn't work the first time.