Documentation Index Fetch the complete documentation index at: https://docs.fyatu.com/llms.txt
Use this file to discover all available pages before exploring further.
Streamline your marketing operations with FYATU virtual cards. Manage ad spend across platforms, pay influencers, and control budgets for multiple clients.
The Challenge
Marketing agencies and media buyers face:
Card sharing - Sharing personal/company cards for ad accounts
Budget control - Difficulty tracking spend per client/campaign
International payments - Paying foreign platforms and creators
Expense reconciliation - Manual tracking of ad spend
Creator payments - Paying influencers across different countries
The FYATU Solution
Virtual Cards Issue unlimited cards for ad platforms and campaigns
Spending Controls Set limits per card, campaign, or team member
Real-time Tracking Monitor spend across all cards in real-time
Creator Payouts Pay influencers and content creators instantly
Use Cases
Issue dedicated cards for each advertising platform:
// Create cards for different ad platforms
const platforms = [ 'Meta Ads' , 'Google Ads' , 'TikTok Ads' , 'LinkedIn Ads' ];
for ( const platform of platforms ) {
const card = await fyatu . cards . create ({
cardholderId: agencyCardholderId ,
currency: 'USD' ,
type: 'virtual' ,
spendingLimit: {
amount: 10000 ,
interval: 'monthly'
},
metadata: {
platform: platform ,
department: 'media_buying' ,
purpose: 'ad_spend'
}
});
console . log ( ` ${ platform } card created: ${ card . last4 } ` );
}
Per-Client Budget Management
Create cards for each client’s campaigns:
// Onboard new client with dedicated ad card
async function onboardClient ( client ) {
// Create cardholder for the client account
const cardholder = await fyatu . cardholders . create ({
firstName: client . companyName ,
lastName: 'Marketing' ,
email: client . billingEmail ,
phone: client . phone ,
externalId: `client- ${ client . id } `
});
// Issue card with client's monthly budget
const card = await fyatu . cards . create ({
cardholderId: cardholder . id ,
currency: 'USD' ,
type: 'virtual' ,
spendingLimit: {
amount: client . monthlyBudget ,
interval: 'monthly'
},
metadata: {
clientId: client . id ,
clientName: client . companyName ,
accountManager: client . accountManagerId
}
});
// Fund the card with first month's budget
await fyatu . cards . fund ( card . id , {
amount: client . monthlyBudget ,
reference: `FUND- ${ client . id } - ${ Date . now () } `
});
return { cardholder , card };
}
Team Member Cards
Issue cards to team members with controlled limits:
// Issue card to media buyer
async function issueTeamCard ( employee , monthlyLimit ) {
const cardholder = await fyatu . cardholders . create ({
firstName: employee . firstName ,
lastName: employee . lastName ,
email: employee . email ,
phone: employee . phone ,
externalId: employee . id
});
const card = await fyatu . cards . create ({
cardholderId: cardholder . id ,
currency: 'USD' ,
type: 'virtual' ,
spendingLimit: {
amount: monthlyLimit ,
interval: 'monthly'
},
allowedCategories: [
'advertising_services' ,
'digital_goods' ,
'software_services'
],
metadata: {
employeeId: employee . id ,
department: employee . department ,
role: employee . role
}
});
return card ;
}
Influencer & Creator Payments
Pay content creators and influencers across Africa:
// Pay influencer for campaign
async function payInfluencer ( campaign , influencer , amount ) {
// Verify influencer's account first
const verification = await fyatu . accounts . verify ( influencer . fyatuAccountId );
if ( ! verification . exists ) {
throw new Error ( 'Influencer account not found' );
}
const payout = await fyatu . payouts . create ({
amount: amount ,
currency: 'USD' ,
reference: `INF- ${ campaign . id } - ${ influencer . id } ` ,
description: `Payment for ${ campaign . name } ` ,
recipient: {
accountId: influencer . fyatuAccountId
},
metadata: {
campaignId: campaign . id ,
influencerId: influencer . id ,
clientId: campaign . clientId ,
deliverables: campaign . deliverables
}
});
// Record payment
await InfluencerPayment . create ({
campaignId: campaign . id ,
influencerId: influencer . id ,
amount: amount ,
payoutId: payout . id ,
status: 'processing'
});
return payout ;
}
Batch Creator Payments
Pay multiple creators for a campaign:
// End of campaign - pay all creators
async function settleCreatorPayments ( campaignId ) {
const payments = await CampaignPayment . findAll ({
where: { campaignId , status: 'pending' }
});
const results = [];
for ( const payment of payments ) {
try {
const payout = await fyatu . payouts . create ({
amount: payment . amount ,
currency: 'USD' ,
reference: `CREATOR- ${ payment . id } ` ,
description: `Campaign: ${ payment . campaignName } ` ,
recipient: {
accountId: payment . creatorFyatuId
},
metadata: {
paymentId: payment . id ,
creatorId: payment . creatorId ,
campaignId: campaignId
}
});
payment . status = 'processing' ;
payment . payoutId = payout . id ;
await payment . save ();
results . push ({ success: true , paymentId: payment . id });
} catch ( error ) {
results . push ({ success: false , paymentId: payment . id , error: error . message });
}
}
return results ;
}
Expense Tracking & Reporting
Real-time Transaction Webhooks
app . post ( '/webhooks/fyatu' , async ( req , res ) => {
const event = req . body ;
switch ( event . type ) {
case 'card.transaction.authorized' :
// Log transaction in real-time
await AdSpendLog . create ({
cardId: event . data . cardId ,
amount: event . data . amount ,
merchant: event . data . merchantName ,
category: event . data . merchantCategory ,
clientId: event . data . metadata . clientId ,
timestamp: new Date ()
});
// Check if approaching budget limit
const monthlySpend = await getMonthlySpend ( event . data . cardId );
const limit = event . data . spendingLimit . amount ;
if ( monthlySpend > limit * 0.8 ) {
await notifyAccountManager ( event . data . metadata . clientId , {
message: `Ad spend at ${ Math . round ( monthlySpend / limit * 100 ) } % of monthly budget`
});
}
break ;
case 'card.transaction.declined' :
// Alert on declined transactions
await notifyTeam ({
type: 'transaction_declined' ,
card: event . data . cardId ,
reason: event . data . declineReason ,
merchant: event . data . merchantName
});
break ;
}
res . status ( 200 ). send ( 'OK' );
});
Monthly Reporting
// Generate monthly spend report per client
async function generateClientReport ( clientId , month , year ) {
const transactions = await fyatu . cards . getTransactions ({
metadata: { clientId: clientId },
startDate: ` ${ year } - ${ month } -01` ,
endDate: ` ${ year } - ${ month } -31`
});
const report = {
client: clientId ,
period: ` ${ month } / ${ year } ` ,
totalSpend: 0 ,
byPlatform: {},
byCampaign: {},
transactions: []
};
for ( const tx of transactions ) {
report . totalSpend += tx . amount ;
// Group by platform
const platform = tx . merchantName ;
report . byPlatform [ platform ] = ( report . byPlatform [ platform ] || 0 ) + tx . amount ;
// Group by campaign
const campaign = tx . metadata . campaignId || 'uncategorized' ;
report . byCampaign [ campaign ] = ( report . byCampaign [ campaign ] || 0 ) + tx . amount ;
report . transactions . push ({
date: tx . createdAt ,
amount: tx . amount ,
platform: platform ,
description: tx . description
});
}
return report ;
}
Card Management Dashboard
View All Cards
// Get all active cards with spend info
async function getCardsDashboard () {
const cards = await fyatu . cards . list ({ status: 'active' });
const dashboard = await Promise . all ( cards . map ( async ( card ) => {
const transactions = await fyatu . cards . getTransactions ( card . id , {
startDate: startOfMonth ( new Date ()),
endDate: new Date ()
});
const monthlySpend = transactions . reduce (( sum , tx ) => sum + tx . amount , 0 );
return {
id: card . id ,
last4: card . last4 ,
clientName: card . metadata . clientName ,
platform: card . metadata . platform ,
monthlyLimit: card . spendingLimit . amount ,
monthlySpend: monthlySpend ,
utilizationPercent: Math . round ( monthlySpend / card . spendingLimit . amount * 100 ),
balance: card . balance
};
}));
return dashboard ;
}
Freeze Card When Budget Exhausted
// Auto-freeze when client budget is reached
async function checkAndFreezeIfOverBudget ( cardId ) {
const card = await fyatu . cards . get ( cardId );
const monthlySpend = await getMonthlySpend ( cardId );
if ( monthlySpend >= card . spendingLimit . amount ) {
await fyatu . cards . freeze ( cardId , {
reason: 'Monthly budget exhausted'
});
await notifyAccountManager ( card . metadata . clientId , {
message: `Card frozen - monthly budget of $ ${ card . spendingLimit . amount } reached`
});
}
}
Manage subscriptions for marketing tools:
// Issue card for SaaS subscriptions
const toolsCard = await fyatu . cards . create ({
cardholderId: agencyCardholderId ,
currency: 'USD' ,
type: 'virtual' ,
spendingLimit: {
amount: 5000 ,
interval: 'monthly'
},
metadata: {
purpose: 'saas_subscriptions' ,
tools: [ 'Semrush' , 'Ahrefs' , 'Canva' , 'Hootsuite' ]
}
});
// Track subscription renewals
app . post ( '/webhooks/fyatu' , ( req , res ) => {
if ( req . body . type === 'card.transaction.authorized' ) {
const tx = req . body . data ;
if ( tx . metadata . purpose === 'saas_subscriptions' ) {
// Log subscription payment
recordSubscriptionRenewal ({
tool: tx . merchantName ,
amount: tx . amount ,
date: new Date ()
});
}
}
res . status ( 200 ). send ( 'OK' );
});
Getting Started
Create Issuing App
Set up an Issuing App for virtual cards
Complete KYC
Submit agency verification documents
Issue Cards
Create cards for clients, campaigns, and team members
Track & Optimize
Monitor spend and optimize budgets in real-time
Resources