🛒 CommandesAvancé PS 1.7 PS 8.x

Personnaliser les produits sur la facture PrestaShop : numéro de série et champs custom

Ajoutez des numéros de série, codes ou informations personnalisées aux produits sur vos factures PrestaShop. Guide technique complet avec override PDF.

En bref : Pour afficher des numéros de série ou codes personnalisés sur les factures PrestaShop, étendez ps_order_detail avec un champ custom, créez un module avec interface d'administration pour la saisie, puis overridez le template PDF et la classe HTMLTemplateInvoice pour injecter ces données dans le rendu.

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

Personnaliser les produits sur la facture PrestaShop : numéro de série et champs custom

Dans le cadre de certaines activités (électronique, logiciels, équipements industriels), il est indispensable d'afficher des informations spécifiques à chaque produit directement sur la facture : numéro de série, code de licence, lot de fabrication, etc. PrestaShop ne propose pas cette fonctionnalité nativement, mais l'architecture du système de facturation permet de l'implémenter proprement.

Comprendre l'architecture de facturation PrestaShop

La génération des factures PDF dans PrestaShop repose sur la classe HTMLTemplateInvoice, située dans classes/pdf/HTMLTemplateInvoice.php. Cette classe utilise des templates Smarty stockés dans pdf/ pour construire le rendu HTML qui sera ensuite converti en PDF.

Le fichier clé pour la liste des produits est :

  • **PrestaShop 1.7** : `pdf/invoice.product-tab.tpl`
  • **PrestaShop 8.x** : même emplacement, avec quelques ajustements de variables Smarty

La méthode getContent() de HTMLTemplateInvoice prépare les données produits via $order->getProducts(), puis les injecte dans le template Smarty.

Étape 1 : Choisir la bonne approche pour stocker l'information

Avant de modifier la facture, il faut déterminer stocker le numéro de série ou le code personnalisé. Plusieurs approches existent :

Option A : Utiliser le champ référence produit

Si votre numéro de série est unique par produit (pas par commande), le champ reference de ps_product peut suffire. C'est la solution la plus simple : ce champ est déjà disponible dans le template de facture via $product.product_reference.

Option B : Utiliser les personnalisations produit (customizations)

PrestaShop gère nativement les personnalisations produit (champs texte ou fichier). Si le numéro de série doit être saisi au moment de la commande, cette approche est pertinente. Les personnalisations sont stockées dans ps_customization et ps_customized_data.

Option C : Ajouter un champ custom sur le détail de commande

Pour les numéros de série attribués après la commande (cas le plus fréquent), il faut étendre la table ps_order_detail avec une colonne supplémentaire. C'est l'approche la plus robuste.

Étape 2 : Étendre la table order_detail (Option C)

Créez un module qui ajoute la colonne nécessaire :


// modules/myserials/myserials.php
public function install()
{
    return parent::install()
        && $this->registerHook('actionOrderDetail')
        && $this->registerHook('displayAdminOrderContentOrder')
        && Db::getInstance()->execute('
            ALTER TABLE `' . _DB_PREFIX_ . 'order_detail`
            ADD `serial_number` VARCHAR(255) DEFAULT NULL
        ');
}

Étape 3 : Interface d'administration pour saisir le numéro de série

Hookez-vous sur displayAdminOrderContentOrder (PrestaShop 1.7) ou displayAdminOrderMain (PrestaShop 8.x) pour ajouter un formulaire de saisie dans le back-office :


public function hookDisplayAdminOrderMain(array $params)
{
    $orderId = $params['id_order'];
    $orderDetails = OrderDetail::getList((int) $orderId);
    
    foreach ($orderDetails as &$detail) {
        $detail['serial_number'] = Db::getInstance()->getValue(
            'SELECT serial_number FROM `' . _DB_PREFIX_ . 'order_detail`
            WHERE id_order_detail = ' . (int) $detail['id_order_detail']
        );
    }
    
    $this->context->smarty->assign([
        'order_details' => $orderDetails,
        'serial_save_url' => $this->context->link->getAdminLink('AdminModules', true, [], [
            'configure' => $this->name,
            'action' => 'saveSerial',
        ]),
    ]);
    
    return $this->display(__FILE__, 'views/templates/hook/admin-order-serials.tpl');
}

Étape 4 : Override du template de facture PDF

Copiez le template dans votre thème pour l'overrider proprement :


# PrestaShop 8.x
cp pdf/invoice.product-tab.tpl themes/votre-theme/pdf/invoice.product-tab.tpl

Modifiez le template pour afficher le numéro de série :


{* Dans la boucle des produits *}
{foreach $order_details as $order_detail}
<tr>
    <td>{$order_detail.product_name}</td>
    <td>{$order_detail.product_reference}</td>
    {* Ajout du numéro de série *}
    <td>
        {if isset($order_detail.serial_number) && $order_detail.serial_number}
            {$order_detail.serial_number}
        {else}
            -
        {/if}
    </td>
    <td>{$order_detail.unit_price_tax_excl_including_ecotax}</td>
    <td>{$order_detail.product_quantity}</td>
    <td>{$order_detail.total_price_tax_excl_including_ecotax}</td>
</tr>
{/foreach}

N'oubliez pas d'ajouter l'en-tête de colonne correspondant dans la partie du tableau.

Étape 5 : Override de HTMLTemplateInvoice

Pour injecter les données de numéro de série dans le template, créez un override de la classe :


// override/classes/pdf/HTMLTemplateInvoice.php
class HTMLTemplateInvoice extends HTMLTemplateInvoiceCore
{
    public function getContent()
    {
        // Récupérer le contenu parent
        $content = parent::getContent();
        
        // Enrichir les order_details avec les numéros de série
        $orderDetails = $this->order->getProductsDetail();
        foreach ($orderDetails as &$detail) {
            $detail['serial_number'] = Db::getInstance()->getValue(
                'SELECT serial_number FROM `' . _DB_PREFIX_ . 'order_detail`
                WHERE id_order_detail = ' . (int) $detail['id_order_detail']
            );
        }
        
        $this->smarty->assign('order_details_with_serials', $orderDetails);
        
        return $content;
    }
}

Important sur PrestaShop 8.x : le système d'override classique fonctionne toujours, mais Symfony encourage l'utilisation de services décorés. Pour un module, l'override reste l'approche la plus pragmatique pour modifier la génération PDF.

Cas particulier : génération automatique de codes

Si vos numéros de série ou codes de licence sont générés automatiquement (produits dématérialisés, licences logicielles), hookez-vous sur actionOrderStatusPostUpdate pour déclencher la génération au moment du paiement :


public function hookActionOrderStatusPostUpdate(array $params)
{
    if ((int) $params['newOrderStatus']->id === (int) Configuration::get('PS_OS_PAYMENT')) {
        $order = new Order((int) $params['id_order']);
        $details = $order->getProductsDetail();
        
        foreach ($details as $detail) {
            $serial = $this->generateSerialNumber($detail['product_id']);
            Db::getInstance()->update('order_detail', [
                'serial_number' => pSQL($serial),
            ], 'id_order_detail = ' . (int) $detail['id_order_detail']);
        }
    }
}

private function generateSerialNumber(int $productId): string
{
    return strtoupper(
        substr(md5($productId . time() . random_bytes(8)), 0, 4) . '-' .
        substr(md5(uniqid('', true)), 0, 4) . '-' .
        substr(md5(random_bytes(16)), 0, 4) . '-' .
        substr(md5(time() . $productId), 0, 4)
    );
}

Bonnes pratiques et pièges à éviter

  • **Ne modifiez jamais les fichiers core directement** : utilisez toujours le système d'override ou un module. Une mise à jour PrestaShop écraserait vos modifications.
  • **Videz le cache** après chaque modification de template PDF : supprimez le contenu de `var/cache/` (PS 8.x) ou `cache/smarty/compile/` (PS 1.7).
  • **Testez avec `Tools::enableCache(false)`** pendant le développement pour voir vos modifications en temps réel.
  • **Les factures déjà générées ne changent pas** : si vous ajoutez un numéro de série après coup, il faudra régénérer la facture (possible via le back-office en modifiant l'état de commande).
  • **Échappez systématiquement** les valeurs avec `pSQL()` côté PHP et `{$variable|escape:'html':'UTF-8'}` côté Smarty.
#facture #PDF #numéro de série #override #HTMLTemplateInvoice #customization

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.