
关于
Plaid API 集成的专家模式,包括 Link Token 流程、账户连接、交易数据获取和金融科技最佳实践。
name: plaid-fintech description: Plaid API 集成的专家模式,包括 Link token 流程、交易同步、身份验证、ACH 的 Auth、余额检查、Webhook 处理和金融科技合规最佳实践。 risk: unknown source: vibeship-spawner-skills (Apache 2.0) date_added: 2026-02-27
Plaid 金融科技
Plaid API 集成的专家模式,包括 Link token 流程、交易同步、身份验证、ACH 的 Auth、余额检查、Webhook 处理和金融科技合规最佳实践。
模式
Link Token 创建和交换
为 Plaid Link 创建 link_token,将 public_token 交换为 access_token。Link token 是短期的、一次性使用的。Access token 不会过期,但当用户更改密码时可能需要更新。
// server.ts - Link token creation endpoint
import { Configuration, PlaidApi, PlaidEnvironments, Products, CountryCode } from 'plaid';
const configuration = new Configuration({
basePath: PlaidEnvironments[process.env.PLAID_ENV || 'sandbox'],
baseOptions: {
headers: {
'PLAID-CLIENT-ID': process.env.PLAID_CLIENT_ID,
'PLAID-SECRET': process.env.PLAID_SECRET,
},
},
});
const plaidClient = new PlaidApi(configuration);
// Create link token for new user
app.post('/api/plaid/create-link-token', async (req, res) => {
const { userId } = req.body;
try {
const response = await plaidClient.linkTokenCreate({
user: {
client_user_id: userId,
},
client_name: 'My Finance App',
products: [Products.Transactions],
country_codes: [CountryCode.Us],
language: 'en',
webhook: 'https://yourapp.com/api/plaid/webhooks',
transactions: {
days_requested: 180,
},
});
res.json({ link_token: response.data.link_token });
} catch (error) {
console.error('Link token creation failed:', error);
res.status(500).json({ error: 'Failed to create link token' });
}
});
// Exchange public token for access token
app.post('/api/plaid/exchange-token', async (req, res) => {
const { publicToken, userId } = req.body;
try {
const exchangeResponse = await plaidClient.itemPublicTokenExchange({
public_token: publicToken,
});
const { access_token, item_id } = exchangeResponse.data;
await db.plaidItem.create({
data: {
userId,
itemId: item_id,
accessToken: await encrypt(access_token),
status: 'ACTIVE',
products: ['transactions'],
},
});
await initiateTransactionSync(item_id, access_token);
res.json({ success: true, itemId: item_id });
} catch (error) {
console.error('Token exchange failed:', error);
res.status(500).json({ error: 'Failed to exchange token' });
}
});
// Frontend - React component
import { usePlaidLink } from 'react-plaid-link';
function BankLinkButton({ userId }: { userId: string }) {
const [linkToken, setLinkToken] = useState<string | null>(null);
useEffect(() => {
async function createLinkToken() {
const response = await fetch('/api/plaid/create-link-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userId }),
});
const { link_token } = await response.json();
setLinkToken(link_token);
}
createLinkToken();
}, [userId]);
const { open, ready } = usePlaidLink({
token: linkToken,
onSuccess: async (publicToken, metadata) => {
await fetch('/api/plaid/exchange-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ publicToken, userId }),
});
},
onExit: (error, metadata) => {
if (error) {
console.error('Link exit error:', error);
}
},
});
return (
<button onClick={() => open()} disabled={!ready}>
Connect Bank Account
</button>
);
}
上下文
- 初始银行关联
- 用户入职
- 连接账户
交易同步
使用 /transactions/sync 进行增量交易更新。比 /transactions/get 更高效。处理 Webhook 以获取实时更新,而非轮询。
// Transactions sync service
interface TransactionSyncState {
cursor: string | null;
hasMore: boolean;
}
async function syncTransactions(
accessToken: string,
itemId: string
): Promise<void> {
const item = await db.plaidItem.findUnique({
where: { itemId },
});
let cursor = item?.transactionsCursor || null;
let hasMore = true;
let addedCount = 0;
let modifiedCount = 0;
let removedCount = 0;
while (hasMore) {
const response = await plaidClient.transactionsSync({
access_token: accessToken,
cursor: cursor || undefined,
});
// Process added, modified, removed transactions
}
}
兼容工具
Claude CodeCursor
标签
SaaS
