Bridge Cards Management
Quick Reference
typescript
type CardChain = 'solana' | 'ethereum' | 'polygon' | 'base' | 'arbitrum'; type CardCurrency = 'usdc' | 'usdb'; type CardStatus = 'active' | 'pending' | 'inactive' | 'frozen'; type CardDesign = string;
Provision Card Account
typescript
interface CreateCardRequest {
client_reference_id?: string;
currency: CardCurrency;
chain: CardChain;
crypto_account: {
type: 'bridge_wallet' | 'standard';
address: string;
};
card_design_shortname?: CardDesign;
}
interface CardAccount {
id: string;
client_reference_id?: string;
customer_id: string;
cardholder_name: {
first_name: string;
middle_name?: string;
last_name: string;
};
card_image_url: string;
status: CardStatus;
status_reason?: string;
card_details: {
last_4: string;
expiry: string; // MM/YY
bin: string;
pin_status: 'not_set' | 'set';
};
balances: {
available: { amount: string; currency: CardCurrency };
hold: { amount: string; currency: CardCurrency };
};
freezes: {
card_account_id: string;
reason: 'lost_or_stolen' | 'fraud' | 'other';
reason_detail?: string;
starting_at?: string;
ending_at?: string;
created_at?: string;
}[];
crypto_account: {
type: string;
address: string;
};
funding_instructions: {
currency: CardCurrency;
chain: CardChain;
address: string;
memo?: string;
};
additional_funding_instructions?: {
currency: CardCurrency;
chain: CardChain;
address: string;
memo?: string;
}[];
}
async function provisionCard(
customerId: string,
request: CreateCardRequest
): Promise<CardAccount> {
const response = await fetch(`${BRIDGE_API_URL}/customers/${customerId}/card_accounts`, {
method: 'POST',
headers: {
'Api-Key': API_KEY,
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Card provisioning failed: ${error.message}`);
}
return response.json();
}
Basic Card Provisioning
typescript
async function createBasicCard(
customerId: string,
walletAddress: string,
chain: CardChain = 'solana'
): Promise<CardAccount> {
return provisionCard(customerId, {
currency: 'usdc',
chain,
crypto_account: {
type: 'bridge_wallet',
address: walletAddress,
},
});
}
// Usage
const card = await createBasicCard(
'cust_alice',
'7bHbB8RwQgyNgxXZx8Q2kNzjEkmyv9Kb1DKZa63K3CtB',
'solana'
);
console.log('Card ID:', card.id);
console.log('Last 4:', card.card_details.last_4);
console.log('Expiry:', card.card_details.expiry);
console.log('Status:', card.status);
console.log('Available Balance:', card.balances.available);
Card with Custom Design
typescript
async function createCustomDesignCard(
customerId: string,
walletAddress: string,
designShortname: string
): Promise<CardAccount> {
return provisionCard(customerId, {
currency: 'usdc',
chain: 'solana',
crypto_account: {
type: 'bridge_wallet',
address: walletAddress,
},
card_design_shortname: designShortname,
});
}
// Available designs would be fetched from Bridge
const designs = ['default', 'metallic', 'minimal', 'premium'];
Fund Card Account
typescript
interface FundCardRequest {
amount: string;
on_behalf_of: string;
source: {
payment_rail: 'ach_push' | 'wire' | 'sepa';
currency: 'usd' | 'eur';
};
destination: {
payment_rail: 'card'; // Special rail for cards
currency: CardCurrency;
card_account_id: string;
};
}
async function fundCard(request: FundCardRequest): Promise<Transfer> {
const response = await fetch(`${BRIDGE_API_URL}/transfers`, {
method: 'POST',
headers: {
'Api-Key': API_KEY,
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Card funding failed: ${error.message}`);
}
return response.json();
}
// Fund card from USD bank account
async function addFundsToCard(
customerId: string,
cardId: string,
amount: string,
walletAddress: string
): Promise<Transfer> {
return fundCard({
amount,
on_behalf_of: customerId,
source: {
payment_rail: 'ach_push',
currency: 'usd',
},
destination: {
payment_rail: 'card',
currency: 'usdc',
card_account_id: cardId,
},
});
}
Card Management
typescript
class CardManager {
async freezeCard(cardId: string, reason: 'lost_or_stolen' | 'fraud' = 'lost_or_stolen'): Promise<CardAccount> {
const response = await fetch(`${BRIDGE_API_URL}/card_accounts/${cardId}/freezes`, {
method: 'POST',
headers: {
'Api-Key': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
reason,
starting_at: new Date().toISOString(),
}),
});
if (!response.ok) {
throw new Error('Failed to freeze card');
}
return response.json();
}
async unfreezeCard(cardId: string, freezeId: string): Promise<CardAccount> {
const response = await fetch(
`${BRIDGE_API_URL}/card_accounts/${cardId}/freezes/${freezeId}`,
{
method: 'DELETE',
headers: { 'Api-Key': API_KEY },
}
);
if (!response.ok) {
throw new Error('Failed to unfreeze card');
}
return response.json();
}
async getCard(cardId: string): Promise<CardAccount> {
const response = await fetch(`${BRIDGE_API_URL}/card_accounts/${cardId}`, {
headers: { 'Api-Key': API_KEY },
});
if (!response.ok) {
throw new Error('Card not found');
}
return response.json();
}
async listCustomerCards(customerId: string): Promise<CardAccount[]> {
const response = await fetch(`${BRIDGE_API_URL}/customers/${customerId}/card_accounts`, {
headers: { 'Api-Key': API_KEY },
});
if (!response.ok) {
throw new Error('Failed to list cards');
}
return response.json();
}
}
Complete Card Service
typescript
interface CreateCardRequest {
customerId: string;
walletAddress: string;
chain?: CardChain;
currency?: CardCurrency;
design?: string;
initialFunding?: {
amount: string;
bankAccountId: string;
};
}
class CardService {
async createAndFundCard(request: CreateCardRequest): Promise<{
card: CardAccount;
fundingTransfer?: Transfer;
}> {
// 1. Create the card
const card = await provisionCard(request.customerId, {
currency: request.currency || 'usdc',
chain: request.chain || 'solana',
crypto_account: {
type: 'bridge_wallet',
address: request.walletAddress,
},
card_design_shortname: request.design,
});
// 2. Fund if requested
let fundingTransfer: Transfer | undefined;
if (request.initialFunding) {
fundingTransfer = await fundCard({
amount: request.initialFunding.amount,
on_behalf_of: request.customerId,
source: {
payment_rail: 'ach_push',
currency: 'usd',
external_account_id: request.initialFunding.bankAccountId,
},
destination: {
payment_rail: 'card',
currency: request.currency || 'usdc',
card_account_id: card.id,
},
});
}
return { card, fundingTransfer };
}
async replaceLostCard(customerId: string, oldCardId: string): Promise<CardAccount> {
const oldCard = await this.getCard(oldCardId);
// Freeze old card
await this.freezeCard(oldCardId, 'lost_or_stolen');
// Create new card with same wallet
return provisionCard(customerId, {
currency: oldCard.balances.available.currency,
chain: oldCard.crypto_account.address.startsWith('0x') ? 'ethereum' : 'solana',
crypto_account: {
type: oldCard.crypto_account.type,
address: oldCard.crypto_account.address,
},
});
}
}
Multi-Card Strategy
typescript
class MultiCardStrategy {
// Create different cards for different spending purposes
async setupExpenseCards(
customerId: string,
walletAddress: string
): Promise<{ dining: CardAccount; travel: CardAccount; daily: CardAccount }> {
const [dining, travel, daily] = await Promise.all([
provisionCard(customerId, {
currency: 'usdc',
chain: 'solana',
crypto_account: { type: 'bridge_wallet', address: walletAddress },
card_design_shortname: 'dining',
}),
provisionCard(customerId, {
currency: 'usdc',
chain: 'solana',
crypto_account: { type: 'bridge_wallet', address: walletAddress },
card_design_shortname: 'travel',
}),
provisionCard(customerId, {
currency: 'usdc',
chain: 'solana',
crypto_account: { type: 'bridge_wallet', address: walletAddress },
card_design_shortname: 'daily',
}),
]);
return { dining, travel, daily };
}
// Allocate budget to cards
async allocateBudget(
customerId: string,
cardId: string,
monthlyBudget: string
): Promise<void> {
// Store budget allocation in your system
// Monitor spending via webhooks
}
}
Card Dashboard
typescript
interface CardDashboard {
totalCards: number;
totalAvailableBalance: string;
cards: {
id: string;
last4: string;
status: CardStatus;
balance: string;
chain: CardChain;
}[];
}
async function getCardDashboard(customerId: string): Promise<CardDashboard> {
const cards = await new CardManager().listCustomerCards(customerId);
return {
totalCards: cards.length,
totalAvailableBalance: cards
.reduce((sum, c) => sum + parseFloat(c.balances.available.amount), 0)
.toFixed(2),
cards: cards.map(c => ({
id: c.id,
last4: c.card_details.last_4,
status: c.status,
balance: c.balances.available.amount,
chain: c.crypto_account.address.startsWith('0x') ? 'ethereum' : 'solana',
})),
};
}
Webhook Events
- •
card_account.created- New card provisioned - •
card_account.status_updated- Card status changed - •
card_account.freeze_created- Card was frozen - •
card_account.freeze_removed- Card was unfrozen - •
card_transaction.completed- Purchase completed
Best Practices
- •One currency per card - Cannot change after creation
- •One chain per card - Cannot change after creation
- •Freeze immediately - If card is lost
- •Multiple funding sources - Support various chains
- •Webhook monitoring - Track transactions in real-time
- •Balance alerts - Notify when balance is low