Ce guide s’adresse aux propriétaires de boutiques OpenCart et aux administrateurs qui gèrent leur hébergement cPanel, et il répond à deux questions : faut-il passer à WooCommerce et, si oui, comment. La question se pose souvent quand une boutique OpenCart 3 doit passer à OpenCart 4 et que ses extensions (les modules complémentaires) ne peuvent pas suivre. La mise à jour devient alors une reconstruction. Tant qu’à reconstruire, WooCommerce est une destination solide. Vous le montez à côté de la boutique en ligne et vous importez depuis la base OpenCart en lecture seule. Ensuite, une redirection 301 (permanente) envoie chaque ancienne URL vers sa nouvelle page. À la fin, WooCommerce prend les commandes sur votre domaine, et OpenCart reste archivé juste à côté, prêt pour un retour arrière.
Ce que vous allez accomplir
- Décider franchement si OpenCart ou WooCommerce convient le mieux à votre boutique.
- Mesurer votre boutique OpenCart en SQL, y compris le nombre de variations que ses options vont produire.
- Importer produits, options, clients, images et anciennes commandes dans WooCommerce, avec un utilisateur de base limité à
SELECTet les courriels aux clients coupés. - Transformer la table
oc_seo_urlen redirections 301, y compris les vieux liensindex.php?route=. - Installer la nouvelle boutique dans
public_htmlpendant une courte fenêtre, tester de vraies connexions et une vraie commande, et garder un retour arrière prêt.
Prérequis
- Un compte cPanel qui héberge la boutique OpenCart, avec accès aux écrans Domains et MySQL Databases (ou un accès root à WHM).
- Un accès SSH avec WP-CLI, l’outil en ligne de commande de WordPress. Vérifiez avec
wp --info. - Un accès administrateur au tableau de bord d’OpenCart.
- Une sauvegarde cPanel complète. Rien ici n’écrit dans la base OpenCart, mais la bascule déplace des fichiers.
- Un choix d’édition pour l’importateur. L’extension gratuite FG OpenCart to WooCommerce importe les produits, catégories, étiquettes, images et pages d’information. Les options, les clients, les commandes et les catégories de taxes demandent l’édition Premium, selon cette page.
Les étapes supposent qu’OpenCart se trouve dans public_html, que le nom d’utilisateur cPanel est exmpl, que la base s’appelle exmpl_oc et que le préfixe des tables est oc_. Remplacez ces valeurs par les vôtres partout où elles apparaissent. OpenCart 2.x fonctionne de la même façon, sauf que sa table d’URL s’appelle oc_url_alias.
OpenCart ou WooCommerce : faut-il migrer?
Les deux sont des applications PHP libres et gratuites qui tournent bien sur cPanel. La vraie différence, c’est tout ce qui entoure le panier.
Restez sur OpenCart si vous gérez plusieurs vitrines depuis une seule administration, ce qu’OpenCart fait d’origine et WooCommerce non. Restez aussi si vous êtes déjà sur OpenCart 4 avec des extensions qui fonctionnent, ou si la boutique est un catalogue sans besoin d’articles, de pages d’atterrissage ou de blogue.
Passez à WooCommerce si vous êtes coincé sur OpenCart 2 ou 3 parce que des extensions bloquent la mise à jour. Passez-y aussi si votre marketing vit déjà dans WordPress, ou si vous payez sans cesse des développeurs pour des fonctions qui existent déjà en extensions WooCommerce maintenues. En échange, attendez-vous à plus d’extensions à tenir à jour et à une administration plus lourde.
Nos guides pour PrestaShop, Magento et Shopify traitent du même choix sur d’autres plateformes.
Comment ça fonctionne
L’importateur lit les tables d’OpenCart par MySQL et crée des objets WordPress, alors OpenCart continue de vendre jusqu’à la bascule. Le MultiPHP Manager de cPanel permet à l’ancienne boutique de garder une version de PHP plus ancienne pendant que le nouveau sous-domaine en utilise une récente.
Produits et langues. oc_product contient le modèle, l’UGS (unité de gestion des stocks), le prix, le stock et l’image principale. oc_product_description contient le nom et la description, avec un rang par language_id. WooCommerce seul ne gère qu’une langue, alors une boutique bilingue a besoin de WPML ou de Polylang avant l’importation. L’importateur Premium offre un module complémentaire pour l’un comme pour l’autre.
Les options sont la partie à bien comprendre avant d’importer. Dans OpenCart, chaque produit a ses propres options, comme Taille et Couleur. Chaque option a des valeurs stockées dans oc_product_option_value. Une valeur peut ajouter ou retrancher un montant au prix et peut suivre sa propre quantité. Elle n’a pas d’UGS à elle, et les options sont indépendantes les unes des autres. Un chandail offert en 3 tailles et 4 couleurs a donc 7 rangs de valeurs dans OpenCart.
WooCommerce fonctionne à l’inverse. Un produit variable a une variation par combinaison, chacune avec son UGS, son prix et son stock. Ce chandail devient 12 variations. Leurs prix viennent du prix de base plus les modificateurs, et le stock doit être recompté, parce qu’OpenCart comptait les tailles et les couleurs séparément. Les options où le client tape du texte, téléverse un fichier ou choisit une date ne sont pas des variations. Elles demandent une extension d’options de produit. L’importateur vend un module Product Options, alors demandez à son auteur quels types d’options il couvre.
Les mots de passe dépendent de la version. Les versions plus anciennes d’OpenCart stockent un hachage SHA-1 salé de 40 caractères dans oc_customer.password, avec le sel dans la colonne salt. Les versions récentes utilisent la fonction PHP password_hash(), qui produit un hachage bcrypt de 60 caractères. Une boutique mise à jour au fil des ans peut contenir les deux. La version exacte du changement varie, alors l’étape 4 vérifie vos données au lieu de se fier au numéro de version. L’importateur Premium indique que les clients peuvent se connecter avec leur mot de passe OpenCart. Prouvez-le sur un compte de chaque type de hachage plutôt que de le tenir pour acquis.
Les images vivent dans image/catalog/. OpenCart stocke des chemins comme catalog/demo/imac_1.jpg et garde des copies redimensionnées dans image/cache/. L’importateur télécharge les originaux en HTTP depuis l’URL de la boutique que vous lui donnez. OpenCart doit donc rester en ligne et hors du mode maintenance pendant l’importation.
Étape par étape
-
Relevez les paramètres de la base et la version.
grep -E "DB_(HOSTNAME|USERNAME|DATABASE|PREFIX)'" ~/public_html/config.php grep "define('VERSION'" ~/public_html/index.phpRésultat attendu :
define('DB_HOSTNAME', 'localhost'); define('DB_USERNAME', 'exmpl_ocuser'); define('DB_DATABASE', 'exmpl_oc'); define('DB_PREFIX', 'oc_'); define('VERSION', '3.0.3.8');Une version qui commence par
4.veut dire OpenCart 4. Si le préfixe n’est pasoc_, utilisez le vôtre dans toutes les requêtes qui suivent. -
Mesurez la boutique et trouvez la langue par défaut.
mysql -u exmpl_ocuser -p exmpl_oc -e "SELECT (SELECT COUNT(*) FROM oc_product WHERE status=1) AS products, (SELECT COUNT(DISTINCT product_id) FROM oc_product_option_value) AS with_options, (SELECT COUNT(*) FROM oc_customer) AS customers, (SELECT COUNT(*) FROM oc_order WHERE order_status_id>0) AS orders;" mysql -u exmpl_ocuser -p exmpl_oc -e "SELECT language_id, code, status FROM oc_language; SELECT \`key\`, value FROM oc_setting WHERE store_id=0 AND \`key\` LIKE 'config_language%';"Attendu : un rang de totaux comme
318 | 96 | 2140 | 5388, puis les langues, puis le code de la langue par défaut, par exempleconfig_language | en-gb. Notez lelanguage_iddont lecodecorrespond à cette valeur ; l’exportation des URL s’en sert. Le filtreorder_status_id>0écarte les paniers abandonnés, qu’OpenCart enregistre comme des commandes au statut 0. -
Vérifiez les types d’options et estimez les variations.
mysql -u exmpl_ocuser -p exmpl_oc -e "SELECT o.type, COUNT(DISTINCT po.product_id) AS products FROM oc_product_option po JOIN oc_option o ON o.option_id=po.option_id GROUP BY o.type;" mysql -u exmpl_ocuser -p exmpl_oc -e "SELECT product_id, ROUND(EXP(SUM(LN(n)))) AS variations FROM (SELECT product_id, product_option_id, COUNT(*) AS n FROM oc_product_option_value GROUP BY product_id, product_option_id) t GROUP BY product_id ORDER BY variations DESC LIMIT 5;"Attendu : un rang par type d’option, comme
select | 88ettext | 6, puis vos cinq produits qui ont le plus de combinaisons. Les optionsselectetradiopeuvent devenir des variations. Les typescheckbox,text,textarea,file,date,timeetdatetimedemandent une extension d’options de produit. Un produit qui affiche des centaines de variations devient lent à modifier dans WooCommerce, alors pensez à le séparer en plusieurs produits. -
Vérifiez comment les mots de passe sont stockés.
mysql -u exmpl_ocuser -p exmpl_oc -e "SELECT LENGTH(password) AS hash_length, COUNT(*) FROM oc_customer GROUP BY hash_length;"Attendu : des rangs à
40(SHA-1 salé), à60(bcrypt), ou les deux. Un rang à32signale de très vieux hachages MD5 d’OpenCart 1.5. Choisissez un vrai client dans chaque groupe pour l’étape 11. -
Montez WordPress et WooCommerce sur un sous-domaine. Dans cPanel, ouvrez Domains et créez
new.example.com. Assurez-vous que sa racine de documents (Document Root) est~/new.example.com, hors depublic_html. Sinon, l’échange de dossiers de l’étape 10 le déplacera avec l’ancienne boutique. Créez une base vide et un utilisateur dans MySQL Databases, par exempleexmpl_wpetexmpl_wpuser. Installez ensuite :cd ~/new.example.com wp core download wp config create --dbname=exmpl_wp --dbuser=exmpl_wpuser --dbpass='REPLACE_ME' wp core install --url=https://new.example.com --title='Example Shop' \ --admin_user=admin --admin_email=you@example.com --skip-email wp rewrite structure '/%postname%/' --hard wp plugin install woocommerce --activateAttendu :
Success: WordPress installed successfully.,Success: Rewrite structure set., puisPlugin 'woocommerce' activated.Les fiches produits vivront sous/product/<slug>/, et c’est ce que visent les redirections. -
Coupez les courriels aux clients et accordez l’accès en lecture seule. Les commandes importées ne doivent envoyer aucun courriel. Désactivez les courriels de commande et de compte de WooCommerce, puis donnez à l’utilisateur de la base WordPress le droit
SELECTsur la base OpenCart :for e in new_order customer_processing_order customer_completed_order customer_on_hold_order customer_refunded_order customer_new_account; do wp option update "woocommerce_${e}_settings" '{"enabled":"no"}' --format=json done uapi Mysql set_privileges_on_database user=exmpl_wpuser database=exmpl_oc privileges=SELECTAttendu : six lignes comme
Success: Updated 'woocommerce_new_order_settings' option., puis un bloc YAML qui contientstatus: 1. Sur une installation neuve de WooCommerce, ces options n’existent pas encore : la commande les crée et WooCommerce remplit les autres réglages de courriel avec ses valeurs par défaut. Comme elle remplace le réglage au complet, personnalisez les objets et les en-têtes des courriels seulement après la bascule. En root, ajoutez--user=exmplaprèsuapi. AvecSELECTseulement, aucun réglage de l’importateur ne peut modifier un rang d’OpenCart. -
Lancez l’importateur.
wp plugin install fg-opencart-to-woocommerce --activateAttendu :
Plugin 'fg-opencart-to-woocommerce' activated.Pour Premium, installez plutôt son fichier zip depuis le site de l’auteur. Dans l’administration WordPress, ouvrez Outils > Importer > OpenCart. Entrez l’URL de la page d’accueil de la boutique (https://example.com), l’hôtelocalhost, la baseexmpl_oc, l’utilisateurexmpl_wpuser, son mot de passe et le préfixeoc_. Testez la connexion, lancez l’importation et gardez l’onglet ouvert. Comptez ensuite ce qui est arrivé :wp post list --post_type=product --post_status=publish --format=count wp post list --post_type=product_variation --format=count wp user list --role=customer --format=countAttendu : des nombres de produits et de clients proches de ceux de l’étape 2, et un nombre de variations cohérent avec l’étape 3. L’édition gratuite affiche zéro variation et zéro client. Ouvrez un produit à deux options et comparez le prix de chaque variation avec OpenCart avant d’aller plus loin.
Un petit catalogue sans options peut plutôt passer par l’importateur CSV de produits intégré à WooCommerce, en associant les colonnes à la main.
-
Confirmez que les images ont suivi.
mysql -u exmpl_ocuser -p exmpl_oc -N -e "SELECT (SELECT COUNT(*) FROM oc_product WHERE image<>'') + (SELECT COUNT(*) FROM oc_product_image);" wp post list --post_type=attachment --post_status=inherit --format=countAttendu : deux nombres du même ordre, ou moins du côté WordPress quand des produits partagent une image. Un total beaucoup plus bas veut dire que les téléchargements ont échoué.
-
Générez la carte de redirections. Avec les URL SEO activées, OpenCart 3 sert un produit à son mot-clé, souvent précédé du chemin de catégorie, comme
/desktops/mac/imac. OpenCart 4 peut ajouter un segment de langue commeen-gb. Avec les URL SEO désactivées, les liens ressemblent à/index.php?route=product/product&product_id=42.Exportez les mots-clés de la langue par défaut (remplacez
language_id=1par votre valeur de l’étape 2). Sur OpenCart 3 :mysql -u exmpl_ocuser -p exmpl_oc -N -e "SELECT SUBSTRING_INDEX(query,'=',1), SUBSTRING_INDEX(query,'=',-1), keyword FROM oc_seo_url WHERE store_id=0 AND language_id=1 AND (query LIKE 'product_id=%' OR query LIKE 'category_id=%');" > ~/oc-urls.tsvSur OpenCart 4, la table range le type et l’identifiant dans deux colonnes distinctes,
keyetvalue. Lancez plutôt ceci :mysql -u exmpl_ocuser -p exmpl_oc -N -e "SELECT \`key\`, value, keyword FROM oc_seo_url WHERE store_id=0 AND language_id=1 AND \`key\` IN ('product_id','category_id','path');" > ~/oc-urls.tsvVérifiez que chaque mot-clé peut entrer tel quel dans un motif de réécriture :
awk -F'\t' '$3 !~ /^[a-z0-9\/-]+$/' ~/oc-urls.tsvAttendu : aucune sortie. Toute ligne affichée contient un mot-clé avec des points, des majuscules ou des accents ; échappez ou corrigez ces règles à la main. Vérifiez ensuite que l’importateur a gardé les mots-clés comme slugs de produits :
wp post list --post_type=product --field=post_name > ~/wc-slugs.txt awk -F'\t' 'NR==FNR{s[$1];next} $1=="product_id" && !($3 in s)' ~/wc-slugs.txt ~/oc-urls.tsvAttendu : aucune sortie. Chaque produit affiché a un autre slug dans WooCommerce. Corrigez-le avec
wp post update <ID> --post_name=<keyword>, ou modifiez cette ligne de la carte. Écrivez maintenant les règles :awk -F'\t' '{ n = split($3, seg, "/"); slug = seg[n] if ($1 == "product_id") { dest = "product/" slug; route = "product/product"; q = "product_id=" $2 } else { dest = "product-category/" slug; route = "product/category"; q = "path=([0-9]+_)*" $2 } printf "RewriteCond %%{REQUEST_URI} !^/(product|product-category)/\n" printf "RewriteRule ^(.+/)?%s/?$ https://example.com/%s/ [R=301,L]\n", $3, dest printf "RewriteCond %%{QUERY_STRING} (^|&)route=%s(&|$)\n", route printf "RewriteCond %%{QUERY_STRING} (^|&)%s(&|$)\n", q printf "RewriteRule ^(index\\.php)?$ https://example.com/%s/? [R=301,L]\n", dest }' ~/oc-urls.tsv > ~/oc-redirects.conf grep -B1 -A3 'imac/?\$' ~/oc-redirects.confAttendu, pour le produit 42 dont le mot-clé est
imac:RewriteCond %{REQUEST_URI} !^/(product|product-category)/ RewriteRule ^(.+/)?imac/?$ https://example.com/product/imac/ [R=301,L] RewriteCond %{QUERY_STRING} (^|&)route=product/product(&|$) RewriteCond %{QUERY_STRING} (^|&)product_id=42(&|$) RewriteRule ^(index\.php)?$ https://example.com/product/imac/? [R=301,L]La partie
(.+/)?accepte n’importe quel chemin de catégorie ou segment de langue avant le mot-clé. La conditionREQUEST_URIempêche une boucle, puisque/product/imac/finit aussi parimac. Les liens de catégorie ressemblent àpath=18_20, alors leur motif accepte d’abord les identifiants parents. Le?final retire l’ancienne chaîne de paramètres.Collez le fichier dans
~/new.example.com/.htaccessau-dessus de# BEGIN WordPress, entre deux lignes de commentaire comme# --- OpenCart legacy URLs ---et# --- end OpenCart legacy URLs ---, avecRewriteEngine Onen tête. Le bloc WordPress arrête le traitement des requêtes versindex.php, alors des règles à paramètres placées dessous ne s’exécutent jamais. L’édition Premium peut aussi rediriger les anciennes URL elle-même ; si vous l’utilisez, sautez la carte mais faites quand même les tests plus bas. -
Refaites la livraison et les paiements, puis basculez. L’importateur ne transporte ni votre thème, ni vos extensions, ni vos modes de livraison, ni vos passerelles de paiement. Configurez-les, puis passez une commande test par mode de paiement sur
new.example.com. Pour une boutique canadienne, comparez les catégories de taxes importées avec notre guide sur les taux de taxes WooCommerce pour la TPS, la TVH et la TVQ.Pendant la fenêtre, lancez une dernière importation, puis notez la commande la plus récente :
mysql -u exmpl_ocuser -p exmpl_oc -e "SELECT MAX(order_id), MAX(date_added) FROM oc_order WHERE order_status_id>0;"Attendu : un rang avec un numéro de commande et un horodatage. Dans OpenCart, ouvrez Système > Paramètres, modifiez la boutique et, dans l’onglet Serveur, réglez le mode maintenance à Oui. Permutez ensuite les dossiers :
cd ~ mkdir opencart-archive mv public_html/* public_html/.htaccess opencart-archive/ mv new.example.com/* new.example.com/.htaccess public_html/ cd ~/public_html wp search-replace 'https://new.example.com' 'https://example.com' --all-tables wp option get siteurlAttendu : un tableau qui se termine par une ligne comme
Success: Made 2870 replacements., puishttps://example.com. Si OpenCart n’a jamais eu de.htaccess(le fichier est livré sous le nom.htaccess.txt), retirezpublic_html/.htaccessdu premiermv. Relancez la requêteMAX(order_id); un numéro plus élevé est une commande passée pendant la permutation, à ressaisir à la main. Réactivez les courriels de l’étape 6 en relançant la même boucle avec"yes".Retour arrière. Si le paiement échoue et que vous ne pouvez pas corriger rapidement, déplacez le contenu de
public_htmldans un dossierwoo-failed, remettezopencart-archiveen place et réglez le mode maintenance à Non. La base OpenCart n’a jamais été modifiée, alors la boutique revient exactement comme avant. -
Testez les connexions des clients, puis réinitialisez par lots au besoin. Connectez-vous sur
/my-account/avec votre client test de chaque groupe de hachage de l’étape 4. Si un test échoue, envoyez des liens de réinitialisation. Bien des serveurs cPanel limitent le nombre de courriels par domaine et par heure, alors séparez la liste des clients en fichiers de 200 :wp user list --role=customer --field=ID | split -l 200 - ~/oc-reset- ls ~/oc-reset-* xargs wp user reset-password < ~/oc-reset-aaAttendu : la liste des fichiers de lots, puis une ligne
Reset password for ...par utilisateur et une ligneSuccess:. Envoyezoc-reset-abune heure plus tard, et continuez chaque heure jusqu’au dernier fichier. Prévenez vos clients d’abord, pour que ces courriels n’aient pas l’air d’hameçonnage.
Valider que ça fonctionne
Testez chaque forme d’URL, ainsi que la nouvelle page elle-même pour prouver qu’il n’y a pas de boucle :
for u in '/desktops/mac/imac' '/en-gb/product/imac' '/index.php?route=product/product&product_id=42' '/product/imac/'; do
printf '%s %s\n' "$(curl -s -o /dev/null -w '%{http_code} %{redirect_url}' "https://example.com$u")" "$u"
done
Attendu : trois lignes qui commencent par 301 https://example.com/product/imac/, et une dernière ligne qui commence par 200. Confirmez ensuite qu’aucun contenu ne pointe encore vers les chemins d’images d’OpenCart :
wp db query "SELECT COUNT(*) FROM wp_posts WHERE post_status='publish' AND post_content LIKE '%image/catalog/%';" --skip-column-names
Attendu : 0. Terminez par une vraie commande sur le domaine en production, payée puis remboursée, et confirmez que le courriel de commande arrive.
Dépannage
- L’importateur ne se connecte pas. Le droit de l’étape 6 manque, ou le préfixe est mauvais. Testez avec
mysql -u exmpl_wpuser -p exmpl_oc -e "SHOW TABLES LIKE 'oc_product';", qui doit afficher le nom de la table. - Les produits sont arrivés sans images. Le champ URL doit contenir la page d’accueil d’OpenCart, et la boutique doit être joignable. Une redirection
httpvershttps, une vérification Cloudflare ou la protection contre le hotlinking de cPanel peuvent bloquer les téléchargements. Corrigez la cause, puis relancez l’importation. - Les prix des variations semblent faux. OpenCart stocke chaque modificateur avec un signe
+ou-dans la colonneprice_prefix. Comparez un produit à deux options avec sa page OpenCart, et corrigez la correspondance avant d’importer le reste. - L’importation s’arrête en chemin. Ajoutez
define('WP_MEMORY_LIMIT', '2G');danswp-config.phpet relancez-la. La FAQ de l’extension indique qu’une nouvelle exécution reprend là où la précédente s’est arrêtée. - Toutes les fiches produits tournent en boucle. La condition
REQUEST_URImanque au-dessus d’une règle de chemin. Lancezgrep -c 'REQUEST_URI' ~/public_html/.htaccess; le résultat doit égaler le nombre de lignes donné parwc -l < ~/oc-urls.tsv.
Quand ce n’est pas la bonne approche
Si la boutique fait tourner plusieurs vitrines, ou dépend d’une extension sans équivalent WooCommerce, réglez cette question avant toute importation. Un catalogue qui suit beaucoup de stock par option peut aussi coûter moins cher à garder sur OpenCart 4 qu’à recompter en variations.
La référence mod_rewrite d’Apache documente les directives utilisées dans la carte de redirections.
Un WordPress qui rapporte vraiment mérite un opérateur — Stack Harbor opère cette pile sous WordPress Entreprise ; réservez une consultation d’infrastructure.