mcpField
P
plaid

plaid

github.com/raintree-technology开发64 次安装
代码仓库

关于 plaid

面向开发者的 Plaid Banking API 实施参考,涵盖账户连接、金融数据读取、支付及身份验证相关产品。还提供 Link 流程、Webhook、环境配置和安全处理说明。

主要功能

  1. 01Plaid Link 账户连接流程
  2. 02读取交易、余额与账户信息
  3. 03Auth、Identity、Investments 和 Liabilities 产品
  4. 04ACH 转账与 Webhook 处理
  5. 05沙盒、开发和生产环境说明
  6. 06令牌安全与重新认证建议

适用场景

  1. 01在金融科技应用中连接银行账户
  2. 02获取交易记录和实时余额
  3. 03实现 ACH 账户信息读取
  4. 04处理交易更新和账户连接错误

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/raintree-technology/claude-starter --skill plaid

安装后在 Claude Code 中输入/plaid确认已加载。

详细介绍

Plaid 银行 API 专家

Plaid 将应用连接到用户的银行账户,以便访问金融数据、进行支付和验证身份。

使用场景

  • 在金融科技应用中连接银行账户
  • 实现 Plaid Link 流程
  • 获取交易记录、余额或账户信息
  • 设置 ACH 转账
  • 验证身份/收入
  • 处理 Plaid Webhook

核心产品

产品用途
Auth获取用于 ACH 的银行账号/路由号码
Transactions交易历史记录(最多 24 个月)
Identity通过银行账户所有权验证用户身份
Balance实时账户余额
Investments投资账户中的持仓
Liabilities贷款和信用卡数据

快速开始

1. 安装 SDK
npm install plaid react-plaid-link
2. 创建 Plaid 客户端
import { Configuration, PlaidApi, PlaidEnvironments } from "plaid";

const client = new PlaidApi(
  new Configuration({
    basePath: PlaidEnvironments.sandbox,
    baseOptions: {
      headers: {
        "PLAID-CLIENT-ID": process.env.PLAID_CLIENT_ID,
        "PLAID-SECRET": process.env.PLAID_SECRET,
      },
    },
  })
);
3. 创建 Link Token(服务端)
// POST /api/plaid/create-link-token
export async function POST(req: Request) {
  const response = await client.linkTokenCreate({
    user: { client_user_id: userId },
    client_name: "Your App",
    products: ["auth", "transactions"],
    country_codes: ["US"],
    language: "en",
  });

  return Response.json({ link_token: response.data.link_token });
}
4. Plaid Link(客户端)
import { usePlaidLink } from "react-plaid-link";

function ConnectBank({ linkToken }) {
  const { open, ready } = usePlaidLink({
    token: linkToken,
    onSuccess: async (public_token, metadata) => {
      // Exchange for access_token on server
      await fetch("/api/plaid/exchange-token", {
        method: "POST",
        body: JSON.stringify({ public_token }),
      });
    },
  });

  return (
    <button onClick={() => open()} disabled={!ready}>
      Connect Bank Account
    </button>
  );
}
5. 交换 Token(服务端)
// POST /api/plaid/exchange-token
export async function POST(req: Request) {
  const { public_token } = await req.json();

  const response = await client.itemPublicTokenExchange({
    public_token,
  });

  // Store access_token securely (encrypted in database)
  await db.users.update(userId, {
    plaid_access_token: response.data.access_token,
    plaid_item_id: response.data.item_id,
  });

  return Response.json({ success: true });
}

获取数据

获取 Auth(账号/路由号码)
const response = await client.authGet({ access_token });

const ach = response.data.numbers.ach[0];
console.log("Account:", ach.account);
console.log("Routing:", ach.routing);
获取交易记录
const response = await client.transactionsGet({
  access_token,
  start_date: "2024-01-01",
  end_date: "2024-12-31",
});

let transactions = response.data.transactions;

// Handle pagination
while (transactions.length < response.data.total_transactions) {
  const more = await client.transactionsGet({
    access_token,
    start_date: "2024-01-01",
    end_date: "2024-12-31",
    offset: transactions.length,
  });
  transactions = transactions.concat(more.data.transactions);
}

交易对象:

{
  transaction_id: "abc123",
  amount: 12.34,           // Positive = outflow
  date: "2024-11-16",
  name: "Starbucks",
  merchant_name: "Starbucks",
  category: ["Food and Drink", "Coffee Shop"],
  pending: false,
}
获取余额
const response = await client.accountsBalanceGet({ access_token });

response.data.accounts.forEach((account) => {
  console.log(`${account.name}: $${account.balances.current}`);
});
获取身份信息
const response = await client.identityGet({ access_token });

const owner = response.data.accounts[0].owners[0];
console.log("Name:", owner.names[0]);
console.log("Email:", owner.emails[0].data);
console.log("Phone:", owner.phone_numbers[0].data);

Webhook

设置端点
// POST /api/plaid/webhook
export async function POST(req: Request) {
  const { webhook_type, webhook_code, item_id } = await req.json();

  switch (webhook_type) {
    case "TRANSACTIONS":
      if (webhook_code === "DEFAULT_UPDATE") {
        // New transactions available - fetch them
        await syncTransactions(item_id);
      }
      break;

    case "ITEM":
      if (webhook_code === "ERROR") {
        // Connection issue - prompt user to re-authenticate
        await notifyUserReauth(item_id);
      }
      break;
  }

  return Response.json({ received: true });
}

主要 Webhook 事件:

事件含义
TRANSACTIONS: INITIAL_UPDATE第一批数据已就绪
TRANSACTIONS: DEFAULT_UPDATE有新交易记录
ITEM: ERROR连接问题
ITEM: PENDING_EXPIRATION凭据即将过期

环境

环境使用场景基础路径
Sandbox测试PlaidEnvironments.sandbox
Development有限的线上使用(100 个连接)PlaidEnvironments.development
Production线上使用PlaidEnvironments.production
Sandbox 测试凭据
  • 用户名:user_good
  • 密码:pass_good
  • MFA:1234

错误处理

重新认证(更新模式)

凭据过期时:

// Create link token for update mode
const response = await client.linkTokenCreate({
  user: { client_user_id: userId },
  client_name: "Your App",
  access_token: existingAccessToken, // Triggers update mode
  country_codes: ["US"],
  language: "en",
});
常见错误
错误解决方案
ITEM_LOGIN_REQUIRED通过 Link 更新模式重新认证
RATE_LIMIT_EXCEEDED实现指数退避
PRODUCT_NOT_READY等待 Webhook 或重试

安全最佳实践

应该:

  • 在数据库中加密存储访问 Token
  • 使用环境变量保存凭据
  • 验证 Webhook 签名
  • 为所有端点使用 HTTPS

不应该:

  • 在客户端暴露密钥
  • 记录访问 Token
  • 将凭据存储在代码中

Next.js App Router 示例

// app/api/plaid/create-link-token/route.ts
import { NextResponse } from "next/server";
import { Configuration, PlaidApi, PlaidEnvironments } from "plaid";

const client = new PlaidApi(
  new Configuration({
    basePath: PlaidEnvironments.sandbox,
    baseOptions: {
      headers: {
        "PLAID-CLIENT-ID": process.env.PLAID_CLIENT_ID!,
        "PLAID-SECRET": process.env.PLAID_SECRET!,
      },
    },
  })
);

export async function POST(req: Request) {
  const session = await getSession();

  const response = await client.linkTokenCreate({
    user: { client_user_id: session.user.id },
    client_name: "Your App",
    products: ["auth", "transactions"],
    country_codes: ["US"],
    language: "en",
    webhook: `${process.env.NEXT_PUBLIC_URL}/api/plaid/webhook`,
  });

  return NextResponse.json({ link_token: response.data.link_token });
}

实现清单

  • 注册 Plaid 账户
  • 获取客户端 ID 和密钥
  • 安装 plaid 和 react-plaid-link
  • 设置环境变量
  • 创建 Link Token 端点
  • 实现 Token 交换端点
  • 在前端集成 Plaid Link
  • 安全存储访问 Token
  • 设置 Webhook 端点
  • 处理重新认证错误
  • 使用 Sandbox 凭据进行测试

资源

评论

支持 Markdown