La guida riluttante alle migrazioni Shopify

Atto V: L'apparenza del completamento

La compliance è uno stato, non un progetto

L’auditor non lo disse con cattiveria. Era proprio questo il dettaglio che il CTO continuò a rivedere nella mente dopo, quel modo gentile in cui l’uomo dall’altra parte del tavolo aveva fatto la domanda, quasi per formalità, come si chiede una ricevuta che si dà del tutto per scontato di ricevere. Erano quasi in fondo a una revisione sulla privacy, in un brand che fatturava duecento milioni l’anno, e stava andando bene. I dati degli ordini erano puliti. La cancellazione nativa funzionava. Le app commerciali nello stack avevano tutte i webhook collegati, perché i vendor li avevano collegati, perché i vendor erano obbligati a farlo. E poi l’auditor guardò la sua lista e disse, con lo stesso tono pacato che aveva usato per tutto il resto, e l’app di loyalty—dov’è l’endpoint di cancellazione per quella?

Il CTO aprì il codice. Conosceva bene l’app; era lì quando era stata definita, tre anni e una piattaforma fa, ai tempi in cui la loyalty era roba da un trimestre di roadmap e nessuno nella stanza aveva pronunciato nemmeno una volta la parola cancellazione. Scorse il codice. Cercò nel repo. Lo cercò di nuovo con un altro termine, perché di sicuro. Non c’era nessun endpoint di cancellazione. Non c’era mai stato nessun endpoint di cancellazione. L’app aveva scritto i dati dei clienti in un suo piccolo database, fedelmente, per tre anni, e da quel database non c’era nessuna porta d’uscita, perché a nessuno era venuto in mente di costruirne una—non per negligenza, non per qualche difetto di carattere, ma perché all’epoca il requisito era un’astrazione e il programma di loyalty era una scadenza. Le ragioni erano ordinarie. La lacuna era totale.

Non andò esattamente nel panico. Ma ebbe la sensazione precisa di un uomo che ha appena scoperto che una stanza davanti a cui passa ogni giorno non ha pavimento, e non ha mai avuto pavimento per tutto il tempo, e l’unico motivo per cui non c’è sprofondato è che non ci aveva mai messo piede nemmeno una volta.


Parliamo allora di quel pavimento, perché ce l’ha anche il brand che sta leggendo. La cosa rassicurante che si dice di Shopify e della normativa sulla privacy è che la piattaforma gestisce il GDPR. La cosa accurata—e la differenza tra le due, in un qualche martedì che ora non riesci a vedere, sarà seduta dall’altra parte di un tavolo davanti al tuo CTO con una cartelletta in mano—è che Shopify gestisce il GDPR in parte. L’intero capitolo vive dentro quell’avverbio.

Ciò che la piattaforma gestisce davvero è reale, e vale la pena conoscerlo con precisione, perché sarai tentato o di fidartene troppo o di liquidarlo, e sono entrambi errori. Quando un cliente chiede di essere cancellato, Shopify elimina ciò che Shopify detiene nativamente: storico degli ordini, indirizzi, metodi di pagamento salvati. Spariti, come si deve, senza asterischi. E ogni app dell’ecosistema—ognuna, come condizione per esistere nell’ecosistema—è obbligata a esporre un webhook di cancellazione. Quando scatta la cancellazione, Shopify bussa diligentemente alla porta di ogni app installata e dice questa persona, per favore, cancella i tuoi dati, e l’app è tenuta a obbedire. C’è persino un effetto collaterale nascosto in questo meccanismo che vale la pena tenere a mente, perché coglie le persone di sorpresa nel momento peggiore: cancellare i dati personali di un cliente annulla qualsiasi pagamento preautorizzato su quell’account. Il preordine. L’abbonamento attivo. La cancellazione non è una silenziosa operazione di contabilità; entra dentro la relazione commerciale e mette fine alle cose. Saperlo in anticipo è la differenza tra un processo pulito e un’escalation di supporto confusa sul perché l’abbonamento di una cliente VIP sia evaporato nella stessa settimana in cui aveva presentato una richiesta sulla privacy.

Questo è l’impianto idraulico, ed è un buon impianto idraulico. Il guaio è che l’impianto raggiunge solo le stanze che ha costruito Shopify e le stanze che hanno costruito i suoi vendor. Non raggiunge la stanza che hai costruito tu.

Una persona che varca una soglia scopre che il pavimento finisce semplicemente a metà stanza, con un vuoto buio che sprofonda sotto il suo piede sospeso; la parete in fondo è ordinaria e intatta.
Il pavimento non c'era mai stato. L'unica cosa che lo aveva protetto era che, fino ad allora, nessuno ci aveva messo piede.

Ecco la regola, e il motivo per cui è pericolosa. Le app custom—quelle su misura che ha scritto il tuo team, il programma di loyalty, il layer di personalizzazione, quella cosa che in silenzio scrive i dati dei clienti in un database lì di lato—sono soggette esattamente allo stesso requisito di ogni app commerciale dello store. Devono esporre un webhook di cancellazione. Devono cancellare davvero quando scatta. La legge non ha un occhio di riguardo per il codice che hai scritto tu.

Ma niente lo fa rispettare. È tutto il problema in una frase. Un’app commerciale ottiene il suo webhook di cancellazione perché il vendor ha dovuto costruirne uno per essere pubblicato, ha dovuto tenerlo funzionante per restare pubblicato, ha un team di compliance e un processo di review e una ragione di business per cui importargliene. La tua app custom è stata costruita perché c’era una data di lancio. Il webhook di cancellazione non era sul ticket, perché all’epoca il requisito era un paragrafo in una normativa che nessuno nel team di sviluppo aveva letto, e la data di lancio era una cosa reale con un numero reale attaccato. Così la metà commerciale del tuo stack è coperta—generosamente, automaticamente, invisibilmente—e la metà custom, la metà con dentro l’effettiva intelligenza del tuo brand, la metà di cui sei più orgoglioso, è la metà senza pavimento. Negli audit di compliance che abbiamo condotto, questa è la lacuna che si trova più costantemente in assoluto. Non ogni tanto. Costantemente. È così affidabile che dovresti dare per scontato, proprio ora, prima di controllare, di averla.

(Senior Engineer che legge alle 23, sai già di quale app si tratta. Ci hai pensato tre paragrafi fa. Quella sensazione è il capitolo che fa il suo lavoro.)

La stessa forma si ripete una stanza più in là, nella portabilità dei dati. Shopify ti dà un pulsante con la scritta Richiedi i dati del cliente, ed è facile leggere quel pulsante come la risposta a una richiesta di portabilità. Non è la risposta; è il primo paragrafo della risposta. Quell’export contiene ciò che Shopify sa del cliente—non ciò che sanno le tue app. Se un cliente esercita il proprio diritto alla portabilità e tu gli consegni l’export di Shopify, gli hai consegnato una risposta parziale spacciandola per completa, che è un suo genere di rilievo a sé. Ricostruire il quadro completo attraverso il tuo stack di app è compito del brand, e nessuno lo farà al posto tuo, e il momento per scoprirlo non è il giorno in cui arriva la richiesta.

Il CCPA, per fortuna, si gestisce per lo più da solo se hai fatto quanto sopra. I due framework si sovrappongono pesantemente sui diritti che generano lavoro—cancellazione, portabilità—e il GDPR è il più severo dei due. Tratta il GDPR come pavimento e avrai costruito abbastanza in alto da superare il CCPA con lo stesso gesto. Divergono sui diritti di opt-out per la vendita di dati personali, ma per il brand DTC che non vende le sue liste clienti a terze parti—che è la maggior parte di loro—quella divergenza resta teorica. Costruisci una volta sullo standard più severo; smetti di mantenere due posture di compliance che dicono in gran parte la stessa cosa.


E poi c’è la direttiva per cui nessuno prende un aereo dagli Stati Uniti per preoccuparsene, ed è esattamente per questo che è quella che li frega.

La Direttiva Omnibus riguarda l’onestà nei prezzi e l’onestà nelle recensioni, e l’istinto del brand statunitense è dare per scontato che non lo riguardi, perché il brand è costituito nel Delaware e Omnibus suona europeo e lontano. L’istinto è sbagliato, e il modo in cui è sbagliato conta. Il GDPR si applica quando tratti i dati personali di residenti UE. Omnibus si applica quando fai marketing verso consumatori UE. Sono trigger diversi. Puoi far scattare il secondo senza nemmeno avvicinarti al primo. Se stai facendo una campagna rivolta a clienti europei—e la tua configurazione Markets, il tuo storefront tradotto, i tuoi prezzi in euro dicono tutti che lo stai facendo—allora sei dentro il raggio d’azione della direttiva.

Non esiste un’esenzione “siamo americani”. Dillo a voce alta una volta, perché qualche parte dell’organizzazione sta tranquillamente dando per scontato che esista.

Il pezzo di Omnibus che frega più brand è la regola dei trenta giorni sullo storico dei prezzi, e vale la pena essere precisi al riguardo, perché la versione imprecisa è inutile. Ogni volta che mostri un prezzo promozionale—un’etichetta prima/ora, un badge di sconto, un prezzo barrato del Black Friday—sei obbligato a mostrare il prezzo più basso che hai effettivamente applicato per quel prodotto nei trenta giorni prima della promozione. Non il prezzo di listino consigliato. Non il prezzo di listino su cui ti piacerebbe ancorarti. Il prezzo più basso a cui hai transato. Il numero che un cliente vero ha davvero pagato, in fondo a una qualunque silenziosa promozioncina che hai fatto sei settimane fa e di cui ti sei dimenticato. È quel numero che il prezzo barrato deve rispettare.

Shopify non tiene nessun registro del genere. Non c’è nessuna funzione nativa di storico prezzi che aspetta di essere accesa. I brand che gestiscono questa cosa lo fanno in uno di due modi: un’app costruita apposta, di cui ne esistono diverse, oppure un lavoro custom—di solito un’operazione giornaliera che fa uno snapshot dei prezzi correnti e li scrive in un metafield o in uno store esterno, accumulando lo storico un giorno alla volta. Entrambi gli approcci vanno bene. Ciò che non va bene, ciò che è l’effettivo punto di rottura, è il brand che imposta la cosa una volta, si fa i complimenti, e la lascia decadere. Perché non è una casella da spuntare al lancio. È un processo che deve girare di continuo—attraverso ogni campagna, su ogni mercato e ogni variante in cui fai sconti—e un registro prezzi con un buco di tre settimane, dal momento in cui il job di snapshot è morto in silenzio, non è un registro prezzi. È una responsabilità legale con buone intenzioni.

Un sistema improvvisato di imbuti e tubi montato a una parete convoglia il gocciolio di un tubo che perde dentro un barattolo di raccolta; un tubo centrale si è staccato e sgocciola sul pavimento senza che nessuno se ne accorga, mentre il barattolo sotto sembra quasi pieno e apparentemente intatto.
Un registro prezzi con un buco di tre settimane non è un registro prezzi. È una responsabilità legale con buone intenzioni.

Le recensioni sono il secondo fronte della direttiva, e per impostazione predefinita falliscono quasi tutti, che è la parte inquietante—non che i brand infrangano la regola di proposito, ma che la regola sia infranta nelle impostazioni di fabbrica. Omnibus vieta di sopprimere le recensioni negative e ti obbliga a dichiarare come le recensioni vengono raccolte, elaborate e verificate. Chi guarda il tuo blocco recensioni dovrebbe poter capire, da qualche parte lì vicino, se le recensioni arrivano da acquirenti verificati, come funziona la moderazione, e se viene applicato qualche filtro. Ora vai a vedere com’è arrivata la tua app di recensioni. La configurazione standard ti permette di mettere in evidenza le recensioni con punteggio più alto, ordinare per voto, sopprimere in silenzio tutto ciò che sta sotto una soglia—e niente di tutto questo è conforme, e moltissimi brand stanno girando esattamente con quei default, in buona fede, da anni. La buona notizia, ed è davvero una buona notizia dopo il paragrafo sullo storico dei prezzi, è che la correzione è piccola. Fai l’audit delle impostazioni dell’app. Riduci il filtraggio che non riesci a sostenere e a descrivere onestamente. Aggiungi una frase o due vicino alle recensioni che spieghi come le raccogli e le verifichi. Un pomeriggio, non un trimestre.

I prezzi personalizzati meritano una breve menzione di passaggio, per i pochi a cui si applicano. Se mostri prezzi diversi a segmenti diversi—fasce per i membri, prezzi B2B, qualunque cosa aggiustata algoritmicamente al momento della visualizzazione—Omnibus vuole che sia dichiarato dove il prezzo viene mostrato. Su Shopify questo livello di personalizzazione del prezzo richiede Shopify Functions o vero sviluppo custom, quindi la maggior parte dei brand non lo fa e può lasciar perdere il paragrafo. Se il tuo lo fa, lo sai già, e ora sai che c’è attaccata una dichiarazione.


Ecco dunque dove mettere le mani, più o meno in ordine di quanto ti costeranno, che è anche—piacevolmente, per una volta—più o meno l’ordine di quanto sono facili da sistemare.

Comincia dall’app di recensioni, perché è un’ora di lavoro e chiude una lacuna che un’autorità di vigilanza potrebbe vedere dallo storefront senza fare login da nessuna parte. Apri le impostazioni, guarda quale filtraggio è attivo, aggiungi il testo della dichiarazione se manca. Fatto prima di pranzo.

Poi gli endpoint di cancellazione delle app custom—l’app di loyalty, il layer di personalizzazione, ogni cosa su misura nello stack che scrive dati dei clienti da qualche parte di suo. Per ciascuno, verifica che ci sia un webhook di cancellazione e che faccia ciò che dichiara, invece di limitarsi a restituire un cortese duecento e non cancellare niente. Questa è la lacuna di compliance che sembra gestita finché non guardi da vicino, e la più facile da sistemare una volta che l’hai trovata. Il guardare è tutto il compito. Il sistemare di solito è un pomeriggio per app. Il non-guardare è la parte che finisce dall’altra parte di un tavolo davanti al tuo CTO.

Poi, per ultimo, perché richiede più preparazione e non lo puoi fare in un pomeriggio, l’infrastruttura per lo storico dei prezzi. Se stai facendo promozioni verso i mercati UE senza un registro prezzi continuo, sei esposto su ogni singola campagna, e il momento giusto per averla in piedi è prima del tuo prossimo saldo, non nella ricostruzione forense del dopo.

Ciò che tiene insieme tutto questo non è una checklist di lancio. È una cadenza. Gli stack di app crescono più in fretta di quanto avvengano gli audit di compliance—qualcuno installa una nuova app un giovedì e la tua superficie d’attacco è cambiata e nessuno ha aperto un ticket al riguardo. I registri prezzi devono sopravvivere ai cicli delle campagne e all’ingegnere che ha scritto il job di snapshot e se n’è andato da un concorrente. Le configurazioni delle recensioni vanno alla deriva ogni volta che un aggiornamento del tema resetta un’impostazione. Niente di tutto questo sta fermo, il che significa che la compliance non può essere una cosa che hai raggiunto al passato. È uno stato in cui il tuo store si trova, o non si trova, proprio adesso, in questo minuto, mentre leggi—e l’unico modo onesto per sapere quale dei due è aver costruito l’abitudine di controllare.

Il CTO con l’app di loyalty senza pavimento l’ha sistemata, comunque. Alla fine è stato un pomeriggio: un webhook di cancellazione, un processo dietro, un test a dimostrare che la porta si apriva davvero. La correzione non è mai stata la parte difficile. La parte difficile era che per tre anni l’unica cosa tra lui e il rilievo era che nessuno aveva messo piede sul pavimento—e l’audit è stato semplicemente il giorno in cui qualcuno l’ha fatto. Non sei tu a scegliere quando arriva quel giorno. Scegli solo se sei andato a cercare prima.

Qui giace l’app di loyalty che ha deliziato diecimila clienti e non è riuscita, quando finalmente glielo hanno chiesto, a dimenticarne nemmeno uno. Era conforme in ogni stanza tranne quella che si era costruita da sola.