Skip to main content
Enable instant payouts for your gig economy platform. FYATU helps you pay drivers, riders, freelancers, and service providers across Africa in real-time.

The Challenge

Gig platforms operating in Africa struggle with:
  • Payout frequency - Workers expect daily or instant payments
  • Payment diversity - Workers prefer different payment methods
  • High volumes - Thousands of small payouts daily
  • Bank limitations - Not all workers have bank accounts
  • Cash handling - Managing cash payments is risky and expensive

The FYATU Solution

Instant Payouts

Pay workers instantly to their Fyatu wallet balances

Batch Processing

Process thousands of payouts efficiently

Worker Cards

Issue USD virtual Mastercards for workers

Collections

Accept payments from Fyatu users for services

Platform Types

Ride-Hailing & Delivery

// End of trip - calculate and pay driver
async function completeTripAndPay(tripId) {
  const trip = await Trip.findById(tripId);

  // Calculate driver earnings
  const driverShare = trip.fare * 0.80; // 80% to driver
  const platformFee = trip.fare * 0.20;

  // Instant payout to driver's Fyatu wallet
  const payout = await fyatu.payouts.create({
    amount: driverShare,
    currency: 'USD',
    reference: `TRIP-${tripId}`,
    description: `Trip earnings - ${trip.pickupLocation} to ${trip.dropoffLocation}`,
    recipient: {
      accountId: trip.driver.fyatuClientId  // Driver's Fyatu account ID
    },
    metadata: {
      tripId: tripId,
      driverId: trip.driverId,
      type: 'trip_earnings'
    }
  });

  // Update trip record
  trip.status = 'completed';
  trip.payoutId = payout.id;
  trip.driverPaidAt = new Date();
  await trip.save();
}

Freelance Marketplaces

// Client releases payment for completed work
async function releasePayment(projectId) {
  const project = await Project.findById(projectId);
  const freelancer = await User.findById(project.freelancerId);

  // Calculate amounts
  const platformFee = project.budget * 0.10;
  const freelancerAmount = project.budget - platformFee;

  const payout = await fyatu.payouts.create({
    amount: freelancerAmount,
    currency: 'USD',
    reference: `PROJECT-${projectId}`,
    description: `Payment for: ${project.title}`,
    recipient: {
      accountId: freelancer.fyatuAccountId
    },
    metadata: {
      projectId: projectId,
      freelancerId: freelancer.id,
      clientId: project.clientId
    }
  });

  project.status = 'paid';
  project.payoutId = payout.id;
  await project.save();

  // Notify freelancer
  await notifyFreelancer(freelancer.id, {
    message: `Payment of $${freelancerAmount} received for "${project.title}"`,
    payoutId: payout.id
  });
}

Home Services

// Pay service provider after job completion
async function payServiceProvider(bookingId) {
  const booking = await Booking.findById(bookingId);
  const provider = await Provider.findById(booking.providerId);

  const providerEarnings = booking.totalAmount * 0.75;

  // Pay directly to provider's Fyatu wallet
  const payout = await fyatu.payouts.create({
    amount: providerEarnings,
    currency: 'USD',
    reference: `BOOKING-${bookingId}`,
    description: `${booking.serviceType} service payment`,
    recipient: {
      accountId: provider.fyatuClientId  // Provider's Fyatu account ID
    },
    metadata: {
      bookingId: bookingId,
      providerId: provider.id,
      serviceType: booking.serviceType
    }
  });

  return payout;
}

Batch Payouts

Process multiple payouts efficiently:
// Daily settlement for all drivers
async function processDailyDriverPayouts() {
  const pendingEarnings = await getUnpaidDriverEarnings();

  // Group by driver
  const byDriver = groupBy(pendingEarnings, 'driverId');

  const payouts = [];

  for (const [driverId, earnings] of Object.entries(byDriver)) {
    const driver = await Driver.findById(driverId);
    const totalAmount = earnings.reduce((sum, e) => sum + e.amount, 0);

    payouts.push({
      amount: totalAmount,
      currency: 'USD',
      reference: `DAILY-${driverId}-${Date.now()}`,
      description: `Daily earnings: ${earnings.length} trips`,
      recipient: {
        accountId: driver.fyatuClientId  // Driver's Fyatu account ID
      },
      metadata: {
        driverId: driverId,
        tripCount: earnings.length,
        tripIds: earnings.map(e => e.tripId)
      }
    });
  }

  // Process all payouts
  const results = await Promise.allSettled(
    payouts.map(p => fyatu.payouts.create(p))
  );

  // Handle results
  results.forEach((result, index) => {
    if (result.status === 'fulfilled') {
      markEarningsAsPaid(payouts[index].metadata.tripIds);
    } else {
      logPayoutFailure(payouts[index], result.reason);
    }
  });
}

Worker Virtual Cards

Issue cards for drivers/workers to use for expenses:
// Onboard driver with virtual card
async function onboardDriver(driver) {
  // Create cardholder
  const cardholder = await fyatu.cardholders.create({
    firstName: driver.firstName,
    lastName: driver.lastName,
    email: driver.email,
    phone: driver.phone,
    externalId: driver.id
  });

  // Issue virtual card
  const card = await fyatu.cards.create({
    cardholderId: cardholder.id,
    currency: 'USD',
    type: 'virtual',
    spendingLimit: {
      amount: 500,
      interval: 'daily'
    },
    metadata: {
      driverId: driver.id,
      purpose: 'fuel_and_expenses'
    }
  });

  driver.cardholderId = cardholder.id;
  driver.cardId = card.id;
  await driver.save();

  return card;
}

// Auto-fund card based on earnings
async function fundDriverCard(driverId, amount) {
  const driver = await Driver.findById(driverId);

  await fyatu.cards.fund(driver.cardId, {
    amount: amount,
    reference: `AUTOFUND-${driverId}-${Date.now()}`
  });
}

Accept Customer Payments

Collect payments for services:
// Customer books a ride
async function createRidePayment(ride) {
  const collection = await fyatu.collections.create({
    amount: ride.estimatedFare,
    currency: 'USD',
    reference: `RIDE-${ride.id}`,
    description: `Ride to ${ride.destination}`,
    customer: {
      email: ride.customer.email,
      phone: ride.customer.phone
    },
    metadata: {
      rideId: ride.id,
      customerId: ride.customerId,
      type: 'ride_payment'
    },
    redirectUrl: `https://app.yourplatform.com/rides/${ride.id}`,
    webhookUrl: 'https://api.yourplatform.com/webhooks/fyatu'
  });

  ride.paymentId = collection.id;
  ride.checkoutUrl = collection.checkoutUrl;
  await ride.save();

  return collection;
}

Why Fyatu for Gig Platforms?

BenefitDescription
Instant PayoutsWorkers receive funds in their Fyatu wallet immediately
No Bank DependenciesWorkers don’t need bank accounts to get paid
Simple OnboardingWorkers just need a Fyatu account
ScalableProcess thousands of payouts efficiently
Virtual CardsIssue cards for worker expenses
Workers can then withdraw from their Fyatu wallet to their preferred payment method.

Payout Timing

DestinationSpeed
Fyatu WalletInstant (seconds)
Virtual Card FundingInstant

Webhook Handling

app.post('/webhooks/fyatu', async (req, res) => {
  const event = req.body;

  switch (event.type) {
    case 'payout.completed':
      // Update worker's payment status
      await markPayoutComplete(event.data.reference, event.data.id);

      // Notify worker
      await sendPushNotification(event.data.metadata.driverId, {
        title: 'Payment Received',
        body: `$${event.data.amount} has been sent to your account`
      });
      break;

    case 'payout.failed':
      // Log failure and retry or notify
      await handlePayoutFailure(event.data);
      break;

    case 'collection.completed':
      // Customer paid, confirm booking
      await confirmBooking(event.data.metadata.rideId);
      break;

    case 'card.transaction.authorized':
      // Track driver spending
      await recordDriverExpense(event.data);
      break;
  }

  res.status(200).send('OK');
});

Handling Payout Failures

async function handlePayoutFailure(payoutData) {
  const { reference, failureReason, metadata } = payoutData;

  // Log the failure
  await PayoutLog.create({
    reference,
    status: 'failed',
    reason: failureReason,
    ...metadata
  });

  // Retry logic based on failure reason
  if (failureReason === 'TEMPORARY_ERROR') {
    // Retry after delay
    await queue.add('retry-payout', { reference }, { delay: 60000 });
  } else if (failureReason === 'INVALID_ACCOUNT') {
    // Notify worker to update payment details
    await notifyWorker(metadata.driverId, {
      message: 'Please update your payment details to receive your earnings'
    });
  }
}

Analytics & Reporting

Track payout performance:
// Get payout statistics
const stats = await fyatu.account.getTransactions({
  type: 'payout',
  startDate: '2026-01-01',
  endDate: '2026-01-31'
});

// Analyze
const summary = {
  totalPayouts: stats.length,
  totalAmount: stats.reduce((sum, t) => sum + t.amount, 0),
  avgPayout: totalAmount / stats.length,
  byStatus: groupBy(stats, 'status'),
  byMethod: groupBy(stats, 'paymentMethod')
};

Getting Started

1

Sign Up

2

Enable Payouts

Configure your payout settings and fund your wallet
3

Integrate

Use our APIs to automate worker payments
4

Test

Test payout flows in sandbox environment
5

Scale

Go live and pay thousands of workers daily

Resources