Plaid Processor Token

Already using Plaid? Generate a processor token with your existing integration and hand it to Paynote to instantly create a verified bank funding source — no micro-deposits required.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

Add a Funding Source via Plaid Processor Token

Already using Plaid? Generate a processor token with your existing integration and pass it to Paynote to instantly add a verified bank account as a funding source.

📘

Who is this for?

Merchants who already have an active Plaid integration and want to connect their customers' bank accounts to Paynote without starting a separate bank verification flow.


How It Works

The flow spans three parties: your server, Plaid, and the Paynote API. Your customer authenticates their bank through Plaid Link, you exchange the resulting tokens on your server, then pass a single processor_token to Paynote.

StepWhoWhat happens
1Your serverCreate a link_token via Plaid
2Customer's browserLaunch Plaid Link → customer picks their bank account → returns public_token + account_id
3Your serverExchange public_token for access_token via Plaid
4Your serverCall Plaid /processor/token/create with processor: "paynote" → get processor_token
5Your serverPOST processor_token + user_id to Paynote → funding source created instantly as Verified

Before You Start

Make sure all of the following are in place before writing any code:

⚠️

Paynote must be enabled in your Plaid Dashboard

If Paynote is not enabled under Plaid's Integrations page, the /processor/token/create call will fail. This is the most common setup mistake — check this first if you get an error.


Step 1 — Create a link_token (your server)

Generate a short-lived link_token from your backend. This authenticates Plaid Link for your user's session. Call this every time a user opens the Link flow — tokens are one-time use.

const { Configuration, PlaidApi, PlaidEnvironments } = require('plaid');

const plaidClient = new PlaidApi(new Configuration({
  basePath: PlaidEnvironments[process.env.PLAID_ENV], // 'sandbox' or 'production'
  baseOptions: {
    headers: {
      'PLAID-CLIENT-ID': process.env.PLAID_CLIENT_ID,
      'PLAID-SECRET':    process.env.PLAID_SECRET,
      'Plaid-Version':   '2020-09-14',
    },
  },
}));

const response = await plaidClient.linkTokenCreate({
  user:          { client_user_id: 'your-internal-user-id' },
  client_name:   'Your App Name',
  products:      ['auth'],
  country_codes: ['US'],
  language:      'en',
});

const linkToken = response.data.link_token;
// Send linkToken to your frontend to launch Plaid Link

💡

Tip: Force single account selection

Set Account Select to "enabled for one account" in your Plaid Dashboard. This forces customers to select a single bank account so metadata.accounts in the onSuccess callback always has exactly one entry — no ambiguity about which account to use.


Step 2 — Launch Plaid Link (customer's browser)

Use the link_token from Step 1 to open the Plaid Link UI. When the customer authenticates and selects their account, onSuccess fires with a public_token and the selected account_id. Send both to your server.

<!-- Include the Plaid Link script -->
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>

<button id="connectBtn">Connect Bank Account</button>

<script>
  (async function () {
    // Fetch the link_token your server created in Step 1
    const { link_token } = await fetch('/create_link_token').then(r => r.json());

    const handler = Plaid.create({
      token: link_token,

      onSuccess: function(public_token, metadata) {
        const account_id = metadata.accounts[0].id;

        // Send both to your server to complete Steps 3 & 4
        fetch('/exchange_token', {
          method:  'POST',
          headers: { 'Content-Type': 'application/json' },
          body:    JSON.stringify({ public_token, account_id }),
        });
      },

      onExit: function(err, metadata) {
        if (err) console.error('Plaid Link error:', err);
      },
    });

    document.getElementById('connectBtn').onclick = () => handler.open();
  })();
</script>

Step 3 — Exchange tokens & create a processor_token (your server)

Receive the public_token and account_id from your frontend. Exchange the public_token for an access_token, then use both to generate a Paynote processor_token. Both API calls happen on your server — never expose your Plaid secret on the client.

async function createPaynoteProcessorToken(publicToken, accountId) {

  // 3a — Exchange public_token → access_token
  const tokenRes = await plaidClient.itemPublicTokenExchange({
    public_token: publicToken,
  });
  const accessToken = tokenRes.data.access_token;

  // 3b — Create a processor token scoped specifically to Paynote
  const processorRes = await plaidClient.processorTokenCreate({
    access_token: accessToken,
    account_id:   accountId,
    processor:    'paynote', // ← must be exactly "paynote" (lowercase)
  });

  return processorRes.data.processor_token;
  // → "processor-sandbox-0asd1-a92nc"
}

The processor value must be exactly "paynote"

The string must be "paynote" — all lowercase, no spaces. Any other value will cause Plaid to return an error and no token will be issued.


Step 4 — Send the processor_token to Paynote (your server)

POST the processor_token from Step 3 and the customer's Paynote user_id to the Paynote API. Paynote securely retrieves the bank account details from Plaid and creates a Verified funding source — no additional verification steps needed.

Endpoint

POST https://{env}-paynote.seamlesschex.com/v2/funding-source/processor/plaid

Environments

EnvironmentBase URL
Sandboxhttps://sandbox-paynote.seamlesschex.com
Productionhttps://paynote.seamlesschex.com

Request Body Parameters

ParameterTypeRequiredDescription
user_idstringRequiredThe Paynote customer ID to attach the bank account to
processor_tokenstringRequiredThe processor_token received from Plaid in Step 3

Example Request

curl -X POST https://sandbox-paynote.seamlesschex.com/v2/funding-source/processor/plaid \
  -H "Authorization: Bearer YOUR_PAYNOTE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id":         "usr_abc123",
    "processor_token": "processor-sandbox-0asd1-a92nc"
  }'
const response = await fetch(
  'https://sandbox-paynote.seamlesschex.com/v2/funding-source/processor/plaid',
  {
    method:  'POST',
    headers: {
      'Authorization': 'Bearer YOUR_PAYNOTE_API_KEY',
      'Content-Type':  'application/json',
    },
    body: JSON.stringify({
      user_id:         'usr_abc123',
      processor_token: 'processor-sandbox-0asd1-a92nc',
    }),
  }
);

const data = await response.json();
// data.funding_source_id → use this for future payments
import requests

response = requests.post(
    'https://sandbox-paynote.seamlesschex.com/v2/funding-source/processor/plaid',
    headers={
        'Authorization': 'Bearer YOUR_PAYNOTE_API_KEY',
        'Content-Type':  'application/json',
    },
    json={
        'user_id':         'usr_abc123',
        'processor_token': 'processor-sandbox-0asd1-a92nc',
    }
)

data = response.json()
# data['funding_source_id'] → use this for future payments

Success Response

{
  "success":           true,
  "funding_source_id": "fs_123abc",
  "status":            "Verified",
  "bank_name":         "Bank of America",
  "last_four":         "4321"
}

👍

The funding source is immediately ready

A status: "Verified" response means the bank account is instantly ready for ACH debits and credits. No micro-deposit confirmation or additional steps required. Save the funding_source_id — you'll use it on all future payment requests for this customer.


Testing in Sandbox

Use Plaid's Sandbox test credentials when launching Link with a link_token created against PlaidEnvironments.sandbox, and use https://sandbox-paynote.seamlesschex.com as your Paynote base URL.

Shortcut — bypass the Link UI during testing:
Instead of running the full Link flow, call Plaid's /sandbox/public_token/create endpoint directly to get a public_token. Note: when using this shortcut, the accounts array won't be populated. Call /accounts/get to retrieve a checking or savings account ID to use in Step 3.

Log in to the Paynote Sandbox Dashboard to inspect test funding sources and verify results end-to-end.


Going to Production

  1. Request Production access in your Plaid Dashboard
  2. Obtain your Paynote Production API key — contact [email protected] if you don't have one
  3. Switch Plaid's basePath from PlaidEnvironments.sandboxPlaidEnvironments.production
  4. Switch your Paynote base URL from sandbox-paynote.seamlesschex.compaynote.seamlesschex.com

Error Reference

ErrorLikely CauseResolution
invalid_processor_tokenToken already used, expired, or malformedRe-run the Plaid Link flow to generate a new token
customer_not_founduser_id does not exist in PaynoteCreate the customer first
unauthorizedMissing or invalid Paynote API keyCheck the Authorization: Bearer header
processor_not_enabledPaynote not enabled in Plaid DashboardEnable Paynote under Plaid Dashboard → Developers → Integrations

For errors from Plaid during token creation, see the Plaid error codes reference.


Important Notes

Processor tokens are single-use and account-scoped.
Each processor_token is tied to one Plaid item and one bank account. Once submitted to Paynote it cannot be reused. If you need to re-link an account, initiate a new Plaid Link flow.

Tokens can become invalid.
A processor token stops working if the customer revokes their Plaid connection, the Plaid item requires re-authentication, or the financial institution is disabled. If Paynote returns an invalid_processor_token error after a previously working integration, prompt the customer to reconnect via Plaid Link.

Set up webhooks.
Configure a webhook listener to receive real-time funding source status events. See Funding Source Webhooks for the full event reference.


Resources

Body Params
string
required
string
required
Headers
string
enum
Defaults to application/json

Generated from available request content types

Allowed:
Language
Credentials
Header
URL
LoadingLoading…
Response
Click Try It! to start a request and see the response here!