← Tutti i case studies

Fashion / E-commerce

Come ho sostituito un'agenzia web per un brand fashion da oltre 10 milioni su Shopify Plus, costruendo nel tempo un sistema di gestione ordini, spedizioni e magazzino RFID su misura

Come ho costruito nel tempo un sistema completo di gestione ordini, spedizioni multi corriere e magazzino con lettori RFID per un brand fashion da oltre 10 milioni su Shopify Plus, lavorando da freelance al posto di un'agenzia.

Cliente: Brand fashion (Shopify Plus, oltre 10M€ di revenue)
Servizi coinvolti: Sviluppo Shopify · Consulenza Tecnica · Applicazioni Web su Misura
Pubblicato: 20 aprile 2026

In breve

Un brand fashion italiano da oltre dieci milioni di euro di fatturato, su Shopify Plus, era ingolfato in un mix di app che funzionavano a metà e processi manuali. Aveva già passato due agenzie web importanti prima di arrivare da me, ma non perché il lavoro fosse fatto male: il problema era che erano “un cliente tra tanti”. Quello che gli serviva era una persona sola, sempre raggiungibile, che costruisse qualcosa davvero pensato sulla loro operatività.

Quella persona sono stato io, per diversi anni. In questo tempo siamo passati da una sola postazione di spedizione con lettore barcode a sei postazioni con sistema RFID completo, integrate con la stampa di etichette su stampanti industriali (codice ZPL scritto a mano), integrazione diretta con le API di UPS, DHL e FedEx, e antenne RFID costruite internamente con componenti importati dalla Cina.

Tutto questo è stato progettato e realizzato anni prima che esistessero ChatGPT, Claude o qualsiasi altro assistente AI per la programmazione. Ogni decisione architetturale è il risultato di datasheet letti, chiamate ai supporti tecnici dei corrieri, e scelte fatte a ragion veduta.

Questo è il racconto di cosa succede quando un cliente compra una persona invece di un fornitore. E di perché costruire piccolo all’inizio, crescendo insieme al business, batte ogni volta i mega progetti pensati il giorno uno.


Il punto di partenza: uno store Shopify Plus che aveva superato i suoi strumenti

Il cliente è un brand fashion di cui tengo il nome riservato. Shopify Plus, attivo su più mercati europei, volumi di ordini alti, e un fatturato che li metteva ben oltre la soglia in cui le app pronte dello store possono reggere la complessità delle operazioni vere.

Sulla carta sembrava tutto sotto controllo. Nella pratica, la quotidianità era questa:

  • Un mosaico di app Shopify, ciascuna che risolveva un pezzo e nessuna che parlava con le altre. L’inventario da una parte, le spedizioni da un’altra, i resi gestiti su un foglio Google condiviso.
  • Passaggi manuali dappertutto. Gli addetti al picking sceglievano gli articoli a memoria o con stampate cartacee. Le etichette si generavano un corriere alla volta, spesso ridigitando l’indirizzo dentro il portale del corriere.
  • Resi che nessuno riusciva davvero a tracciare. Nel fashion, dove i resi arrivano abitualmente al 30–40%, questo non è un fastidio: è un’erosione silenziosa del margine.
  • Scostamenti di magazzino. Quello che Shopify diceva essere disponibile e quello che c’era davvero a scaffale divergevano di giorno in giorno.

Avevano già fatto la cosa più ovvia: assumere un’agenzia web grossa. Due, a dire il vero. Entrambe avevano consegnato. Con nessuna delle due la cosa era andata avanti.

Perché hanno lasciato le agenzie (e perché è importante)

Quando il cliente mi ha spiegato perché se ne era andato dalle agenzie precedenti, non ha parlato di codice scritto male o di scadenze saltate. Ha detto, con parole semplici:

“Eravamo un cliente tra tanti. Nessuno si prendeva in carico i nostri problemi. Ci serviva qualcuno che ci rispondesse al telefono, che conoscesse il nostro lavoro, e che costruisse le cose pensando a noi, non una soluzione generica con il nostro logo sopra.”

È la storia che sento più spesso da founder e responsabili di operations in aziende italiane di medie dimensioni. Non è che le agenzie lavorino male. È che l’economia di un’agenzia rende quasi impossibile dare a un cliente da 10–20 milioni la stessa attenzione che dà a uno da 100. Ti ritrovi con un project manager, un gruppo di sviluppatori a rotazione e un canale Slack dove le risposte arrivano dopo due giorni.

Quello che volevano loro era semplice:

  • Una persona, raggiungibile, che si ricordasse tutta la storia del progetto.
  • Su misura, nel senso di davvero pensato sulla loro operatività, non un modello preconfezionato con il loro nome incollato sopra.
  • Verticale, nel senso di qualcuno che imparasse come funziona davvero un magazzino fashion: i flussi di picking, la logistica dei resi, i cut off di spedizione, il caos dei periodi di saldi.

Questa è la richiesta che ho raccolto. Ed è anche, non per caso, la forma esatta che ha la mia professione da freelance in questi ultimi quindici anni.

La scelta architetturale che ha salvato il progetto: partire piccoli

Questa è la parte che quasi tutti i case study non raccontano. Le agenzie grosse vendono progetti grossi. Una piattaforma, un portale, una dashboard, una migrazione. Sulla carta fa colpo, e in produzione fa morire i progetti.

Noi non abbiamo fatto così.

La prima versione del sistema faceva una cosa sola: prendeva gli ordini da Shopify dentro una webapp custom e permetteva a una singola postazione di spedizione di stampare l’etichetta giusta usando un lettore barcode. Punto. Una postazione. Niente RFID. Nessun flusso per i resi. Nessuna logica multi corriere oltre al “questo ordine va con il corriere X”.

È andato online in poche settimane. L’effetto immediato è stato che gli errori manuali della postazione di spedizione sono crollati quasi a zero, perché l’operatore non doveva più ridigitare niente: scansiona, conferma, stampa.

Poi abbiamo lasciato il sistema vivere in produzione per mesi prima di aggiungere il pezzo successivo.

Questa è la disciplina architetturale che consiglierei a qualsiasi founder stia leggendo. Ogni nuovo pezzo aggiunto in seguito (il supporto multi corriere, la gestione resi, il magazzino RFID, la ricezione merci, i controlli periodici di inventario) è stato costruito perché il cliente è tornato con un problema concreto di operatività, non perché qualcuno aveva disegnato una roadmap due anni prima. Ogni aggiunta è stata pagata dai ricavi e dalla stabilità che i pezzi precedenti avevano già creato.

Anni dopo, il sistema gira su sei postazioni di spedizione e copre ogni passaggio dopo la presa d’ordine. Ma guardando il codice non sembra una cattedrale: sembra quello che è, un sistema che è cresciuto rispondendo a problemi reali, uno alla volta.

Come parla con Shopify

La webapp vive al di fuori di Shopify. Non è un’app Shopify installabile dallo store, è un sistema custom separato che parla con Shopify attraverso tre canali, ognuno scelto per un motivo preciso:

  1. Webhook per le cose che devono arrivare in tempo reale: nuovi ordini, ordini pagati, modifiche agli ordini, rimborsi avviati da Shopify. Gli handler dei webhook sono idempotenti e salvano il payload grezzo prima di qualsiasi elaborazione, così possiamo rilanciare qualsiasi passaggio se qualcosa va storto a valle.
  2. API REST per le operazioni standard di lettura e scrittura: prodotti, clienti, livelli di inventario. Affidabili, ben documentate, con caching dove utile.
  3. API GraphQL per i casi in cui REST avrebbe richiesto cinque chiamate separate. Recuperare un ordine con tutte le sue righe, le spedizioni e i rimborsi in una singola chiamata. GraphQL dà anche un controllo molto più fine sui campi richiesti, cosa che conta quando si fanno migliaia di chiamate al giorno e i limiti delle API diventano reali.

Se devo riassumere la regola che tiene in piedi questo pezzo: non fidarsi mai di un solo canale. I webhook possono saltare, arrivare in ritardo, arrivare fuori ordine. Un job notturno di riconciliazione confronta lo stato degli ordini nella webapp con quello su Shopify, segnala le divergenze, e permette a un operatore di sistemarle prima che diventino lamentele dei clienti.

Spedizioni multi corriere: UPS, DHL, FedEx direttamente

All’inizio abbiamo valutato l’idea di usare un aggregatore di spedizioni (tipo EasyPost o ShipStation). Il conto era semplice: un aggregatore ti risparmia il lavoro di integrazione iniziale e ti chiede una piccola fee su ogni spedizione. A volumi bassi va bene. A migliaia di spedizioni al mese su tre corrieri diversi, la fee cumulata inizia a diventare seria, e intanto hai scambiato il lavoro di integrazione con un vincolo verso un fornitore e uno strato che non puoi controllare quando qualcosa va storto.

Siamo andati dritti sulle API native.

Ogni corriere ha la sua integrazione diretta con le API ufficiali: autenticazione, confronto tariffe, generazione etichette, recupero dei numeri di tracking, aggiornamento degli stati. Il codice sta dietro un’interfaccia ShippingProvider, quindi dal punto di vista della webapp “stampare un’etichetta UPS” e “stampare un’etichetta DHL” sono la stessa chiamata con un valore diverso.

Cosa ci ha portato questa scelta in pratica:

  • Zero costi per spedizione oltre a quelli dei corrieri stessi.
  • Supporto diretto: quando qualcosa va storto con un’etichetta, parlo direttamente con il corriere, non con un aggregatore che parla con il corriere.
  • Controllo fine su cose come la scelta del servizio, il valore dichiarato, le assicurazioni, e i documenti doganali (critici per un brand che spedisce tra paesi UE).

È stato più lavoro? Sì, parecchio. Lo rifarei? Per questo volume e per questo cliente, senz’altro. Per un merchant più piccolo, di solito consiglio un aggregatore e di andare avanti.

Generazione etichette: scrivere ZPL a mano (e perché)

Le etichette di spedizione, i documenti di trasporto, i barcode per l’uso interno del magazzino: tutto viene generato dalla webapp come ZPL grezzo (Zebra Programming Language), inviato direttamente alle stampanti industriali Zebra attraverso la rete.

Avrei potuto prendere la strada più facile. Generare un PDF, mandarlo al driver di stampa del sistema operativo, e lasciare che se ne occupasse il driver. Tante app Shopify fanno esattamente così.

ZPL è più difficile. È un linguaggio testuale in cui ogni elemento dell’etichetta viene posizionato a coordinate assolute, si dichiarano i font, si disegnano i barcode, si compone l’etichetta byte dopo byte. Ma i vantaggi sono grossi:

  • Velocità nativa della stampante. Un’etichetta ZPL si stampa in millisecondi. Un PDF passato via driver ci mette secondi. Moltiplicato per sei postazioni e per una giornata di saldi, è la differenza tra un pomeriggio liscio e una coda di pacchi.
  • Zero dipendenze dal sistema operativo. Nessun driver di stampa, nessun sistema di code Windows, nessuna chiamata di supporto per “abbiamo aggiornato il PC e le stampanti non vanno più”. La webapp apre un socket TCP e manda byte.
  • Controllo assoluto del layout. Posizione di tutto, dimensione dei barcode, spaziatura del testo, posizionamento del logo: tutto deterministico, tutto versionato nel codice.
  • Anche i barcode interni, usati per il tracciamento dentro il magazzino (codici dei bin, tickets di prelievo, etichette degli scaffali), vengono generati con la stessa logica. Una sola pipeline di stampa, tanti casi d’uso.

ZPL è una di quelle competenze di cui nessuno pensa finché non serve. Ed è uno dei segnali più chiari che un progetto è stato costruito da qualcuno che conosce il lato operativo della faccenda, non solo quello web.

Il sistema RFID: costruire hardware e software insieme

Dopo qualche anno, l’operatività del cliente aveva superato i lettori barcode. Nel fashion le SKU sono tante, visivamente simili, e chi fa picking deve essere veloce. Il barcode funziona, ma è un codice per volta e richiede di inquadrare ogni singolo pezzo.

La risposta era RFID, ed è qui che il progetto ha smesso di somigliare a un normale lavoro di sviluppo web.

Abbiamo costruito postazioni RFID fisse a ognuna delle sei postazioni di spedizione. Le antenne sono posizionate sotto il piano di lavoro, creando una zona di lettura direttamente sopra l’area dove gli articoli vengono messi durante il picking, la ricezione resi o il controllo in ingresso.

Le postazioni sono state costruite con lettori RFID pronti e lavoro custom sulle antenne, con componenti importati direttamente da produttori in Cina. Questo ha tenuto il costo per postazione a una frazione di quello che avrebbe chiesto una soluzione industriale chiavi in mano e, cosa non secondaria, ci ha dato il controllo totale sullo stack hardware.

Generazione degli EPC e stampa dei tag RFID

Ecco una parte che molti non si rendono conto essere un problema da costruire da zero: da dove arrivano i codici dei tag RFID?

Ogni tag RFID porta un EPC (Electronic Product Code), un identificativo univoco scritto nella memoria del tag. Non compri tag già programmati dallo scaffale: li scrivi tu nel momento in cui li produci. Il che significa che chi costruisce il sistema deve decidere:

  • Lo schema di numerazione degli EPC (come i codici sono legati alle SKU, alle varianti, ai lotti di produzione).
  • Chi li genera, quando, e dove vengono salvati nel database.
  • Come vengono scritti nei tag fisici.

In questo sistema, la webapp genera gli EPC a richiesta, seguendo uno schema di numerazione interno pensato sulla struttura delle SKU del cliente. Quando serve un nuovo lotto di tag, la webapp mette in coda gli EPC e li manda a una stampante industriale con funzionalità RFID, che in un solo passaggio:

  1. Scrive l’EPC nella memoria di ogni tag.
  2. Stampa sull’adesivo del tag l’etichetta leggibile (anche questa in ZPL).
  3. Verifica che il tag sia stato scritto correttamente prima di passare al successivo.

Il risultato è una pipeline di generazione tag che è completamente sotto il controllo del cliente. Non c’è nessun servizio di terzi nel mezzo per la codifica dei tag. Nessun abbonamento mensile a una piattaforma di etichettatura. Nessuna dipendenza che possa essere chiusa, rincarata, o rotta da un cambio di API.

Il ponte Python tra hardware e webapp

Il collegamento tra l’hardware RFID e la webapp è un piccolo servizio Python che gira su ogni postazione. Il lato Python gestisce il protocollo di basso livello del lettore, filtra le letture duplicate (i lettori RFID sono generosi, un singolo tag può essere letto decine di volte al secondo), e manda eventi puliti all’API della webapp sulla rete locale. La webapp non parla mai direttamente col lettore: parla con il ponte Python, cosa che ci permette di aggiornare la webapp e lo stack hardware in modo indipendente.

Cosa ha cambiato l’RFID nelle operazioni

  • Picking: l’operatore appoggia gli articoli nella zona di lettura e il sistema conferma in tempo reale che gli articoli corretti per l’ordine sono presenti. Articolo sbagliato? L’interfaccia lo segnala prima che il pacco venga chiuso.
  • Ricezione resi: quando arriva un reso, la scatola va appoggiata sulla postazione RFID, i tag vengono letti, e il sistema associa automaticamente gli articoli all’ordine originale, segnando i controlli di condizione da fare. Niente da digitare, niente da cercare.
  • Ricezione merce: i bancali in ingresso vengono controllati contro l’ordine d’acquisto passando gli articoli sulla postazione, con il sistema che riconcilia automaticamente le quantità attese e quelle arrivate.
  • Controlli periodici di inventario: lo stesso hardware fa anche da strumento di audit dell’inventario. Passi un carrello davanti alla postazione, ottieni un conteggio in tempo reale.

Una nota sui tempi: tutto questo è stato costruito prima degli assistenti AI

Vale la pena dirlo chiaramente, perché cambia il modo in cui un case study come questo va letto nel 2026.

Quando questo sistema è stato progettato e costruito, non esistevano ChatGPT, Claude, Copilot o nessun altro tipo di assistente AI per programmare. Ogni decisione di questo case study, l’integrazione a tre canali con Shopify, l’astrazione delle API dei corrieri, la pipeline ZPL, lo schema di generazione EPC, l’architettura del ponte Python, la scelta delle antenne, è arrivata da datasheet letti la notte, esperimenti fatti in produzione, chiamate ai supporti tecnici dei corrieri e tante piccole versioni sbagliate prima di arrivare a quella giusta.

Non ho niente contro gli strumenti AI. Li uso ogni giorno, per quello in cui sono bravi. Ma il giudizio che decide quale pattern usare, quando integrare direttamente e quando passare per un’astrazione, e dove si nasconde la vera complessità di un’operazione aziendale, quello non sta nei pesi di un modello. Sta negli anni di lavoro che esistevano prima che il modello esistesse.

Quando un cliente oggi mi ingaggia, sta ingaggiando quel giudizio. L’AI è solo un acceleratore di digitazione.

Lo stack tecnico, e perché non è il punto

Per i curiosi: la webapp nasce in origine in CakePHP. Oggi, su un progetto nuovo per un cliente simile, partirei con Laravel per il backend, React con Inertia per il frontend, e MySQL come database.

Ma il framework non è davvero la parte interessante di questo case study. Le parti interessanti sono:

  • Decidere cosa costruire prima, non poi.
  • Scegliere tra aggregatori e integrazioni dirette con i corrieri in base a volumi e vincoli, non in base a cosa è più facile.
  • Trattare l’hardware come parte del sistema, non come un acquisto separato.
  • Tenersi la pipeline di generazione dei tag dalla A alla Z, schema di numerazione EPC incluso.
  • Scrivere ZPL a mano quando la velocità di stampa fa la differenza nei periodi di picco.
  • Costruire uno strato di ponte (Python + RFID) che permette alla webapp e all’hardware di evolvere in modo indipendente.
  • Far lavorare webhook e job di riconciliazione insieme, così nessun canale da solo è un punto di rottura.

Queste decisioni valgono su Laravel. Valgono su Rails. E valevano su CakePHP, che era quello che avevamo all’inizio.

Cosa ha ottenuto questo cliente che un’agenzia non poteva dargli

Dopo diversi anni di lavoro insieme, questa è la forma della nostra relazione:

  • Ogni riga di codice nel sistema è stata scritta pensando alla loro specifica operatività. Non c’è niente di “generico”, perché non c’era nessun modello da cui partire.
  • Quando chiamano, rispondo. Quando arriva un vincolo nuovo (un corriere nuovo, un paese nuovo, un flusso nuovo), ne parliamo quella settimana, non dopo una trattativa su un documento di scope.
  • Il sistema è cresciuto con il business. Da una postazione con barcode a sei postazioni con RFID, sempre sulla stessa architettura di fondo. Nessuna riscrittura, nessuna migrazione, nessuna “versione 2”.
  • Non c’è nessun vincolo verso di me. Il sistema gira su un’infrastruttura che controllano loro. Il codice è loro. Se domani mi mettesse sotto un treno, un altro sviluppatore senior potrebbe prenderlo in mano senza dover fare archeologia su una scatola nera.

Quando un ingaggio del genere ha senso per te

Se stai leggendo questa pagina come founder, responsabile di operations, o CTO, questo tipo di lavoro ha senso quando:

  • La tua operatività ha superato quello che le app Shopify possono fare, ma non sei abbastanza grande da giustificare un team di sviluppo interno.
  • Hai già provato un’agenzia e ti sei sentito un numero.
  • Ti serve qualcuno che sia ancora lì tra tre anni, perché il sistema che costruisci adesso dovrà crescere con te.
  • Capisci che “su misura” non è una scusa per sovrastrutturare: è una licenza per costruire esattamente quello che serve, niente di più, e aggiungere il resto quando diventa reale.

Una call breve per capire contesto, vincoli e cosa andremmo a costruire. Niente slide, niente sales script — solo una conversazione tecnica. Se c'è il fit andiamo avanti. Se non c'è, ti indico qualcuno con cui ci sia.

Scrivimi