Le WordPress d'aujourd'hui, décodé pour les développeurs

E-commerce

Stocker un identifiant de commande en session plutôt que dans une meta persistante

Un client se reconnecte et sa commande en cours a disparu. La cause : un identifiant conservé uniquement en session PHP, jamais dans une donnée persistante.

Par WordPress Développement • 31 janvier 2024 • 5 min de lecture • Aucun commentaire
Stocker un identifiant de commande en session plutôt que dans une meta persistante

30 minutes : c’est, par défaut, la durée de vie d’une session PHP inactive sur de nombreuses configurations d’hébergement, avant que son contenu ne soit purgé automatiquement. Ce chiffre suffit à expliquer une catégorie récurrente de commandes perdues : celles où l’identifiant de la commande en cours n’était conservé qu’en session, jamais ailleurs.

Ce qu’on voit

Le symptôme est presque toujours le même : un client commence une commande, quitte la page de paiement pour vérifier un détail — souvent en ouvrant un nouvel onglet ou en changeant de réseau, ce qui provoque parfois une nouvelle session côté serveur — puis revient plus tard pour finaliser son achat. À son retour, le tunnel de commande repart de zéro, sans trace de la commande commencée, alors même que celle-ci existe bel et bien en base de données avec un statut « en attente ».

Dans le code d’une extension personnalisée à l’origine de ce comportement, on retrouve typiquement une ligne de ce type, censée retrouver la commande en cours :

$order_id = WC()->session->get( 'commande_en_cours_id' );

Pourquoi c’est un problème

La session gérée par WooCommerce via WC_Session_Handler repose sur un cookie identifiant la session côté client, associé à des données stockées côté serveur — historiquement dans une table dédiée, ou selon la configuration dans un système de cache. Cette session est conçue pour disparaître : c’est son rôle, elle ne doit pas devenir un mécanisme de persistance à long terme. Un changement d’appareil, une navigation privée, un cookie effacé par un bloqueur de traqueurs, ou simplement l’expiration naturelle de la session suffisent à rendre cette clé introuvable, alors que la commande, elle, continue d’exister dans la table des commandes.

Ce problème est aggravé sur les configurations où la session est stockée dans un cache objet volatile, comme certaines configurations Redis avec politique d’éviction agressive : la session peut disparaître encore plus tôt que prévu si le serveur de cache manque de mémoire disponible.

L'essentiel à retenir : La session PHP ne survit pas à un changement de connexion ; Une méta de commande persiste indépendamment de la session ; Le HPOS reste compatible avec une recherche par méta-donnée

Quoi faire à la place

L’identifiant d’une commande en cours doit être retrouvable indépendamment de toute session, à partir d’une information stable : le compte client connecté, ou un jeton persistant transmis dans l’URL de retour de la commande. La bonne pratique consiste à écrire cet identifiant en méta-donnée sur la commande elle-même, via update_meta_data(), et à le retrouver par une requête sur cette méta plutôt que par la session.

$order = wc_get_order( $order_id );
$order->update_meta_data( '_jeton_reprise_commande', $jeton );
$order->save();

// Plus tard, pour retrouver la commande à partir du jeton :
$commandes = wc_get_orders( [
    'meta_key'   => '_jeton_reprise_commande',
    'meta_value' => $jeton,
    'limit'      => 1,
] );

Avec le stockage des commandes en tables dédiées (HPOS, activable depuis WooCommerce 8.2 et devenu la valeur par défaut sur les nouvelles installations à partir de WooCommerce 8.2), cette recherche par méta reste prise en charge par wc_get_orders(), qui redirige la requête vers la structure de stockage active sans changement de code côté développeur.

Ce qui reste vrai malgré tout pour la session

  • La session reste parfaitement adaptée au panier en cours de construction, tant qu’aucune commande n’a encore été créée.
  • Elle convient à des données réellement temporaires, comme un indicateur d’affichage d’une bannière déjà vue.
  • Elle ne doit jamais devenir la seule source de vérité pour retrouver une commande déjà enregistrée en base.

Un cas particulier : les commandes créées par une tâche planifiée

Ce piège se manifeste aussi, sous une forme différente, lorsqu’une commande est générée par une tâche exécutée via Action Scheduler plutôt que par une visite directe du client — un renouvellement d’abonnement, par exemple. Dans ce contexte, il n’existe tout simplement aucune session PHP associée à l’exécution de la tâche, puisque celle-ci ne provient d’aucune requête HTTP d’un visiteur. Un code qui suppose la présence d’une session pour retrouver ou compléter une commande créée dans ce contexte échoue systématiquement, ce qui rend l’erreur encore plus difficile à repérer en test manuel, un test réalisé depuis un navigateur disposant toujours d’une session active.

En résumé

La confusion entre donnée de session et donnée persistante coûte cher précisément parce qu’elle ne se voit pas en test rapide, effectué sans interruption de session par le développeur lui-même. Une méta-donnée écrite sur la commande, retrouvable par une requête classique, élimine cette classe entière de commandes perdues, quel que soit le comportement du navigateur ou du réseau du client entre deux visites.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi