Shopify est la solution facile, mais 4 % de commission sur 50M FCFA/mois = 2M FCFA/mois jeté. Pour un e-commerce qui scale au-delà de 30M FCFA mensuel — typiquement les marketplaces Lagos, Abidjan, Nairobi, Douala — Medusa devient la bonne réponse. Voici comment monter une stack pan-africaine.
TL;DR
- Medusa = backend Node.js + Postgres open-source, frontend Next.js de votre choix.
- Coût hébergement : 35-80€/mois (Hetzner Cloud + Neon Postgres) vs 80€/mois Shopify Basic + 4 % de fees.
- Couverture paiement : Wave (SN, CI), MTN MoMo (CI, GH, NG, CM, UG, RW, ZM), Airtel Money (NG, KE, TZ, MW), Orange Money (SN, CI, CM, ML, BF, GN, MG), M-Pesa (KE, TZ).
Pourquoi Medusa pan-africain en 2026
Le commerce en Afrique se fragmente par devise et passerelle :
- UEMOA (XOF) : Wave + Orange Money + PayDunya
- CEMAC (XAF) : Orange Money + MTN MoMo + Express Union
- Nigeria (NGN) : Paystack + Flutterwave + Squad
- Ghana (GHS) : MTN MoMo + Vodafone Cash + Hubtel
- Kenya/Tanzanie (KES/TZS) : M-Pesa + Tigo Pesa + Stripe
- Rwanda/Ouganda (RWF/UGX) : MTN MoMo + Airtel Money
Shopify ne supporte nativement aucun de ces moyens (sauf Stripe/Paystack via partenaires). Medusa permet de coder un PaymentProvider par passerelle et de couvrir 19 pays africains.
Architecture cible
`
[Next.js storefront]
↓
[Medusa.js backend (Node)]
↓
[Postgres (Neon)] + [Redis (Upstash)]
↓
[Custom Payment Providers]
├── WavePaymentProvider (UEMOA)
├── MtnMomoPaymentProvider (Anglophone + CEMAC)
├── MPesaPaymentProvider (Afrique de l'Est)
├── PaystackPaymentProvider (NG, GH)
└── StripePaymentProvider (international)
↓
[Algolia (search) + Cloudinary (images)]
`
Étape 1 — initialiser Medusa
`bash
# Crée le backend
npx create-medusa-app@latest --skip-db
cd kolonell-store
yarn install
`
Configurez medusa-config.js :
`js
module.exports = defineConfig({
projectConfig: {
redis_url: process.env.REDIS_URL,
database_url: process.env.DATABASE_URL,
database_type: 'postgres',
},
modules: [
{ resolve: '@medusajs/cache-redis', options: { redisUrl: process.env.REDIS_URL } },
{ resolve: '@medusajs/event-bus-redis', options: { redisUrl: process.env.REDIS_URL } },
{ resolve: './src/modules/wave-payment' },
{ resolve: './src/modules/mtn-momo-payment' },
{ resolve: './src/modules/mpesa-payment' },
],
});
`
Étape 2 — Wave Payment Provider (custom)
`ts
// src/modules/wave-payment/service.ts
import { AbstractPaymentProvider } from '@medusajs/framework/utils';
class WavePaymentProvider extends AbstractPaymentProvider {
static identifier = 'wave';
async initiatePayment({ amount, currency_code, data }) {
const res = await fetch('https://api.wave.com/v1/checkout/sessions', {
method: 'POST',
headers: {
'Authorization': Bearer ${process.env.WAVE_API_KEY},
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: String(amount),
currency: currency_code.toUpperCase(),
success_url: data.success_url,
error_url: data.error_url,
client_reference: data.cart_id,
}),
});
const session = await res.json();
return { data: { wave_id: session.id, wave_launch_url: session.wave_launch_url } };
}
async authorizePayment({ data }) {
const res = await fetch(
https://api.wave.com/v1/checkout/sessions/${data.wave_id},
{ headers: { 'Authorization': Bearer ${process.env.WAVE_API_KEY} } }
);
const session = await res.json();
return {
status: session.payment_status === 'succeeded' ? 'authorized' : 'pending',
data: session,
};
}
async capturePayment(input) { return { data: input.data }; }
async cancelPayment(input) { return { data: input.data }; }
async refundPayment({ data, amount }) {
await fetch('https://api.wave.com/v1/refunds', {
method: 'POST',
headers: {
'Authorization': Bearer ${process.env.WAVE_API_KEY},
'Idempotency-Key': refund_${data.wave_id}_${amount},
},
body: JSON.stringify({ payment_id: data.wave_id, amount: String(amount) }),
Besoin d'un site web professionnel ?
Kolonell crée des sites web qui attirent des clients, optimisés pour le marché sénégalais. Devis gratuit en 2 minutes.
});
return { data };
}
}
export default WavePaymentProvider;
`
Étape 3 — MTN MoMo Provider (Anglophone Africa)
MTN MoMo couvre Ghana, Côte d'Ivoire, Cameroun, Ouganda, Rwanda, Zambie, Bénin :
`ts
// src/modules/mtn-momo-payment/service.ts
class MtnMomoProvider extends AbstractPaymentProvider {
static identifier = 'mtn-momo';
async initiatePayment({ amount, currency_code, data }) {
const apiUserId = process.env.MTN_API_USER_ID;
const apiKey = process.env.MTN_API_KEY;
const subKey = process.env.MTN_SUB_KEY;
// 1. Get OAuth token
const tokenRes = await fetch('https://sandbox.momodeveloper.mtn.com/collection/token/', {
method: 'POST',
headers: {
'Authorization': Basic ${Buffer.from(${apiUserId}:${apiKey}).toString('base64')},
'Ocp-Apim-Subscription-Key': subKey,
},
});
const { access_token } = await tokenRes.json();
// 2. Request to pay
const referenceId = crypto.randomUUID();
await fetch('https://sandbox.momodeveloper.mtn.com/collection/v1_0/requesttopay', {
method: 'POST',
headers: {
'Authorization': Bearer ${access_token},
'X-Reference-Id': referenceId,
'X-Target-Environment': 'sandbox',
'Ocp-Apim-Subscription-Key': subKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: String(amount),
currency: currency_code.toUpperCase(),
externalId: data.cart_id,
payer: { partyIdType: 'MSISDN', partyId: data.payer_msisdn },
payerMessage: 'Order ' + data.cart_id,
payeeNote: 'Kolonell store',
}),
});
return { data: { mtn_reference: referenceId } };
}
async authorizePayment({ data }) {
// Poll status
const tokenRes = await fetch('https://sandbox.momodeveloper.mtn.com/collection/token/', { /* ... */ });
const { access_token } = await tokenRes.json();
const statusRes = await fetch(
https://sandbox.momodeveloper.mtn.com/collection/v1_0/requesttopay/${data.mtn_reference},
{ headers: { 'Authorization': Bearer ${access_token}, 'X-Target-Environment': 'sandbox' } }
);
const status = await statusRes.json();
return { status: status.status === 'SUCCESSFUL' ? 'authorized' : 'pending', data: status };
}
}
`
Étape 4 — frontend Next.js storefront
Medusa fournit un starter Next.js. Adaptez le composant Checkout pour proposer le bon provider selon le pays détecté :
`tsx
// app/checkout/payment-method.tsx
const providers = useMemo(() => {
switch (cart.region.country_code) {
case 'sn':
case 'ci': return ['wave', 'orange-money', 'paydunya'];
case 'gh': return ['mtn-momo', 'vodafone-cash', 'paystack'];
case 'ng': return ['paystack', 'flutterwave'];
case 'ke':
case 'tz': return ['mpesa', 'stripe'];
case 'cm': return ['orange-money', 'mtn-momo', 'express-union'];
default: return ['stripe'];
}
}, [cart.region.country_code]);
`
Étape 5 — déploiement & coût mensuel
| Composant | Service | Coût/mois |
|---|---|---|
| Medusa backend | Hetzner Cloud CX21 (4 vCPU, 8 GB) | 8 € |
| Postgres | Neon Pro (5 GB) | 19 € |
| Redis | Upstash Free → Pay (faible volume) | 0-5 € |
| Storefront Next.js | Vercel Hobby ou Cloudflare Pages | 0-20 € |
| CDN images | Cloudflare R2 | 5-15 € |
| Domaine + DNS | Cloudflare | 1 € |
| Total | 33-68 €/mois |
À comparer à Shopify Basic (29 €/mois) + 2 % transaction si paiement non-Shopify Payments sur volume 50M FCFA = ~840 €/mois extra.
Pièges connus
- Medusa v2 vs v1 : la v2 (sortie fin 2024) refactore les modules. Tutoriels v1 obsolètes — toujours vérifier la version doc.
- Migrations Postgres : Medusa génère les schémas, mais en pan-africain multi-devise, vérifier le scaling sur
pricestable. - Performance images : Cloudinary > Cloudflare Images si vous voulez les transformations à la volée.
- Sandbox MTN MoMo : très instable, prévoir un fallback fixture local pour les tests CI.
FAQ
Q : Medusa fonctionne avec Vercel ?
R : Le storefront Next.js oui (Edge runtime). Le backend Medusa nécessite Node long-running → préférer Hetzner, Railway, Render ou Fly.io.
Q : Multi-devise XOF + NGN + KES dans la même boutique ?
R : Oui via les Regions de Medusa. Chaque region = devise + pays + providers.
Q : Combien d'heures pour la stack complète ?
R : ~14 jours-développeur (1 dev senior). 2 jours setup + auth, 5 jours providers paiement, 4 jours storefront + checkout, 3 jours admin & tests.
Conclusion
Medusa devient en 2026 le choix pragmatique pour les e-commerces panafricains qui veulent garder le contrôle, payer 8x moins de fees, et brancher 5+ passerelles locales. Le ticket d'entrée technique est plus haut que Shopify, mais le ROI à 6 mois est sans appel sur les volumes > 30M FCFA/mois.
Mohamed Bah
Fondateur, Kolonell
Passionné par le digital et l'entrepreneuriat en Afrique, Mohamed accompagne les entreprises sénégalaises dans leur transformation digitale depuis 2020. Fondateur de Kolonell, il croit que chaque PME mérite une présence en ligne professionnelle et accessible.

