Genera pass Apple e Google Wallet da Laravel
Un pass mobile è quella cosa nell'app Wallet del tuo iPhone. Una carta d'imbarco, un biglietto per un concerto, una carta fedeltà per il caffè, un abbonamento in palestra. Apple li chiama pass. Google li chiama oggetti. Entrambe le app Wallet ti permettono di generarli, distribuirli e inviare aggiornamenti in tempo reale alla copia già presente sul dispositivo di qualcuno.
Abbiamo appena rilasciato Laravel Mobile Pass, un pacchetto che ti consente di generare questi pass Apple e Google da un'app Laravel e inviare aggiornamenti ai pass già emessi.
Insieme al pacchetto, abbiamo anche pubblicato un sito demo dove puoi creare pass Apple Wallet e inviare un aggiornamento per vederli funzionare sul tuo dispositivo iOS.
Dan Johnson e io ci abbiamo lavorato per un po'. Lascia che ti mostri cosa può fare.
Un esempio semplice
Ecco la cosa più breve e utile che puoi costruire. Una carta d'imbarco per Apple Wallet per un volo:
use Spatie\LaravelMobilePass\Builders\Apple\AirlinePassBuilder;
use Spatie\LaravelMobilePass\Enums\BarcodeType;
$mobilePass = AirlinePassBuilder::make()
->setOrganizationName('Artisan Airways')
->setSerialNumber('ART-103')
->setDescription('Carta d''imbarco')
->addHeaderField('flight-no', 'ART103', label: 'Volo')
->addHeaderField('seat', '66F')
->addField('departure', 'ABU', label: 'Abu Dhabi International')
->addField('destination', 'LHR', label: 'London Heathrow')
->addSecondaryField('name', 'Mary Smith')
->setBarcode(BarcodeType::Pdf417, 'ART-103-66F')
->save();Chiamare save() ti restituisce un modello MobilePass. Non viene scritto nulla su disco. L'intero pass (campi, immagini, codice a barre, tutto quanto) vive come riga nella tabella mobile_passes inclusa nel pacchetto.
Consegnare il pass a un utente
Quindi nell'esempio precedente, la variabile $mobilePass contiene un modello Eloquent MobilePass. Interagisce bene con le parti di Laravel che già conosci. Ecco alcuni modi per usarlo e inviare un mobile pass a un utente:
Restituiscilo direttamente da un controller. Il modello implementa Responsable, quindi il pacchetto si occupa della firma e della distribuzione del file .pkpass.
// in un controller
return $mobilePass;Allega a una mail in uscita. Il modello implementa anche Attachable, il che significa che puoi inserirlo nel metodo attachments() di un Mailable e Laravel si occupa del resto.
class FlightBooked extends Mailable
{
public function __construct(public MobilePass $mobilePass) {}
public function attachments(): array
{
return [$this->mobilePass];
}
}L'utente tocca, vede l'anteprima del pass in Apple Wallet e tocca Aggiungi.
Apple quindi richiama la tua app per registrare il dispositivo sul pass. Il pacchetto gestisce quell'endpoint e memorizza la registrazione. Quel collegamento tra pass e dispositivo è ciò che ti permette di inviare aggiornamenti in seguito.
Inviare un aggiornamento in tempo reale
Ecco la parte che preferisco. Se un posto viene riassegnato o un gate cambia, puoi aggiornare il pass dalla tua app e la versione sul telefono dell'utente si aggiorna entro un minuto, senza che l'utente faccia nulla.
$mobilePass->updateField('seat', '13A');Sotto il cofano, il pacchetto lancia un job che notifica Apple tramite APNs. Apple pinga il dispositivo. Il dispositivo recupera la nuova versione dal tuo server. Wallet sostituisce il vecchio pass con il nuovo.
Ora tutto ciò avviene in silenzio, senza avvisare l'utente. Se vuoi che l'utente veda una notifica quando il valore cambia, passa un changeMessage:
$mobilePass->updateField(
'seat',
'13A',
changeMessage: 'Il tuo posto è stato cambiato in :value',
);Molto bello! Se tocchi quella notifica, noterai che Passbook evidenzia cosa è cambiato.
Anche Google Wallet è supportato
Google Wallet funziona in modo leggermente diverso. Google vuole che dichiari una Class una volta (un modello condiviso per un lotto di pass) e poi emetta Oggetti individuali contro quella classe. Il pacchetto copre entrambi i casi.
use Spatie\LaravelMobilePass\Builders\Google\EventTicketPassBuilder;
use Spatie\LaravelMobilePass\Enums\BarcodeType;
$mobilePass = EventTicketPassBuilder::make()
->setClass('spring-tour-2026')
->setAttendeeName('Mary Smith')
->setSection('Piano A')
->setRow('12')
->setSeat('24')
->setBarcode(BarcodeType::Qr, 'TICKET-12345')
->save();Restituire $mobilePass da un controller fa la cosa giusta su entrambe le piattaforme. Gli utenti Android vengono reindirizzati all'URL di salvataggio di Google Wallet. Gli utenti iPhone ricevono il download del .pkpass. L'implementazione di Responsable sceglie la risposta giusta per la piattaforma per cui è stato costruito il pass.
Altre cose utili da sapere
Immagina la carta d'imbarco di prima. La dai all'utente tre giorni prima del volo. Lui la installa e si dimentica che esista. Un'ora prima della partenza, o nel momento in cui entra in aeroporto, il pass appare sulla schermata di blocco senza che lui faccia nulla. Quando arriva al gate, il suo pollice è già lì.
Questo trucco si chiama rilevanza del pass, e configurarlo richiede due chiamate sul builder:
$builder
->addLocation(latitude: 25.2528, longitude: 55.3644)
->setRelevantDate($flight->departs_at);La posizione attiva la geofence. La data attiva l'orologio. Combina entrambi e Wallet mostrerà il pass nel momento e nel luogo giusti. È il piccolo dettaglio che fa sembrare un pass Wallet come se appartenesse al dispositivo invece che a una email.
I pass non devono restare per sempre una volta esaurito il loro scopo. Quando un coupon è stato riscattato o un biglietto è di ieri sera, chiama expire() sul modello e Wallet lo oscurerà e lo toglierà dalla schermata di blocco:
$mobilePass->expire();Se emetti pass Google Wallet, probabilmente vorrai sapere quando qualcuno li salva effettivamente nel suo Wallet, o in seguito li rimuove. Google pinga la tua app in entrambi i casi. Il pacchetto ascolta quei callback e lancia normali eventi Laravel a cui puoi iscriverti:
Event::listen(GoogleMobilePassSaved::class, function (GoogleMobilePassSaved $event) {
// $event->mobilePass ora è nel Wallet dell'utente
});Aggiungi un listener se vuoi registrare le attivazioni, inviare una mail di ringraziamento o avviare qualsiasi altro flusso. È il tipo di integrazione che altrimenti richiederebbe leggere le specifiche dei callback di Google e firmare JWT a mano. Non dovresti doverlo fare.
Provalo dal vivo
Abbiamo creato una demo su mobile-pass-demo.spatie.be. Scegli un tipo di pass nella pagina iniziale, scansiona il codice QR con il tuo iPhone, installa il pass e premi il pulsante simula-modifica. Il tuo Wallet scaricherà la nuova versione un attimo dopo. Il codice sorgente completo dell'app demo è su GitHub se vuoi vedere come tutto si collega.
In conclusione
A Laracon India 2025, Dan Johnson mi mostrò un prototipo su cui stava lavorando per generare pass Apple Wallet. L'idea mi è piaciuta molto, abbiamo deciso di collaborare, e questo pacchetto è ciò che è venuto fuori. Ci è voluto un po', ma alla fine gli abbiamo dato la rifinitura che volevamo.
I pass mobili non sono una novità. Apple ha lanciato Wallet (allora chiamato Passbook) con iOS 6 nel 2012, e Google ha seguito con i propri pass Wallet qualche anno dopo.
Dato che esistono da così tanto tempo, sono rimasto sorpreso che nessuno avesse ancora creato un pacchetto Laravel solido per nessuna delle due piattaforme. Fortunatamente ora ce n'è uno. Spero che vi piaccia!
Il codice è su GitHub. La documentazione completa è su spatie.be.
Questo è uno dei tanti pacchetti che abbiamo creato a Spatie. Se vuoi sostenere il nostro lavoro open source, considera l'acquisto di uno dei nostri prodotti a pagamento.
Altri articoli recenti
Laravel AI 1.1 e 1.2: Agent Skills, Cohere e structured output più solidi
Le release 1.1.0 e 1.2.0 di laravel/ai portano gli Agent Skills, l'approvazione obbligatoria per i tool built-in e nuovi provider come Cohere e Laya self-hosted. Sul fronte qualità arrivano i fix allo structured output per Bedrock e il supporto alle provider options. Aggiornati anche i modelli di default, con Claude 4.7+ che ignora i sampling params.
Laravel 13.35.0: scheduler più controllabile, code più flessibili e response Markdown
Laravel 13.35.0 porta Schedule::alwaysOnOneServer(), il supporto a schedule:interrupt per i comandi di lunga durata, --memory in percentuale per queue:work e il nuovo metodo markdown() sulla response factory. Tante piccole migliorie anche a test, view compilate in parallelo e dischi local.
BashBox: un interprete Bash in sandbox per agenti AI in PHP
BashBox è un interprete bash scritto in puro PHP che permette di eseguire gli script generati dagli agenti AI senza mai ricorrere a proc_open, exec o shell_exec. Ogni comando è una classe PHP che lavora su un filesystem virtuale, con limiti di esecuzione, quote disco e accesso di rete configurabili. Ideale per chi sviluppa agenti con il Laravel AI SDK o altre librerie simili.