Plaid Banking API
Integrate bank accounts via Plaid for ACH transfers, account linking, and wallet funding. Supports both sandbox and production environments with comprehensive connection management and transaction simulation capabilities.
Create Link Token
Create Link Token
Create a Plaid Link token for frontend connection flow. Generates secure token for user to connect their bank account via Plaid Link frontend component. Requires valid wallet_id and uses user_id from wallet lookup.
Parameters
wallet_idnumberrequiredWallet ID to associate with bank connection
phone_numberstringUser phone number for Plaid verification (default: +1 415 5550123)
Request Body
{
"wallet_id": 123,
"phone_number": "+1 415 5550123"
}Response
{
"status": "SUCCESS",
"link_token": "link-sandbox-12345678-abcd-1234-5678-123456789abc",
"expiration": "2024-01-15T11:30:00Z"
}{
"status": "FAILED",
"message": "wallet_id is required"
}{
"status": "FAILED",
"message": "User not found for given wallet_id"
}{
"status": "FAILED",
"message": "Error creating Plaid link token",
"error": "Plaid service unavailable"
}curl -X POST https://api.brdz.link/api/plaid/link-token/create \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"wallet_id": 123,
"phone_number": "+1 415 5550123"
}'Save Public Token
Save Public Token from Frontend
Receive and log public token from Plaid Link frontend component. This is an intermediate step before exchanging for access token. Logs public token and metadata for processing.
Parameters
public_tokenstringrequiredPublic token received from Plaid Link frontend
metadataobjectMetadata object from Plaid Link containing institution info
Request Body
{
"public_token": "public-sandbox-12345678-abcd-1234-5678-123456789abc",
"metadata": {
"institution": {
"name": "Chase",
"institution_id": "ins_3"
},
"accounts": [
{
"id": "account_id",
"name": "Checking Account",
"type": "depository",
"subtype": "checking"
}
]
}
}Response
{
"status": "SUCCESS",
"message": "Public token received"
}{
"status": "FAILED",
"message": "public_token is required"
}curl -X POST https://api.brdz.link/api/plaid/link-token/exchange \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"public_token": "public-sandbox-12345678-abcd-1234-5678-123456789abc",
"metadata": {
"institution": {
"name": "Chase",
"institution_id": "ins_3"
}
}
}'Exchange Public Token to Access Token
Exchange Public Token to Access Token
Exchange public token for permanent access token and save connection to database. Creates entry in plaid_connections table with access token, item_id, and institution info. Logs connection event to plaid_connection_logs.
Parameters
public_tokenstringrequiredPublic token from Plaid Link
metadataobjectInstitution metadata from Plaid Link
Request Body
{
"public_token": "public-sandbox-12345678-abcd-1234-5678-123456789abc",
"metadata": {
"institution": {
"name": "Chase",
"institution_id": "ins_3"
}
}
}Response
{
"status": "SUCCESS",
"access_token": "access-sandbox-12345678-abcd-1234-5678-123456789abc",
"item_id": "item_12345678abcd1234567890123456"
}{
"status": "FAILED",
"message": "Missing public_token"
}{
"status": "FAILED",
"message": "Failed to exchange public_token",
"error": "Invalid public token"
}{
"status": "ALREADY_CONNECTED",
"access_token": "access-sandbox-12345678-abcd-1234-5678-123456789abc",
"item_id": "item_12345678abcd1234567890123456"
}curl -X POST https://api.brdz.link/api/plaid/item/public-token/exchange \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"public_token": "public-sandbox-12345678-abcd-1234-5678-123456789abc",
"metadata": {
"institution": {
"name": "Chase",
"institution_id": "ins_3"
}
}
}'Check Plaid Connection
Check Plaid Connection
Check if wallet is already connected to Plaid by looking up plaid_connections table. Returns boolean indicating connection status.
Parameters
wallet_idstringrequiredWallet ID to check connection status (path parameter)
Response
{
"connected": true
}{
"error": "Gagal cek koneksi plaid",
"details": "Database connection failed"
}{
"connected": false
}curl -X GET https://api.brdz.link/api/plaid/123/check \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Disconnect Plaid (Combined)
Disconnect Plaid Connection
Remove Plaid item from Plaid service and delete connection from database. Logs DISCONNECT action to plaid_connection_logs before removing from plaid_connections table.
Parameters
wallet_idstringrequiredWallet ID to disconnect (path parameter)
Response
{
"message": "✅ Plaid disconnected successfully"
}{
"error": "wallet_id wajib diisi dan harus valid"
}{
"error": "Gagal disconnect plaid",
"details": "Plaid service error"
}{
"message": "Tidak ada koneksi plaid untuk wallet ini (sudah terhapus)"
}curl -X DELETE https://api.brdz.link/api/plaid/123/plaid \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Get Plaid Accounts
Get Bank Accounts
Retrieve bank accounts from Plaid for connected user. Looks up access_token from plaid_connections table and calls Plaid accounts/get endpoint.
Parameters
user_idstringrequiredUser ID to get accounts for (path parameter)
Response
{
"accounts": [
{
"account_id": "account_12345",
"balances": {
"available": 1000.5,
"current": 1200.75,
"iso_currency_code": "USD"
},
"name": "Checking Account",
"type": "depository",
"subtype": "checking",
"mask": "0000"
},
{
"account_id": "account_67890",
"balances": {
"available": 5000,
"current": 5000,
"iso_currency_code": "USD"
},
"name": "Savings Account",
"type": "depository",
"subtype": "savings",
"mask": "1111"
}
]
}{
"error": "user_id wajib diisi"
}{
"error": "Plaid connection tidak ditemukan untuk user ini"
}{
"error": "Gagal ambil akun Plaid",
"details": "Plaid service unavailable"
}curl -X GET https://api.brdz.link/api/plaid/123/accounts \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"Remove Plaid Item
Remove Plaid Item
Remove Plaid item from Plaid service only (does not remove from database). Use disconnect endpoint for complete removal.
Parameters
access_tokenstringrequiredPlaid access token for the item to remove
Request Body
{
"access_token": "access-sandbox-12345678-abcd-1234-5678-123456789abc"
}Response
{
"message": "Plaid item removed successfully",
"data": {
"removed": true
}
}{
"error": "access_token wajib diisi"
}{
"error": "Gagal remove item",
"details": "Invalid access token"
}curl -X POST https://api.brdz.link/api/plaid/remove-item \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"access_token": "access-sandbox-12345678-abcd-1234-5678-123456789abc"
}'Get Access Token by Wallet
Get Access Token by Wallet
Retrieve Plaid access token for a specific wallet. Used for direct Plaid API calls from frontend or other services.
Parameters
wallet_idstringrequiredWallet ID to get access token for (path parameter)
Response
{
"access_token": "access-sandbox-12345678-abcd-1234-5678-123456789abc"
}{
"error": "Plaid connection tidak ditemukan"
}{
"error": "Gagal ambil access_token",
"details": "Database query failed"
}curl -X GET https://api.brdz.link/api/plaid/123/access-token \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"ACH Transfer Simulation
Simulate ACH Transfer (Sandbox)
Simulate ACH transfer events in Plaid sandbox environment. Used for testing transfer workflows without real money movement.
Parameters
transfer_idstringrequiredTransfer ID to simulate
event_typestringEvent type to simulate (default: 'settled')
Request Body
{
"transfer_id": "transfer_12345678abcd",
"event_type": "settled"
}Response
{
"message": "Simulasi ACH Transfer 'settled' berhasil",
"data": {
"transfer_id": "transfer_12345678abcd",
"event_type": "settled",
"timestamp": "2024-01-15T10:30:00Z"
}
}{
"error": "transfer_id wajib diisi"
}{
"error": "Gagal simulasi transfer",
"details": "Invalid transfer_id"
}curl -X POST https://api.brdz.link/api/plaid/transfer \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"transfer_id": "transfer_12345678abcd",
"event_type": "settled"
}'SEPA Payment Simulation
Simulate SEPA Payment (Sandbox)
Simulate SEPA payment completion in Plaid sandbox environment. Used for testing European payment workflows.
Parameters
payment_idstringrequiredPayment ID to simulate completion
Request Body
{
"payment_id": "payment_12345678abcd"
}Response
{
"message": "Simulasi SEPA Payment COMPLETED berhasil",
"data": {
"payment_id": "payment_12345678abcd",
"status": "COMPLETED",
"timestamp": "2024-01-15T10:30:00Z"
}
}{
"error": "payment_id wajib diisi"
}{
"error": "Gagal simulasi payment",
"details": "Invalid payment_id"
}curl -X POST https://api.brdz.link/api/plaid/payment \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"payment_id": "payment_12345678abcd"
}'Plaid Topup
Topup Wallet via Plaid
Fund wallet using connected bank account through Plaid. Creates transaction record using transactionModel with type 'TOPUP' and status 'SUCCESS_RECEIVED'. Logs to transaction history.
Parameters
wallet_idnumberrequiredWallet ID to fund
amountnumberrequiredAmount to transfer in USD
currencystringCurrency code (default: 'USD')
Request Body
{
"wallet_id": 123,
"amount": 500,
"currency": "USD"
}Response
{
"status": "SUCCESS",
"transaction_id": "TXN-1705317000-1234"
}{
"status": "FAILED",
"message": "wallet_id dan amount wajib diisi"
}{
"status": "FAILED",
"message": "Koneksi Plaid tidak ditemukan untuk wallet ini"
}{
"status": "FAILED",
"message": "Gagal topup via Plaid",
"error": "Transaction processing error"
}curl -X POST https://api.brdz.link/api/plaid/topup \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"wallet_id": 123,
"amount": 500.00,
"currency": "USD"
}'Integration Flow
Complete Plaid Integration Workflow
-
Frontend Integration:
// 1. Create link token
const linkToken = await createLinkToken({ wallet_id: 123 });
// 2. Initialize Plaid Link (frontend)
const handler = Plaid.create({
token: linkToken.link_token,
onSuccess: async (public_token, metadata) => {
// 3. Save public token
await savePublicTokenFromFrontend({ public_token, metadata });
// 4. Exchange for access token
await exchangePublicTokenToAccessToken({ public_token, metadata });
}
}); -
Connection Management:
// Check connection status
const isConnected = await checkPlaidConnection('123');
// Get bank accounts
if (isConnected.connected) {
const accounts = await getPlaidAccounts('user_123');
}
// Disconnect when needed
await disconnectPlaidCombined('123'); -
Funding Workflow:
// Fund wallet from bank account
const topup = await plaidTopup({
wallet_id: 123,
amount: 500.00,
currency: 'USD'
});
Database Tables Used
Based on controller implementation:
- plaid_connections: Main connection storage (user_id, wallet_id, access_token, item_id, institution info)
- plaid_connection_logs: Audit trail (CONNECT/DISCONNECT actions)
- wallets: Wallet ownership verification
- transactions: Topup transaction logging (via transactionModel)
Environment Configuration
Required environment variables:
PLAID_CLIENT_ID=your_plaid_client_id
PLAID_SECRET=your_plaid_secret_key
# Uses sandbox environment by default
Error Handling
All endpoints follow standard AOL error format:
- SUCCESS:
{ status: "SUCCESS", data: {...} } - FAILED:
{ status: "FAILED", message: "...", error: "..." } - Database errors:
{ error: "...", details: "..." }
Sandbox vs Production
- Sandbox: Uses
PlaidEnvironments.sandboxfor testing - Test institutions: Available in sandbox for development
- Simulation endpoints: ACH Transfer and SEPA Payment for testing
All endpoints require valid JWT token + API key. Wallet operations verify ownership through database lookups.
This API works with Plaid Link frontend component. Create link token server-side, initialize Plaid Link client-side, then exchange tokens server-side.
Use check endpoint before attempting operations. Always disconnect properly to clean up both Plaid service and database records.