Fiche incident

Checkout not working sur WooCommerce - Causes & solutions

Rédigé par Soulaimane Aattar — 850+ interventions e-commerce documentées Mis à jour le 14 juin 2026 Versions concernées : WooCommerce 7.x, 8.x et 9.x (checkout shortcode classique et Cart/Checkout Blocks par défaut depuis 8.3), sur PHP 7.4+ (8.0+ recommandé)

Ton tunnel de commande WooCommerce ne valide plus rien : bouton "Commander" inerte, spinner infini après la saisie de la carte, ou redirection vers un panier vide. Chaque minute dans cet état, ton trafic payant continue d'arriver et repart sans acheter. Le coût n'est pas l'erreur technique, c'est le chiffre d'affaires qui fuit en temps réel pendant que tes campagnes Ads tournent.

Sur WooCommerce, le checkout est un assemblage fragile : sessions, cookies, requêtes AJAX (wc-ajax), template form-checkout.php, passerelle de paiement et désormais bloc Gutenberg. Une seule de ces couches qui casse fige toute la commande. La bonne nouvelle : dans plus de 80 % des cas l'erreur remonte dès la première tentative dans la console du navigateur. Ce guide te donne la procédure exacte pour la trouver et la corriger, sans toucher à ta production à l'aveugle.

Contexte technique

Sur WooCommerce, l'écosystème plugin est à la fois la force et la faiblesse du checkout. Une mise à jour mineure de WooCommerce peut casser l'intégration d'un gateway Stripe, PayPal ou Mollie si le thème override le template checkout/form-checkout.php. Les blocks Gutenberg Checkout introduits depuis WooCommerce 8.3 ne sont pas compatibles avec certains plugins de frais de livraison custom, créant des erreurs silencieuses côté console. Autre cause fréquente : un plugin de cache full-page qui cache la page /checkout/ alors qu'elle devrait être exclue par défaut.

woocommerce checkout not workingcheckout woocommerce bugpaiement woocommerce bloque

Cet incident peut impacter votre chiffre d’affaires.

Si ce problème touche le checkout, la disponibilité ou la performance, la perte de revenu peut être immédiate.

Note expert BugRescue

Toujours reproduire l'incident en navigation privée avec DevTools ouvert. Les erreurs JS du checkout WooCommerce remontent 80% des cas dès la première tentative de paiement. Ne jamais modifier le template checkout en production sans rollback prêt.

Prise en charge par des experts avec 15+ ans d’expérience e-commerce.

Équipe senior full-stack PrestaShop, WooCommerce, Magento, Shopify et WordPress. Intervention rapide sur incidents critiques et stabilisation durable — France, Maroc, Belgique et Suisse.

Symptômes : comment confirmer le diagnostic

Avant de toucher quoi que ce soit, identifie précisément quel maillon casse. Ouvre ta boutique en navigation privée avec les DevTools ouverts (F12), ajoute un produit, va jusqu'au paiement et observe trois onglets : Console, Network (filtre Fetch/XHR) et Application > Cookies. Le symptôme exact pointe directement vers la famille de cause.

  • Bouton "Commander" inactif / sans action : presque toujours une erreur JavaScript (Console rouge : Uncaught TypeError, Uncaught ReferenceError) qui interrompt le script avant le submit.
  • Spinner / chargement infini après "Commander" : la requête AJAX wc-ajax=checkout échoue. Vérifie dans Network un statut 403 ou 500 sur /?wc-ajax=checkout, ou une réponse HTML renvoyée au lieu de JSON.
  • Redirection vers un panier vide : la session WooCommerce ne persiste pas. Dans Application > Cookies, le cookie woocommerce_cart_hash ou woocommerce_items_in_cart est absent ou écrasé.
  • Moyens de paiement absents à l'étape paiement : SSL manquant, devise/géolocalisation incompatible, ou clés API mal configurées côté passerelle.
  • Écran blanc (WSOD) ou message 500 Internal Server Error : erreur PHP fatale, souvent un conflit plugin/thème ou un manque de mémoire.
  • Message "session expired" / commande qui reste en pending : webhook de paiement qui ne revient pas (403/500) ou session purgée trop tôt.
  • Erreur ssl_error_rx_record_too_long ou échec handshake : mauvaise configuration HTTPS/redirection.

Impact business immédiat

Un checkout cassé n'est pas un bug "esthétique" : c'est une perte sèche et mesurable. Contrairement à une page produit lente, ici la conversion tombe à zéro pour le canal touché, pendant que tous tes coûts continuent.

  • Commandes perdues en direct : chaque visiteur arrivé jusqu'au panier part sans payer, et il ne reviendra pas pour la plupart.
  • Budget Ads gaspillé : tes campagnes Google/Meta paient des clics qui ne peuvent mécaniquement pas convertir tant que le tunnel est mort.
  • Explosion des tickets support : les clients qui réessaient signalent "ça ne marche pas", saturant ton service client au pire moment.
  • Atteinte à la réputation : un acheteur bloqué au paiement doute de la fiabilité de la boutique et le dit souvent publiquement (avis, réseaux).

Causes classées par probabilité

D'après les incidents réels remontés sur WooCommerce, voici l'ordre statistique des coupables. Traite-les dans cet ordre : tu résous la majorité des cas avant la cause 3.

  • 1. Cache / sessions (coupable n°1, ~7 cas sur 10) : un cache full-page (WP Rocket, W3 Total Cache, LiteSpeed, WP Fastest Cache) ou serveur (Varnish, Nginx, Cloudflare) sert une version mise en cache de /cart/ ou /checkout/, tuant la session et le hash du panier.
  • 2. Conflit plugin / thème : une mise à jour mineure de WooCommerce casse un gateway (Stripe, PayPal, Mollie) si le thème override checkout/form-checkout.php, ou un plugin récent injecte un JS qui plante.
  • 3. Incompatibilité Checkout Blocks (depuis WooCommerce 8.3) : le bloc Gutenberg n'expose pas l'API Store à certaines extensions (frais de livraison custom, passerelles anciennes) → "ce moyen de paiement n'est pas disponible avec le checkout par blocs" ou erreurs silencieuses en console.
  • 4. Passerelle de paiement mal configurée : SSL absent, devise non supportée, géolocalisation client hors zone, clés API en mode test sur un site live (ou l'inverse), webhook qui renvoie 403/500.
  • 5. AJAX bloqué côté serveur : ModSecurity / pare-feu applicatif bloque les POST vers /wc-ajax/, renvoyant un 403.
  • 6. Erreur PHP fatale / mémoire : WP_MEMORY_LIMIT trop bas (défaut ~40 Mo), max_execution_time dépassé, envoi d'emails synchrone qui fige le checkout.
  • 7. Bandeau cookies RGPD : le consentement bloque les cookies woocommerce_* avant acceptation → panier vide systématique tant que l'utilisateur n'a pas cliqué "Accepter".

Diagnostic : les commandes à lancer

Passe du symptôme à la preuve. Voici l'arbre de décision 60 secondes, puis les commandes exactes à exécuter en SSH ou via les outils intégrés. Lance d'abord WP_DEBUG_LOG pour capturer les erreurs PHP du tunnel.

  1. Écran blanc / 500 → va lire les logs PHP (debug.log, error.log).
  2. Spinner infini → ouvre Network, repère le statut HTTP sur /?wc-ajax=checkout (403 = pare-feu/ModSecurity, 500 = PHP).
  3. Panier vide → ouvre Application > Cookies, cherche woocommerce_cart_hash ; absent = cache ou consentement RGPD qui bloque les cookies.
  4. Moyen de paiement manquant → vérifie SSL, devise et clés API dans WooCommerce > Réglages > Paiements.
Activer le debug WooCommerce (wp-config.php)
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );    // écrit dans /wp-content/debug.log
define( 'WP_DEBUG_DISPLAY', false ); // ne JAMAIS afficher en prod
define( 'WP_MEMORY_LIMIT', '256M' ); // le défaut ~40M ne suffit pas au checkout
Surveiller les logs en direct pendant un test de checkout
# Suivre les erreurs PHP WordPress en temps réel
tail -f /wp-content/debug.log

# Repérer spécifiquement les erreurs liées au checkout / sessions / gateway
tail -n 200 /wp-content/debug.log | grep -iE 'checkout|session|stripe|paypal|mollie|fatal'

# Côté serveur Apache (un 500 sur wc-ajax y apparaît)
tail -f /var/log/apache2/error.log | grep -i 'wc-ajax'
Diagnostic WP-CLI : isoler plugin/thème sans toucher au front
# Lister les plugins actifs (chercher les MAJ récentes)
wp plugin list --status=active

# Purger toutes les sessions WooCommerce bloquées
wp wc tool run clear_sessions --user=1

# Vider tous les transients (cache objet parasite)
wp transient delete --all

# Bascule thème de test sans casser le live (faire sur staging)
wp theme activate storefront
Vérifier sessions et intégrité BDD (phpMyAdmin / SQL)
-- Sessions WooCommerce orphelines / volumineuses
SELECT COUNT(*) FROM wp_woocommerce_sessions;

-- Optimiser les tables sollicitées par le tunnel
OPTIMIZE TABLE wp_posts, wp_woocommerce_order_items, wp_woocommerce_sessions;
Tester si le pare-feu sortant bloque la passerelle
# Si vide ou timeout, ton serveur ne joint pas Stripe (paiement refusé sans raison)
curl -v https://api.stripe.com 2>&1 | grep -i 'HTTP\|SSL'

Solutions pas-à-pas

Applique les correctifs dans l'ordre du plus probable au moins probable. Travaille sur un environnement de staging dès qu'une étape modifie un template ou la BDD.

  1. Exclure le tunnel du cache. Dans ton plugin de cache, exclus les URLs /cart/, /checkout/, /my-account/ et les cookies woocommerce_cart_hash, woocommerce_items_in_cart, woocommerce_session_*. Sur Cloudflare : Page Rule Cache Level = Bypass sur */checkout/* et */cart/*, et désactive Rocket Loader (il casse le JS du checkout). Demande à ton hébergeur de whitelister /wc-ajax/ et /?wc-ajax= côté Varnish/ModSecurity.
  2. Isoler un conflit plugin/thème. En staging : wp theme activate storefront puis teste le checkout. Si ça marche, ton thème override le template — vérifie la présence de checkout/form-checkout.php dans le thème et compare-le à la version WooCommerce. Sinon, désactive les plugins par lots (wp plugin deactivate --all) et réactive un par un jusqu'à reproduire l'erreur.
  3. Décider blocs vs shortcode. Ouvre la page Validation/Checkout dans l'éditeur : si tu vois un bloc "Validation de la commande", tu es en Checkout Blocks. Si une extension affiche "non disponible avec le checkout par blocs", clique sur "Passer au shortcode classique" (Switch to classic shortcode) dans la barre du bloc — la page repasse sur [woocommerce_checkout], compatible avec toutes les extensions.
  4. Réparer la session / panier vide. Purge les sessions (wp wc tool run clear_sessions), va dans WooCommerce > Statut > Outils > Vider les sessions client. Force la persistance via object cache : define('WC_SESSION_CACHE_GROUP', 'wc_session_id'); si tu utilises Redis/Memcached. Vérifie que ton bandeau RGPD n'attend pas le consentement pour poser les cookies woocommerce_*.
  5. Revalider la passerelle. Dans WooCommerce > Réglages > Paiements : confirme le SSL actif, la devise supportée par la passerelle, et que les clés API sont en mode live (pas test). Pour Stripe/Mollie/Systempay/PayZen, vérifie l'URL de webhook et qu'elle renvoie bien 200 (un 403/500 laisse les commandes en pending). Force TLS et l'unification www/non-www.
  6. Régler le cas mobile / Safari iOS. Safari bloque les cookies tiers : assure-toi que les cookies de session sont posés en SameSite=None; Secure et sur le même domaine que le checkout. Unifie www et non-www (une seule version canonique) et force la redirection HTTP→HTTPS proprement pour éviter de perdre la session entre étapes.
  7. Traiter PHP/mémoire. Passe WP_MEMORY_LIMIT à 256M, max_execution_time à 120s (php.ini), et diffère les emails transactionnels qui figent parfois la validation : add_filter( 'woocommerce_defer_transactional_emails', '__return_true' );
  8. Resave les permaliens et pages. WooCommerce > Réglages > Avancé > Page Setup : confirme que la page Checkout est bien assignée. Puis Réglages > Permaliens > Enregistrer (sans rien changer) pour régénérer les règles de réécriture / endpoints.

Spécificités par version

Le comportement du checkout a profondément changé entre versions majeures. Identifie ta version (WooCommerce > État > Statut système) avant d'appliquer un correctif.

  • WooCommerce 7.x et antérieur : checkout shortcode [woocommerce_checkout] par défaut. Les bugs viennent surtout du cache, des overrides de thème et des conflits gateway. Pas de problématique blocs.
  • WooCommerce 8.3+ : les Cart/Checkout Blocks Gutenberg deviennent le défaut sur les nouvelles installations. Beaucoup d'extensions de paiement et de livraison custom ne supportent pas encore l'API Store des blocs → erreurs silencieuses. Le bouton "Passer au shortcode classique" est ta soupape de secours.
  • WooCommerce 9.x : l'API Store des blocs est plus mature mais les extensions anciennes restent à risque. PHP 7.4 reste le minimum, PHP 8.0+ est recommandé (et certaines extensions exigent désormais 8.1). Une montée de version PHP sans vérifier la compatibilité des gateways peut casser le paiement.
  • Tous : après chaque mise à jour majeure de WooCommerce, teste le tunnel complet en staging avant de pousser en prod, template form-checkout.php compris.

Quand appeler un expert

Tu as exclu le cache, basculé sur Storefront + shortcode classique, lu debug.log et le checkout reste mort : tu es face à une cause profonde (conflit de code dans un plugin custom, corruption de session liée à l'object cache, configuration serveur/ModSecurity, ou webhook passerelle non joignable). Au-delà de 30 minutes d'indisponibilité, chaque test à l'aveugle en production coûte plus cher que l'intervention.

C'est exactement le type d'incident que BugRescue traite en urgence : diagnostic ciblé sur staging, correction sécurisée avec rollback prêt, et remise en service du tunnel sans perdre de commandes. Si le chiffre d'affaires saigne en direct, ne tâtonne pas seul — fais auditer la pile complète (cache, blocs, passerelle, serveur) par quelqu'un qui l'a déjà vu casser.

FAQ

Pourquoi ma page de paiement WooCommerce reste en chargement infini ?

Le spinner infini signifie que la requête AJAX wc-ajax=checkout n'aboutit pas. Ouvre F12 > Network (Fetch/XHR) et regarde le statut sur /?wc-ajax=checkout : un 403 indique un pare-feu/ModSecurity qui bloque les POST vers /wc-ajax/ (demande à l'hébergeur de whitelister ce chemin), un 500 indique une erreur PHP à lire dans /wp-content/debug.log. Une réponse HTML au lieu de JSON pointe aussi vers une erreur PHP.

Pourquoi WooCommerce redirige vers un panier vide au checkout ?

La session ne persiste pas. Le plus souvent un cache full-page (ou Cloudflare/Varnish) sert une version cachée de /cart/ ou /checkout/ : exclus ces URLs et les cookies woocommerce_cart_hash, woocommerce_items_in_cart, woocommerce_session_*. Vérifie aussi ton bandeau RGPD : s'il bloque les cookies woocommerce_* avant consentement, le panier se vide systématiquement.

Un plugin de cache ou Cloudflare peut-il casser le checkout, et quelles URL exclure ?

Oui, c'est la cause n°1. Exclus toujours /cart/, /checkout/ et /my-account/ du cache full-page (WP Rocket, W3TC, LiteSpeed, WP Fastest Cache). Sur Cloudflare, crée une Page Rule Cache Level = Bypass sur */checkout/* et */cart/* et désactive Rocket Loader qui réordonne le JS du tunnel. Côté serveur, fais exclure ces chemins de Varnish/Nginx par l'hébergeur.

Comment corriger les erreurs AJAX 403 ou 500 du checkout ?

Un 403 sur /?wc-ajax= vient d'un pare-feu applicatif (ModSecurity) qui bloque les POST : demande le whitelisting de /wc-ajax/ à l'hébergeur. Un 500 est une erreur PHP : active WP_DEBUG_LOG, reproduis le checkout, puis tail -f /wp-content/debug.log pour lire l'erreur fatale (souvent un conflit plugin ou un dépassement mémoire — passe WP_MEMORY_LIMIT à 256M).

Pourquoi mes moyens de paiement n'apparaissent pas ?

Quatre causes : pas de SSL actif (HTTPS obligatoire pour la plupart des passerelles), devise non supportée par la passerelle, géolocalisation du client hors zone autorisée, ou clés API en mode test sur un site live. Vérifie tout cela dans WooCommerce > Réglages > Paiements. En Checkout Blocks (8.3+), une extension non compatible affiche aussi le message "non disponible avec le checkout par blocs" : bascule en shortcode classique.

Comment tester le checkout sans risquer d'affecter les vraies commandes ?

Clone le site sur un environnement de staging avec les mêmes plugins, le même thème et la même version PHP, puis reproduis le tunnel en mode test (clés sandbox Stripe/PayPal/Mollie). En production, teste seulement en navigation privée avec DevTools, et n'utilise le mode test de la passerelle que temporairement pour ne pas refuser de vraies commandes.

Appeler WhatsApp