DataFirefly Odoo Connector — guide d’installation et de configuration
Connectez Shopware 6.6 / 6.7 à Odoo 12 → 18 via XML-RPC natif. Installation, configuration de la clé API, directions de synchronisation, tâches planifiées et dépannage.
Ce guide couvre l’installation, la configuration et l’exploitation du plugin DataFirefly Odoo Connector pour Shopware 6.6 et 6.7. À la fin, votre boutique synchronisera produits, stock, clients et commandes avec votre instance Odoo via XML-RPC natif, sans aucune dépendance externe ni surcoût d’API tierce.
Présentation
Le plugin établit un pont bidirectionnel entre Shopware et Odoo en parlant directement le protocole XML-RPC d’Odoo (stable depuis la version 8). Aucun module à installer côté Odoo, aucun middleware payant, aucun SaaS intermédiaire.
| Entité | Odoo → Shopware (pull) | Shopware → Odoo (push) |
|---|---|---|
| Produits (product.template) | ✅ | ✅ |
| Stock (qty_available / free_qty) | ✅ | — |
| Catégories (product.category) | ✅ | ✅ |
| Clients (res.partner) | — | ✅ avec adresses enfants |
| Commandes (sale.order) | — | ✅ avec confirmation et facture optionnelles |
Prérequis
- Shopware 6.6.x ou 6.7.x (toutes versions mineures).
- PHP 8.2, 8.3 ou 8.4.
- Extensions PHP : curl, xml, simplexml (présentes par défaut sur la quasi-totalité des hébergeurs).
- Odoo 12, 13, 14, 15, 16, 17 ou 18, en Community ou Enterprise. Odoo.sh, Odoo Online (SaaS) et instances auto-hébergées fonctionnent identiquement.
- Un utilisateur Odoo dédié à l’API (recommandé) avec droits de lecture/écriture sur les modèles utilisés (product.template, product.product, res.partner, sale.order, stock.warehouse, product.category, res.country, account.tax).
Installation
Via téléversement dans l’administration
- Téléchargez l’archive
DfOdooConnector-v1.0.0.zipdepuis votre compte client. - Dans l’administration Shopware : Extensions → Mes extensions → Téléverser une extension.
- Sélectionnez le ZIP puis cliquez sur Installer.
- Activez l’extension en cliquant sur l’interrupteur.
Via console SSH
cd /chemin/vers/shopware
cp DfOdooConnector-v1.0.0.zip custom/plugins/
cd custom/plugins && unzip DfOdooConnector-v1.0.0.zip
sudo -u www-data setsid php bin/console plugin:refresh
sudo -u www-data setsid php bin/console plugin:install --activate DfOdooConnector
sudo -u www-data setsid php bin/console cache:clear
Recompilation de l’administration pour charger le module Vue 3 :
sudo -u www-data setsid php bin/build-administration.sh
df_odoo_mapping (correspondances persistantes Shopware ↔ Odoo) et df_odoo_log (journal des opérations). Aucune table existante n’est modifiée.
Configuration côté Odoo
Créer un utilisateur dédié
Il est fortement recommandé de créer un utilisateur Odoo dédié à l’intégration plutôt que d’utiliser un compte administrateur personnel. Cela permet d’auditer précisément les actions du connecteur et de révoquer son accès indépendamment.
- Dans Odoo : Paramètres → Utilisateurs et sociétés → Utilisateurs.
- Créez un utilisateur nommé par exemple
Shopware Bridge. - Donnez-lui les droits requis : Inventaire (utilisateur), Ventes (administrateur des documents), Facturation (utilisateur si vous activez la création de facture), Contacts (utilisateur).
Générer une clé API
- Connectez-vous à Odoo avec ce nouvel utilisateur.
- Cliquez sur l’avatar en haut à droite → Préférences.
- Onglet Compte → Clés API → Nouvelle clé API.
- Donnez un nom descriptif (par exemple
Shopware Connector) et copiez la valeur générée.
Configuration côté Shopware
Renseigner la connexion
Dans l’administration Shopware : Paramètres → Système → Plugins → Df Odoo → Paramètres, ou directement via le menu latéral Paramètres → Df Odoo → Paramètres.
- URL Odoo : URL complète de votre instance sans slash final, par exemple
https://moncompte.odoo.com. - Nom de la base : visible dans l’URL Odoo après
?db=, ou dans Paramètres → Technique → Base de données. - Utilisateur : login de l’utilisateur dédié, généralement son adresse email.
- Clé API Odoo : valeur copiée à l’étape précédente.
- Délai d’attente : 30 secondes par défaut, suffisant dans la majorité des cas.
Tester la connexion
Cliquez sur le bouton Tester la connexion en haut à droite. Si tout est correct, une notification verte affiche la version d’Odoo et l’identifiant utilisateur (uid). Si la connexion échoue, le message d’erreur retourné par Odoo est affiché tel quel.
curl -X POST -H "Authorization: Bearer ADMIN_TOKEN" https://votreshopware.com/api/_action/df-odoo/test-connection
Directions de synchronisation
Chaque entité dispose d’un sélecteur indépendant : désactivé, Odoo → Shopware (pull), Shopware → Odoo (push), ou bidirectionnel. Les valeurs par défaut sont :
- Produits : bidirectionnel
- Stock : Odoo → Shopware (Odoo est la source de vérité)
- Clients : Shopware → Odoo
- Commandes : Shopware → Odoo
- Catégories : désactivé (à activer manuellement selon votre organisation)
Synchronisation des produits
Stratégies de correspondance
Trois stratégies sont configurables :
- SKU (recommandé) : Shopware
productNumber↔ Odoodefault_code. - ID Odoo : repose uniquement sur la table de mapping persistante. Utile si vos SKU sont volatiles.
- Code-barres (EAN) : Shopware
ean↔ Odoobarcode. Exige des EAN renseignés des deux côtés.
Une fois liés, deux produits restent appariés via la table df_odoo_mapping, même si la SKU change ensuite.
Pull depuis Odoo
La tâche planifiée lit les product.template modifiés depuis la dernière exécution (champ write_date) et crée ou met à jour les produits correspondants côté Shopware. Les champs synchronisés sont : nom, SKU, prix de vente, prix de revient, description courte, description longue, poids, volume, état actif, catégorie, taxes.
Push vers Odoo
Les produits maîtres Shopware (avec parentId = null) actifs sont envoyés vers Odoo en tant que product.template de type product (article stockable). Les variantes Shopware sont remontées sous leur produit parent.
skipped. Cela évite de saturer Odoo lors des cron successifs.
Synchronisation du stock
Le stock est toujours tiré depuis Odoo (jamais l’inverse). Toutes les 15 minutes, la tâche planifiée lit les variantes product.product par lots de 100 par identifiant de template parent, agrège qty_available ou free_qty (configurable globalement) puis met à jour le champ stock de chaque produit Shopware en une seule requête DAL.
qty_available reflète le stock physique présent en entrepôt. free_qty retire les quantités déjà réservées sur des commandes non livrées. free_qty est généralement préférable pour un site marchand car il évite la survente.
Synchronisation des catégories
Désactivée par défaut. Activez-la si votre arborescence de catégories doit rester synchrone avec celle d’Odoo. La hiérarchie parent_id est préservée des deux côtés. Comme pour les produits, un hash de contenu évite les écritures inutiles.
Synchronisation des clients
Les clients Shopware sont poussés comme res.partner Odoo avec :
- Déduplication par email : avant toute création, un partenaire existant avec le même email et
parent_id = falseest cherché. S’il existe, il est mis à jour au lieu d’être dupliqué. - company_type : company si le champ société de l’adresse de facturation est renseigné, person sinon.
- Adresses enfants : l’adresse de facturation par défaut est créée comme partenaire enfant avec
type='invoice', l’adresse de livraison comme partenaire enfant avectype='delivery'. - TVA intracommunautaire : reportée sur le champ
vatdu partenaire principal. - Pays et région : résolus par code ISO avec cache mémoire intra-requête.
Synchronisation des commandes
En temps réel au checkout
Si l’option Pousser chaque commande dès validation est activée, un event subscriber écoute CheckoutOrderPlacedEvent et envoie immédiatement la commande vers Odoo après la finalisation du checkout. Le client est créé dans Odoo si nécessaire (via la synchronisation client), puis la commande est créée comme sale.order avec :
partner_idrésolu via le mapping client.order_lineen syntaxe tuple Odoo :[0, 0, {name, product_uom_qty, price_unit, product_id}].- Une ligne supplémentaire pour les frais de transport si
totalPricedu shipping est supérieur à zéro. company_id,warehouse_id,pricelist_idselon les valeurs par défaut configurées.
df_odoo_log et la commande sera reprise dans les 10 minutes par la tâche planifiée df_odoo.order_sync, qui scanne les commandes des 7 derniers jours non encore mappées.
Filtre d’état
Le filtre État des commandes permet de restreindre les commandes poussées :
- Toutes : toute commande validée est envoyée (recommandé en B2C avec paiement immédiat).
- Payées uniquement : seules les commandes dont l’état de paiement est paid sont poussées. Évite de remonter des paniers abandonnés à paiement manuel.
- Payées ou expédiées : ajoute aux précédentes les commandes expédiées avant paiement (B2B avec délais).
Confirmation et facture automatiques
Deux options pilotent ce qui se passe côté Odoo une fois la commande créée :
- Confirmer la commande : appelle
action_confirmsur lasale.order, qui passe alors directement à l’état commande confirmée au lieu de rester devis. - Créer la facture : appelle
_create_invoicespour générer immédiatement une facture validée. L’identifiant de la facture créée est mémorisé comme mapping de typeinvoice.
Multi sales channel
Tous les paramètres du plugin peuvent être surchargés par canal de vente. En haut de la page Paramètres, le sélecteur natif Shopware permet de basculer entre Tous les canaux et un canal spécifique.
Cas d’usage typiques :
- Un canal B2C qui pousse vers un Odoo principal et un canal B2B qui pousse vers un Odoo distinct.
- Un canal de production avec direction push et un canal staging avec direction désactivée.
- Différents identifiants Odoo (warehouse, sales team, pricelist) selon le canal.
Tâches planifiées
| Nom interne | Fréquence | Action |
|---|---|---|
df_odoo.product_sync |
1 heure | Pull puis push produits selon la direction configurée. Le pull n’examine que les fiches modifiées depuis -2 h. |
df_odoo.stock_sync |
15 minutes | Pull du stock depuis Odoo pour tous les produits déjà mappés. |
df_odoo.customer_sync |
1 heure | Push des clients actifs non encore mappés (100 max par exécution). |
df_odoo.order_sync |
10 minutes | Push des commandes des 7 derniers jours non encore mappées (50 max par exécution). |
Forcer l’exécution d’une tâche depuis la console :
sudo -u www-data setsid php bin/console scheduled-task:run-single df_odoo.product_sync
messenger:consume ou tâche systemd). Vérifiez dans Paramètres → Système → File d’attente que scheduled_task est consommée régulièrement.
Module d’administration
Une section Df Odoo apparaît dans Paramètres → Plugins avec quatre pages.
Dashboard
Compteurs en direct (mappings actifs par entité, activité des dernières 24 h par statut), boutons de synchronisation manuelle par entité (pull et push), bandeau d’état de la connexion, liste des erreurs récentes et raccourcis vers les autres pages.
Paramètres
Formulaire complet avec sélecteur de canal de vente. Bouton Tester la connexion et Enregistrer dans la barre d’actions.
Journal
Toutes les opérations sont tracées dans df_odoo_log avec leur statut (success, error, warning, skipped), leur direction, l’entité concernée, la durée en millisecondes et le message complet. Filtres combinables par statut, type d’entité et direction. Pagination serveur.
Correspondances
Vue lecture sur la table df_odoo_mapping avec recherche, filtre par type d’entité et tri par date de dernière synchronisation. Pratique pour vérifier qu’un produit donné est bien mappé à l’ID Odoo attendu.
API REST admin
Tous les endpoints requièrent une authentification admin standard (Bearer token).
| Méthode | Endpoint | Paramètres |
|---|---|---|
| POST | /api/_action/df-odoo/test-connection |
salesChannelId (optionnel) |
| POST | /api/_action/df-odoo/sync/products |
direction=pull|push, salesChannelId |
| POST | /api/_action/df-odoo/sync/stock |
salesChannelId |
| POST | /api/_action/df-odoo/sync/customers |
salesChannelId |
| POST | /api/_action/df-odoo/sync/orders |
salesChannelId, limit (1-500) |
| POST | /api/_action/df-odoo/sync/categories |
direction=pull|push |
| GET | /api/_action/df-odoo/stats |
— |
| GET | /api/_action/df-odoo/logs |
status, entityType, direction, page, perPage |
Exemple d’appel pour forcer un push produit :
curl -X POST
-H "Authorization: Bearer ADMIN_TOKEN"
-d "direction=push"
https://votreshopware.com/api/_action/df-odoo/sync/products
Tables et données stockées
Le plugin crée deux tables MySQL :
df_odoo_mapping— correspondances persistantes (identifiant Shopware ↔ identifiant Odoo) avec hash de synchronisation et payload optionnel. Une ligne est unique sur le couple (type d’entité, identifiant Shopware) et sur (type d’entité, identifiant Odoo).df_odoo_log— journal des opérations avec statut, durée, message, payload, identifiant du canal de vente.
Aucune table Shopware standard n’est modifiée.
Désinstallation
Depuis l’administration : Extensions → Mes extensions → Df Odoo → Désinstaller.
Une boîte de dialogue propose deux options :
- Conserver les données utilisateur coché : les tables
df_odoo_mappingetdf_odoo_logsont préservées, ainsi que les paramètres système. Pratique en cas de réinstallation ultérieure. - Conserver les données utilisateur décoché : les deux tables sont supprimées (DROP TABLE) à la désinstallation. L’instance Odoo n’est jamais touchée.
Dépannage
« Configuration Odoo incomplète » au test de connexion
L’un des quatre champs obligatoires (URL, base, utilisateur, clé API) est vide. Vérifiez que vous avez bien sélectionné le bon canal de vente avant d’enregistrer.
« 401 Unauthorized » ou « access denied »
La clé API a été révoquée côté Odoo, ou l’utilisateur n’a pas les droits requis sur le modèle ciblé. Régénérez une clé API et vérifiez les droits Odoo de l’utilisateur (notamment Inventaire → Utilisateur et Ventes → Administrateur des documents).
« Connexion refusée » ou timeout
L’URL Odoo n’est pas accessible depuis le serveur Shopware. Vérifiez que le pare-feu autorise les connexions sortantes HTTPS vers le domaine Odoo. Augmentez le délai d’attente si votre instance Odoo est lente à répondre.
Les produits ne se synchronisent pas
Vérifiez le journal (page Journal) pour des entrées en erreur. Activez le mode debug pour tracer également les opérations skipped et identifier si le hash de contenu fait que rien ne change réellement.
Les commandes ne partent pas au checkout
Vérifiez que l’option Pousser chaque commande dès validation est cochée et que la direction Commandes est sur Shopware → Odoo. Si le filtre d’état est sur Payées uniquement et que le paiement est asynchrone, c’est la tâche planifiée qui pousse la commande quelques minutes après l’encaissement.
Limites connues
- Les attributs de variantes Odoo (
product.attribute) ne sont pas encore mappés automatiquement. Les variantes Shopware sont remontées comme produits parents Odoo (product.template). Les variantes Odoo créées manuellement restent correctement liées via leur template parent. Une gestion native est prévue en version 1.1. - Les remises de ligne de commande sont reportées comme
price_unitajusté, pas commediscountOdoo. - Les modes de paiement et expédition Shopware ne sont pas mappés vers les
journal_idOdoo — les valeurs par défaut Odoo sont utilisées.
Support
Pour toute question, contactez l’équipe DataFirefly via le formulaire de contact sur datafirefly.com. Pensez à joindre l’export du journal (page Journal → bouton d’export à venir) ou à minima une capture de la ligne en erreur ainsi que la version exacte de Shopware, PHP et Odoo.