Skip to main content
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

Ad Platform Spending

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`
    });
  }
}

SaaS & Tool Subscriptions

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

1

Sign Up

2

Create Issuing App

Set up an Issuing App for virtual cards
3

Complete KYC

Submit agency verification documents
4

Issue Cards

Create cards for clients, campaigns, and team members
5

Track & Optimize

Monitor spend and optimize budgets in real-time

Resources