01.Pourquoi le CMI est incontournable pour votre e-commerce
Au Maroc, le Centre Monétique Interbancaire (CMI) est l'opérateur unique qui fédère l'ensemble des banques marocaines (Attijariwafa bank, Banque Populaire, Bank of Africa, CIH, Société Générale, Crédit du Maroc, etc.) ainsi que les réseaux internationaux (Visa, Mastercard, cpay).
Si le paiement à la livraison (Cash on Delivery) reste très répandu, il engendre un coût caché dramatique : 25% à 35% de taux d'échec et de retour, des livreurs immobilisés et une trésorerie retardée de 15 à 30 jours. L'encaissement direct par carte bancaire CMI supprime ces pertes.
Toutes les cartes bancaires marocaines et internationales sont acceptées sans friction ni redirection vers des passerelles étrangères non reconnues.
Authentification OTP par SMS ou application bancaire garantissant l'irrévocabilité du paiement et protégeant le marchand contre les contestations abusives.
02.Les 4 étapes pour obtenir votre agrément CMI
Avant de déployer votre code en production, vous devez compléter le parcours administratif et bancaire d'homologation :
Structure juridique et compte professionnel
Vous devez disposer d'une entreprise immatriculée au Maroc (SARL, SAS ou Auto-entrepreneur) et d'un compte bancaire professionnel ouvert auprès d'une banque marocaine.
Signature du Contrat VAD (Vente à Distance)
Faites la demande de contrat e-commerce VAD auprès de votre conseiller bancaire. La banque étudie votre dossier, définit vos taux de commission (généralement 1.2% à 2.5%) et transmet vos coordonnées au CMI pour création de votre compte marchand (clientid).
Audit de conformité & Tests en Sandbox
Le CMI vérifie les mentions légales obligatoires : CGV complètes, politique de remboursement, conformité CNDP (Loi 09-08) et certificat SSL actif. Vous effectuez ensuite les simulations de paiement requises sur la plateforme de test.
Réception de la clé de production & Passage en Direct
Une fois le procès-verbal de recette validé, le CMI vous délivre votre clé secrète de production (storeKey) pour activer les encaissements réels.
03.Architecture du Flux de Paiement 3D-Secure 2.0
Le paiement CMI s'effectue via une redirection sécurisée vers l'environnement PCI-DSS du CMI. Votre serveur applicatif ne manipule jamais directement les coordonnées de carte bancaire :
04.L'Algorithme de Signature SHA-512 (Spécification V3)
Toute tentative de paiement échoue avec l'erreur Invalid Hash Signature si une seule de ces 6 règles n'est pas scrupuleusement respectée :
- Exclusion des champs réservés : Retirer systématiquement
hash,storekeyetencodingdu calcul. - Tri insensible à la casse : Trier toutes les clés alphabétiquement en minuscules (ex:
amount,clientid,currency,oid,okUrl). - Échappement obligatoire : Remplacer chaque antislash
\par\\et chaque barre|par\|dans les valeurs. - Concaténation ordonnée : Joindre chaque valeur terminée par un séparateur
|. - Clé secrète finale : Ajouter la
storeKeyéchappée à la fin de la chaîne. - Digest Base64 : Calculer le hash SHA-512 et l'encoder en Base64.
05.Implémentation Complète sur Next.js App Router
Voici le code complet, sécurisé et prêt pour la production en utilisant le SDK triplew-cmi-morocco :
# Configuration Passerelle CMI Maroc CMI_CLIENT_ID=600001234 CMI_STORE_KEY=votreCleSecreteFournieParLeCMI123456 NODE_ENV=development # Basculer en 'production' pour les vrais paiements NEXT_PUBLIC_APP_URL=https://votre-boutique.ma
import { CMIGateway } from 'triplew-cmi-morocco';
export const cmiClient = new CMIGateway({
clientId: process.env.CMI_CLIENT_ID || '600001234',
storeKey: process.env.CMI_STORE_KEY || 'TEST_STORE_KEY',
isProduction: process.env.NODE_ENV === 'production',
okUrl: `${process.env.NEXT_PUBLIC_APP_URL}/checkout/success`,
failUrl: `${process.env.NEXT_PUBLIC_APP_URL}/checkout/failed`,
callbackUrl: `${process.env.NEXT_PUBLIC_APP_URL}/api/cmi/ipn`, // Notification IPN serveur
shopUrl: `${process.env.NEXT_PUBLIC_APP_URL}/boutique`,
currency: '504', // 504 = MAD (Dirham Marocain)
lang: 'fr'
});import { NextRequest, NextResponse } from 'next/server';
import { cmiClient } from '@/lib/cmi';
export async function POST(req: NextRequest) {
try {
const { orderId, totalAmount, customer } = await req.json();
if (!orderId || !totalAmount) {
return NextResponse.json({ error: 'Paramètres de commande incomplets' }, { status: 400 });
}
// 1. Génération des paramètres signés SHA-512
const paymentParams = cmiClient.createPaymentParams({
orderId: String(orderId),
amount: Number(totalAmount),
email: customer?.email,
billToName: customer?.fullName,
tel: customer?.phone
});
// 2. Génération du formulaire HTML auto-soumis pour redirection CMI
const autoSubmitHtml = cmiClient.createAutoSubmitHtml(paymentParams);
return new NextResponse(autoSubmitHtml, {
status: 200,
headers: { 'Content-Type': 'text/html; charset=utf-8' }
});
} catch (error) {
console.error('[CMI Checkout] Erreur initiation:', error);
return NextResponse.json({ error: 'Erreur passerelle CMI' }, { status: 500 });
}
}import { NextRequest, NextResponse } from 'next/server';
import { cmiClient } from '@/lib/cmi';
export async function POST(req: NextRequest) {
try {
const formData = await req.formData();
const payload: Record<string, string> = {};
formData.forEach((value, key) => { payload[key] = value.toString(); });
// Validation cryptographique timing-safe du hash de réponse
const validation = cmiClient.handleCallback(payload);
if (!validation.isValid) {
console.error('[CMI IPN] Alerte : Signature HASH CMI invalide ou falsifiée !');
return new NextResponse('FAILURE', { status: 400 });
}
if (validation.isApproved) {
const { orderId, amount, transactionId, authCode } = validation;
// TODO: Mettre à jour votre commande en BDD (ex: Prisma, Drizzle, Supabase)
// await db.orders.update({
// where: { id: orderId },
// data: { status: 'PAID', cmiTransId: transactionId, authCode }
// });
console.log(`[CMI IPN] Commande #${orderId} payée (${amount} MAD). TransID: ${transactionId}`);
// ⚠️ RÉPONSE IMPÉRATIVE EXIGÉE PAR LE CMI :
return new NextResponse('ACTION=POSTAUTH', {
status: 200,
headers: { 'Content-Type': 'text/plain' }
});
} else {
console.warn(`[CMI IPN] Paiement refusé pour commande #${validation.orderId}. Code: ${validation.errorCode}`);
return new NextResponse('APPROVED', { status: 200 });
}
} catch (err) {
console.error('[CMI IPN] Erreur interne:', err);
return new NextResponse('FAILURE', { status: 500 });
}
}06.Dictionnaire des Codes de Retour CMI
Lors de la réponse de la passerelle, le paramètre ProcReturnCode indique l'état exact de la transaction bancaire :
| ProcReturnCode | Signification | Diagnostic & Résolution |
|---|---|---|
| 00 | Transaction Approuvée | Autorisation bancaire accordée. Commande validée. |
| 05 | Ne pas honorer | Refus de la banque émettrice. Le client doit contacter son agence. |
| 51 | Provision insuffisante | Solde bancaire insuffisant sur le compte du porteur. |
| 54 | Carte expirée | Date d'expiration de la carte dépassée ou mal saisie. |
| 58 | Transaction non permise | Paiement en ligne non activé sur la carte bancaire. |
| 99 | Erreur système / Timeout | Problème technique temporaire de communication interbancaire. |
| Invalid Hash | Signature SHA-512 invalide | Clé storeKey erronée, tri incorrect ou caractères non échappés. |
07.Conformité CNDP (Loi 09-08) & Sécurité PCI-DSS
L'acceptation des paiements en ligne au Maroc impose le strict respect de la Loi 09-08 relative à la protection des données à caractère personnel encadrée par la CNDP :
Conformément aux normes PCI-DSS, votre application ne doit jamais enregistrer le numéro complet de carte, le CVV ou la date d'expiration en base de données.
Le traitement du webhook IPN doit être strictement idempotent pour éviter qu'un double envoi réseau ne valide deux fois une même commande.
08.Comparatif CMI : WooCommerce, Shopify ou Next.js sur Mesure ?
Si le Centre Monétique Interbancaire (CMI) reste le passage obligé pour encaisser les cartes bancaires marocaines, la méthode d'intégration varie drastiquement selon votre socle technique e-commerce. Chaque solution présente des compromis techniques et financiers notables :
Solution la plus courante pour les TPE au Maroc. L'intégration s'effectue via le plugin officiel CMI pour WooCommerce ou un module WordPress tiers.Points d'attention : risque fréquent de conflits lors des mises à jour WooCommerce/PHP, temps de chargement souvent dégradé et maintenance des hooks de confirmation de commande requise.
Shopify Payments n'étant pas disponible pour les comptes bancaires marocains, le CMI s'intègre via une passerelle de redirection externe hébergée (HPS).Le coût caché : Shopify prélève une commission supplémentaire (0.5% à 2% selon votre forfait) en plus des commissions bancaires CMI, rognant fortement vos marges.
Très implanté historiquement sur le marché marocain. Des modules CMI PrestaShop existent (payants ou fournis par des intégrateurs locaux). La gestion des logs de transaction et des retours IPN nécessite un suivi serveur rigoureux pour éviter les paniers orphelins.
L'architecture moderne par excellence. En connectant directement le CMI via notre SDK TypeScript open-source, vous éliminez tout tiers payant intermédiaire : 0% de frais Shopify additionnels, temps de chargement sous les 800ms, SEO e-commerce maximal et contrôle total sur le funnel d'achat.
| Plateforme | Type d'Intégration | Frais Additionnels | Performance & Conversion | Idéal Pour |
|---|---|---|---|---|
| WooCommerce | Extension / Plugin PHP | 0% (Commissions CMI seules) | Moyenne (ralentie par les plugins) | Catalogues modestes, boutiques WP existantes |
| Shopify | Passerelle externe HPS | +0.5% à +2% (Frais Shopify) | Bonne (mais redirection externe) | Boutiques mono-produits ou DNVB non techniques |
| PrestaShop | Module CMI tiers | 0% (Commissions CMI seules) | Correcte si hébergement dédié optimisé | E-commerçants B2B et catalogues complexes |
| Next.js Headless | API Directe & SDK TripleW | 0% (Commissions CMI seules) | Excellente (Core Web Vitals parfaits, < 1s) | Marques ambitieuses, SaaS, fort volume de vente |
09.Frais et Grille Tarifaire CMI Maroc 2026
La tarification de l'encaissement en ligne par le CMI au Maroc se décompose en trois postes principaux : les frais de dossier d'adhésion, la redevance annuelle de maintenance et le taux de commission par transaction négocié avec votre banque partenaire.
| Poste Tarifaire | Fourchette Indicative | Périodicité | Détails & Conditions |
|---|---|---|---|
| Frais d'Adhésion & Dossier CMI | 2 500 à 4 000 MAD HT | Unique (à l'ouverture) | Frais d'ouverture du compte marchand et configuration de la passerelle. |
| Redevance Annuelle Passerelle | 500 à 1 500 MAD HT | Annuelle | Maintenance technique, support et renouvellement des certificats de sécurité. |
| Commission Cartes Marocaines (CMI) | 1,2% à 2,5% HT | Par transaction | Taux appliqué sur les cartes émises par les banques marocaines (Attijari, BCP, BOA, CIH...). Dégressif avec le volume. |
| Commission Cartes Internationales | 2,8% à 3,2% HT | Par transaction | Cartes Visa et Mastercard étrangères. Des frais de conversion de change peuvent s'appliquer. |
| Caution / Réserve de Garantie (Rolling Reserve) | 5% à 10% (selon profil) | Bloqué 30 à 90 jours | Exigé par certaines banques pour les activités à risque élevé d'impayés ou de litiges clients. |
Simulateur de Rentabilité : Frais CMI vs Cash on Delivery (COD)
Comparez l'impact réel des commissions CMI face aux coûts cachés du paiement à la livraison au Maroc (taux de retour de 25% à 35%, frais de retour transporteur, trésorerie bloquée).
Suite à la décision n°152/D/2024 du Conseil de la Concurrence et aux directives de Bank Al-Maghrib, les commissions d'acquisition marchande sont en forte baisse. Pour adapter votre stratégie et choisir entre le CMI et des alternatives internationales, consultez nos analyses approfondies :
10.Données et Cartes de Test Sandbox CMI (Plateforme Homologation)
Pour obtenir la validation de votre procès-verbal (PV) de recette par l'équipe technique du CMI, vous devez exécuter une série de tests obligatoires sur leur passerelle sandbox (environnement testpayment.cmi.co.ma).
Voici les numéros de cartes de test standardisés et les comportements attendus lors de la phase d'homologation :
| Scénario de Test | Numéro de Carte Test | Expiration / CVV | OTP 3D-Secure | Code Retour Attendu |
|---|---|---|---|---|
| Paiement Réussi (Succès) | 4111 1111 1111 1111 | 12/28 - 123 | 123456 (ou tout code) | 00 (Approuvé) |
| Solde Insuffisant | 4000 0000 0000 0002 | 12/28 - 123 | 123456 | 51 (Provision insuffisante) |
| Carte Expirée | 4000 0000 0000 0003 | 01/24 - 123 | - | 54 (Carte expirée) |
| Refus d'Autorisation (Do Not Honor) | 4000 0000 0000 0005 | 12/28 - 123 | - | 05 (Ne pas honorer) |
- Signature SHA-512 : Vérifiez que votre calcul de hash correspond exactement à l'attendu du CMI en environnement de test avec votre
storeKeyde test fournie. - Accessibilité de l'URL IPN (Callback) : Le CMI doit impérativement pouvoir contacter votre webhook par requête POST HTTPS directe. Les URLs locales (
localhost) sont rejetées : utilisez un tunnel SSL (ngrok / Cloudflare Tunnel) ou votre serveur de staging en ligne. - Réponse ACTION=POSTAUTH : Assurez-vous que votre endpoint IPN retourne le statut HTTP 200 avec le corps brut
ACTION=POSTAUTHen moins de 3 secondes, sans redirection ni balise HTML.
Quelle plateforme e-commerce choisir au Maroc en 2026 ?
Découvrez notre comparatif complet entre YouCan, Shopify, WooCommerce et Next.js Commerce sur les critères de commissions, passerelle CMI et SEO.
Shopify vs Next.js E-Commerce au Maroc
Analyse détaillée du coût total de possession (TCO), des blocages de paiement multidevises et des gains de conversion sur mesure.
Besoin d'intégrer le CMI sur votre plateforme e-commerce ?
L'équipe d'ingénieurs TripleW Digital vous accompagne de la constitution du dossier VAD bancaire jusqu'à la mise en production sécurisée de vos paiements.
Guides techniques, benchmarks et décryptages digitaux au Maroc
Rejoignez fondateurs et directeurs techniques au Maroc pour recevoir nos analyses exclusives : TCO Next.js, passerelle CMI, SEO local et conformité CNDP.
