Mirakl n'est pas une marketplace où vendre. C'est le logiciel avec lequel un retailer monte la sienne : Leroy Merlin, Carrefour, Kingfisher, Macy's ou Best Buy figurent aujourd'hui comme clients sur le site de Mirakl. Quand l'un d'eux vous invite, vous vendez chez l'opérateur (ses catégories, sa commission, son contrat), mais votre Odoo parle à l'API de Mirakl, la même pour tous. Un connecteur Mirakl bien conçu n'est pas « le connecteur de Leroy Merlin » : ce sont N marketplaces avec une seule API et des identifiants différents. Et le plus difficile n'est pas l'API : c'est de répartir le stock entre les canaux qui regardent le même entrepôt.
Correction apportée à notre propre site : pendant des mois, nous avons traité Leroy Merlin et GACD comme des intégrations distinctes. Ce sont deux comptes du même connecteur : le même code avec un hôte, une clé et un catalogue différents.
Ce que tous les opérateurs Mirakl ont en commun et ce qui change
L'API vendeur de Mirakl a un code d'opération pour chaque chose, le même quel que soit l'opérateur : OR11 liste les commandes, OR23 et OR24 envoient le suivi et marquent l'expédition, OR28 rembourse, OF01 envoie des offres par fichier, IV01 renvoie les documents de règlement, M11 est la messagerie avec l'acheteur et SH21 liste les transporteurs. Un opérateur peut avoir désactivé certaines familles (certains n'ont ni messagerie ni transporteurs, et le connecteur marque l'endpoint comme indisponible en cas de 404 ou de 410), mais lorsqu'elle est exposée, c'est le même appel.
Ce qui change, c'est tout ce qui n'est pas l'API : l'hôte (adeo-marketplace.mirakl.net chez Leroy Merlin), la clé et la boutique, l'arbre des catégories et les attributs obligatoires (4 844 catégories et 35 364 attributs sur notre compte Leroy Merlin), les transporteurs admis (165 codes), les motifs de remboursement, la devise et, surtout, le mode de taxes : certains envoient les prix TTC (TAX_INCLUDED) et d'autres HT (TAX_EXCLUDED). Ce point nous a valu un vrai défaut : le connecteur prenait le prix TTC comme base, Odoo ajoutait de nouveau la TVA et 48,86 € entraient comme 59,12 €. Vérifié sur les 20 commandes réelles du compte.
Comment le modéliser dans Odoo : un compte par opérateur
Dans notre connecteur Mirakl, chaque opérateur est une instance : un enregistrement avec son URL de base, son URL d'API, sa clé, sa boutique, sa société, son entrepôt et son équipe commerciale. En testant la connexion, il lit /platform/configuration, /account et /channels et note quelle plateforme répond, de quelle boutique il s'agit et quelles fonctions elle expose. Sur la capture, la plateforme détectée est « Marketplace Adeo » et le fournisseur détecté, leroy_merlin.

Tout ce qui concerne l'opérateur dépend de l'instance : le dictionnaire de catégories, d'attributs et de valeurs (unique par instance et par code, donc deux opérateurs ne se marchent jamais dessus), le mappage des catégories et des transporteurs, et les règles de prix et de stock. Un produit Odoo a un binding par instance : le même produit, une offre différente chez chaque opérateur, avec son SKU, son prix et sa quantité. Ajouter un second opérateur (GACD, dont l'API vendeur répond sur tdmp.mirakl.net, ou tout autre) revient à ajouter une instance. Les profils du catalogue ne font que remplir des valeurs par défaut ; le code qui parle à Mirakl est unique.
Le vrai problème : répartir le stock
Deux opérateurs Mirakl, ManoMano, Amazon, Temu ou votre site peuvent regarder le même entrepôt. Seuls les deux premiers sont Mirakl : les autres ont leur propre API vendeur (Amazon, la SP-API) et sont des connecteurs à part. Mais tous vendent sur le même stock et aucun ne connaît les autres : chacun reçoit la quantité que vous exportez et vend dessus jusqu'à l'export suivant. Cela ne se résout pas « en temps réel », car ni l'API ni l'opérateur ne fonctionnent ainsi ; cela se résout avec des règles par canal. Chaque instance décide de quatre choses avant de publier une quantité :
- Quelle quantité elle regarde : disponible, prévue, libre (hors réservé) ou disponible uniquement dans les entrepôts de cette instance.
- Combien elle met de côté : un volant de sécurité par instance qui couvre les ventes des autres canaux entre deux exports.
- Minimum pour publier : si, après le volant, il reste moins de N unités, on publie zéro : vendre la dernière unité à trois endroits est la survente classique.
- Maximum publié : un plafond par instance, pour ne pas montrer à un opérateur un stock déjà promis à un autre.
L'ordre est dans le code : quantité selon la stratégie, moins le volant, zéro si le minimum n'est pas atteint, écrêtage au maximum. Avec 12 unités libres, volant 2, minimum 3 et maximum 5, chaque opérateur voit 5. Si tous reçoivent simplement la quantité disponible, le premier qui vend la dernière unité laisse les autres vendre du vent. Nous traitons le volant et la cadence dans stock en temps réel pour les marketplaces, et la façon de tout piloter depuis un seul Odoo dans vendre sur plusieurs marketplaces et dans solutions.
Commandes et statuts : de Mirakl à Odoo et retour
Mirakl a plus de statuts de commande qu'Odoo n'en a besoin et les réduit à six : WAITING_ACCEPTANCE, WAITING_DEBIT, STAGING et INCIDENT_OPEN sont « en attente » ; SHIPPING, « en cours d'expédition » (l'acheteur a payé et le délai d'expédition court) ; SHIPPED, « expédié » ; RECEIVED et CLOSED, « clôturé » ; CANCELED et REFUSED, « annulé » ; REFUNDED, « remboursé ». La commande de la capture est entrée en SHIPPED, a été mappée sur « Enviado » et liée à la commande client S00509, avec la devise, le total et la taxe issus du payload de l'opérateur.

Le cycle retour : la commande en attente est acceptée par un PUT vers /orders/{id}/accept, par lots avec un plafond par passage ; à la validation du bon de livraison, le suivi est envoyé (OR23) et l'expédition est marquée (OR24), et le bon de livraison est estampillé avec la requête et la réponse ; la facture validée est envoyée sur la commande (OR74) après suppression de la précédente du même type (OR72, OR76). Et la fenêtre incrémentale se demande par date de mise à jour, non de création : une commande qui change de statut des semaines plus tard ne reviendrait jamais.
Où des doublons apparaissent si le connecteur n'est pas idempotent
Trois endroits. La commande : la base refuse deux enregistrements avec le même identifiant dans la même instance (unique(instance_id, mirakl_order_id)) ; l'import met à jour l'existant. L'expédition : le connecteur relit d'abord le statut ; s'il est déjà SHIPPED, il ne la répète pas, et si la relecture échoue il ne présume rien et appelle, car tenir pour acquis « déjà expédié » après un timeout laissait des commandes sans suivi. Et le remboursement, qui est de l'argent : dans l'audit de la 16.15.1, nous avons vu que le client HTTP réessayait n'importe quelle requête en cas de 5xx ou de timeout, y compris celle de OR28. Un timeout ne dit pas que la requête n'est pas arrivée : il dit que vous ne le savez pas. Aujourd'hui, seules les lectures sont réessayées, sauf le 429, qui garantit que rien n'a été traité ; et le bouton refuse d'envoyer un second remboursement complet si la commande figure déjà comme remboursée.
Règlements : ce que renvoie l'API et pourquoi ils méritent un rapprochement à part
Mirakl ne vous paie pas commande par commande : il vire périodiquement un net, et IV01 renvoie le document qui l'explique, avec le montant viré et quatre postes : commandes, commissions, remboursements et commissions remboursées. Le connecteur conserve chaque document par instance (période, devise, statut de paiement) et calcule un net propre à partir des postes. Ce qui manque pour arriver au montant viré, ce sont les « autres frais », presque toujours l'abonnement de l'opérateur : un règlement réel traînait 39,00 € d'écart jusqu'à ce que nous intégrions ce résidu, et il apparaît ainsi comme une ligne de plus au lieu de se cacher dans une différence sans nom.
Quand un opérateur Mirakl n'en vaut pas la peine
Que l'API soit la même ne veut pas dire que chaque invitation mérite un oui. Le coût d'entrée est dans le catalogue, pas dans l'intégration : mapper vos catégories sur un arbre de milliers de nœuds et renseigner les attributs obligatoires de chaque famille est un travail humain, et il se répète chez chaque opérateur. Peu de catégories pertinentes, une commission qui mange la marge après l'abonnement ou un délai d'acceptation que votre entrepôt ne tient pas : aucun cas ne vaut la peine, aussi simple soit-il à connecter. Le signal sort de l'instance avant de publier quoi que ce soit : synchronisez le dictionnaire, mappez dix familles et comptez combien d'attributs obligatoires vous manquent. S'ils se comptent par centaines, cela vous coûtera plus que ce que cela vous rapportera.
Le connecteur avec lequel nous avons fait ce qui précède est en production avec des commandes réelles et au vert (163 tests sur 163) sur Odoo 19, 18 et 17, après l'audit de la 16.15.1 (121 constats candidats, 18 confirmés). Si vous héritez d'un connecteur Mirakl d'un autre prestataire, ce qu'il faut regarder se trouve dans auditer un connecteur Odoo hérité ; si la plateforme qui doit parler à Odoo est la vôtre, c'est un connecteur Odoo pour votre logiciel.
Questions fréquentes
Donc je vends « sur Mirakl » ?
Non. Vous vendez chez l'opérateur qui vous a invité : il fixe les catégories, la commission, les délais et le contrat. Mirakl est le logiciel avec lequel cet opérateur gère sa marketplace, et son API est ce à quoi votre Odoo s'intègre.
Me faut-il un connecteur par opérateur Mirakl ?
Non. Il vous faut une instance par opérateur au sein du même connecteur : hôte, clé, boutique, dictionnaire, transporteurs et règles de stock propres. Le code qui parle à l'API est le même.
Pourquoi le stock ne peut-il pas être « en temps réel » ?
Parce que chaque opérateur reçoit la quantité que vous exportez et vend dessus jusqu'à l'export suivant, sans connaître les autres. Ce qui évite la survente, c'est la règle par canal : quelle quantité est regardée, volant, minimum et maximum, plus une cadence raisonnable.
Liens utiles chez FlexigoTech
Ce que nous faisons à ce sujet
Un opérateur Mirakl vous a invité et vous vendez avec Odoo ?
Dites-nous de quel opérateur il s'agit, combien de canaux regardent déjà votre entrepôt et sur quelle version d'Odoo vous êtes. Nous vous dirons ce qu'il faut pour le connecter comme une instance de plus et quelles règles de stock vous devriez fixer avant de publier. Écrivez à comercial@flexigobe.com ou appelez le +34 616 809 504.

