# Emails transactionnels WordPress : pourquoi wp_mail() échoue et comment le fiabiliser

> Un client se plaint que les e-mails de commande ou de réinitialisation de mot de passe n'arrivent jamais. Le coupable est presque toujours la fonction mail() du serveur, pas WordPress.

- Auteur : Clément Hadrot
- Publié le : 2021-10-13
- Mis à jour le : 2021-10-13
- Catégorie : Hébergement &amp; serveurs
- URL : https://wpmoderne.dev.wordpress-developpement.fr/hebergement/wp-mail-echoue-smtp-fiabiliser-emails-transactionnels/

## L’essentiel

- wp_mail() repose par défaut sur la fonction mail() de PHP, peu fiable
- Un serveur SMTP authentifié résout la majorité des cas de non-livraison
- phpmailer_init permet de brancher SMTP sans plugin

« Le client dit qu'il ne reçoit jamais les commandes par e-mail. » Cette phrase revient régulièrement en support, et la première réaction est souvent de chercher un bug dans le code du site, dans le thème ou dans l'extension d'e-commerce. Dans l'immense majorité des cas, le problème est ailleurs : la fonction `wp_mail()`, qui gère l'envoi de tous les e-mails générés par WordPress, s'appuie par défaut sur la fonction `mail()` native de PHP, connue pour sa fiabilité limitée.

Comprendre pourquoi cette fonction pose problème, et comment la remplacer par un envoi SMTP authentifié, résout la quasi-totalité des cas de non-réception — qu'il s'agisse d'un e-mail de réinitialisation de mot de passe, d'une confirmation de commande, ou d'une notification de formulaire de contact.

## Pourquoi mail() est un mauvais point de départ

La fonction `mail()` de PHP transmet le message directement à l'agent de transfert de courrier local du serveur (souvent Sendmail ou Postfix en configuration minimale), qui tente ensuite de le livrer directement au serveur de messagerie du destinataire. Ce trajet direct, sans authentification ni réputation d'expéditeur établie, est traité avec une grande méfiance par les grands fournisseurs de messagerie comme Gmail ou Outlook, qui filtrent agressivement ce type d'envoi vers le dossier spam, voire le rejettent silencieusement.

Le symptôme le plus trompeur est que `wp_mail()` retourne souvent `true`, laissant croire que l'e-mail est parti avec succès, alors que cette valeur signifie seulement que le message a été transmis à l'agent local — pas qu'il a été livré à son destinataire final.

## Basculer vers un envoi SMTP authentifié

La solution consiste à faire transiter les e-mails par un serveur SMTP authentifié, qu'il s'agisse d'un service dédié (comme un fournisseur d'e-mail transactionnel) ou d'une adresse professionnelle classique avec identifiants. Ce mécanisme s'appuie sur le hook `phpmailer_init`, qui permet de configurer directement l'objet PHPMailer utilisé en interne par WordPress :

```
add_action( 'phpmailer_init', function( $phpmailer ) {
    $phpmailer->isSMTP();
    $phpmailer->Host       = 'smtp.exemple.fr';
    $phpmailer->SMTPAuth   = true;
    $phpmailer->Port       = 587;
    $phpmailer->Username   = 'envoi@exemple.fr';
    $phpmailer->Password   = getenv( 'SMTP_PASSWORD' );
    $phpmailer->SMTPSecure = 'tls';
    $phpmailer->From       = 'envoi@exemple.fr';
    $phpmailer->FromName   = 'Exemple';
} );
```

> L'essentiel à retenir : wp_mail() repose par défaut sur la fonction mail() de PHP, peu fiable ; Un serveur SMTP authentifié résout la majorité des cas de non-livraison ; phpmailer_init permet de brancher SMTP sans plugin

Le mot de passe ne doit jamais être écrit en dur dans le thème : il doit provenir d'une variable d'environnement ou d'une constante définie dans `wp-config.php`, en dehors du dossier public du site. C'est un détail de sécurité trop souvent négligé sur ce type de configuration.

## Passer par un plugin plutôt qu'un code personnalisé

Pour un client qui doit pouvoir modifier ces réglages sans intervention d'un développeur, un plugin dédié à la configuration SMTP reste préférable à du code personnalisé dans le thème. L'interface graphique de ces extensions inclut généralement un test d'envoi qui confirme immédiatement si la configuration fonctionne, sans attendre qu'un vrai client se plaigne de ne rien recevoir.

### Points à vérifier avant de considérer le problème résolu

- Le nom de domaine d'expédition correspond-il au domaine réellement autorisé à envoyer (voir SPF) ?
- L'adresse d'expédition existe-t-elle réellement, plutôt qu'un `noreply@localhost` générique ?
- Le test d'envoi arrive-t-il en boîte de réception, ou toujours en spam malgré le SMTP ?

## Diagnostiquer sans deviner

Un plugin de journalisation des e-mails, ou un simple hook temporaire sur `wp_mail_failed`, permet de capturer les erreurs réelles plutôt que de supposer :

```
add_action( 'wp_mail_failed', function( $error ) {
    error_log( 'Échec envoi mail : ' . $error->get_error_message() );
} );
```

> Un e-mail « envoyé » selon WordPress et un e-mail réellement reçu par un destinataire sont deux affirmations très différentes. Ne jamais confondre les deux en support client.

## En résumé

La fiabilité des e-mails transactionnels ne se joue pas dans le code métier du site, mais dans la façon dont ils quittent le serveur. Remplacer la fonction `mail()` native par un envoi SMTP authentifié, avec une adresse d'expédition cohérente avec le domaine, résout la grande majorité des cas de non-réception constatés sur des sites WordPress en production.
