_Docs/
Get StartedModulesPlatformDeployCookbookChangelogReference
_Stack
_Modules
  • Ledger
  • Numscript
  • Connectivity
    • Capabilities
    • Operations
    • Accounts
    • Payments
    • Orders
    • Conversions
    • Payment Initiation
    • Account Pools
    • Payment Service Users
    • Connectors
      • Generic Connector
        • Getting Started
        • How it Works
      • PSP Connectors
        • Adyen
        • Atlar
        • Banking Circle
        • Column
        • Currencycloud
        • Increase
        • Mangopay
        • Modulr
        • Moneycorp
        • Qonto
        • Stripe
        • Wise
        • Banking BridgeEE
        • RoutableEE
      • Exchange Connectors
        • Coinbase PrimeEE
        • FireblocksEE
        • BitstampEE
      • Open Banking
        • Getting Started with Open Banking
        • Plaid
        • Tink
        • Powens
      • Build a connector
  • WalletsEE
  • FlowsEE
  • ReconciliationEE
  1. Modules
  2. Connectivity
  3. Connectors
  4. Open Banking
  5. Plaid
Plaid
Open Banking

Plaid

Connect Plaid to Formance Connectivity to let end users link their bank accounts and sync the resulting accounts, balances, and transactions.

The Plaid connector links Formance to Plaid's bank-aggregation platform. It drives the Open Banking PSU flow: create a Payment Service User, forward them to Plaid, hand them a Plaid Link session, and sync the resulting accounts, balances, and transactions back through Connectivity. Available from Payments 3.2.0.

Prerequisites#

You need a Plaid account and a clientID + clientSecret pair. The key needs access to Auth, Transactions, and Identity at minimum (set products on the Plaid dashboard before issuing the key).

Plaid signs every webhook with a JWT verified against Plaid's public key — no shared secret to configure.

Make sure to create an API key dedicated to Formance. Doing so will improve your auditability and security and will allow you to revoke access to Formance at any time if needed.

Installation#

curl -X POST $FORMANCE_API_URL/api/payments/v3/connectors/install/plaid \
  -H "Content-Type: application/json" \
  -d @config.json
POST/api/payments/v3/connectors/install/plaid

Configuration fields#

FieldTypeRequiredDefault
clientIDstringYes
clientSecretstringYes
isSandboxbooleanNo
pageSizeintegerNo25
pollingPeriodstringNo30m

isSandbox: true flips to Plaid's sandbox host (https://sandbox.plaid.com); production uses https://production.plaid.com. No separate "development" environment.

Capabilities#

  • FETCH_ACCOUNTS — depository, credit, and loan accounts per PSU connection.
  • FETCH_BALANCES — available + current balance via Plaid's /accounts/balance/get.
  • FETCH_EXTERNAL_ACCOUNTS — counterparty accounts identified by Plaid's Transfer product when present.
  • FETCH_PAYMENTS — transactions via Plaid's incremental /transactions/sync cursor.
  • CREATE_WEBHOOKS + TRANSLATE_WEBHOOKS — webhooks per Item (Plaid's connection primitive), provisioned on link.

The connector doesn't initiate transfers or payouts — Plaid's Transfer product is read-only here. Use a PSP connector (Stripe, Increase) for outbound flows.

Account model#

Every Connectivity internal account is one Plaid Account on a linked Item (depository, credit, or loan). The reference is the Plaid account_id; name is the Plaid account name; defaultAsset is the account's ISO currency at standard precision. Each account is PSU-scoped — psuID carries the Connectivity PSU and openBankingConnectionID carries the Plaid Item. EXTERNAL accounts come from Plaid's Transfer product when present. See Accounts for the cross-connector model.

Linking a user#

Plaid's auth ceremony runs through Plaid Link. The Connectivity surface:

  1. Create a PSU — v3CreatePaymentServiceUser returns a PSU ID.
  2. Forward to Plaid — v3ForwardPaymentServiceUserToProvider calls /link/token/create and stores the link_token as PSU metadata.
  3. Create a Link session — v3CreateLinkForPaymentServiceUser returns a public Link URL + attemptID.
  4. Frontend redirect — the user picks a bank, authenticates, and lands on your clientRedirectURL.
  5. Item-creation webhook — the connector exchanges the public_token for an access_token and stores it on the connection.

Step-by-step walkthrough on the Open Banking Getting Started guide.

Redirect URL requirements#

  • HTTPS in production.
  • Registered in the Plaid dashboard under Developers → API → Allowed redirect URIs before issuing a Link token targeting it. The connector doesn't auto-register; mismatches surface as INVALID_OAUTH_STATE_PARAMETER at the Link step.
  • Mobile apps must use Plaid's universal-link patterns (iOS, Android). The connector returns the URL unchanged — universal-link routing is a frontend concern.

Asset model#

Multi-currency, formatted to UMN at ISO 4217 precision (USD/2, EUR/2, GBP/2). Amounts arrive as decimal strings; the connector applies major-to-minor scaling.

Status mapping#

Plaid transactions are non-stateful — Plaid surfaces them only after they post, so the connector emits each as SUCCEEDED. The pending flag maps to PENDING until Plaid clears it and the row's pending_transaction_id is replaced by a permanent transaction_id; at that point the connector swaps the reference and moves the row to SUCCEEDED.

Metadata keys#

Under com.plaid.spec/:

  • Account: account_id, mask (account-number last4), name, official_name, subtype (checking / savings / credit card / …), verification_status.
  • External account: account_number_last4, routing_number, wire_routing_number (where available).
  • Payment: transaction_id, pending_transaction_id (when pending=true), category, category_id, merchant_name, personal_finance_category.primary, payment_channel, iso_currency_code.

PSU-level metadata also carries user_token and link_token — connector internals, not editable.

Workflow tree#

FetchAccounts (periodic) — per PSU/Item
  ├── FetchBalances (FromPayload — no extra API call)
  └── FetchPayments (periodic) — per PSU/Item, /transactions/sync cursor
FetchExternalAccounts (periodic)
CreateWebhooks — one hook per Item, provisioned automatically on link

Pagination and recovery#

/transactions/sync is cursor-based and idempotent. The connector persists the latest cursor per Item in platform-managed State; restarts resume from the last committed cursor (Plaid's at-least-once semantics aside).

Known gaps#

  • Identity and Income products aren't surfaced — only Auth, Transactions, and (when present) Transfer.
  • Investment accounts are surfaced as accounts but their holdings are not — only depository balances and transactions land.
  • Webhooks failing signature verification are dropped silently with a single-line log. Look for plaid: webhook signature failed verification.
Getting Started with Open BankingTink
On This Page
  • Prerequisites
  • Installation
  • Configuration fields
  • Capabilities
  • Account model
  • Linking a user
  • Redirect URL requirements
  • Asset model
  • Status mapping
  • Metadata keys
  • Workflow tree
  • Pagination and recovery
  • Known gaps