Wave Money exploded in Senegal (2018) then expanded to Ivory Coast (2021), Mali, Burkina Faso, Uganda. For a pan-African e-commerce, integrating Wave in several countries is tempting but tricky: each country has its endpoint, limits, currencies, fees.
TL;DR
- Wave SN: XOF, 1% fees, ~52% market leader.
- Wave CI: XOF, 1% too, ~30% share, strong growth.
- Separate API endpoints per country + separate API keys.
- Recommended architecture: 1 Wave connector with per-country config.
Wave SN vs Wave CI comparison
| Criterion | Wave Senegal | Wave Côte d'Ivoire |
|---|---|---|
| Launch | 2018 | 2021 |
| Currency | XOF | XOF |
| Merchant fees | 1% | 1% |
| Daily payment cap | 5M XOF/day | 3M XOF/day |
| API endpoint | api.wave.com (SN) | api.wave.com/ci (CI) |
| Webhook | HMAC-SHA256 | HMAC-SHA256 |
| Settlement | T+1 UEMOA IBAN | T+1 UEMOA IBAN |
| Sandbox | ✗ | ✗ |
| Market share | ~52% | ~30% |
| Competition | OM, Free | MTN MoMo, Orange CI |
No sandbox in either country forces production testing with small amounts.
Multi-country connector architecture
`ts
type WaveCountry = 'sn' | 'ci' | 'ml' | 'bf' | 'ug';
interface WaveConfig {
country: WaveCountry;
apiKey: string;
webhookSecret: string;
apiBase: string;
currency: string;
maxAmountPerDay: number;
}
const WAVE_CONFIGS: Record
sn: { country: 'sn', apiBase: 'https://api.wave.com', currency: 'XOF', maxAmountPerDay: 5_000_000 },
ci: { country: 'ci', apiBase: 'https://api.wave.com/ci', currency: 'XOF', maxAmountPerDay: 3_000_000 },
ml: { country: 'ml', apiBase: 'https://api.wave.com/ml', currency: 'XOF', maxAmountPerDay: 2_000_000 },
bf: { country: 'bf', apiBase: 'https://api.wave.com/bf', currency: 'XOF', maxAmountPerDay: 2_000_000 },
ug: { country: 'ug', apiBase: 'https://api.wave.com/ug', currency: 'UGX', maxAmountPerDay: 7_500_000 },
};
function getWaveConfig(country: WaveCountry): WaveConfig {
const base = WAVE_CONFIGS[country];
const apiKey = process.env[WAVE_${country.toUpperCase()}_API_KEY];
const webhookSecret = process.env[WAVE_${country.toUpperCase()}_WEBHOOK_SECRET];
if (!apiKey || !webhookSecret) throw new Error(Missing Wave config for: ${country});
return { ...base, apiKey, webhookSecret };
}
export async function initWavePayment(country: WaveCountry, orderId: string, amountXof: number) {
const config = getWaveConfig(country);
if (amountXof > config.maxAmountPerDay) {
throw new Error(Amount exceeds Wave ${country.toUpperCase()} daily cap);
}
const res = await fetch(${config.apiBase}/v1/checkout/sessions, {
method: 'POST',
headers: { 'Authorization': Bearer ${config.apiKey}, 'Content-Type': 'application/json' },
body: JSON.stringify({
amount: String(amountXof),
currency: config.currency,
success_url: https://kolonell.com/checkout/success?order=${orderId},
error_url: https://kolonell.com/checkout/error?order=${orderId},
client_reference: orderId,
}),
});
return res.json();
}
`
Unified webhook handler
`ts
// app/api/webhooks/wave/[country]/route.ts
Need a professional website?
Kolonell builds websites that attract clients, optimized for the Sénégalese market. Free quote in 2 minutes.
export async function POST(req: NextRequest, { params }: { params: { country: string }}) {
const country = params.country as WaveCountry;
const config = getWaveConfig(country);
const rawBody = await req.text();
const signature = req.headers.get('wave-signature') ?? '';
const expected = crypto
.createHmac('sha256', config.webhookSecret)
.update(rawBody)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return NextResponse.json({ error: 'invalid_signature' }, { status: 401 });
}
const event = JSON.parse(rawBody);
// ... idempotency + persist
}
`
Exposed URLs: https://kolonell.com/api/webhooks/wave/sn and https://kolonell.com/api/webhooks/wave/ci.
Auto country detection
In checkout, detect country from:
- Entered phone (E.164 prefix)
- IP geolocation
- User manual selection
`ts
function detectWaveCountry(msisdn: string): WaveCountry | null {
if (msisdn.startsWith('+221')) return 'sn';
if (msisdn.startsWith('+225')) return 'ci';
if (msisdn.startsWith('+223')) return 'ml';
if (msisdn.startsWith('+226')) return 'bf';
if (msisdn.startsWith('+256')) return 'ug';
return null;
}
`
Multi-account Wave strategy
For pan-African e-commerce, two options:
Option A — One Wave account per country
- Wave SN account with SN legal entity
- Wave CI account with CI legal entity
- Etc.
- Local IBAN settlement per country
Option B — One Wave account in main country
- SN account only, declare international revenue
- Tolerance for minority CI/ML payments
- Central XOF settlement
Option A is cleaner fiscally but heavier. Option B works as long as non-main country revenue stays <30%.
Common pitfalls
- Mixing API keys — using SN key on CI endpoint = 401. Always prefix with country.
- Daily cap — past it, transactions rejected without clear customer message. Always validate amount before init.
- Multi-country webhook URL — prefer parameterized route
/wave/[country]over separate routes. - Tax reporting — each country revenue = local declaration obligation. Build into your accounting.
Real case — Dakar → Abidjan e-commerce shop
SN fashion shop, CI market opening 2025:
- 6 months post-launch CI: 22% of total revenue
- Wave CI = 68% of CI payments (vs 52% in SN)
- Difference: Wave CI captures younger users; in SN, OM is more entrenched
FAQ
Q: Does Wave CI accept payments from SN numbers?
A: No, payer must have a Wave CI account (CI number). For an SN customer paying in CI, requires SN payment.
Q: Wave CI vs SN onboarding delay?
A: SN: 5-10 business days. CI: 7-15 (stricter KYC, mandatory CI RCCM).
Q: Wave US or Europe?
A: No Wave presence outside Africa as of May 2026. Stripe remains the option for those markets.
Conclusion
Multi-country Wave is feasible and rewarding for an e-commerce scaling beyond Senegal. Technical complexity is manageable with a good connector abstraction. Real challenge is legal/fiscal: multiplying local entities costs admin time. Test first with Option B (single account), scale complexity as secondary country revenue exceeds 30%.
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.

