TL;DRImporter un catalogue dans PrestaShop n'a rien de compliqué, mais l'opération est irréversible et le moindre détail de format se paie en heures de rattrapage. Voici la méthode complète, dans l'ordre, testée sur PrestaShop 9.1.5.

Une mise en ligne se joue rarement sur le design. Elle se joue sur le catalogue. Thème installé, transporteur configuré, et puis arrive le fichier du fournisseur : 1 400 références, des prix en virgule, des catégories en texte, des photos hébergées on ne sait où. C'est là que les plannings dérapent.

L'import natif fait bien le travail, mais il est littéral : il exécute ce que dit votre fichier sans vous demander si vous êtes sûr. Il ne devine pas qu'une catégorie s'appelait "Chaussures" et pas "45". Et il n'a pas de bouton "annuler".

Voici la méthode que nous appliquons chez Websource : l'ordre des opérations, la préparation du fichier, les colonnes qui comptent, les réglages de l'écran d'import et la checklist d'après-import que tout le monde oublie – plus le seuil à partir duquel le CSV ne suffit plus.

⚠️ À lire avant de toucher à quoi que ce soit#

L'import PrestaShop n'a pas d'annulation. Aucun bouton de retour, aucun historique, aucune corbeille.

Pire : l'option "Supprimer toutes les données avant l'import" ne vide pas que la table des produits. Sur l'entité Produits, elle vide une trentaine de tables – produits, déclinaisons, images, prix spécifiques, stocks, caractéristiques, paniers en cours – et efface physiquement le contenu du dossier img/p/. C'est écrit noir sur blanc dans la méthode truncateTables() du contrôleur d'import de PrestaShop 9.1.5. Une case cochée par curiosité, et la boutique est vide, images comprises.

Avant tout import : sauvegarde de la base de données ET du dossier img/. La base seule ne contient pas vos fichiers images ; le dossier seul ne contient pas les liens produits ↔ images.

mysqldump -u UTILISATEUR -p BASE > sauvegarde-avant-import.sql
tar czf img-avant-import.tar.gz img/

Et tant qu'à faire : jouez le premier import sur une copie de préproduction.

Les 3 façons d'importer un catalogue#

1. L'import CSV natif, dans Paramètres avancés > Importer. Un CSV est un fichier texte où chaque ligne est un enregistrement et chaque colonne est séparée par un caractère convenu. Depuis la 1.7, PrestaShop accepte aussi .xls, .xlsx, .ods et .ots, qu'il convertit avant traitement (documentation officielle).

2. Un module d'import du marketplace, qui apporte ce qui manque au natif : planification, transformations de colonnes, import depuis un flux. Nous n'en citons aucun ici par souci de neutralité ; nous avons déjà écrit sur ce que fait vraiment un module import/export PrestaShop.

3. Un script sur mesure : commande Symfony exécutée dans le noyau, ou programme externe attaquant le Webservice ou, en 9.x, la nouvelle Admin API basée sur API Platform et OAuth.

Import CSV natifModule marketplaceScript sur mesure
Volume confortable~2 000 lignes par fichierquelques dizaines de milliersillimité en pratique
Coûtinclus50 à 300 €1 à 5 jours de dev
Récurrencenon, manueloui selon le moduleoui (cron, Messenger)
CompétencestableurtableurPHP, SQL, API
Transformationsaucunelimitéeslibres
Limitespas de reprise sur erreur fine, aucune logique conditionnelledépendance à un tiersà maintenir

Quand le natif ne suffit plus ? Un seul de ces signaux suffit : le catalogue dépasse quelques milliers de références et doit être découpé à la main ; l'import doit être répété (prix et stocks d'un fournisseur chaque jour) ; les données doivent être transformées avant d'entrer. Un chargement unique reste du ressort du CSV. Dès qu'il y a une fréquence ou une règle métier, le CSV devient un coût récurrent déguisé.

Préparer son fichier : là où tout se joue#

Quatre-vingts pour cent des imports ratés se règlent dans le tableur, pas dans PrestaShop.

L'encodage#

L'encodage définit comment les caractères accentués sont stockés. PrestaShop recommande l'UTF-8 ; à défaut, il teste le fichier et, s'il n'est pas de l'UTF-8 valide, le convertit depuis l'ISO-8859-1. Un fichier Windows-1252 contenant des € ou des œ passe dans cette moulinette et en ressort abîmé.

Le BOM (Byte Order Mark) est une signature invisible de trois octets placée en tête de fichier par certains logiciels Windows. Bonne nouvelle : depuis la 1.7, l'import le détecte et le saute – méthode rewindBomAware(), toujours présente en 9.1.5. Mauvaise nouvelle : il reste fatal dès que le fichier sort du back-office (scripts maison, LOAD DATA INFILE, modules tiers), et il trahit un fichier passé par le "CSV UTF-8" d'Excel, qui réserve d'autres surprises : zéros de tête supprimés sur les références et les EAN, 12345678901234 en notation scientifique, dates réinterprétées.

D'où la règle : ne finalisez jamais un CSV d'import dans Excel. LibreOffice Calc propose une boîte de dialogue explicite (Unicode (UTF-8), séparateur point-virgule, séparateur de chaîne guillemet double) et permet de forcer une colonne en Texte pour préserver les zéros de tête.

sed -i '1s/^\xEF\xBB\xBF//' produits.csv   # retirer un BOM existant
file -i produits.csv                        # doit répondre charset=utf-8

Pour aller plus loin La conversion de repli est un utf8_encode(), donc un ISO-8859-1 → UTF-8. Elle est fausse pour tout caractère présent en Windows-1252 mais absent de l'ISO-8859-1 : €, œ, ’, “ ”, –. Si votre source vient de Windows, convertissez explicitement : iconv -f WINDOWS-1252 -t UTF-8 source.csv > produits.csv.

Les deux séparateurs#

Le séparateur de champ sépare les colonnes : PrestaShop recommande le point-virgule ;. Le séparateur de valeurs multiples sépare plusieurs valeurs dans une même cellule – plusieurs catégories, plusieurs images, plusieurs caractéristiques : par défaut la virgule ,.

Règle pratique : ; entre les colonnes, , à l'intérieur d'une colonne, guillemets doubles autour de toute cellule qui contient l'un ou l'autre.

Les prix#

Point décimal, aucun séparateur de milliers : 1299.90, jamais 1 299,90 ni 1,299.90.

Précisons, car la nuance est utile : PrestaShop remplace bien la virgule par un point avant conversion, donc 19,90 passe. Ce qui ne passe pas, c'est le séparateur de milliers – 1 299,90 devient 1 – et surtout le cas où la virgule est aussi le séparateur de valeurs multiples : la cellule est coupée en deux et toute la ligne se décale d'une colonne. Le point décimal supprime les deux risques.

Les retours à la ligne dans les descriptions#

Un retour à la ligne non protégé termine l'enregistrement : la suite est lue comme une nouvelle ligne produit et l'import part en vrille. Soit vous encadrez le champ de guillemets doubles – le lecteur CSV les respecte et accepte alors les sauts de ligne internes, à condition de doubler les guillemets du HTML (class=""prix"") –, soit, plus sûr, vous mettez la description sur une seule ligne physique en remplaçant les retours par des <br> et </p><p>.

Les doublons de référence#

À traiter avant, pas après : la référence est votre clé de mise à jour, et deux produits qui la partagent rendent tout import ultérieur imprévisible.

cut -d';' -f8 produits.csv | sort | uniq -d   # référence en 8e colonne

Dans LibreOffice : =SI(NB.SI($H$2:$H$5000;H2)>1;"DOUBLON";"").

L'ordre d'import, et pourquoi il n'est pas négociable#

PrestaShop importe une entité à la fois. L'ordre suivant n'est pas une préférence, c'est une dépendance technique : 1. marques et fournisseurs → 2. catégories (parentes avant enfantes) → 3. produits → 4. déclinaisons.

Ce qui casse si vous inversez :

  • Produits avant catégories. La colonne Catégories attend des ID. Si l'ID n'existe pas, PrestaShop ne renonce pas : il crée une catégorie dont le nom est le nombre écrit, placée sous Accueil. Vous héritez d'un arbre peuplé de catégories nommées "12", "45", "108".
  • Enfantes avant parentes. La catégorie parente est résolue au moment de l'import. Si elle n'existe pas encore, l'enfante est rattachée à Accueil – et elle y reste, même après l'import de la parente. Triez votre fichier par profondeur.
  • Déclinaisons avant produits. Sans produit à rattacher, la ligne est ignorée, sans erreur bruyante.
  • Produits avant marques. Là, PrestaShop est souple : il crée la marque au vol à partir du nom. Le résultat est fonctionnel mais brut – ni logo, ni description, ni meta.

L'étape que tout le monde rate : les ID de catégories#

C'est le passage le plus important de cet article.

Dans le fichier produits, la colonne Catégories (x,y,z…) attend des identifiants numériques séparés par le séparateur de valeurs multiples, pas des noms. Ces identifiants n'existent pas tant que les catégories ne sont pas créées : ils sont attribués par la base pendant l'import. Vous ne pouvez donc pas remplir le fichier produits avant d'avoir importé les catégories. D'où une manœuvre en trois temps.

Temps 1 – Importer les catégories. Fichier trié par profondeur, colonne ID laissée vide. Vérifiez ensuite l'arborescence dans Catalogue > Catégories : une erreur de hiérarchie corrigée maintenant coûte deux minutes, corrigée après l'import produits elle coûte une demi-journée.

Temps 2 – Récupérer les ID générés.Catalogue > Catégories, dépliez l'arborescence et cliquez sur Exporter. PrestaShop produit un CSV contenant la colonne ID en face de chaque nom. C'est votre table de correspondance nom → ID.

Temps 3 – La RECHERCHEV. Ouvrez l'export dans un onglet de votre classeur (cats, ID en A, nom en B) et votre fichier produits dans un autre. Dans le fichier produits, une colonne temporaire à côté du nom de catégorie fourni :

=RECHERCHEV(D2;cats.$B$2:$C$500;2;0)

La colonne recherchée doit être à gauche de la colonne renvoyée. Sinon, on inverse les colonnes de l'export, ou on utilise :

=INDEX(cats.$A$2:$A$500;EQUIV(D2;cats.$B$2:$B$500;0))

Pour un produit rangé dans plusieurs catégories, concaténez les ID avec le séparateur de valeurs multiples et entourez le tout de guillemets : =""""&E2&","&F2&"""".

Deux détails qui font gagner une heure :

  • Traquez les #N/A. Chacun signale un nom de catégorie inexistant chez vous : faute de frappe, accent, espace insécable, ou catégorie oubliée. Filtrez dessus et traitez-les avant l'import, sinon ces produits atterriront dans Accueil.
  • Collez en valeurs. Figez les résultats par un collage spécial avant d'exporter : un CSV contenant des formules vivantes est une source d'erreurs silencieuses.

Pour aller plus loin La colonne Catégories accepte aussi des noms, voire des chemins Accueil/Homme/T-shirts, résolus via Category::searchByPath(). Mais cette méthode crée les catégories manquantes au lieu d'échouer, et cherche sur le nom dans la langue de l'import : deux homonymes dans des branches différentes donnent un résultat imprévisible. En production, on passe par les ID.

SELECT c.id_category, cl.name, c.id_parent FROM ps_category c
JOIN ps_category_lang cl ON cl.id_category = c.id_category
WHERE cl.id_lang = 1 ORDER BY c.nleft;

Les colonnes du fichier produits, expliquées#

Le mapping – l'écran où vous associez chaque colonne à un champ PrestaShop – ne lit pas vos en-têtes. Seul l'ordre des colonnes compte, et la première ligne se saute avec le champ "Sauter X lignes" (valeur 1).

Champ PrestaShopFormat attenduExemple
IDentier, ou vide pour laisser PrestaShop décider(vide)
Actif (0/1)0 ou 11
NomtexteT-shirt col rond
Catégories (x,y,z…)ID séparés par le séparateur multiple"2,12,15"
Prix hors taxesdécimal à point24.90
ID règle de taxesID d'une règle existante1
Référence #texte, uniqueTSH-COL-001
Quantitéentier120
URL simplifiéeminuscules, tirets, sans accentt-shirt-col-rond
URL des images (x,y,z…)URL absolues, séparateur multiple"https://exemple.fr/a.jpg,https://exemple.fr/b.jpg"
Caractéristique (Nom:Valeur:Position:Personnalisé)quatre segments séparés par :"Matière:Coton bio:1:0"

Prix HT ou TTC, et la règle de taxes. Prix HT seul : enregistré tel quel. Prix TTC seul : PrestaShop le divise par le taux de la règle indiquée dans ID règle de taxes. Les deux renseignés : le HT gagne, le TTC est ignoré. Conséquence : si ID règle de taxes est vide ou pointe vers une règle inexistante, un prix fourni en TTC est stocké tel quel comme HT et toute la boutique affiche des prix majorés de 20 %. Ne renseignez qu'une colonne, et vérifiez la règle dans International > Taxes.

Quantité. Un entier, appliqué à la boutique courante. En 8.x et 1.7.x, avec la gestion avancée des stocks (ASM) activée, cette quantité entrait en conflit avec la gestion par entrepôts. Ce point disparaît en PrestaShop 9 : l'ASM a été entièrement retirée du cœur, entrepôts et commandes fournisseurs compris (changements 9.0). À noter : la documentation utilisateur v9 mentionne encore les commandes fournisseurs parmi les entités importables ; le code de la 9.x ne les propose plus.

URL simplifiée et SEO. Le segment d'URL de la fiche. Vide ou invalide (accents, espaces, majuscules), PrestaShop la régénère depuis le nom du produit ; si même cela échoue, il écrit friendly-url-autogeneration-failed. Sur une migration, reprenez ici les URL de l'ancienne boutique : c'est ce qui vous évitera un plan de redirections à trois cents lignes.

URL des images. Des liens absolus, publiquement accessibles, que le serveur télécharge un par un. Chemins locaux ou URL protégées échouent silencieusement. Comptez 1 à 2 secondes par image : c'est le premier facteur de lenteur d'un import.

Caractéristiques. Format Nom:Valeur:Position:Personnalisé, et non trois segments comme on le lit souvent – le quatrième indique une valeur propre au produit. Les trois derniers sont facultatifs. Plusieurs caractéristiques se séparent avec le séparateur multiple : "Matière:Coton bio:1:0,Origine:Portugal:2:0".

Pour aller plus loin Deux comportements à connaître. Les champs booléens sont convertis par un simple (bool) : toute chaîne non vide autre que "0" vaut vrai, donc écrire non dans Actif publie le produit. N'utilisez que 0 et 1. Les champs traduisibles (nom, description, URL simplifiée, meta) sont recopiés dans toutes les langues installées : sur une boutique multilingue, un import français remplit aussi les champs anglais. Prévoyez un fichier par langue.

Les déclinaisons#

Une déclinaison (ou combinaison) est une variante achetable d'un produit : le T-shirt rouge en taille M. Elle a son stock, sa référence, et peut modifier prix et poids. Elle associe un attribut (Taille, Couleur) et une valeur (M, Rouge).

Elles s'importent dans un fichier séparé, via l'entité Déclinaisons, après les produits. Deux colonnes structurent tout : Attribut (Nom:Type:Position) et Valeur (Valeur:Position).

Le Type est une chaîne de caractères, pas un chiffre. Trois valeurs acceptées, vérifiées dans la classe AttributeGroup de PrestaShop 9.1.5 :

TypeAffichage en boutique
selectliste déroulante (valeur par défaut si le segment est omis)
radioboutons radio
colorpastille de couleur

Vous verrez circuler la notation 0, 1, 2 : elle date des versions 1.5 / 1.6. Sur 1.7, 8.x et 9.x, écrire Couleur:2:1 crée un groupe dont le type vaut littéralement "2", qui ne s'affichera comme aucun des trois modes attendus.

Une ligne par combinaison : 3 tailles × 2 couleurs = 6 lignes. Les attributs multiples d'une même ligne se séparent avec le séparateur de valeurs multiples, et les deux colonnes se lisent par position – le premier attribut correspond à la première valeur.

"Référence produit";"Attribut (Nom:Type:Position)";"Valeur (Valeur:Position)";"Référence";"Impact sur le prix";"Quantité";"Par défaut (0/1)"
"TSH-COL-001";"Taille:select:1,Couleur:color:2";"S:1,Rouge:1";"TSH-COL-001-S-RGE";"0";"12";"1"
"TSH-COL-001";"Taille:select:1,Couleur:color:2";"M:2,Rouge:1";"TSH-COL-001-M-RGE";"0";"18";"0"
"TSH-COL-001";"Taille:select:1,Couleur:color:2";"L:3,Rouge:1";"TSH-COL-001-L-RGE";"2.00";"7";"0"
"TSH-COL-001";"Taille:select:1,Couleur:color:2";"S:1,Bleu:2";"TSH-COL-001-S-BLE";"0";"9";"0"
"TSH-COL-001";"Taille:select:1,Couleur:color:2";"M:2,Bleu:2";"TSH-COL-001-M-BLE";"0";"14";"0"
"TSH-COL-001";"Taille:select:1,Couleur:color:2";"L:3,Bleu:2";"TSH-COL-001-L-BLE";"2.00";"5";"0"

Les règles à respecter#

Douze règles, toutes vérifiées dans le contrôleur d'import de PrestaShop 9.1.5. La colonne de droite dit ce qui se passe quand on ne les respecte pas – et la plupart du temps, il ne se passe rien de visible, ce qui est le pire cas.

RègleCe qui se passe sinon
Importer les produits avant les déclinaisonsLa ligne est écartée sans aucun message d'erreur. Le fichier passe à "100 % importé" et rien n'est créé.
Rattacher chaque ligne au parent par ID produit, ou par Référence produit avec l'option "Utiliser la référence du produit comme clé" cochéeSans l'un des deux, la ligne est ignorée silencieusement. La colonne Référence produit n'est pas lue si la case n'est pas cochée.
Donner une Référence unique à chaque déclinaisonC'est la clé de mise à jour des combinaisons : PrestaShop cherche une combinaison de ce produit portant cette référence et la met à jour. Référence vide → une nouvelle combinaison est créée à chaque relance.
Autant d'éléments dans Attribut que dans Valeur, dans le même ordreLes deux colonnes sont lues par position : un décalage associe la taille au groupe Couleur et crée des attributs absurdes.
Mettre le stock sur la ligne de déclinaison, pas sur la ligne produitLa quantité du fichier produits alimente l'enregistrement de stock "sans déclinaison" ; une fois les combinaisons créées, c'est le stock de chaque combinaison qui est vendu. Mettez 0 sur le parent.
Impact sur le prix et Impact sur le poids sont des écarts signés59.00 ajoute 59 € au prix du produit au lieu de le fixer à 59 €.
Une seule ligne à Par défaut = 1 par produitMarquer 1 efface d'abord les défauts précédents du produit. Si aucune ligne n'est marquée, PrestaShop choisit lui-même la déclinaison par défaut – pas de blocage, mais pas de contrôle non plus.
Remplir une seule colonne d'imageLes deux colonnes s'excluent : si URL des images est remplie, Choisir parmi les images du produit par position est purement ignorée.
Préférer Choisir parmi les images du produit par position (1,2,3…) pour les déclinaisonsAvec URL des images, la même photo est retéléchargée et dupliquée autant de fois qu'il y a de combinaisons – six combinaisons, six copies du même fichier.
Fixer le type d'attribut (select, radio, color) dès la première création du groupeLe type n'est appliqué qu'à la création. Si un groupe "Couleur" existe déjà, écrire Couleur:color:2 ne le convertira jamais en pastilles : il faudra le changer à la main dans le back-office.
EAN-13 valide, ou colonne videUn EAN invalide déclenche un avertissement et le champ est vidé – la déclinaison est créée, mais sans code-barres.
Écotaxe renseignée seulement si elle est activéeLa valeur est ignorée quand l'écotaxe est désactivée dans la boutique.

Pour aller plus loin La correspondance des groupes et des valeurs se fait sur le nom, dans la langue par défaut de la boutique, pas dans la langue de l'import : sur une boutique dont la langue par défaut n'est pas celle du fichier, "Taille" et "Size" produiront deux groupes distincts. Une valeur est identifiée par le couple groupe + nom : "Rouge" dans Couleur et "Rouge" dans Finition restent deux valeurs. Enfin, le fichier des déclinaisons accepte une colonne ISBN depuis la 9.1 ; elle n'existe pas en 9.0 ni en 8.x.

Les étapes, dans l'ordre#

Un catalogue à déclinaisons se charge en deux fichiers et deux passes. Ne mettez jamais les combinaisons dans le fichier produits : ce sont deux entités distinctes, chacune avec son écran d'import.

  1. Sauvegarder la base de données et le dossier img/.
  2. Préparer les deux fichiers. Le fichier produits contient une ligne par modèle (le T-shirt, pas le T-shirt rouge en M). Le fichier déclinaisons contient une ligne par combinaison.
  3. Importer marques et fournisseurs, puis les catégories, et récupérer les ID générés par export (voir plus haut).
  4. Importer les produits parents. Quantité à 0, une référence unique sur chaque ligne, option "Utiliser la référence du produit comme clé" cochée, "Pas de régénération des miniatures" cochée.
  5. Vérifier trois fiches dans le back-office : le produit existe, sa référence est bien enregistrée, et ses images sont attachées dans l'ordre du fichier. Cet ordre donne les positions 1, 2, 3… que vous utiliserez à l'étape suivante.
  6. Relever les positions d'images. La première URL de la colonne URL des images du fichier produits devient la position 1, la deuxième la position 2, et ainsi de suite. C'est ce numéro, et non une URL, que le fichier déclinaisons utilisera.
  7. Préparer le fichier déclinaisons : référence du produit parent, paires Attribut / Valeur dans le même ordre, une référence de combinaison unique, la quantité réelle, l'impact sur le prix, une seule ligne à Par défaut = 1, et la position d'image.
  8. Importer les déclinaisons via l'entité Déclinaisons, avec l'option "Utiliser la référence du produit comme clé" à nouveau cochée – elle est propre à chaque import, et sans elle la colonne Référence produit n'est pas lue.
  9. Contrôler un produit complet : onglet Déclinaisons de la fiche, le nombre de combinaisons attendu (3 tailles × 2 couleurs = 6), le stock de chacune, la déclinaison par défaut, l'image associée.
  10. Régénérer les miniatures, vider le cache, reconstruire l'index de recherche (voir la checklist d'après-import).
  11. Vérifier en boutique, pas seulement en back-office : le sélecteur s'affiche bien sous la forme attendue (liste déroulante, boutons radio ou pastille), le prix bouge avec l'impact, et une combinaison à stock zéro se comporte comme prévu.

Pour mettre à jour les stocks ou les prix ensuite, réimportez le même fichier déclinaisons avec les mêmes références de combinaison : PrestaShop les retrouve et les met à jour en place, sans créer de doublon. C'est ce qui rend l'opération rejouable – à condition que l'étape 7 ait bien donné une référence unique à chaque ligne.

Les options de l'écran d'import, une par une#

OptionRéglage recommandéPourquoi
Supprimer toutes les … avant l'import ?DécochéVide une trentaine de tables et efface le contenu de img/p/. À réserver à une boutique de test, ou à une décision assumée avec sauvegarde fraîche. En multiboutique, l'option est réservée au SuperAdmin.
Utiliser la référence du produit comme clé ?CochéFait de la référence la clé d'identification : une relance met à jour au lieu de dupliquer. Exige une référence unique et non vide partout. C'est la seule option qui rend un import rejouable.
Forcer tous les identifiants lors de l'importation ?Décoché, sauf reprise à l'identiqueImpose les ID du fichier. Utile pour une migration qui conserve les ID d'origine (donc les URL et les statistiques) ; dangereux sinon, car un ID déjà pris écrase un produit existant.
Pas de régénération des miniaturesCochéVoir ci-dessous.
Envoyer une notification par e-mailCochéSur un gros fichier, l'e-mail vous prévient de la fin sans monter la garde devant l'écran.

Pourquoi cocher "Pas de régénération des miniatures". À chaque image téléchargée, PrestaShop génère par défaut toutes les tailles définies dans Paramètres d'images – vignette de liste, image de fiche, zoom. Multipliez par le nombre de formats, d'images et de produits : c'est de loin le poste le plus coûteux de l'import et la cause n°1 des imports qui s'arrêtent en route. L'option cochée, PrestaShop se contente de stocker l'image source.

Ce qu'il faut faire ensuite : régénérer en une seule fois, après l'import, depuis Design > Paramètres d'images (documentation). Sur un gros catalogue, cette page dépasse souvent le temps d'exécution du navigateur : passez par la ligne de commande, qui n'a pas cette limite.

php bin/console prestashop:thumbnails:regenerate products
php bin/console prestashop:thumbnails:regenerate all --delete

Time-out, mémoire et gros volumes#

L'import du back-office ne s'exécute pas d'un bloc : il est découpé en appels AJAX traitant chacun un lot de lignes, et le contrôleur force max_execution_time à 0 dès son chargement. La limite d'exécution PHP n'est donc généralement pas le vrai coupable.

Ce qui bloque réellement, par ordre de fréquence :

  • Le délai du serveur web ou de PHP-FPM : request_terminate_timeout (FPM), proxy_read_timeout (Nginx), Timeout (Apache). Souvent à 60 ou 120 secondes, ils coupent la requête AJAX sans que PHP ait son mot à dire. C'est la cause n°1 d'un import "qui s'arrête à la moitié".
  • memory_limit : 256 Mo minimum confortable, 512 Mo raisonnable.
  • upload_max_filesize et post_max_size, qui plafonnent l'envoi du fichier. Contournement : déposer le CSV en FTP dans le sous-dossier import/ de votre dossier d'administration, puis le sélectionner via "Sélectionnez un fichier dans l'historique".
  • Le téléchargement des images, à 1 à 2 secondes pièce.
VolumeSans imagesAvec images
< 500 produitsconfortableconfortable
500 à 2 000confortabledécouper en lots de 500
2 000 à 10 000lots de 1 000 à 2 000découpage obligatoire, plusieurs heures
> 10 000envisager un scriptscript fortement recommandé

Découper, c'est scinder le CSV en conservant la ligne d'en-têtes dans chaque fichier, puis les importer à la suite avec le même mapping – enregistré une fois pour toutes via l'outil de configuration de correspondances.

tail -n +2 produits.csv | split -l 500 - lot_
for f in lot_*; do { head -1 produits.csv; cat "$f"; } > "${f}.csv"; rm "$f"; done

Les signes qu'il faut passer à un script : vous importez le même fichier chaque semaine ; vous découpez en plus de cinq lots ; vous devez transformer des données avant de les charger ; vous avez besoin de savoir précisément quelles lignes ont échoué. À ce stade, une commande Symfony ou un client de l'Admin API est plus rapide à écrire qu'à subir – nous détaillons les mécanismes d'accès programmatique dans notre article sur comment utiliser l'API de PrestaShop.

La checklist d'après-import#

L'import affiche "100 % importé". Vous n'avez pas fini.

  1. Régénérer les miniatures (Design > Paramètres d'images, ou la commande ci-dessus). Sans cela, les images existent mais les vignettes de listing sont vides.
  2. Vider le cache (Paramètres avancés > Performances). Les pages catégories et le menu restent sinon figés. Si la boutique utilise Redis ou Memcached, videz-le aussi – nous expliquons pourquoi cocher la case ne suffit pas toujours.
  3. Reconstruire l'index de recherche. C'est l'oubli classique. L'index est une table qui associe des mots aux produits ; le moteur interne ne lit que celle-là. Tant qu'elle n'est pas reconstruite, la recherche du site ne renvoie rien, alors que le catalogue est bien en ligne. Paramètres de la boutique > Rechercher → "Re-build entire index", ou php bin/console prestashop:search:index --full.
  4. Vérifier les taxes sur cinq produits représentatifs : un écart systématique de 20 % signale une colonne prix inversée ou une règle de taxes absente.
  5. Contrôler catégories et positions : la catégorie Accueil ne doit pas s'être remplie de produits, l'arborescence doit être intacte, et la catégorie par défaut de chaque produit est la première de sa liste.
  6. Filtrer sur "Actif = Non" dans Catalogue > Produits : dix secondes pour révéler une colonne mal mappée.

Cas particulier : la migration depuis une autre boutique#

Un CSV transporte un catalogue, pas une boutique. Ce qui ne passe pas par l'import :

  • Les avis clients, qui dépendent du module d'avis, source comme destination. Les perdre a un coût SEO réel si les étoiles apparaissaient dans les résultats de recherche.
  • L'historique des commandes : reprise en SQL ou via l'API, chantier à part entière.
  • Les comptes clients avec leurs mots de passe. L'entité Clients existe, mais les mots de passe sont des hachages propres à l'algorithme d'origine. Sauf migration depuis un PrestaShop de même génération, prévoyez une campagne de réinitialisation à l'ouverture.
  • Les paniers en cours, bons de réduction actifs et statistiques.

Le plan de redirections 301 fait la différence entre une migration réussie et six mois de trafic perdu. Une 301 indique définitivement à Google que la page a déménagé et transfère l'essentiel de son autorité ; sans elle, chaque ancienne URL devient une 404.

  1. Avant de couper l'ancien site, exportez la liste de ses URL : sitemap, crawl, et surtout export Search Console des pages qui reçoivent réellement du trafic.
  2. Constituez la table de correspondance ancienne → nouvelle URL. En reprenant les slugs d'origine dans la colonne URL simplifiée, vous supprimez l'essentiel des redirections à écrire.
  3. Traitez d'abord les 20 % d'URL qui font 80 % du trafic.
  4. Écrivez les règles en .htaccess, en configuration Nginx ou via un module, sans les placer dans un bloc que PrestaShop régénère – voir notre article sur le .htaccess de PrestaShop.
  5. Vérifiez après bascule qu'aucune redirection n'en appelle une autre, et surveillez la couverture Search Console pendant un mois.

Les erreurs d'import les plus fréquentes et leur cause#

Message ou symptômeCause réelleCorrection
Tous les produits rangés dans AccueilColonne Catégories non mappée, contenant des noms, ou des ID inexistants au moment de l'importImporter les catégories d'abord, récupérer les ID par export, refaire la RECHERCHEV, réimporter avec la référence comme clé
Des catégories nommées "12", "45", "108" sous AccueilLe fichier produits citait des ID inexistants : PrestaShop les a créées avec le nombre pour nomSupprimer ces catégories, importer le vrai fichier de catégories, corriger les ID, réimporter
Prix multipliés ou divisés par ~1,2Prix TTC dans la colonne HT (ou l'inverse), ou colonne ID règle de taxes vide / invalideNe renseigner qu'une seule colonne prix, vérifier la règle dans International > Taxes
Prix aberrants (1 au lieu de 1299,90)Séparateur de milliers, ou virgule décimale interprétée comme séparateur de valeurs multiplesReformater en point décimal sans séparateur de milliers
Accents remplacés par é, è, °Fichier Windows-1252 converti comme de l'ISO-8859-1, ou double encodageiconv -f WINDOWS-1252 -t UTF-8, ré-enregistrer en UTF-8 depuis LibreOffice
Images absentesURL relatives, non publiques, certificat HTTPS invalide, ou serveur source qui bloqueURL absolues publiquement accessibles ; tester avec curl -I avant l'import
Images présentes mais vignettes videsMiniatures non régénérées après un import avec l'option cochéeDesign > Paramètres d'images, ou prestashop:thumbnails:regenerate products
L'import s'arrête à la moitiéDélai serveur web / PHP-FPM atteint pendant un lot, souvent à cause des imagesCocher "Pas de régénération des miniatures", découper en lots, augmenter les délais serveur
Doublons créés à chaque relance"Utiliser la référence du produit comme clé" décochée, ou références vides / non uniquesCocher l'option, garantir une référence unique par ligne
Les déclinaisons ne se créent pasFichier importé avant les produits, ou référence produit utilisée sans cocher l'option de cléImporter les produits d'abord, cocher l'option, relancer
La recherche du site ne renvoie rienIndex de recherche non reconstruit"Re-build entire index", ou prestashop:search:index --full
Produits invisibles en boutiqueColonne Actif mal mappée, ou valeur textuelle (oui, non) au lieu de 0 / 1N'utiliser que 0 et 1 ; filtrer sur Actif = Non pour mesurer l'ampleur

Vos fichiers CSV modèles#

Trois fichiers prêts à l'emploi – catégories, produits, déclinaisons – avec les en-têtes dans le bon ordre, le bon encodage et deux lignes d'exemple chacun.

Leur contenu exact figure en annexe, en fin d'article : copiez-le dans un fichier texte enregistré en UTF-8 sans BOM, avec le point-virgule comme séparateur.

Récupérez-les avant de préparer vos données : partir d'un modèle correct économise l'essentiel des allers-retours. Rappel : les en-têtes de la première ligne sont indicatifs – PrestaShop ne les lit pas, seul l'ordre des colonnes compte, et vous indiquerez 1 dans "Sauter X lignes".

La checklist complète#

Avant

  • ☐ Sauvegarde de la base de données réalisée et testée
  • ☐ Sauvegarde du dossier img/ réalisée
  • ☐ Import d'abord joué sur une copie de préproduction
  • ☐ Fichiers en UTF-8 sans BOM, vérifiés avec file -i
  • ☐ Séparateur de champ ;, séparateur de valeurs multiples ,
  • ☐ Prix en point décimal, sans séparateur de milliers
  • ☐ Descriptions HTML sur une seule ligne ou encadrées de guillemets
  • ☐ Aucune référence en doublon
  • ☐ Règles de taxes créées, ID notés
  • ☐ URL d'images absolues et testées

Pendant

  • ☐ Marques et fournisseurs importés
  • ☐ Catégories importées, parentes avant enfantes, arborescence vérifiée
  • ☐ Export des catégories réalisé, ID récupérés
  • ☐ RECHERCHEV effectuée, zéro #N/A, résultats collés en valeurs
  • ☐ "Supprimer toutes les données" décochée
  • ☐ "Utiliser la référence du produit comme clé" cochée
  • ☐ "Pas de régénération des miniatures" cochée
  • ☐ Produits importés (quantité à 0 si le produit a des déclinaisons), mapping enregistré pour les lots suivants
  • ☐ Positions d'images relevées sur trois fiches produits
  • ☐ Fichier déclinaisons : une référence unique par combinaison, une seule ligne à Par défaut = 1
  • ☐ Déclinaisons importées après les produits, option de clé re-cochée sur cet import

Après

  • ☐ Miniatures régénérées
  • ☐ Cache vidé (y compris Redis / Memcached)
  • ☐ Index de recherche reconstruit
  • ☐ Taxes contrôlées sur cinq produits
  • ☐ Catégorie Accueil vide de produits
  • ☐ Produits actifs contrôlés par filtre
  • ☐ Redirections 301 en place, s'il s'agit d'une migration

FAQ#

Peut-on annuler un import PrestaShop ? Non. Il n'existe aucune fonction d'annulation ni d'historique permettant de revenir en arrière. La seule marche arrière possible est la restauration d'une sauvegarde de la base de données et du dossier img/ réalisée avant l'import.

Combien de produits peut-on importer d'un coup ? PrestaShop n'impose pas de limite : elle vient de votre hébergement. Jusqu'à 500 références par fichier, l'import passe sans précaution ; entre 500 et 2 000 avec images, mieux vaut découper ; au-delà de 10 000, un script est plus fiable. Le facteur limitant est le téléchargement des images, pas le nombre de lignes.

Comment importer les images des produits ? Par la colonne URL des images (x,y,z…), qui attend des URL absolues publiquement accessibles : PrestaShop télécharge chaque image depuis son serveur. Plusieurs images se séparent avec le séparateur de valeurs multiples, la première devenant la couverture. Cochez "Pas de régénération des miniatures" pendant l'import, puis régénérez tout ensuite.

Peut-on mettre à jour des produits existants sans créer de doublons ? Oui, en cochant "Utiliser la référence du produit comme clé". PrestaShop cherche alors un produit portant la même référence et le met à jour. Cela suppose une référence unique et non vide sur chaque ligne. Sans cette option, chaque relance recrée l'intégralité des produits.

Faut-il un module payant pour importer un catalogue ? Non pour un import ponctuel : le natif suffit. Un module devient pertinent quand l'import doit être répété, planifié, ou quand les données doivent être transformées avant d'entrer. Au-delà, un script sur mesure est souvent plus économique qu'un abonnement.

Comment importer les déclinaisons dans PrestaShop ? Dans un fichier séparé, via l'entité Déclinaisons, après les produits. Une ligne par combinaison, l'attribut au format Nom:Type:Position – le Type valant select, radio ou color – et la valeur au format Valeur:Position. Pour désigner le produit parent par sa référence, cochez également l'option de clé.

Conclusion#

L'import PrestaShop n'est pas difficile, il est impitoyable : il exécute ce que vous écrivez, dans l'ordre où vous le lui donnez, sans retour possible. La différence entre un import qui passe du premier coup et trois jours de rattrapage tient à quatre choses : une sauvegarde faite avant, l'ordre marques → catégories → produits → déclinaisons respecté, les ID de catégories récupérés par export plutôt que devinés, et la checklist d'après-import déroulée jusqu'au bout, index de recherche compris.

Si vous préférez ne pas apprendre ces pièges sur votre catalogue de production, c'est exactement le type de mission que nous menons : préparation des fichiers, import, reprise des URL et plan de redirections, contrôle qualité après bascule. Parlons-en – vingt minutes suffisent généralement à savoir si votre catalogue relève du CSV ou du script.

Pour replacer ces contraintes dans leur contexte, notre article sur les avantages et inconvénients de PrestaShop pour une boutique en ligne complète utilement celui-ci.

Annexe : contenu exact des 3 fichiers CSV modèles#

categories.csv#

"ID";"Actif (0/1)";"Nom";"Categorie parente";"Categorie racine (0/1)";"Description";"Meta title";"Meta description";"URL simplifiee";"URL de l'image"
"";"1";"Vetements";"Accueil";"0";"<p>Toute la collection de vêtements.</p>";"Vêtements";"Découvrez notre sélection de vêtements pour homme et femme.";"vetements";"https://exemple.fr/import/cat-vetements.jpg"
"";"1";"T-shirts";"Vetements";"0";"<p>T-shirts en coton biologique.</p>";"T-shirts";"T-shirts en coton biologique, fabriqués au Portugal.";"t-shirts";"https://exemple.fr/import/cat-tshirts.jpg"

produits.csv#

"ID";"Actif (0/1)";"Nom";"Categories (x,y,z...)";"Prix hors taxes";"ID regle de taxes";"Prix d'achat";"Reference #";"Marque";"Fournisseur";"EAN-13";"Poids";"Quantite";"Resume";"Description";"URL simplifiee";"Meta title";"Meta description";"Caracteristique (Nom:Valeur:Position:Personnalise)";"URL des images (x,y,z...)"
"";"1";"T-shirt col rond";"2,12";"24.90";"1";"9.50";"TSH-COL-001";"Websource Wear";"Atelier Porto";"3701234567890";"0.180";"120";"<p>T-shirt en coton biologique, coupe droite.</p>";"<p>Coupe droite, col rond côtelé, jersey 180 g/m². Fabriqué au Portugal.</p>";"t-shirt-col-rond";"T-shirt col rond en coton bio";"T-shirt col rond en coton biologique 180 g/m², fabriqué au Portugal. Livraison 48 h.";"Matiere:Coton bio:1:0,Origine:Portugal:2:0";"https://exemple.fr/import/tsh-001-face.jpg,https://exemple.fr/import/tsh-001-dos.jpg"
"";"1";"Sweat capuche";"2,13";"59.00";"1";"22.00";"SWT-CAP-002";"Websource Wear";"Atelier Porto";"3701234567906";"0.620";"45";"<p>Sweat à capuche molletonné, doublure brossée.</p>";"<p>Molleton 320 g/m², poche kangourou, cordon de serrage plat.</p>";"sweat-capuche";"Sweat à capuche molletonné";"Sweat à capuche molletonné 320 g/m², poche kangourou. Coupe unisexe.";"Matiere:Coton bio:1:0,Origine:Portugal:2:0";"https://exemple.fr/import/swt-002-face.jpg"

declinaisons.csv#

"ID produit";"Reference produit";"Attribut (Nom:Type:Position)";"Valeur (Valeur:Position)";"Reference";"EAN-13";"Impact sur le prix";"Impact sur le poids";"Quantite";"Quantite minimale";"Par defaut (0 = Non, 1 = Oui)";"Choisir parmi les images du produit par position (1,2,3...)"
"";"TSH-COL-001";"Taille:select:1,Couleur:color:2";"S:1,Rouge:1";"TSH-COL-001-S-RGE";"3701234567913";"0";"0";"12";"1";"1";"1"
"";"TSH-COL-001";"Taille:select:1,Couleur:color:2";"M:2,Bleu:2";"TSH-COL-001-M-BLE";"3701234567920";"0";"0";"18";"1";"0";"2"