Ajouter des boutons de choix transporteur pour le retour produit PrestaShop
Personnalisez le formulaire de retour produit PrestaShop avec des boutons de choix transporteur (Colissimo, Mondial Relay) et notification email automatique.
En bref : Pour ajouter un choix de transporteur (Colissimo / Mondial Relay) au formulaire de retour produit PrestaShop, modifiez le template front-office avec des boutons radio, traitez le choix dans un override de OrderReturnController via postProcess(), puis envoyez une notification email personnalisée avec Mail::Send(). L'approche module via le hook actionOrderReturn est recommandée pour la maintenabilité.
Introduction
Le processus de retour produit natif de PrestaShop est fonctionnel mais minimaliste. Par défaut, le client remplit un formulaire de demande de retour sans pouvoir choisir le mode d'expédition pour renvoyer son article. Dans le cadre d'une boutique proposant plusieurs transporteurs retour — typiquement Colissimo et Mondial Relay — il est pertinent de laisser le client sélectionner son option préférée dès la demande de retour, puis d'envoyer un email récapitulatif au marchand.
Cet article détaille comment modifier le formulaire de retour marchandise pour y intégrer des boutons de sélection transporteur, traiter le choix côté back-end via postProcess(), et déclencher une notification email personnalisée avec Mail::Send().
Comprendre le mécanisme de retour natif
Le retour produit dans PrestaShop est géré par le controller OrderReturnController (front-office). Lorsqu'un client soumet sa demande, la méthode postProcess() intercepte le formulaire via Tools::isSubmit() et crée une entrée dans la table ps_order_return.
Le flux standard est le suivant :
- Le client accède à l'historique de commande
- Il sélectionne les produits à retourner
- Il soumet le formulaire `submitReturnMerchandise`
- PrestaShop enregistre le retour et envoie un email basique
- **`Tools::getValue()`** récupère une valeur POST/GET de manière sécurisée (avec échappement). C'est la méthode standard PrestaShop — ne jamais utiliser `$_POST` directement.
- **Validation stricte** : Toujours vérifier que la valeur reçue fait partie des choix autorisés. Un champ radio peut être manipulé côté client.
- **`parent::postProcess()`** : Essentiel pour ne pas casser le flux natif de création du retour produit.
- **Ne jamais coder en dur les adresses email.** Utilisez `Configuration::get('PS_SHOP_EMAIL')` pour récupérer l'email configuré dans le back-office.
- **Toujours passer l'ID de la langue** (`$this->context->language->id`) pour que le bon template linguistique soit sélectionné.
- **En multiboutique**, le paramètre `$idShop` est crucial pour que l'email utilise le bon en-tête et les bonnes coordonnées.
- **Aucun override** : pas de conflit avec d'autres modules
- **Mise à jour facilitée** : le hook survit aux mises à jour de PrestaShop
- **Activation/désactivation** depuis le back-office sans toucher au code
Notre objectif : injecter une étape de choix transporteur entre les points 2 et 3, puis enrichir l'email de notification.
Étape 1 : Modifier le template front-office
Dans le thème actif, localisez le template de retour. En PrestaShop 8.x, il s'agit du fichier :
themes/votre-theme/templates/customer/order-return.tpl
En PrestaShop 1.7.x :
themes/votre-theme/templates/customer/order-follow.tpl
Ajoutez les boutons radio de sélection transporteur dans le formulaire, avant le bouton de soumission :
<div class="form-group return-shipping-choice">
<label class="form-control-label">{l s='Choisissez votre mode de retour' d='Shop.Theme.CustomerAccount'}</label>
<div class="custom-control custom-radio">
<input type="radio"
id="return-colissimo"
name="return_carrier"
value="colissimo"
class="custom-control-input"
required>
<label class="custom-control-label" for="return-colissimo">
<img src="{$urls.img_url}carriers/colissimo-icon.png" alt="Colissimo" width="24" height="24">
Colissimo - Retour en bureau de poste
</label>
</div>
<div class="custom-control custom-radio">
<input type="radio"
id="return-mondial-relay"
name="return_carrier"
value="mondial_relay"
class="custom-control-input">
<label class="custom-control-label" for="return-mondial-relay">
<img src="{$urls.img_url}carriers/mondial-relay-icon.png" alt="Mondial Relay" width="24" height="24">
Mondial Relay - Retour en point relais
</label>
</div>
</div>
Bonne pratique PrestaShop 8.x : Utilisez le domaine de traduction
Shop.Theme.CustomerAccountpour que vos chaînes soient traduisibles depuis le back-office.
Étape 2 : Traiter le choix dans postProcess()
La logique métier se place dans un override du controller OrderReturnController. Créez ou éditez le fichier :
override/controllers/front/OrderReturnController.php
<?php
/**
* @author Alexandre Carette <contact@alexandrecarette.fr>
* @copyright 2026 Alexandre Carette
* @license Propriétaire et Confidentiel
*/
class OrderReturnController extends OrderReturnControllerCore
{
public function postProcess()
{
if (Tools::isSubmit('submitReturnMerchandise')) {
// Récupérer le choix transporteur
$returnCarrier = Tools::getValue('return_carrier');
// Valider la valeur reçue
$allowedCarriers = ['colissimo', 'mondial_relay'];
if (!in_array($returnCarrier, $allowedCarriers, true)) {
$this->errors[] = $this->trans(
'Veuillez sélectionner un mode de retour.',
[],
'Shop.Notifications.Error'
);
return;
}
// Préparer le libellé lisible pour l'email
$carrierLabels = [
'colissimo' => 'Colissimo (Bureau de poste)',
'mondial_relay' => 'Mondial Relay (Point relais)',
];
$carrierLabel = $carrierLabels[$returnCarrier];
// Variables pour le template email
$templateVars = [
'{carrier_choice}' => $carrierLabel,
'{firstname}' => $this->context->customer->firstname,
'{lastname}' => $this->context->customer->lastname,
'{email}' => $this->context->customer->email,
'{order_reference}' => Tools::getValue('id_order'),
];
// Envoyer l'email de notification au marchand
Mail::Send(
(int) $this->context->language->id,
'return_carrier_notification',
$this->trans('Nouveau retour produit - %carrier%', ['%carrier%' => $carrierLabel], 'Emails.Subject'),
$templateVars,
Configuration::get('PS_SHOP_EMAIL'),
Configuration::get('PS_SHOP_NAME'),
null,
null,
null,
null,
_PS_MAIL_DIR_,
false,
(int) $this->context->shop->id
);
}
// Appeler le traitement parent pour créer le retour
parent::postProcess();
}
}
Points techniques importants
Étape 3 : Créer le template email
PrestaShop utilise des templates HTML et TXT pour les emails. Créez deux fichiers dans le dossier mails/fr/ de votre thème :
Template HTML : `return_carrier_notification.html`
<!DOCTYPE html>
<html>
<body>
<table width="100%">
<tr>
<td>
<h2>Nouvelle demande de retour produit</h2>
<p><strong>Client :</strong> {firstname} {lastname} ({email})</p>
<p><strong>Commande :</strong> #{order_reference}</p>
<p><strong>Mode de retour choisi :</strong> {carrier_choice}</p>
</td>
</tr>
</table>
</body>
</html>
Template TXT : `return_carrier_notification.txt`
Nouvelle demande de retour produit
Client : {firstname} {lastname} ({email})
Commande : #{order_reference}
Mode de retour choisi : {carrier_choice}
Attention : Les deux fichiers (HTML et TXT) sont obligatoires. Si le fichier TXT est absent,
Mail::Send()lèvera une exception silencieuse et l'email ne partira pas.
Étape 4 : Vider le cache des overrides
Après avoir créé l'override du controller, vous devez régénérer l'index des classes :
# Supprimer le cache des classes
rm -f var/cache/prod/class_index.php
rm -f var/cache/dev/class_index.php
Ou depuis le back-office : Paramètres avancés → Performances → Vider le cache.
En PrestaShop 8.x, le système de cache Symfony peut également nécessiter un vidage :
php bin/console cache:clear --env=prod
Comprendre Mail::Send() en profondeur
La méthode Mail::Send() est le point central d'envoi d'emails dans PrestaShop. Voici la signature complète avec les paramètres les plus utilisés :
Mail::Send(
int $idLang, // ID de la langue
string $template, // Nom du template (sans extension)
string $subject, // Objet de l'email
array $templateVars, // Variables {clé} => valeur
string $to, // Email destinataire
string $toName, // Nom destinataire
string $from = null, // Email expéditeur (défaut: config boutique)
string $fromName = null,// Nom expéditeur
array $fileAttachment = null,
null $mode_smtp = null,
string $templatePath = _PS_MAIL_DIR_,
bool $die = false, // Arrêter l'exécution en cas d'erreur
int $idShop = null, // ID boutique (multiboutique)
string $bcc = null, // Copie cachée
string $replyTo = null // Adresse de réponse
);
Bonnes pratiques pour Mail::Send()
Alternative recommandée : utiliser un module
Pour une solution plus maintenable et compatible avec les mises à jour PrestaShop, l'approche module est préférable aux overrides. Un module peut s'accrocher au hook actionOrderReturn (disponible depuis PrestaShop 1.7.7) pour intercepter la création du retour sans modifier le controller :
public function hookActionOrderReturn(array $params)
{
$orderReturn = $params['orderReturn'];
$carrier = Tools::getValue('return_carrier');
// Logique d'envoi email ici
}
Cette approche offre plusieurs avantages :
Résumé des fichiers modifiés
Questions fréquentes
Tout ce que vous devez savoir sur ce sujet.
Un projet PrestaShop ?
Discutons-en directement.
193 projets livrés
Lire sur le blog

Alexandre Carette
Expert PrestaShop & Architecture E-commerce
Développeur PrestaShop depuis 2014, 193 projets livrés. Je conçois des architectures headless Nuxt + PrestaShop et des outils d'automatisation IA pour les e-commerçants.