Add Dwolla to your app 
=======================

#### Use Dwolla with Plaid Auth to send and receive payments 

(An image of "Plaid and Dwolla logos, side by side.")

  

Plaid and Dwolla have partnered to offer businesses an easier way to connect to the U.S. banking system. Plaid enables businesses to instantly authenticate a customer's bank account, giving them the ability to leverage the Dwolla API to connect to the ACH or RTP® networks for sending and receiving payments. Dwolla's solution offers frictionless ACH or real-time payments for companies looking to automate their current payments process and scale their business.

With the Plaid + Dwolla integration, your users can verify their accounts in seconds by inputting their banking credentials in Plaid's front-end module. Plaid's mobile-friendly module handles input validation, error handling, and multi-factor authentication–providing a seamless onboarding experience to convert more users for your business.

As part of the integration, Dwolla customers can access Plaid's full suite of APIs for clean, categorized transaction data, real-time balances, and more.

#### Getting started 

You'll first want to familiarize yourself with [Plaid Link](https://plaid.com/docs/link/index.html.md) , a drop-in client-side integration for the Plaid API that handles input validation, error handling, and multi-factor authentication.

Your customers will use Link to authenticate with their financial institution and select the depository account they wish to use for ACH or RTP® transactions. From there, you'll receive a Plaid `access_token`, allowing you to leverage real-time balance checks and transaction data, and a Dwolla `processor_token`, which allows you to quickly and securely verify a bank funding source via [Dwolla's API](https://www.dwolla.com/?utm_campaign=Plaid-Documentation&utm_source=Plaid&utm_medium=Referral) without having to store any sensitive banking information. Utilizing Plaid + Dwolla enables a seamless workflow for sending and receiving payments.

As a complement to this guide, you can also use [Dwolla's guide to integrating with Plaid](https://developers.dwolla.com/docs/secure-exchange/plaid) .

#### Instructions 

##### Set up your Plaid and Dwolla accounts 

You'll need accounts at both Plaid and Dwolla in order to use the Plaid + Dwolla integration. You'll also need to be a Dwolla customer in order to add a bank funding source.

First, [sign up for a Dwolla account](https://accounts.dwolla.com/sign-up/pay-as-you-go?utm_campaign=Plaid-Documentation&utm_source=Plaid&utm_medium=Referral) if you don't already have one.

Next, verify that your Plaid account is enabled for the integration. If you do not have a Plaid account, [create one](https://dashboard.plaid.com/signup/dwolla) . Your account will be automatically enabled for integration access.

To verify that your Plaid account is enabled for the integration, go to the [Integrations](https://dashboard.plaid.com/developers/integrations) section of the account dashboard. If the integration is off, simply click the 'Enable' button for Dwolla to enable the integration.

Use the [Dwolla Sandbox](https://developers.dwolla.com/docs/testing) to test the Plaid + Dwolla integration for free.

##### Complete your Plaid application profile and company profile 

After connecting your Plaid and Dwolla accounts, you'll need to complete your Plaid [application profile](https://dashboard.plaid.com/settings/company/app-branding) and [company profile](https://dashboard.plaid.com/settings/company/profile) in the Dashboard, which involves filling out basic information about your app, such as your company name and website. This step helps your end-users learn more about how your product uses their bank information and is also required for connecting to some banks.

##### Create a link\_token 

In order to integrate with Plaid Link, you will first need to create a `link_token`. A `link_token` is a short-lived, one-time use token that is used to authenticate your app with Link. To create one, make a [/link/token/create](https://plaid.com/docs/api/link/index.html.md#linktokencreate) request with your `client_id`, `secret`, and a few other required parameters from your app server. View the [/link/token/create](https://plaid.com/docs/api/link/index.html.md#linktokencreate) documentation for a full list of `link_token` configurations.

To see your `client_id` and `secret`, visit the [Plaid Dashboard](https://dashboard.plaid.com/developers/keys) .

```node
app.post('/api/create_link_token', async function (request, response) {
  // Get the client_user_id by searching for the current user
  const user = await User.find(...);
  const clientUserId = user.id;
  const linkTokenRequest = {
    user: {
      // This should correspond to a unique id for the current user.
      client_user_id: clientUserId,
    },
    client_name: 'Plaid Test App',
    products: ['auth'],
    language: 'en',
    webhook: 'https://webhook.example.com',
    redirect_uri: 'https://domainname.com/oauth-page.html',
    country_codes: ['US'],
  };
  try {
    const createTokenResponse = await client.linkTokenCreate(linkTokenRequest);
    response.json(createTokenResponse.data);
  } catch (error) {
    // handle error
  }
});

```

```bash
curl -X POST https://sandbox.plaid.com/link/token/create \
-H 'Content-Type: application/json' \
-d '{
  "client_id": "${PLAID_CLIENT_ID}",
  "secret": "${PLAID_SECRET}",
  "client_name": "Plaid Test App",
  "user": { "client_user_id": "${UNIQUE_USER_ID}" },
  "products": ["auth"],
  "country_codes": ["US"],
  "language": "en",
  "webhook": "https://webhook.example.com",
  "redirect_uri": "https://domainname.com/oauth-page.html"
}'

```

```ruby
post '/api/create_link_token' do
  # Get the client_user_id by searching for the current user
  current_user = User.find(...)
  client_user_id = current_user.id

  # Create a link_token for the given user
  request = Plaid::LinkTokenCreateRequest.new(
    {
      user: { client_user_id: client_user_id },
      client_name: 'Plaid Test App',
      products: ['auth'],
      country_codes: ['US'],
      language: "en",
      redirect_uri: nil_if_empty_envvar('PLAID_REDIRECT_URI'),
      webhook: 'https://webhook.example.com'
    }
  )
  response = client.link_token_create(request)
  content_type :json
  response.to_json
end

```

```java
import com.plaid.client.model.Products;
import com.plaid.client.model.CountryCode;
import com.plaid.client.model.LinkTokenCreateRequest;
import com.plaid.client.model.LinkTokenCreateRequestUser;
import com.plaid.client.model.LinkTokenCreateResponse;

public class PlaidExample {

  ...
  static class GetLinkToken implements HttpHandler {
    private static PlaidApi plaidClient;

    public void handle(HttpExchange t) throws IOException {
      // Create your Plaid client
      HashMap apiKeys = new HashMap();
      apiKeys.put("clientId", CLIENT_ID);
      apiKeys.put("secret", SECRET);
      ApiClient apiClient = new ApiClient(apiKeys);
      apiClient.setPlaidAdapter(ApiClient.Sandbox);

      plaidClient = apiClient.createService(PlaidApi.class);

      // Get the clientUserId by searching for the current user
      User userFromDB = db.find(...);
      String clientUserId = userFromDB.id;
      LinkTokenCreateRequestUser user = new LinkTokenCreateRequestUser()
        .clientUserId(clientUserId);

      // Create a link_token for the given user
      LinkTokenCreateRequest request = new LinkTokenCreateRequest()
        .user(user)
        .clientName("Plaid Test App")
        .products(Arrays.asList(Products.fromValue("auth")))
        .countryCodes(Arrays.asList(CountryCode.US))
        .language("en")
        .redirectUri("https://domainname.com/oauth-page.html")
        .webhook("https://webhook.example.com");

      Response response = plaidClient
        .linkTokenCreate(request)
        .execute();

      // Send the data to the client
      return response.body();
    }
  }
}

```

```python
from plaid.model.link_token_create_request import LinkTokenCreateRequest
from plaid.model.link_token_create_request_user import LinkTokenCreateRequestUser
from plaid.model.products import Products
from plaid.model.country_code import CountryCode

@app.route("/create_link_token", methods=['POST'])
def create_link_token():
    # Get the client_user_id by searching for the current user
    user = User.find(...)
    client_user_id = user.id

    # Create a link_token for the given user
    request = LinkTokenCreateRequest(
            products=[Products("auth")],
            client_name="Plaid Test App",
            country_codes=[CountryCode('US')],
            redirect_uri='https://domainname.com/oauth-page.html',
            language='en',
            webhook='https://webhook.example.com',
            user=LinkTokenCreateRequestUser(
                client_user_id=client_user_id
            )
        )
    response = client.link_token_create(request)

    # Send the data to the client
    return jsonify(response.to_dict())


```

```go
func createLinkToken(c *gin.Context) {
  ctx := context.Background()

  // Get the client_user_id by searching for the current user
  user, _ := usermodels.Find(...)
  clientUserId := user.ID.String()

  // Create a link_token for the given user
  request := plaid.NewLinkTokenCreateRequest("Plaid Test App", "en", []plaid.CountryCode{plaid.COUNTRYCODE_US}, *plaid.NewLinkTokenCreateRequestUser(clientUserId))
  request.SetWebhook("https://webhook.sample.com")
  request.SetRedirectUri("https://domainname.com/oauth-page.html")
  request.SetProducts([]plaid.Products{plaid.PRODUCTS_AUTH})

  resp, _, err := testClient.PlaidApi.LinkTokenCreate(ctx).LinkTokenCreateRequest(*request).Execute()

  // Send the data to the client
  c.JSON(http.StatusOK, gin.H{
    "link_token": resp.GetLinkToken(),
  })
}


```

##### Integrate with Plaid Link 

Once you have a `link_token`, all it takes is a few lines of client-side JavaScript to launch Link. Then, in the `onSuccess` callback, you can call a simple server-side handler to exchange the Link `public_token` for a Plaid `access_token` and a Dwolla `processor_token`.

Integrate Link

```javascript
<button id="linkButton">Open Link - Institution Select</button>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
<script>
  (async function(){
    var linkHandler = Plaid.create({
      // Make a request to your server to fetch a new link_token.
      token: (await $.post('/create_link_token')).link_token,
      onLoad: function() {
          // The Link module finished loading.
      },
      onSuccess: function(public_token, metadata) {
        // The onSuccess function is called when the user has
        // successfully authenticated and selected an account to
        // use.
        //
        // When called, you will send the public_token and the selected accounts,
        // metadata.accounts, to your backend app server.

        sendDataToBackendServer({
           public_token: public_token,
           accounts: metadata.accounts
        });
        console.log('Public Token: ' + public_token);
        console.log('Customer-selected account ID: ' + metadata.accounts[0].id);
      },
      onExit: function(err, metadata) {
        // The user exited the Link flow.
        if (err != null) {
            // The user encountered a Plaid API error
            // prior to exiting.
        }
        // metadata contains information about the institution
        // that the user selected and the most recent
        // API request IDs.
        // Storing this information can be helpful for support.
      },
    });
  })();

  // Trigger the authentication view
  document.getElementById('linkButton').onclick = function() {
    linkHandler.open();
  };
</script>
```

See the [Link parameter reference](https://plaid.com/docs/link/web/index.html.md#create) for complete documentation on possible configurations.

`Plaid.create` accepts one argument, a configuration `Object`, and returns an `Object` with three functions, [open](https://plaid.com/docs/link/web/index.html.md#open) , [exit](https://plaid.com/docs/link/web/index.html.md#exit) , and [destroy](https://plaid.com/docs/link/web/index.html.md#destroy) . Calling `open` will display the "Institution Select" view, calling `exit` will close Link, and calling `destroy` will clean up the iframe.

##### Write server-side handler 

The Link module handles the entire onboarding flow securely and quickly, but does not actually retrieve account data for a user. Instead, the Link module returns a `public_token` and an `accounts` array, which is a property on the `metadata` object, via the `onSuccess` callback. Exchange this `public_token` for a Plaid `access_token` using the [/item/public\_token/exchange](https://plaid.com/docs/api/items/index.html.md#itempublic_tokenexchange) API endpoint.

The `accounts` array will contain information about bank accounts associated with the credentials entered by the user, and may contain multiple accounts if the user has more than one bank account at the institution. In order to avoid any confusion about which account your user wishes to use with Dwolla, it is recommended to set [Account Select](https://dashboard.plaid.com/link/account-select) to "enabled for one account" in the Plaid Dashboard. When this setting is selected, the `accounts` array will always contain exactly one account.

Once you have identified the account you will use, you will send the `account_id` property of the account to Plaid, along with the `access_token`, to create a Dwolla `processor_token`. You'll send this token to Dwolla and they will use it to securely retrieve account and routing numbers from Plaid.

```bash
# Exchange the public token from Plaid Link for an access token.
curl \
  -H 'Content-Type: application/json' \
  -d '{
    "client_id": "${PLAID_CLIENT_ID}",
    "secret": "${PLAID_SECRET}",
    "public_token": "${PUBLIC_TOKEN}"
  }' \
  -X POST \
  https://sandbox.plaid.com/item/public_token/exchange

# Create a processor token for a specific account id.
curl \
  -H 'Content-Type: application/json' \
  -d '{
    "client_id": "${PLAID_CLIENT_ID}",
    "secret": "${PLAID_SECRET}",
    "access_token": "${ACCESS_TOKEN}",
    "account_id": "${ACCOUNT_ID}",
    "processor": "dwolla"
  }' \
  -X POST \
  https://sandbox.plaid.com/processor/token/create

```

```java
import com.plaid.client.model.ItemPublicTokenExchangeRequest;
import com.plaid.client.model.ItemPublicTokenExchangeResponse;
import com.plaid.client.model.ProcessorTokenCreateRequest;
import com.plaid.client.model.ProcessorTokenCreateResponse;

// Change sandbox to production when you're ready to go live!
HashMap apiKeys = new HashMap();
apiKeys.put("clientId", plaidClientId);
apiKeys.put("secret", plaidSecret);
apiKeys.put("plaidVersion", "2020-09-14");
apiClient = new ApiClient(apiKeys);
apiClient.setPlaidAdapter(ApiClient.Sandbox);

plaidClient = apiClient.createService(PlaidApi.class);

// Exchange the public token from Plaid Link for an access token.
ItemPublicTokenExchangeRequest request = new ItemPublicTokenExchangeRequest()
  .publicToken(publicToken);

Response exchangeResponse = client()
  .itemPublicTokenExchange(request)
  .execute();

// Create a processor token for a specific account id.
if (exchangeResponse.isSuccessful()) {
  String accessToken = exchangeResponse.body().getAccessToken();
  ProcessorTokenCreateRequest processorRequest = new ProcessorTokenCreateRequest()
    .accessToken(accessToken)
    .processor("dwolla")
    .accountId("FooBarAccountId");

  Response dwollaResponse = client()
    .processorTokenCreate(processorRequest)
    .execute();

    if (dwollaResponse.isSuccessful()) {
      String dwollaProcessorToken = dwollaResponse.body().getProcessorToken();
    }
}

```

```ruby
require 'plaid'

# Change sandbox to production when you're ready to go live!
configuration = Plaid::Configuration.new
configuration.server_index = Plaid::Configuration::Environment[ENV['PLAID_ENV'] || 'sandbox']
configuration.api_key['PLAID-CLIENT-ID'] = ENV['PLAID_CLIENT_ID']
configuration.api_key['PLAID-SECRET'] = ENV['PLAID_SECRET']
configuration.api_key['Plaid-Version'] = '2020-09-14'

api_client = Plaid::ApiClient.new(
  configuration
)

client = Plaid::PlaidApi.new(api_client)

# Exchange the public token from Plaid Link for an access token.
item_public_token_exchange_request = Plaid::ItemPublicTokenExchangeRequest.new
item_public_token_exchange_request.public_token = public_token

exchange_token_response = client.item_public_token_exchange(item_public_token_exchange_request)

access_token = exchange_token_response.access_token

# Create a processor token for a specific account id.
processor_token_create_request = Plaid::ProcessorTokenCreateRequest.new
processor_token_create_request.access_token = access_token
processor_token_create_request.account_id = account_id
processor_token_create_request.processor = "dwolla"

create_response = client.processor_token_create(processor_token_create_request)
processor_token = create_response.processor_token

```

```python
import plaid
from plaid.api import plaid_api
from plaid.model.item_public_token_exchange_request import ItemPublicTokenExchangeRequest
from plaid.model.processor_token_create_request import ProcessorTokenCreateRequest

# Change sandbox to production when you're ready to go live!
configuration = plaid.Configuration(
    host=plaid.Environment.Sandbox,
    api_key={
        'clientId': PLAID_CLIENT_ID,
        'secret': PLAID_SECRET,
        'plaidVersion': '2020-09-14'
    }
)
api_client = plaid.ApiClient(configuration)
client = plaid_api.PlaidApi(api_client)

# Exchange the public token from Plaid Link for an access token.
exchange_request = ItemPublicTokenExchangeRequest(public_token=public_token)
exchange_token_response = client.item_public_token_exchange(exchange_request)
access_token = exchange_token_response['access_token']

# Create a processor token for a specific account id.
create_request = ProcessorTokenCreateRequest(
    access_token=access_token,
    account_id=account_id,
    processor='dwolla'
)
create_response = client.processor_token_create(create_request)
processor_token = create_response['processor_token']

```

```node
const {
  Configuration,
  PlaidApi,
  PlaidEnvironments,
  ProcessorTokenCreateRequest,
} = require('plaid');
// Change sandbox to production when you're ready to go live!
const configuration = new Configuration({
  basePath: PlaidEnvironments[process.env.PLAID_ENV],
  baseOptions: {
    headers: {
      'PLAID-CLIENT-ID': process.env.PLAID_CLIENT_ID,
      'PLAID-SECRET': process.env.PLAID_SECRET,
      'Plaid-Version': '2020-09-14',
    },
  },
});

const plaidClient = new PlaidApi(configuration);

try {
  // Exchange the public_token from Plaid Link for an access token.
  const tokenResponse = await plaidClient.itemPublicTokenExchange({
    public_token: publicToken,
  });
  const accessToken = tokenResponse.data.access_token;

  // Create a processor token for a specific account id.
  const request: ProcessorTokenCreateRequest = {
    access_token: accessToken,
    account_id: accountID,
    processor: 'dwolla',
  };
  const processorTokenResponse = await plaidClient.processorTokenCreate(
    request,
  );
  const processorToken = processorTokenResponse.data.processor_token;
} catch (error) {
  // handle error
}

```

```go
import (
  "context"
  "os"

  plaid "github.com/plaid/plaid-go/v42/plaid"
)

// create the client
configuration := plaid.NewConfiguration()
configuration.AddDefaultHeader("PLAID-CLIENT-ID", os.Getenv("CLIENT_ID"))
configuration.AddDefaultHeader("PLAID-SECRET", os.Getenv("SECRET"))
configuration.UseEnvironment(plaid.Sandbox)

// exchange the public_token for an access_token
exchangePublicTokenResp, _, err := client.PlaidApi.ItemPublicTokenExchange(ctx).ItemPublicTokenExchangeRequest(
  *plaid.NewItemPublicTokenExchangeRequest("PUBLIC_TOKEN"),
).Execute()
accessToken := exchangePublicTokenResp.GetAccessToken()

// get the account id
accountsResp, _, err := client.PlaidApi.AccountsGet(ctx).AccountsGetRequest(plaid.AccountsGetRequest{
  AccessToken: accessToken,
}).Execute()
accountID := accountsResp.GetAccounts()[0].GetAccountId()

// create a dwolla token for the specific account id
request := plaid.NewProcessorTokenCreateRequest(accessToken, accountID, "dwolla")
processorTokenResp, _, err := client.PlaidApi.ProcessorTokenCreate(ctx).ProcessorTokenCreateRequest(
  *request,
).Execute()

```

For a valid request, the API will return a JSON response similar to:

```json
{
  "processor_token": "processor-sandbox-0asd1-a92nc",
  "request_id": "[Unique request ID]"
}
```

##### Make a request to Dwolla 

Once you've obtained the `processor_token`, you'll then pass it to Dwolla as the value of the `plaidToken` request parameter, along with a funding source `name`, to create a funding source for a Dwolla Customer:

```bash
POST https://api-sandbox.dwolla.com/customers/AB443D36-3757-44C1-A1B4-29727FB3111C/funding-sources
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

{
  "plaidToken": "processor-sandbox-161c86dd-d470-47e9-a741-d381c2b2cb6f",
  "name": "Jane Doe's Checking"
}

...

HTTP/1.1 201 Created
Location: https://api-sandbox.dwolla.com/funding-sources/375c6781-2a17-476c-84f7-db7d2f6ffb31
```

Once you've received a successful response from the Dwolla API, you'll use the unique funding source URL to identify the Customer's bank when [initiating ACH](https://docs.dwolla.com/#initiate-a-transfer?utm_campaign=Plaid-Documentation&utm_source=Plaid&utm_medium=Referral) or [RTP transfers](https://developers.dwolla.com/concepts/real-time-payments#real-time-payments?utm_campaign=Plaid-Documentation&utm_source=Landing-Page&utm_medium=Referral) .

##### Testing your Dwolla integration 

You can create Dwolla `processor_tokens` in Sandbox (sandbox.plaid.com, allows testing with simulated users) or Production (production.plaid.com, requires Dwolla Production credentials).

To test the integration in Sandbox mode, simply use the Plaid [Sandbox credentials](https://plaid.com/docs/sandbox/test-credentials/index.html.md) when launching Link with a `link_token` created in the Sandbox environment.

When testing in the Sandbox, you have the option to use the [/sandbox/public\_token/create](https://plaid.com/docs/api/sandbox/index.html.md#sandboxpublic_tokencreate) endpoint instead of the end-to-end Link flow to create a `public_token`. When using the [/sandbox/public\_token/create](https://plaid.com/docs/api/sandbox/index.html.md#sandboxpublic_tokencreate) \-based flow, the Account Select flow will be bypassed and the `accounts` array will not be populated. On Sandbox, instead of using the `accounts` array, you can call [/accounts/get](https://plaid.com/docs/api/accounts/index.html.md#accountsget) and test with any returned account ID associated with an account with the subtype `checking` or `savings`.

##### Get ready for production 

Your account is immediately enabled for our Sandbox environment ([https://sandbox.plaid.com](https://sandbox.plaid.com) ). To move to Production, please request access from the [Dashboard](https://dashboard.plaid.com/developers/keys) .

#### Example code in Plaid Pattern 

For a real-life example of an app that incorporates the creation of processor tokens, see the Node-based [Plaid Pattern Account Funding](https://github.com/plaid/pattern-account-funding) sample app. Pattern Account Funding is a sample account funding app that creates a processor token to send to your payment partner. The processor token creation code can be found in [items.js](https://github.com/plaid/pattern-account-funding/blob/master/server/routes/items.js#L126-L135) .

For a tutorial walkthrough of creating a similar app with Dwolla support, see [Account funding tutorial](https://github.com/plaid/account-funding-tutorial) .

#### Support and questions 

Find answers to many common integration questions and concerns—such as pricing, sandbox and test mode usage, and more, in our [docs](https://plaid.com/docs/index.html.md) .

If you're still stuck, open a [support ticket](https://dashboard.plaid.com/support/new) with information describing the issue that you're experiencing and we'll get back to you as soon as we can.