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.
Power your travel business with FYATU. Accept bookings from African travelers and issue virtual cards for corporate travel expenses.
The Challenge
Travel and hospitality businesses face:
- Payment diversity - Travelers use various payment methods
- Corporate travel - Managing employee travel expenses
- Multi-currency - Handling different currencies for bookings
- Refunds - Processing cancellations and refunds
The FYATU Solution
Collections
Accept bookings from 1M+ Fyatu users paying from their wallets
Virtual Cards
Issue USD virtual Mastercards for corporate travel and expenses
Payouts
Pay partners directly to their Fyatu wallet balances
Booking Payments
Accept Booking Payment
// Create booking payment
async function createBookingPayment(booking) {
const collection = await fyatu.collections.create({
amount: booking.totalAmount,
currency: 'USD',
reference: `BOOK-${booking.id}`,
description: `${booking.type}: ${booking.title}`,
customer: {
email: booking.customer.email,
name: booking.customer.fullName,
phone: booking.customer.phone
},
metadata: {
bookingId: booking.id,
bookingType: booking.type, // flight, hotel, tour, etc.
travelDate: booking.travelDate,
guests: booking.guestCount
},
redirectUrl: `https://yourtravelsite.com/booking/${booking.id}/confirmed`,
webhookUrl: 'https://api.yourtravelsite.com/webhooks/fyatu'
});
booking.paymentId = collection.id;
booking.checkoutUrl = collection.checkoutUrl;
await booking.save();
return collection;
}
Handle Booking Confirmation
app.post('/webhooks/fyatu', async (req, res) => {
const event = req.body;
if (event.type === 'collection.completed') {
const { bookingId, bookingType } = event.data.metadata;
const booking = await Booking.findById(bookingId);
booking.status = 'confirmed';
booking.paidAt = new Date();
await booking.save();
// Send confirmation
await sendBookingConfirmation(booking);
}
res.status(200).send('OK');
});
Corporate Travel Cards
Issue cards for business travelers:
// Issue travel card for employee
async function issueTravelCard(employee, trip) {
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: trip.approvedBudget,
interval: 'total' // One-time limit
},
expiresAt: trip.endDate,
metadata: {
employeeId: employee.id,
tripId: trip.id,
destination: trip.destination,
purpose: trip.purpose
}
});
// Fund the card
await fyatu.cards.fund(card.id, {
amount: trip.approvedBudget,
reference: `TRAVEL-${trip.id}`
});
return card;
}
Track Travel Expenses
app.post('/webhooks/fyatu', async (req, res) => {
const event = req.body;
if (event.type === 'card.transaction.authorized') {
const { tripId, employeeId } = event.data.metadata;
// Log expense
await TravelExpense.create({
tripId: tripId,
employeeId: employeeId,
amount: event.data.amount,
merchant: event.data.merchantName,
category: categorizeExpense(event.data.merchantCategory),
timestamp: new Date()
});
// Check remaining budget
const trip = await Trip.findById(tripId);
const totalSpent = await getTripSpending(tripId);
const remaining = trip.approvedBudget - totalSpent;
if (remaining < trip.approvedBudget * 0.2) {
await notifyTravelManager({
message: `${employee.name}'s travel budget is 80% used`,
tripId: tripId
});
}
}
res.status(200).send('OK');
});
function categorizeExpense(mcc) {
const categories = {
'3000-3999': 'flights',
'7011': 'hotels',
'7512': 'car_rental',
'5812': 'meals',
'4121': 'taxi'
};
// ... categorization logic
}
Booking Cancellations & Refunds
async function cancelBooking(bookingId, reason) {
const booking = await Booking.findById(bookingId);
// Calculate refund based on cancellation policy
const refundAmount = calculateRefund(booking);
if (refundAmount > 0) {
const refund = await fyatu.refunds.create(booking.paymentId, {
amount: refundAmount,
reason: reason,
reference: `CANCEL-${bookingId}`
});
booking.refundId = refund.id;
booking.refundAmount = refundAmount;
}
booking.status = 'cancelled';
booking.cancelledAt = new Date();
await booking.save();
// Send cancellation confirmation
await sendCancellationEmail(booking, refundAmount);
return booking;
}
function calculateRefund(booking) {
const daysUntilTravel = daysBetween(new Date(), booking.travelDate);
if (daysUntilTravel > 30) return booking.totalAmount; // Full refund
if (daysUntilTravel > 14) return booking.totalAmount * 0.75; // 75%
if (daysUntilTravel > 7) return booking.totalAmount * 0.50; // 50%
if (daysUntilTravel > 2) return booking.totalAmount * 0.25; // 25%
return 0; // No refund
}
Partner Payouts
Pay hotels, tour operators, and partners directly to their Fyatu wallets:
// Settlement to hotel partner
async function settleWithHotel(bookings, hotel) {
const totalAmount = bookings.reduce((sum, b) => sum + b.hotelAmount, 0);
const commission = totalAmount * 0.15; // 15% commission
const settlementAmount = totalAmount - commission;
// Pay directly to partner's Fyatu wallet
const payout = await fyatu.payouts.create({
amount: settlementAmount,
currency: 'USD',
reference: `HOTEL-${hotel.id}-${Date.now()}`,
description: `Settlement for ${bookings.length} bookings`,
recipient: {
accountId: hotel.fyatuClientId // Partner's Fyatu account ID
},
metadata: {
hotelId: hotel.id,
bookingIds: bookings.map(b => b.id),
periodStart: bookings[0].createdAt,
periodEnd: bookings[bookings.length - 1].createdAt
}
});
return payout;
}
Getting Started
Configure Apps
Set up Collection App for payments and Issuing App for virtual cards
Integrate Booking Flow
Add FYATU checkout to your booking process
Launch
Start accepting bookings and issuing travel cards
Resources