Skip to main content

Plaid Integration

Secure identity verification and bank account connection via Plaid.

Products

ID Verification

Document + selfie verification:
{
  type: "plaid_id_verification",
  id: "id-verify",
  label: { en: "Verify Your Identity" },
  plaidTemplateId: "idvtmp_xxx"  // From Plaid Dashboard
}
Flow:
  1. User clicks “Verify Identity”
  2. Plaid Link opens
  3. User uploads ID + takes selfie
  4. Plaid returns verification status

Bank Verification

Secure bank account connection:
{
  type: "plaid_bank_verification",
  id: "bank-verify",
  label: { en: "Connect Your Bank" }
}
Flow:
  1. User clicks “Connect Bank”
  2. Plaid Link opens
  3. User logs into bank
  4. Plaid returns account details (masked)

Implementation

// /api/plaid/link-token/route.ts
export async function POST() {
  const linkToken = await plaidClient.linkTokenCreate({
    user: { client_user_id: uniqueId },
    client_name: "Terra",
    products: ["identity_verification"],
    country_codes: ["US"],
    language: "en",
  });

  return Response.json({ linkToken: linkToken.link_token });
}

Exchanging Public Tokens

After user completes Link:
const { access_token } = await plaidClient.itemPublicTokenExchange({
  public_token: publicToken,
});

// Store encrypted access token
await saveAccessToken(submissionId, fieldId, access_token);

Security

  • Access tokens are encrypted at rest
  • Bank account numbers are masked (last 4 only)
  • Full data only retrieved when needed