Il link "recover_cart" rimanda alla home: perché il recupero carrello smette di funzionare
Il sintomo
Un link di recupero carrello generato dal back office, del tipo /ordine?step=0&recover_cart=ID&token_cart=TOKEN, non apre il checkout: rimbalza in home, senza nessun messaggio di errore visibile. Non è un problema del link in sé: il token è corretto (viene calcolato con un hash che combina la chiave del negozio e l'ID del carrello), e non è scaduto. Semplicemente, il click non porta dove dovrebbe.
Cosa sembrava e non era
Il primo sospetto, ragionevole, era un problema di generazione del link: token calcolato male, o formato dell'URL cambiato da un aggiornamento recente. Non era così: confrontando il link generato dal back office con quello che PrestaShop si aspetta di ricevere, i due combaciavano esattamente. Il secondo sospetto era una cache o una regola di redirect lato server che intercettava l'URL prima che arrivasse a PrestaShop. Anche questo escluso: la richiesta arrivava regolarmente al controller giusto.
A quel punto è diventato chiaro che il problema non era nel link, ma in qualcosa che riguardava il carrello o il cliente a cui appartiene, dato che alcuni link funzionavano regolarmente e altri no, con lo stesso formato identico.
La causa vera
Il recupero di un carrello, in PrestaShop, passa dal metodo recoverCart() chiamato durante FrontController::init(). Confrontando i carrelli che fallivano con quelli che funzionavano, emergono due condizioni distinte che portano allo stesso identico sintomo (redirect in home), e solo una delle due è quella da correggere.
- Il carrello è già stato ordinato. Se esiste già un ordine collegato a quel carrello, PrestaShop non lo riapre: è un comportamento corretto, non un bug, e non va toccato.
- Il cliente proprietario del carrello è stato cancellato in modo "soft". PrestaShop non cancella mai davvero un cliente dal database: imposta un flag (
ps_customer.deleted = 1) e mantiene lo storico ordini. Il metodorecoverCart()però non recupera un carrello il cui proprietario risulta cancellato, anche se il token è valido: semplicemente non lo trova, come se il carrello non esistesse, e la richiesta finisce in home.
Un cliente può risultare cancellato per motivi che non sono un errore tecnico: può aver usato un modulo di conformità GDPR che offre l'auto-cancellazione dell'account, oppure può essere stato cancellato da un operatore del back office. In entrambi i casi il comportamento di PrestaShop è corretto dal suo punto di vista: un account cancellato non deve poter tornare operativo da solo con un semplice click su un link. Il problema pratico è che quel link, in questo scenario, è spesso l'unico modo che un cliente reale ha per riprendere un acquisto che aveva iniziato, e il messaggio che riceve (una home page qualunque, senza spiegazioni) non gli dice nulla del perché.
La correzione
La correzione interviene sul metodo recoverCart(): quando il token è valido ma il cliente proprietario risulta cancellato, invece di abbandonare il recupero, il codice controlla se esiste un altro account, attivo, con la stessa email.
- Se non esiste un account attivo gemello, il cliente cancellato viene riattivato (
deleted = 0) e il recupero prosegue normalmente. - Se esiste già un account attivo con la stessa email (il caso tipico è un cliente che si è ri-registrato dopo aver cancellato il vecchio account), il carrello viene spostato sul nuovo account attivo, e gli indirizzi collegati vengono azzerati per essere riselezionati al checkout, invece di essere trascinati da un account che non esiste più attivamente. Questa distinzione è la parte che conta di più: riattivare un account quando ne esiste già un altro attivo con la stessa email creerebbe due account paralleli con la stessa credenziale di accesso, che in PrestaShop rompe il login.
Entrambi i percorsi vengono registrati in un log applicativo, prima di procedere con il recupero normale del carrello: è l'unico modo per poter ricostruire, in seguito, perché un account cancellato è tornato attivo.
C'è un punto di policy, non solo tecnico, che vale la pena scrivere esplicitamente: se un cliente aveva chiesto la cancellazione del proprio account per motivi legati alla protezione dei dati, questa correzione la annulla nel momento in cui lui stesso clicca il proprio link di recupero. È difendibile perché l'iniziativa parte dal cliente stesso, sullo stesso link che gli era stato inviato, ma resta una scelta di policy da valutare caso per caso, non un dettaglio puramente implementativo.
Come verificare che tenga
- Riprodurre entrambi i casi: un cliente cancellato senza account gemello (deve riattivarsi e il checkout deve caricare), e un cliente cancellato con un account gemello attivo sulla stessa email (il carrello deve spostarsi sull'account attivo, con gli indirizzi azzerati, senza toccare lo stato del vecchio account).
- Verificare che un carrello già associato a un ordine resti correttamente non recuperabile: questa correzione non deve cambiare quel comportamento, che è corretto così com'è.
- Controllare il log applicativo dopo ogni recupero che ha coinvolto un cliente cancellato: deve comparire una riga per ogni riattivazione o spostamento, con l'informazione di quale dei due casi si è verificato.
- Se il negozio ha un modulo di conformità GDPR con auto-cancellazione dell'account, includere questo scenario nei test dopo ogni aggiornamento di quel modulo: è lì che la cancellazione morbida dei clienti viene generata più spesso.
Il negozio su cui è stato diagnosticato questo caso resta anonimo di proposito. Se un link di recupero carrello con token corretto rimanda alla home invece di aprire il checkout, e il carrello in questione non risulta già ordinato, il posto giusto dove guardare è lo stato del cliente proprietario, non il link in sé. Chi si occupa di manutenzione ricorrente su un negozio PrestaShop trova un riepilogo dei servizi su questa pagina.
