npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xenterprises/fastify-xplaid

v1.1.1

Published

Fastify plugin for Plaid financial data integration - bank account linking, transactions, and identity verification

Readme

xPlaid

Fastify plugin for Plaid financial data integration - bank account linking, transactions, identity verification, and more.

Installation

npm install xplaid plaid

Usage

import Fastify from "fastify";
import xPlaid from "xplaid";

const fastify = Fastify();

await fastify.register(xPlaid, {
  clientId: process.env.PLAID_CLIENT_ID,
  secret: process.env.PLAID_SECRET,
  environment: "sandbox", // 'sandbox' | 'development' | 'production'
});

// The plugin is now available at fastify.xplaid

Configuration Options

| Option | Type | Required | Default | Description | |--------|------|----------|---------|-------------| | clientId | string | Yes | - | Your Plaid client ID | | secret | string | Yes | - | Your Plaid secret | | environment | string | No | 'sandbox' | Plaid environment: 'sandbox', 'development', or 'production' | | active | boolean | No | true | Enable/disable the plugin |

Link Flow

The Plaid Link flow is the primary way users connect their bank accounts:

1. Create a Link Token

// Create a link token for the frontend
const linkToken = await fastify.xplaid.link.createToken({
  userId: "user_123",
  clientName: "My App",
  products: ["transactions", "auth"],
  countryCodes: ["US"],
  language: "en",
  // Optional: webhook for real-time updates
  webhook: "https://myapp.com/webhooks/plaid",
  // Optional: redirect URI for OAuth flows
  redirectUri: "https://myapp.com/oauth-callback",
});

// Return linkToken.link_token to your frontend

2. Exchange Public Token

After the user completes Plaid Link, exchange the public token for an access token:

// Exchange the public token from Plaid Link
const result = await fastify.xplaid.link.exchangePublicToken("public-token-from-link");

// Store these securely
const accessToken = result.access_token;
const itemId = result.item_id;

3. Get Link Token Info

const tokenInfo = await fastify.xplaid.link.getToken("link-token-id");

Accounts

// Get all accounts for an item
const accounts = await fastify.xplaid.accounts.get(accessToken);

// Get real-time balance
const balance = await fastify.xplaid.accounts.getBalance(accessToken, {
  accountIds: ["account_id_1", "account_id_2"], // Optional: filter by accounts
});

Transactions

Sync Transactions (Recommended)

The sync endpoint is the recommended way to get transactions:

// Initial sync - get all available transactions
let cursor = null;
let allTransactions = [];

let response = await fastify.xplaid.transactions.sync(accessToken, { cursor });

allTransactions.push(...response.added);
cursor = response.next_cursor;

// Store the cursor for future syncs
// On subsequent syncs, pass the cursor to get only new/updated transactions

Get Transactions (Legacy)

const transactions = await fastify.xplaid.transactions.get(accessToken, {
  startDate: "2024-01-01",
  endDate: "2024-12-31",
  count: 100,
  offset: 0,
  accountIds: ["account_id"], // Optional
});

Refresh Transactions

Force a refresh of transaction data:

await fastify.xplaid.transactions.refresh(accessToken);

Identity

Get identity information (name, email, phone, address) from the bank:

const identity = await fastify.xplaid.identity.get(accessToken, {
  accountIds: ["account_id"], // Optional
});

Auth

Get ACH routing and account numbers:

const auth = await fastify.xplaid.auth.get(accessToken, {
  accountIds: ["account_id"], // Optional
});

// Returns account numbers including:
// - ACH routing numbers
// - Account numbers
// - Wire routing numbers (if available)

Investments

Get Holdings

const holdings = await fastify.xplaid.investments.getHoldings(accessToken, {
  accountIds: ["account_id"], // Optional
});

Get Investment Transactions

const investmentTx = await fastify.xplaid.investments.getTransactions(accessToken, {
  startDate: "2024-01-01",
  endDate: "2024-12-31",
  count: 100,
  offset: 0,
  accountIds: ["account_id"], // Optional
});

Liabilities

Get loan and credit card liability information:

const liabilities = await fastify.xplaid.liabilities.get(accessToken, {
  accountIds: ["account_id"], // Optional
});

// Returns credit, mortgage, and student loan details

Item Management

Get Item Info

const item = await fastify.xplaid.items.get(accessToken);

Remove an Item

Permanently delete an item and revoke access:

await fastify.xplaid.items.remove(accessToken);

Get Institution

const institution = await fastify.xplaid.items.getInstitution("ins_123", {
  countryCodes: ["US"],
  includeOptionalMetadata: true,
  includeStatus: true,
});

Search Institutions

const institutions = await fastify.xplaid.items.searchInstitutions({
  query: "Chase",
  products: ["transactions"],
  countryCodes: ["US"],
  count: 10,
  offset: 0,
});

Webhooks

Update Webhook URL

await fastify.xplaid.webhooks.update(accessToken, "https://myapp.com/new-webhook-url");

Get Verification Key

Verify webhook signatures:

const key = await fastify.xplaid.webhooks.getVerificationKey("key_id_from_webhook_header");

Constants

The plugin exposes useful constants:

const { ENVIRONMENTS, PRODUCTS, COUNTRY_CODES } = fastify.xplaid.constants;

// Or import directly
import { ENVIRONMENTS, PRODUCTS, COUNTRY_CODES } from "xplaid";

// ENVIRONMENTS
ENVIRONMENTS.SANDBOX      // 'sandbox'
ENVIRONMENTS.DEVELOPMENT  // 'development'
ENVIRONMENTS.PRODUCTION   // 'production'

// PRODUCTS
PRODUCTS.AUTH           // 'auth'
PRODUCTS.TRANSACTIONS   // 'transactions'
PRODUCTS.IDENTITY       // 'identity'
PRODUCTS.INVESTMENTS    // 'investments'
PRODUCTS.LIABILITIES    // 'liabilities'
PRODUCTS.ASSETS         // 'assets'

// COUNTRY_CODES
COUNTRY_CODES.US  // 'US'
COUNTRY_CODES.CA  // 'CA'
COUNTRY_CODES.GB  // 'GB'
COUNTRY_CODES.IE  // 'IE'
COUNTRY_CODES.FR  // 'FR'
COUNTRY_CODES.ES  // 'ES'
COUNTRY_CODES.NL  // 'NL'

Raw Client Access

For advanced use cases, access the underlying Plaid client directly:

const plaidClient = fastify.xplaid.raw;

// Use any Plaid API method
const response = await plaidClient.sandboxItemFireWebhook({
  access_token: accessToken,
  webhook_code: "DEFAULT_UPDATE",
});

Error Handling

Plaid errors include detailed error codes:

try {
  const accounts = await fastify.xplaid.accounts.get(accessToken);
} catch (error) {
  if (error.response?.data) {
    const plaidError = error.response.data;
    console.error("Plaid error:", {
      errorType: plaidError.error_type,
      errorCode: plaidError.error_code,
      errorMessage: plaidError.error_message,
      displayMessage: plaidError.display_message,
    });
  }
}

Common error types:

  • INVALID_REQUEST - Invalid parameters
  • INVALID_INPUT - Invalid input data
  • INSTITUTION_ERROR - Bank is unavailable
  • RATE_LIMIT_EXCEEDED - Too many requests
  • API_ERROR - Plaid internal error
  • ITEM_ERROR - Item-specific error (e.g., login required)

Configuration Access

const config = fastify.xplaid.config;
// {
//   clientId: '***id', // Masked for security
//   environment: 'sandbox'
// }

Complete Example

import Fastify from "fastify";
import xPlaid from "xplaid";

const fastify = Fastify({ logger: true });

await fastify.register(xPlaid, {
  clientId: process.env.PLAID_CLIENT_ID,
  secret: process.env.PLAID_SECRET,
  environment: process.env.PLAID_ENV || "sandbox",
});

// Create link token endpoint
fastify.post("/api/create-link-token", async (request, reply) => {
  const { userId } = request.body;

  const linkToken = await fastify.xplaid.link.createToken({
    userId,
    clientName: "My Finance App",
    products: ["transactions"],
    countryCodes: ["US"],
    language: "en",
  });

  return { linkToken: linkToken.link_token };
});

// Exchange public token endpoint
fastify.post("/api/exchange-token", async (request, reply) => {
  const { publicToken, userId } = request.body;

  const result = await fastify.xplaid.link.exchangePublicToken(publicToken);

  // Store accessToken and itemId in your database
  // associated with the userId

  return { success: true };
});

// Get transactions endpoint
fastify.get("/api/transactions", async (request, reply) => {
  const { userId } = request.user; // From your auth middleware

  // Retrieve accessToken from your database for this user
  const accessToken = await getAccessTokenForUser(userId);

  const transactions = await fastify.xplaid.transactions.sync(accessToken);

  return { transactions: transactions.added };
});

await fastify.listen({ port: 3000 });

Testing

npm test

License

ISC