SW Shopware 6 Intermédiaire

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.

Mis à jour Version du module 1.0.0

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

  1. Téléchargez l’archive DfOdooConnector-v1.0.0.zip depuis votre compte client.
  2. Dans l’administration Shopware : Extensions → Mes extensions → Téléverser une extension.
  3. Sélectionnez le ZIP puis cliquez sur Installer.
  4. 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
Note — L’installation crée deux tables : 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.

  1. Dans Odoo : Paramètres → Utilisateurs et sociétés → Utilisateurs.
  2. Créez un utilisateur nommé par exemple Shopware Bridge.
  3. 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

  1. Connectez-vous à Odoo avec ce nouvel utilisateur.
  2. Cliquez sur l’avatar en haut à droite → Préférences.
  3. Onglet CompteClés APINouvelle clé API.
  4. Donnez un nom descriptif (par exemple Shopware Connector) et copiez la valeur générée.
Important — La clé API ne s’affiche qu’une seule fois. Si vous la perdez, il faudra en générer une nouvelle. Stockez-la dans un gestionnaire de mots de passe avant de fermer la modale.

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.

Conseil — Le test de connexion peut aussi être appelé depuis la console pour scripter une vérification :
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 ↔ Odoo default_code.
  • ID Odoo : repose uniquement sur la table de mapping persistante. Utile si vos SKU sont volatiles.
  • Code-barres (EAN) : Shopware ean ↔ Odoo barcode. 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.

Détection des changements — Avant chaque écriture, un hash SHA-1 du contenu est comparé à celui mémorisé dans le mapping. Si rien n’a changé, l’écriture est ignorée et l’opération est journalisée comme 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 vs free_qtyqty_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 = false est 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 avec type='delivery'.
  • TVA intracommunautaire : reportée sur le champ vat du 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_id résolu via le mapping client.
  • order_line en syntaxe tuple Odoo : [0, 0, {name, product_uom_qty, price_unit, product_id}].
  • Une ligne supplémentaire pour les frais de transport si totalPrice du shipping est supérieur à zéro.
  • company_id, warehouse_id, pricelist_id selon les valeurs par défaut configurées.
Le checkout n’est jamais bloqué — Si Odoo est inaccessible, l’erreur est tracée dans 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_confirm sur la sale.order, qui passe alors directement à l’état commande confirmée au lieu de rester devis.
  • Créer la facture : appelle _create_invoices pour générer immédiatement une facture validée. L’identifiant de la facture créée est mémorisé comme mapping de type invoice.

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
Worker Shopware — Pour que les tâches planifiées se déclenchent automatiquement, le worker messenger Shopware doit tourner (cron 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.

Mode debug — Les opérations skipped ne sont écrites dans le journal que si le mode debug est activé dans les paramètres. À utiliser ponctuellement pour diagnostiquer un comportement, à désactiver en production pour éviter de saturer la table.

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_mapping et df_odoo_log sont 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_unit ajusté, pas comme discount Odoo.
  • Les modes de paiement et expédition Shopware ne sont pas mappés vers les journal_id Odoo — 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.

Cette page vous a-t-elle été utile ?

Toujours bloqué ? Contactez le support