Ce guide aide les propriétaires et les développeurs de boutiques WooCommerce à régler les commandes qui restent « En attente de paiement » alors que le client a été débité. Vous voyez un paiement réussi dans Stripe ou PayPal, mais la commande ne passe jamais à « En cours », et une heure plus tard WooCommerce l’annule. La cause est presque toujours un webhook, le message que la passerelle de paiement renvoie à votre site pour dire « ce paiement a réussi ». Ce message n’atteint jamais WooCommerce, ou il est rejeté à l’arrivée. À la fin, vous saurez quelle couche le bloque, vous l’aurez corrigée et les commandes bloquées seront rapprochées en toute sécurité.
Ce que vous allez accomplir
- Une idée claire du trajet d’une confirmation de paiement, de la passerelle jusqu’à votre commande.
- Le code d’état HTTP exact que renvoie votre point de terminaison de webhook, et la couche qui l’a produit.
- Une correction du blocage, qu’il vienne de Cloudflare, d’un pare-feu serveur, d’une redirection, d’une extension ou d’un mauvais secret.
- Un événement de test qui arrive avec une réponse
200et fait passer une commande à « En cours ». - Des commandes bloquées vérifiées auprès de la passerelle et mises à jour, avec une note qui explique pourquoi.
Prérequis
Il vous faut un compte administrateur WordPress et un accès au tableau de bord de votre passerelle (Stripe ou PayPal). Un accès SSH au serveur et WP-CLI, l’outil officiel en ligne de commande de WordPress, accélèrent plusieurs étapes. Lancez wp --info une fois connecté ; s’il affiche une version, vous êtes prêt.
Les étapes prennent comme exemples l’extension WooCommerce Stripe Payment Gateway et l’extension WooCommerce PayPal Payments. Les autres passerelles suivent la même logique. Sur cPanel, l’étape ModSecurity demande un accès root ou l’aide de votre hébergeur. ModSecurity est un module de pare-feu applicatif web pour Apache et LiteSpeed.
Remplacez example.com par votre domaine dans chaque commande. Les commandes avec --user=1 supposent que l’utilisateur 1 est administrateur ; changez ce numéro au besoin.
Comment ça fonctionne
Quand un client clique sur Commander, WooCommerce crée tout de suite la commande avec le statut « En attente de paiement ». Ce statut veut dire « la commande existe, mais personne ne nous a confirmé qu’elle est payée ». Notre guide sur les statuts de commande WooCommerce les décrit tous en détail.
Le client paie ensuite auprès de la passerelle. Le résultat final arrive souvent à part, surtout après 3D Secure (l’étape d’approbation supplémentaire de la banque). La passerelle l’envoie sous forme de webhook, une requête HTTPS POST envoyée par ses serveurs vers une adresse fixe de votre site. Chez PayPal, l’ancien nom de ce mécanisme est IPN, pour Instant Payment Notification. L’extension de la passerelle lit le message, vérifie qu’il est authentique et marque la commande comme payée, ce qui la fait passer à « En cours ».
Le webhook traverse chaque couche qui protège votre site, et chacune peut l’arrêter. La dernière vérification porte sur le secret de signature, une clé partagée qui prouve que le message vient bien de la passerelle. L’extension rejette tout message dont la signature ne correspond pas.
Une deuxième minuterie aggrave le problème. Sous WooCommerce, Réglages, Produits, Inventaire, le réglage Hold stock (minutes) (« Retenir le stock » dans l’interface française) réserve le stock des commandes impayées. La valeur par défaut est 60. Une fois ce délai écoulé, WooCommerce annule toute commande encore « En attente de paiement ». Il ajoute une note indiquant que la commande impayée a été annulée parce que le délai est dépassé. Un webhook brisé transforme donc une commande payée en commande annulée en moins d’une heure.
Étape par étape
1. Confirmez que le paiement a vraiment réussi. Notez le total et le courriel du client d’une commande bloquée. Cherchez ce courriel sous Payments dans Stripe, ou sous Activité dans PayPal. Un paiement marqué Succeeded (Stripe) ou Terminé (PayPal) confirme que ce guide s’applique. Si le paiement est incomplet ou refusé, le client n’a pas fini de payer et le statut de la commande est correct.
Pour lister toutes les commandes bloquées d’un coup, utilisez WP-CLI.
wp wc shop_order list --status=pending --user=1 --fields=id,date_created,total,payment_method --format=table
Vous devriez voir un tableau avec une ligne par commande « En attente de paiement ». Gardez cette liste pour l’étape 9.
2. Lisez le journal de la passerelle dans WooCommerce. Ouvrez WooCommerce, État, Journaux. Choisissez le journal le plus récent dont le nom commence par celui de la passerelle, comme woocommerce-gateway-stripe ou woocommerce-paypal-payments. Dans l’extension Stripe, activez d’abord le journal de débogage s’il n’existe aucun journal, puis attendez la prochaine commande.
Cherchez les lignes qui parlent de webhooks entrants. Un webhook qui a « failed validation » a atteint WordPress avec le mauvais secret ; passez à l’étape 7. Aucun webhook entrant veut dire que quelque chose arrête la requête avant que WordPress démarre. Continuez à l’étape 3.
3. Lisez les tentatives de livraison dans le tableau de bord de la passerelle. Dans Stripe, ouvrez Developers, puis Webhooks (les comptes récents l’affichent sous Workbench). Sélectionnez le point de terminaison et ouvrez ses livraisons d’événements récentes. Chaque tentative montre le code d’état HTTP renvoyé par votre site et le début du corps de la réponse.
Vérifiez d’abord l’URL du point de terminaison. L’extension Stripe affiche l’URL exacte du webhook sur sa page de réglages, et elle ressemble habituellement à https://example.com/?wc-api=wc_stripe. L’URL enregistrée chez Stripe doit correspondre exactement, y compris https et la présence ou non de www. Pour PayPal Payments, ouvrez les réglages de l’extension et trouvez la section d’état des webhooks. Elle affiche le webhook inscrit et offre un bouton pour le réinscrire.
Voici comment lire les codes d’état.
| Code | Ce que ça veut dire habituellement | Aller à |
|---|---|---|
| 403 avec une page Cloudflare | Cloudflare a mis la requête au défi ou l’a bloquée | Étape 5 |
| 403 ou 406 avec une page du serveur | ModSecurity ou Imunify l’a rejetée | Étape 6 |
| 301 ou 302 | Une redirection ; Stripe la traite comme un échec de livraison | Étape 6 |
| 503 | Mode maintenance ou serveur surchargé | Étape 6 |
| 400 | WordPress a répondu ; la vérification de signature a échoué | Étape 7 |
4. Reproduisez la requête vous-même avec curl. Vous verrez ainsi ce que voit la passerelle. Utilisez l’URL exacte des réglages de l’extension.
curl -s -o /dev/null -D - -X POST -H 'Content-Type: application/json' -d '{}' 'https://example.com/?wc-api=wc_stripe'
La première ligne de la sortie donne le code d’état. Un point de terminaison Stripe en bon état répond HTTP/2 400 à ce test non signé, parce que l’extension rejette toute requête sans signature valide. Ici, ce 400 est une bonne nouvelle : la requête a traversé toutes les couches et atteint l’extension.
Toute autre réponse indique un blocage. Un en-tête cf-mitigated: challenge veut dire que Cloudflare a lancé un défi. Un en-tête location: signale une redirection. Un 403 ou un 406 avec server: Apache ou server: LiteSpeed pointe vers ModSecurity ou Imunify.
5. Laissez passer le webhook dans Cloudflare. Ouvrez Cloudflare, Security, Events, et filtrez sur le chemin du webhook. Si le mode Bot Fight ou une règle WAF (une règle de pare-feu applicatif web) l’a bloqué, l’événement l’indique. Avec un forfait Cloudflare payant, une règle personnalisée peut sauter ces vérifications pour le chemin du webhook. Avec le forfait gratuit, le mode Bot Fight ne peut pas être exempté par chemin. Notre guide sur le mode Bot Fight qui bloque les webhooks détaille les options de chaque forfait.
6. Retirez les blocages du serveur et de WordPress. Traitez celui qui correspond à votre code d’état.
- ModSecurity ou Imunify (403 ou 406). Sur cPanel, cherchez la requête dans le journal d’erreurs d’Apache.
grep -i modsecurity /etc/apache2/logs/error_log | grep wc-api | tail -n 5
Chaque résultat affiche un identifiant de règle comme [id "949110"]. Désactivez cette règle pour ce domaine dans WHM, sous ModSecurity Tools, ou demandez-le à votre hébergeur. Notre guide sur ModSecurity qui bloque wp-admin explique la même méthode. Aucun résultat veut dire que ModSecurity n’a rien bloqué. Consultez plutôt la liste d’incidents d’Imunify360, une suite de sécurité répandue sur les serveurs cPanel.
- Redirections (301 ou 302). Quand un POST suit une redirection 301, la plupart des clients le renvoient en GET et les données du paiement sont perdues. Stripe ne suit pas les redirections du tout. Inscrivez l’adresse finale, avec la bonne forme
httpsetwww, dans le tableau de bord de la passerelle pour qu’aucune redirection n’ait lieu. - Mode maintenance ou « bientôt disponible » (503). Une extension de maintenance, ou un fichier
.maintenanceoublié après une mise à jour interrompue, répond à tout le monde avec une page d’attente. Désactivez le mode, ou supprimez le fichier à la racine du site. - Extensions de sécurité. Certains réglages bloquent l’API REST de WordPress (l’interface web intégrée qu’appellent les autres services) ou les chaînes de requête inconnues. PayPal Payments utilise l’API REST pour ses webhooks. Autorisez le point de terminaison de la passerelle dans l’extension, ou désactivez ce réglage.
Après chaque changement, relancez la commande curl de l’étape 4. Arrêtez quand vous obtenez HTTP/2 400 pour Stripe.
7. Corrigez le secret de signature ou l’URL du site. Chaque point de terminaison de webhook Stripe a son propre secret de signature, qui commence par whsec_. Le mode test et le mode production ont des points de terminaison et des secrets distincts. Les clones de préproduction, les migrations et les restaurations laissent souvent le mauvais secret dans WooCommerce.
Vérifiez à quelle adresse WordPress croit se trouver.
wp option get home
wp option get siteurl
Les deux devraient afficher votre adresse de production, comme https://example.com. Si elles affichent un domaine de préproduction ou un ancien domaine, corrigez-le d’abord. Ouvrez ensuite le point de terminaison dans Stripe, affichez son secret de signature et collez-le dans le champ du secret de webhook de l’extension Stripe. Les versions récentes de l’extension peuvent créer le webhook pour vous quand vous reconnectez le compte. Pour PayPal Payments, utilisez le bouton de réinscription pour que PayPal enregistre le webhook du domaine actuel.
8. Vérifiez que les tâches de fond s’exécutent. WooCommerce confie le travail de suivi à WP-Cron, le planificateur de tâches intégré à WordPress. Il utilise aussi Action Scheduler, sa propre file de tâches de fond. Ce travail inclut l’annulation des commandes impayées et certaines tâches des passerelles.
wp cron test
Un site en bon état affiche Success: WP-Cron spawning is working as expected. Si le message dit que la constante DISABLE_WP_CRON est activée, c’est correct seulement si une tâche cron du serveur appelle WP-Cron à la place. Toute autre erreur veut dire que le travail planifié, y compris Action Scheduler, risque de ne jamais s’exécuter. Ouvrez ensuite WooCommerce, État, Actions planifiées et filtrez sur les actions en retard. Des centaines d’actions en retard veulent dire que la file est bloquée. Notre guide sur l’arriéré d’Action Scheduler montre comment la vider et lancer le cron depuis le serveur.
9. Rapprochez les commandes déjà bloquées. Ne marquez jamais une commande comme payée sans vérifier d’abord dans la passerelle. Pour chaque commande de l’étape 1, trouvez le paiement correspondant et confirmez qu’il est Succeeded ou Terminé, avec le même total.
Pour Stripe, la correction la plus sûre consiste à renvoyer l’événement. Dans la liste d’événements du point de terminaison, ouvrez la livraison payment_intent.succeeded en échec et cliquez sur Resend. L’extension met alors la commande à jour exactement comme prévu, avec l’identifiant de transaction. En mode production, Stripe réessaie les livraisons en échec pendant jusqu’à trois jours, donc les commandes récentes peuvent se régler seules une fois l’étape 5, 6 ou 7 terminée.
Si le renvoi est impossible, mettez la commande à jour à la main et laissez une note.
wp wc shop_order update 1234 --status=processing --user=1
wp wc order_note create 1234 --note="Payment verified in Stripe (pi_XXXX) on 2026-09-24. Webhook was blocked; status set manually." --user=1
Passer une commande à « En cours » envoie le courriel habituel de commande en cours. Si la commande était déjà annulée, le stock est aussi retiré de nouveau, puisque l’annulation l’avait remis en inventaire. Si l’article d’une commande annulée est épuisé depuis, communiquez avec le client avant de changer le statut.
Vérifier que ça fonctionne
Utilisez un vrai événement de test. Mettez d’abord le site en mode test Stripe, avec ses clés de test et son point de terminaison de test. Installez ensuite la CLI Stripe (l’outil en ligne de commande de Stripe) et connectez-vous.
stripe login
stripe trigger payment_intent.succeeded
Le déclencheur crée un paiement de test et affiche des lignes comme Trigger succeeded! Check dashboard for event details. Stripe livre ensuite l’événement à votre point de terminaison de test. Ouvrez ce point de terminaison dans le tableau de bord ; la livraison la plus récente devrait afficher 200. Le journal de l’extension de l’étape 2 devrait montrer le webhook entrant. Il peut ajouter qu’aucune commande correspondante n’a été trouvée, ce qui est normal pour un test déclenché.
Pour suivre les événements en direct pendant vos tests, lancez stripe listen dans une deuxième fenêtre de terminal. Enfin, passez une petite vraie commande en mode production et payez avec votre propre carte. La commande devrait passer à « En cours » en quelques secondes. Remboursez-la ensuite depuis l’écran de la commande.
Dépannage
Le test curl renvoie 400, mais Stripe affiche encore des échecs. Stripe appelle peut-être une autre URL que celle que vous avez testée. Comparez caractère par caractère l’URL du point de terminaison chez Stripe avec celle de la page de réglages de l’extension. Vérifiez aussi que vous regardez le mode production et non le mode test.
Les livraisons réussissent avec 200, mais les commandes restent en attente. Le webhook a atteint l’extension, mais elle n’a pas pu associer le paiement à une commande. C’est le cas après une restauration de sauvegarde, quand les numéros de commande connus de Stripe ne correspondent plus à la base de données. Cherchez dans le journal de l’extension le numéro de commande qu’elle cherchait.
Seules certaines livraisons échouent. Cloudflare et Imunify évaluent les requêtes selon l’adresse IP et le comportement, donc seuls certains serveurs de la passerelle sont parfois mis au défi. Cherchez des réponses 403 intermittentes dans la liste des livraisons, puis appliquez les corrections des étapes 5 et 6.
Des commandes sont annulées avant la fin des modes de paiement lents. Les prélèvements bancaires et certains modes de paiement locaux peuvent prendre des jours à se confirmer. La plupart des extensions de passerelle mettent ces commandes « En attente » plutôt que « En attente de paiement ». Si la vôtre ne le fait pas, augmentez la valeur de réservation du stock, ou laissez le champ vide pour désactiver l’annulation automatique. Notre guide sur les courriels WooCommerce qui n’arrivent jamais couvre un cas voisin où la commande est correcte mais où personne n’est averti.
Quand cette approche ne convient pas
Si Stripe ou PayPal affiche le paiement comme incomplet ou refusé, le statut de la commande est correct. Le client n’a pas terminé son paiement et la correction se trouve du côté de la caisse. Notre guide sur une passerelle de paiement qui n’apparaît pas à la caisse est un meilleur point de départ pour les problèmes de caisse.
Si vous ne pouvez pas modifier Cloudflare ni le pare-feu du serveur, envoyez à votre hébergeur la sortie curl de l’étape 4 et les codes d’état de l’étape 3. Ces deux éléments suffisent habituellement pour trouver la règle qui bloque.
La documentation officielle de Stripe sur les webhooks explique en détail les nouvelles tentatives et les signatures, et la documentation de WooCommerce couvre les réglages de chaque extension de passerelle.
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.