Francophone African boutique hotels — Saly Senegal, Cap Skirring, Assinie Ivory Coast, Diani Kenya, Zanzibar — pay an average 22% commission to Booking.com / Expedia. For a 50,000-150,000 XOF/night hotel, that's 11-33K XOF lost per booking. Direct booking changes the game.
TL;DR
- Direct site + booking engine = -18-25% OTA commission recovered.
- Stack: Next.js + booking engine + channel manager + email/WhatsApp marketing.
- 30-50% revenue in direct booking is healthy goal (vs 100% Booking.com).
Direct vs OTA economics
12-room boutique hotel, 50K XOF/night avg, 65% occupancy:
| Source | Nights/year | Revenue | OTA commission | Hotel net |
|---|---|---|---|---|
| 100% Booking.com | 2,847 | 142M XOF | 28.4M (20%) | 113.6M |
| 60% Booking + 40% direct | 2,847 | 142M | 17.0M | 125M (+11.4M) |
| 30% Booking + 70% direct | 2,847 | 142M | 8.5M | 133.5M (+19.9M) |
20M XOF/year = ~6-month ROI on direct booking investment.
Hotel site + booking architecture
`
[Hotel site]
├── Hero + room gallery + restaurant + spa
├── Integrated booking engine
├── Customer reviews (Google + TripAdvisor + own)
├── Visible dynamic pricing
├── Neighborhood / local activities
└── Returning-customer promo code (-15%)
[Booking engine]
├── Real-time availability (PMS sync)
├── Room type + dates selection
├── Add-ons (breakfast, spa, airport transfers)
├── Promo code
├── Wave / Stripe / card payment
└── Instant confirmation
`
Step 1 — custom booking engine
`tsx
'use client';
export default function BookingEngine() {
const [dates, setDates] = useState({ checkIn: null, checkOut: null });
const [guests, setGuests] = useState({ adults: 2, children: 0 });
const [availableRooms, setAvailableRooms] = useState([]);
async function searchAvailability() {
const res = await fetch('/api/availability', {
method: 'POST',
body: JSON.stringify({ ...dates, ...guests }),
});
setAvailableRooms(await res.json());
}
return (
{availableRooms.length > 0 && ( {availableRooms.map(room => ( ))} )}Book direct - Save 15%
);
}
function RoomCard({ room, dates, onSelect }) {
const nights = differenceInDays(dates.checkOut, dates.checkIn);
const totalPrice = room.pricePerNight * nights;
return (
{room.description} {room.amenities.slice(0, 4).map(a => {nights} night(s) · {room.pricePerNight.toLocaleString()}/night Book Kolonell builds websites that attract clients, optimized for the Sénégalese market. Free quote in 2 minutes. ✓ Free cancellation up to D-2{room.name}
Need a professional website?
✓ No hidden fees
);
}
`
Step 2 — channel manager for sync
Prevents overbooking. Syncs availability across:
- Direct site
- Booking.com
- Expedia
- Airbnb (if applicable)
- Trivago (meta-search)
| Channel manager | Monthly cost | Notes |
|---|---|---|
| SiteMinder | €100-300/month | Most complete |
| Cloudbeds | $150-400/month | All-in-one (PMS + CM + booking engine) |
| Hotelogix | $80-200/month | Good price-quality |
| RoomCloud | €60-150/month | European, FR support |
| Beds24 | €30-100/month | Cheap, configurable |
Step 3 — returning customer capture
Lock in customers for future direct bookings, no Booking.com:
`
[Customer check-out]
↓
[D+1 email: thanks + stay photos]
↓
[D+7: Google + TripAdvisor review request]
↓
[D+30: -15% direct return promo code]
↓
[Customer birthday: exclusive offer]
↓
[Seasons: exclusive quarterly newsletter]
`
Key strategy: get email signed at check-in (not just passport).
Step 4 — direct booking meta-search
Trivago / Google Hotels / Kayak compare Booking.com prices vs direct site. If you're cheaper direct → +50% conversions.
`json
{
"@context": "https://schema.org",
"@type": "Hotel",
"name": "Riad Almadies",
"address": "...",
"priceRange": "60K-180K XOF/night",
"starRating": { "@type": "Rating", "ratingValue": "4" },
"containsPlace": [{
"@type": "HotelRoom",
"bed": "Queen",
"occupancy": { "@type": "QuantitativeValue", "minValue": 1, "maxValue": 2 },
"offers": {
"@type": "Offer",
"price": "65000",
"priceCurrency": "XOF",
"availability": "https://schema.org/InStock"
}
}]
}
`
Step 5 — dynamic pricing
See Airbnb dynamic pricing method →.
Hotel tools:
- Duetto
- IDeaS
- Atomize
- Beyond (originally Airbnb but OK hotel)
Variables:
- Day of week
- Seasonality
- Local competition (price scraping)
- Booking lead time
- Events (AFCON, Magal, EU school holidays)
Real case — Saly boutique hotel
| Metric | Before | After 12 months |
|---|---|---|
| Booking.com bookings | 92% | 48% |
| Direct site bookings | 8% | 52% |
| OTA commission paid/year | 22M XOF | 11M XOF |
| Total annual revenue | 110M | 132M |
| Net margin | 65M | 95M (+46%) |
Common pitfalls
- Higher price than Booking.com — Booking imposes price parity. Trick: better perks (breakfast included, upgrade, late check-out) without showing lower price.
- No email strategy — mailing list = under-leveraged treasure.
- Slow site — booking engine must load <2s. Lazy load + edge.
- No WhatsApp Business — for customers wanting to negotiate or ask info.
- Misconfigured channel manager — overbookings = reputation catastrophe.
FAQ
Q: Does Stripe accept Senegal hotels?
A: Not directly (SN incorporation). Solutions: CI / Mauritius entity + Stripe, or PayDunya for XOF customers + Stripe for EUR customers.
Q: How long to migrate 50% revenue to direct?
A: 12-18 months on clean execution. Compounding: reviews + SEO + returning customers.
Q: Will Booking.com penalize?
A: No if you respect parity and keep providing volume. But avoid aggressively promoting "direct cheaper".
Conclusion
Direct booking is the #1 investment for an African boutique hotel in 2026. Site + engine + channel manager + email = 18 months to recover 30-50% revenue from OTAs. Net margin +30-50% vs 100% Booking.com.
Mohamed Bah
Fondateur, Kolonell
Passionate about digital and entrepreneurship in Africa, Mohamed has been helping Sénégalese businesses with their digital transformation since 2020. Founder of Kolonell, he believes every SME deserves a professional and accessible online présence.


