Fiche incident

Paiement bloqué sur PrestaShop - Causes & solutions

Rédigé par Soulaimane Aattar — 850+ interventions e-commerce documentées Mis à jour le 14 juin 2026 Versions concernées : PrestaShop 1.6.x, 1.7.x et 8.x (modules PS Checkout, Stripe, PayPal, SystemPay/Payzen, Mercanet, Mollie)

Quand le paiement bloque sur PrestaShop, le tunnel d'achat se ferme exactement là où le client allait payer : chaque minute d'indisponibilité est du chiffre d'affaires qui part chez un concurrent, et pire encore, certains clients sont débités sans que la commande apparaisse en back-office. C'est l'incident le plus coûteux d'une boutique en production.

Avant de toucher quoi que ce soit, il faut comprendre une chose : un paiement bloqué peut venir de trois niveaux totalement différents, et le réflexe de tout rembourser ou de couper la passerelle est presque toujours une erreur. Niveau 1 : la configuration de la boutique (le moyen de paiement n'est tout simplement pas proposé). Niveau 2 : la passerelle ou la banque (la transaction part mais elle est refusée). Niveau 3 : le serveur (erreur technique, webhook qui ne répond pas, mémoire PHP). 90 % des cas se résolvent dès qu'on a identifié le bon niveau.

Ce guide te fait remonter du symptôme exact (le message affiché au client) jusqu'à la cause et au correctif, avec les chemins back-office FR, les fichiers, les commandes shell et les requêtes SQL à lancer. Pas de généralités : du diagnostic concret pour une boutique en panne.

Contexte technique

Sur PrestaShop, les incidents de paiement se concentrent sur trois points : la passerelle (module PayPal, Stripe, Payzen, Mercanet, Systempay) souvent incompatible avec la version en production, les webhooks de confirmation qui échouent silencieusement côté serveur, et le One Page Checkout des thèmes custom qui interfère avec le flux de validation. Une erreur récurrente : la commande est créée en base avec statut « En attente » alors que le client a été débité, ce qui crée un décalage entre passerelle et commandes visibles en back-office.

paiement prestashop bugcheckout prestashop bloquemodule paiement prestashop erreur

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

Priorité absolue : ne jamais rembourser aveuglément. Vérifier d'abord l'état réel en base (table ps_orders + ps_order_payment) et les logs passerelle. Une double facturation masquée vaut toujours mieux qu'un remboursement non justifié.

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

Le premier travail n'est pas de réparer mais de classer. Le symptôme exact détermine le niveau du problème, donc l'arbre de diagnostic. Commence par regarder ce que voit le client à l'étape de paiement, puis confronte-le à l'état réel en base de données — car le débit côté banque et la commande côté PrestaShop ne sont pas toujours synchrones.

  • « Malheureusement, aucun moyen de paiement n'est disponible » à l'étape paiement → niveau config boutique (devise, pays, groupe client, transporteur). Le symptôme n°1 du SERP, toutes versions confondues.
  • Le module de paiement (PS Checkout, SystemPay, CB) n'apparaît plus au front alors qu'il est actif et configuré → hook non enregistré, cache, ou SSL.
  • Le client clique sur « Payer », est renvoyé vers la banque puis revient avec un refus → niveau passerelle/banque (3D Secure, fonds, devise, identifiants API).
  • Commande créée avec statut « En attente de paiement » alors que le client a été débité → webhook / notification URL non appelé. C'est le cas le plus dangereux financièrement.
  • Page blanche, timeout, erreur 500 ou boucle d'installation du module au checkout → niveau serveur (mémoire PHP, temps d'exécution, hooks, conflit d'état de commande).
  1. Reproduis le parcours en navigation privée avec un vrai produit dans le panier, jusqu'à l'écran de paiement, et note le message mot pour mot.
  2. Ouvre la console navigateur (F12 → onglet Network) et regarde si une requête part en erreur (500, 4xx) ou tourne en boucle quand le module devrait s'afficher.
  3. Croise immédiatement avec la base : une commande « débitée mais en attente » ne se traite pas du tout comme un « aucun moyen de paiement ».

Impact business immédiat

Contrairement à un bug d'affichage, un paiement bloqué touche directement la caisse et la relation client. L'enjeu n'est pas seulement la vente perdue de l'instant, mais l'effet de traîne : un client débité sans confirmation ouvre un litige, conteste auprès de sa banque (chargeback), et ne revient pas.

  • Perte directe de chiffre d'affaires sur chaque session qui atteint l'étape paiement — les visiteurs les plus qualifiés du tunnel.
  • Décalage comptable : des clients débités côté passerelle, des commandes en « En attente » côté PrestaShop, donc un risque de double facturation si on relance manuellement.
  • Litiges et chargebacks : un débit sans commande livrée se transforme en contestation bancaire, avec frais et dégradation du taux d'acceptation de la passerelle.
  • Gaspillage des budgets pub : les campagnes en cours continuent d'envoyer du trafic payant vers un tunnel qui ne convertit pas.
  • Érosion de la confiance : un acheteur bloqué au paiement teste rarement deux fois.

Causes classées par probabilité

Voici les causes ordonnées par fréquence réelle observée sur les fils de support et la doc éditeurs, regroupées par niveau. Traite-les dans cet ordre : la cause la plus probable est aussi la moins coûteuse à vérifier.

  • TRÈS FRÉQUENT — Restriction de config qui rend le module invisible : devise du panier non autorisée, pays du client désactivé, groupe client non coché, ou transporteur indisponible qui casse l'étape précédente (Modules > Paiement > Préférences).
  • FRÉQUENT — Module obsolète ou incompatible avec la version PrestaShop en production (cas classique : module bancaire qui plante après une mise à jour du cœur).
  • FRÉQUENT — Cache à vider et hooks à réinitialiser après une mise à jour : le hook displayPayment / paymentOptions n'est plus enregistré, donc le module n'apparaît pas.
  • FRÉQUENT — Webhook / notification URL non appelée : la transaction réussit côté banque mais PrestaShop ne reçoit jamais la confirmation, d'où la commande qui reste « En attente ».
  • COURANT — Refus côté banque/passerelle : carte expirée, fonds ou plafond insuffisants, échec 3D Secure (SCA), devise non supportée, identifiants API erronés.
  • COURANT — Erreur serveur : memory_limit PHP trop bas, max_execution_time dépassé, certificat SSL expiré qui bloque l'exécution du paiement.
  • PONCTUEL — Conflit JS d'un thème custom ou d'un One Page Checkout qui casse la soumission, ou contrainte SQL (Duplicate entry 1062) sur une nouvelle boutique PS 8.x.

Diagnostic : les commandes à lancer

Avant toute manipulation, regarde l'état réel — en base et dans les logs. La règle d'or de l'expert : ne jamais rembourser ni recréer une commande à l'aveugle. On confirme d'abord ce que la passerelle a réellement fait.

Active le mode debug pour voir l'erreur PHP réelle au lieu d'une page blanche. Édite le fichier de config (chemin différent selon la version, voir plus bas).

Activer le mode debug (PrestaShop 1.7 / 8.x)
// config/defines.inc.php
define('_PS_MODE_DEV_', true);   // passe à true le temps du diagnostic
// PrestaShop 1.6 : même fichier, ligne identique
Lire les logs PrestaShop en temps réel
# Log applicatif PS 1.7+/8.x
tail -f var/logs/prod.log

# Filtrer ce qui touche le paiement / la passerelle
grep -iE 'payment|stripe|paypal|systempay|payzen|mollie|webhook|notification' var/logs/prod.log | tail -n 50

# Si rien dans PS, le problème est plus bas : logs serveur
tail -n 100 /var/log/apache2/error.log    # Apache
tail -n 100 /var/log/nginx/error.log      # Nginx
Vérifier l'état réel des transactions en base
-- Commandes débitées mais restées "En attente" (le cas dangereux)
SELECT o.id_order, o.reference, o.total_paid, o.payment, os.name AS statut, o.date_add
FROM ps_orders o
JOIN ps_order_state_lang os ON os.id_order_state = o.current_state AND os.id_lang = 1
WHERE o.date_add >= NOW() - INTERVAL 1 DAY
ORDER BY o.date_add DESC;

-- Confronter avec les paiements réellement enregistrés par la passerelle
SELECT id_order, payment_method, amount, transaction_id, date_add
FROM ps_order_payment
WHERE date_add >= NOW() - INTERVAL 1 DAY
ORDER BY date_add DESC;
Vérifier le hook du module de paiement
-- Le module est-il bien branché sur le hook qui l'affiche au front ?
SELECT m.name, h.name AS hook
FROM ps_module m
JOIN ps_hook_module hm ON hm.id_module = m.id_module
JOIN ps_hook h ON h.id_hook = hm.id_hook
WHERE m.name LIKE '%payment%' OR m.name IN ('ps_checkout','stripe_official','paypal','systempaylegacy');
-- Si paymentOptions / displayPayment n'apparaît pas, le module ne s'affichera pas.

Solutions pas-à-pas

Applique le correctif correspondant au niveau identifié. Chaque famille a sa procédure ; ne mélange pas les deux.

  1. AUCUN MOYEN DE PAIEMENT — Va dans Modules > Paiement > Préférences. Vérifie que le module est autorisé pour la DEVISE du panier, le PAYS du client (qui doit aussi être activé dans Localisation > Pays) et son GROUPE (Visiteur vs Client). Décoche/recoche pour forcer l'enregistrement.
  2. AUCUN MOYEN DE PAIEMENT (suite) — Vérifie qu'un transporteur valide est disponible pour ce panier : une plage de poids/prix manquante côté transporteur casse l'étape avant le paiement et renvoie le même message. Teste avec un transporteur sans restriction.
  3. MODULE DISPARU — Modules > Module Manager > [ton module] > flèche déroulante > Réinitialiser. Le reset recrée les hooks displayPayment / paymentOptions manquants.
  4. MODULE DISPARU (suite) — Vide le cache : Paramètres avancés > Performances > Vider le cache (Smarty + cache PS). Étape quasi obligatoire après toute mise à jour. Vérifie aussi que ton certificat SSL n'est pas expiré : un HTTPS invalide bloque l'affichage et l'exécution du paiement.
  5. CARTE REFUSÉE — Contrôle dans la config du module les identifiants API (ID contrat/boutique, clé API, mot de passe de production vs test). Une clé de test en prod fait échouer chaque paiement. Vérifie que la devise du panier est bien supportée par le contrat marchand.
  6. WEBHOOK / COMMANDE EN ATTENTE — Récupère l'URL de notification dans la config du module et déclare-la à l'identique côté back-office de la passerelle (SystemPay/Payzen, Stripe, PayPal IPN). Teste qu'elle répond en HTTP 200 sans redirection ni maintenance, et qu'aucun pare-feu/htaccess ne bloque l'appel serveur-à-serveur.
  7. ERREUR 500 / PAGE BLANCHE — Avec le debug activé, lis l'erreur. Allowed memory size exhausted → passe memory_limit = 256M dans php.ini. Maximum execution time exceeded → max_execution_time = 300. Puis redémarre PHP-FPM.
  8. CONTRAINTE SQL (PS 8.x) — Le message SQLSTATE[23000] ... 1062 Duplicate entry sur une boutique neuve se règle en redémarrant le module et en se reconnectant à la passerelle. Pour Unable to install ... statuses, supprime l'état de commande en conflit puis réinstalle le module.
  9. REMETS LE DEBUG À FALSE une fois le diagnostic terminé (_PS_MODE_DEV_ = false) — ne jamais laisser le debug actif en production.

3D Secure, SCA et webhooks : la cause sous-estimée 2024-2026

Depuis la généralisation de l'authentification forte (SCA / 3D Secure 2), une part croissante des paiements bloqués vient non pas de la carte mais du parcours d'authentification et du retour de notification. Symptôme typique : le client valide bien sur la page de sa banque, mais revient sur une page d'échec, ou la commande reste « En attente » alors que le débit a eu lieu.

La quasi-totalité de ces cas se joue sur la notification URL (webhook) : la passerelle confirme le paiement à PrestaShop par un appel serveur-à-serveur indépendant du navigateur du client. Si cet appel n'aboutit pas, PrestaShop ne valide jamais la commande, même si le client a payé.

  • Vérifie que la notification URL déclarée dans le back-office de la passerelle est identique à celle attendue par le module (HTTPS, sans slash en trop, sans redirection www/non-www).
  • Assure-toi que l'URL répond hors session : un pare-feu applicatif, une protection anti-bot ou une page de maintenance qui bloque les requêtes non-navigateur empêche la notification d'arriver.
  • Pour un cas « PayPal/PS Checkout marche mais Mastercard échoue », teste explicitement une carte 3DS de test : l'échec est souvent côté authentification, pas côté module.
  • Conserve la trace : grep 'notification' ou 'webhook' dans var/logs/prod.log confirme si l'appel a été reçu et traité, ou jamais reçu (donc problème réseau/URL).

Spécificités par version

Les chemins back-office, les fichiers et même le message « aucun moyen de paiement » diffèrent selon la version majeure. Identifie ta version avant de suivre une procédure trouvée en ligne — la moitié des fils de forum mélangent 1.6 et 1.7+.

  • PrestaShop 1.6 — Onglet « Modules et services » ; restrictions de paiement dans Modules > Paiement. Pas de var/logs/prod.log : les logs applicatifs sont dans Paramètres avancés > Logs et dans log/ ; debug via define('_PS_MODE_DEV_', true) dans config/defines.inc.php.
  • PrestaShop 1.7.x — Module Manager moderne, restrictions dans Modules > Paiement > Préférences, logs dans var/logs/prod.log et var/logs/dev.log. Attention au bug versionné 1.7.6.0 : des modules bancaires tombaient en erreur (e-transaction : « Protection error. We regret not being able to give a favorable answer... » ; SystemPay : « 500 error calling the notification url »). Le retour en 1.7.5.2 rétablissait le fonctionnement (issue GitHub #14648). C'est l'exemple type du couple version PS ↔ version module à vérifier.
  • PrestaShop 8.x — Mêmes chemins que 1.7 mais socle Symfony plus strict : c'est sur les boutiques 8.x neuves qu'apparaît le SQLSTATE[23000] 1062 Duplicate entry à l'activation d'un module de paiement (fix : redémarrer le module + reconnexion passerelle). Compatibilité PHP 8.1+ obligatoire — un module compilé pour PHP 7 peut planter en page blanche.

Vérifier que c'est réparé

Un correctif n'est validé que par un achat de bout en bout, pas par l'affichage du module. Déroule ce protocole avant de rouvrir la vanne du trafic.

  1. Passe la passerelle en mode test/sandbox et commande un vrai produit jusqu'à la confirmation, avec une carte de test 3DS fournie par l'éditeur.
  2. Vérifie que la commande passe bien de « En attente » à « Paiement accepté » automatiquement (preuve que le webhook fonctionne).
  3. Confronte ps_orders et ps_order_payment : le montant, le transaction_id et le statut doivent concorder.
  4. Contrôle var/logs/prod.log : aucune nouvelle erreur de paiement pendant le test.
  5. Repasse en production, fais une dernière commande réelle de petit montant, puis rembourse-la proprement depuis la passerelle pour clôturer.

FAQ

Pourquoi PrestaShop affiche « aucun moyen de paiement n'est disponible » ?

Dans la quasi-totalité des cas, le module est actif mais filtré par une restriction. Va dans Modules > Paiement > Préférences et vérifie que le moyen de paiement est autorisé pour la devise du panier, le pays du client (qui doit aussi être activé dans Localisation > Pays) et son groupe (Visiteur/Client). Vérifie aussi qu'un transporteur valide existe pour ce panier : une étape transporteur cassée renvoie le même message.

Où trouver les logs de paiement sur PrestaShop ?

Deux endroits. Côté back-office : Paramètres avancés > Logs. Côté fichier (PS 1.7+/8.x) : var/logs/prod.log, à lire avec tail -f var/logs/prod.log et à filtrer par grep -i 'payment\|webhook'. Si rien n'apparaît côté PrestaShop, le problème est plus bas : consulte les logs Apache (/var/log/apache2/error.log) ou Nginx.

Comment réinitialiser un module de paiement sans perdre sa config ?

Modules > Module Manager > ton module > menu déroulant > Réinitialiser. Le reset recrée les hooks d'affichage (displayPayment / paymentOptions) sans désinstaller le module, donc sans effacer tes identifiants API. C'est différent de Désinstaller, qui efface la configuration. Enchaîne avec un Vider le cache dans Paramètres avancés > Performances.

Le client a été débité mais la commande reste « En attente », que faire ?

Ne rembourse pas et ne recrée pas la commande à l'aveugle. Le paiement a réussi côté banque mais la notification URL (webhook) n'a pas atteint PrestaShop. Vérifie dans ps_order_payment que la transaction existe, puis corrige l'URL de notification côté passerelle et relance manuellement la confirmation. C'est un problème de webhook, pas de débit.

Pourquoi le paiement par carte échoue alors que PayPal fonctionne ?

Quand PayPal passe mais que la carte (Mastercard/Visa) échoue, la cause est presque toujours l'authentification 3D Secure / SCA ou des identifiants API carte erronés (clé de test en prod, contrat marchand mal configuré), pas le module lui-même. Teste avec une carte 3DS de test en sandbox et vérifie que la devise du panier est bien couverte par ton contrat bancaire.

Comment activer le mode debug pour voir l'erreur réelle au checkout ?

Édite config/defines.inc.php et passe define('_PS_MODE_DEV_', true);. Une page blanche ou une erreur 500 affichera alors le message PHP exact (mémoire épuisée, temps d'exécution dépassé, hook manquant). Important : repasse la valeur à false une fois le diagnostic terminé, ne jamais laisser le debug actif en production.

Appeler WhatsApp