💻 DéveloppementIntermédiaire PS 1.7 PS 8.x

Personnaliser le formulaire de création de compte PrestaShop

Guide complet pour personnaliser le formulaire d'inscription client PrestaShop : ajout de champs, hooks, validation et module custom. Compatible 1.7 et 8.x.

En bref : Pour personnaliser le formulaire d'inscription PrestaShop, créez un module exploitant le hook `additionalCustomerFormFields` qui injecte des champs via l'API FormField, avec validation serveur et stockage dans une table dédiée — sans jamais modifier le core.

Publié le 21 mars 2026 7 min de lecture Alexandre Carette

Pourquoi personnaliser le formulaire d'inscription PrestaShop

Le formulaire de création de compte par défaut de PrestaShop collecte les informations essentielles : nom, prénom, email et mot de passe. Mais dans de nombreux contextes B2B ou métiers spécifiques, ce formulaire est insuffisant. On peut avoir besoin d'un numéro SIRET, d'un code client, d'un champ société obligatoire, ou de toute autre donnée métier dès l'inscription.

Plutôt que de modifier les fichiers core — ce qui compromettrait toute mise à jour future — la bonne approche consiste à développer un module qui exploite le système de hooks natifs de PrestaShop.

Architecture du formulaire d'inscription

Avant de coder, il faut comprendre comment PrestaShop gère ce formulaire.

Le flow côté contrôleur

Le formulaire de création de compte est géré par le contrôleur AuthController (fichier controllers/front/AuthController.php). Ce contrôleur utilise le composant CustomerForm situé dans src/Core/Form/ (PrestaShop 1.7+) qui implémente le pattern FormField.

Le rendu du formulaire passe par le template Smarty :


themes/votre-theme/templates/customer/_partials/customer-form.tpl

Les hooks disponibles

PrestaShop expose plusieurs hooks pour intervenir sur le formulaire client :

HookRôleContexte `additionalCustomerFormFields`Ajouter des champs au formulaireFront-office `actionSubmitAccountBefore`Intercepter avant la soumissionValidation `actionCustomerAccountAdd`Réagir après la création du comptePost-traitement `actionObjectCustomerAddAfter`Après l'insertion en basePersistance `validateCustomerFormFields`Valider les champs additionnelsValidation custom

Créer un module de personnalisation du formulaire

Structure du module

Voici la structure minimale d'un module qui ajoute des champs au formulaire d'inscription :


mon_module_customer_form/
├── mon_module_customer_form.php
├── sql/
│   ├── install.sql
│   └── uninstall.sql
├── views/
│   └── templates/
│       └── hook/
└── logo.png

Le fichier principal du module


<?php

if (!defined('_PS_VERSION_')) {
    exit;
}

class Mon_Module_Customer_Form extends Module
{
    public function __construct()
    {
        $this->name = 'mon_module_customer_form';
        $this->tab = 'front_office_features';
        $this->version = '1.0.0';
        $this->author = 'Alexandre Carette';
        $this->need_instance = 0;
        $this->ps_versions_compliancy = [
            'min' => '1.7.0.0',
            'max' => '8.99.99',
        ];

        parent::__construct();

        $this->displayName = $this->l('Personnalisation formulaire client');
        $this->description = $this->l('Ajoute des champs personnalisés au formulaire de création de compte.');
    }

    public function install()
    {
        return parent::install()
            && $this->registerHook('additionalCustomerFormFields')
            && $this->registerHook('validateCustomerFormFields')
            && $this->registerHook('actionObjectCustomerAddAfter')
            && $this->registerHook('actionObjectCustomerUpdateAfter')
            && $this->installDb();
    }

    private function installDb()
    {
        $sql = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'customer_custom_fields` (
            `id_customer` INT(10) UNSIGNED NOT NULL,
            `company_siret` VARCHAR(14) DEFAULT NULL,
            `customer_code` VARCHAR(50) DEFAULT NULL,
            `activity_sector` VARCHAR(100) DEFAULT NULL,
            PRIMARY KEY (`id_customer`)
        ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8mb4;';

        return Db::getInstance()->execute($sql);
    }

    public function uninstall()
    {
        return parent::uninstall()
            && Db::getInstance()->execute(
                'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'customer_custom_fields`'
            );
    }
}

Ajouter des champs avec le hook `additionalCustomerFormFields`

C'est le hook central. Il permet d'injecter des objets FormField directement dans le formulaire natif, sans modifier le template :


public function hookAdditionalCustomerFormFields($params)
{
    $extraFields = [];

    // Champ SIRET (optionnel)
    $fieldSiret = (new FormField())
        ->setName('company_siret')
        ->setType('text')
        ->setLabel($this->l('Numéro SIRET'))
        ->setRequired(false)
        ->addConstraint('isGenericName');

    $extraFields['company_siret'] = $fieldSiret;

    // Champ code client (optionnel)
    $fieldCode = (new FormField())
        ->setName('customer_code')
        ->setType('text')
        ->setLabel($this->l('Code client (si existant)'))
        ->setRequired(false);

    $extraFields['customer_code'] = $fieldCode;

    // Liste déroulante secteur d'activité
    $fieldSector = (new FormField())
        ->setName('activity_sector')
        ->setType('select')
        ->setLabel($this->l('Secteur d\'activité'))
        ->setRequired(true)
        ->addAvailableValue('', $this->l('-- Choisir --'))
        ->addAvailableValue('retail', $this->l('Commerce de détail'))
        ->addAvailableValue('wholesale', $this->l('Commerce de gros'))
        ->addAvailableValue('services', $this->l('Services'))
        ->addAvailableValue('industry', $this->l('Industrie'))
        ->addAvailableValue('other', $this->l('Autre'));

    $extraFields['activity_sector'] = $fieldSector;

    // Pré-remplir si le client existe déjà (édition de profil)
    if ($this->context->customer && $this->context->customer->id) {
        $data = $this->getCustomerData($this->context->customer->id);
        if ($data) {
            $fieldSiret->setValue($data['company_siret'] ?? '');
            $fieldCode->setValue($data['customer_code'] ?? '');
            $fieldSector->setValue($data['activity_sector'] ?? '');
        }
    }

    return $extraFields;
}

Valider les champs personnalisés

Le hook validateCustomerFormFields permet d'ajouter une logique de validation métier :


public function hookValidateCustomerFormFields($params)
{
    $errors = [];
    $formFields = $params['fields'];

    // Validation du SIRET (14 chiffres si renseigné)
    if (isset($formFields['company_siret'])) {
        $siret = $formFields['company_siret']->getValue();
        if (!empty($siret) && !preg_match('/^\d{14}$/', $siret)) {
            $formFields['company_siret']->addError(
                $this->l('Le numéro SIRET doit contenir exactement 14 chiffres.')
            );
        }
    }

    // Vérifier que le secteur d'activité est bien sélectionné
    if (isset($formFields['activity_sector'])) {
        $sector = $formFields['activity_sector']->getValue();
        if (empty($sector)) {
            $formFields['activity_sector']->addError(
                $this->l('Veuillez sélectionner votre secteur d\'activité.')
            );
        }
    }

    return $formFields;
}

Sauvegarder les données en base


public function hookActionObjectCustomerAddAfter($params)
{
    $this->saveCustomerData($params['object']->id);
}

public function hookActionObjectCustomerUpdateAfter($params)
{
    $this->saveCustomerData($params['object']->id);
}

private function saveCustomerData($idCustomer)
{
    $siret = Tools::getValue('company_siret', '');
    $code = Tools::getValue('customer_code', '');
    $sector = Tools::getValue('activity_sector', '');

    // Upsert : INSERT ... ON DUPLICATE KEY UPDATE
    $sql = 'INSERT INTO `' . _DB_PREFIX_ . 'customer_custom_fields`
            (`id_customer`, `company_siret`, `customer_code`, `activity_sector`)
            VALUES ('
            . (int) $idCustomer . ', '
            . '\'' . pSQL($siret) . '\', '
            . '\'' . pSQL($code) . '\', '
            . '\'' . pSQL($sector) . '\')'
            . ' ON DUPLICATE KEY UPDATE '
            . '`company_siret` = \'' . pSQL($siret) . '\', '
            . '`customer_code` = \'' . pSQL($code) . '\', '
            . '`activity_sector` = \'' . pSQL($sector) . '\'';

    return Db::getInstance()->execute($sql);
}

private function getCustomerData($idCustomer)
{
    return Db::getInstance()->getRow(
        'SELECT * FROM `' . _DB_PREFIX_ . 'customer_custom_fields`
         WHERE `id_customer` = ' . (int) $idCustomer
    );
}

Afficher les champs custom dans le back-office

Pour que les données soient visibles dans la fiche client du back-office, exploitez le hook displayAdminCustomers :


public function hookDisplayAdminCustomers($params)
{
    $idCustomer = $params['id_customer'];
    $data = $this->getCustomerData($idCustomer);

    if (!$data) {
        return '';
    }

    $this->context->smarty->assign([
        'siret' => $data['company_siret'],
        'customer_code' => $data['customer_code'],
        'activity_sector' => $data['activity_sector'],
    ]);

    return $this->display(__FILE__, 'views/templates/hook/admin-customer.tpl');
}

Spécificités PrestaShop 8.x

Sur PrestaShop 8.x, le système de formulaires a évolué avec l'adoption plus large de Symfony. Quelques points de vigilance :

  • **Les hooks fonctionnent toujours** : `additionalCustomerFormFields` reste la méthode recommandée pour le front-office. La rétrocompatibilité est maintenue.
  • **Back-office Symfony** : pour personnaliser le formulaire client côté admin dans PS 8.x, privilégiez les **form extensions** Symfony plutôt que les hooks legacy.
  • **Validation** : PrestaShop 8.x utilise les contraintes Symfony Validator en plus des validations legacy. Votre module peut supporter les deux.

// Exemple d'extension de formulaire pour le back-office PS 8.x
use Symfony\Component\Form\AbstractTypeExtension;
use PrestaShopBundle\Form\Admin\Type\CustomerType;

class CustomerTypeExtension extends AbstractTypeExtension
{
    public static function getExtendedTypes(): iterable
    {
        yield CustomerType::class;
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->add('company_siret', TextType::class, [
            'label' => 'SIRET',
            'required' => false,
            'constraints' => [
                new Regex([
                    'pattern' => '/^\d{14}$/',
                    'message' => 'Le SIRET doit contenir 14 chiffres.',
                ]),
            ],
        ]);
    }
}

Bonnes pratiques

Ce qu'il faut faire

  • **Utiliser les hooks natifs** plutôt que des overrides de contrôleur ou de template.
  • **Stocker dans une table dédiée** plutôt que d'altérer `ps_customer` directement. Cela préserve la compatibilité avec les mises à jour.
  • **Valider côté serveur** systématiquement, même si vous ajoutez une validation JavaScript en front.
  • **Utiliser `pSQL()`** pour échapper toutes les entrées utilisateur dans vos requêtes.
  • **Penser à l'édition de profil** : le hook `additionalCustomerFormFields` est aussi appelé sur la page Mon Compte.

Ce qu'il ne faut pas faire

  • **Ne jamais modifier `AuthController.php`** directement.
  • **Ne pas surcharger `customer-form.tpl`** si le hook suffit — les surcharges de template compliquent les mises à jour de thème.
  • **Ne pas stocker de données sensibles** (pièce d'identité, coordonnées bancaires) sans chiffrement côté base.
  • **Ne pas oublier le RGPD** : tout champ supplémentaire collectant des données personnelles doit être déclaré dans votre politique de confidentialité et supprimable sur demande.

Aller plus loin : rendre les champs configurables

Pour un module réutilisable, ajoutez une page de configuration dans le back-office permettant de choisir quels champs afficher, lesquels sont obligatoires, et leur ordre d'apparition. Stockez cette configuration avec Configuration::updateValue() et chargez-la dans votre hook additionalCustomerFormFields.

Cette approche transforme un module sur-mesure en un outil générique que vous pouvez déployer sur plusieurs boutiques sans toucher au code.

#formulaire inscription #module prestashop #hook customer #personnalisation compte #FormField

Questions fréquentes

Tout ce que vous devez savoir sur ce sujet.

Un projet PrestaShop ?

Discutons-en directement.

★★★★★

193 projets livrés

Gratuit & sans engagement — réponse sous 24h

Alexandre Carette

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.