Scopri in che modo il passaggio alle PWA ha aiutato l'attività di MishiPay.
MishiPay consente agli acquirenti di scansionare e pagare i propri acquisti con lo smartphone, anziché perdere tempo in coda alla cassa. Con la tecnologia Scan & Go di MishiPay, gli acquirenti possono utilizzare il proprio smartphone per scansionare il codice a barre degli articoli e pagarli, per poi uscire dal negozio. Gli studi rivelano che ogni anno le code in negozio costano al settore della vendita al dettaglio globale 200 miliardi di dollari.
La nostra tecnologia si basa sulle funzionalità hardware dei dispositivi, come i sensori GPS e le fotocamere, che consentono agli utenti di individuare i negozi abilitati a MishiPay, scansionare i codici a barre degli articoli all'interno del negozio fisico e poi pagare utilizzando il metodo di pagamento digitale di loro scelta. Le versioni iniziali della nostra tecnologia Scan & Go erano applicazioni specifiche per le piattaforme iOS e Android e i primi utenti hanno apprezzato molto la tecnologia. Continua a leggere per scoprire come il passaggio a una PWA ha aumentato le transazioni di 10 volte e ha risparmiato 2 anni e mezzo di code.
10×
Aumento delle transazioni
2 anni e mezzo
Queuing saved
La sfida
Gli utenti trovano la nostra tecnologia estremamente utile quando aspettano in coda o alla cassa, in quanto consente loro di saltare la coda e di avere un'esperienza fluida in negozio. Tuttavia, la difficoltà di scaricare un'applicazione Android o iOS ha fatto sì che gli utenti non scegliessero la nostra tecnologia nonostante il valore. Era una sfida sempre più difficile per MishiPay e avevamo bisogno di aumentare l'adozione da parte degli utenti con una barriera all'ingresso inferiore.
Soluzione
I nostri sforzi per creare e lanciare la PWA ci hanno aiutato a eliminare il problema dell'installazione e hanno incoraggiato i nuovi utenti a provare la nostra tecnologia all'interno di un negozio fisico, a saltare la coda e a vivere un'esperienza di acquisto senza interruzioni. Dal lancio, abbiamo registrato un aumento massiccio dell'adozione da parte degli utenti della nostra PWA rispetto alle nostre applicazioni specifiche per piattaforma.
Approfondimento tecnico
Individuare i negozi abilitati a MishiPay
Per abilitare questa funzionalità, ci affidiamo all'API
getCurrentPosition()
insieme a una soluzione di fallback basata su IP.
const geoOptions = {
timeout: 10 * 1000,
enableHighAccuracy: true,
maximumAge: 0,
};
window.navigator.geolocation.getCurrentPosition(
(position) => {
const cords = position.coords;
console.log(`Latitude : ${cords.latitude}`);
console.log(`Longitude : ${cords.longitude}`);
},
(error) => {
console.debug(`Error: ${error.code}:${error.message}`);
/**
* Invoke the IP based location services
* to fetch the latitude and longitude of the user.
*/
},
geoOptions,
);
Questo approccio ha funzionato bene nelle versioni precedenti dell'app, ma in seguito si è rivelato un enorme problema per gli utenti di MishiPay per i seguenti motivi:
- Imprecisioni della posizione nelle soluzioni di riserva basate sull'IP.
- Un elenco crescente di negozi abilitati a MishiPay per regione richiede agli utenti di scorrere un elenco e identificare il negozio corretto.
- A volte gli utenti scelgono per errore il negozio sbagliato, causando la registrazione errata degli acquisti.
Per risolvere questi problemi, abbiamo incorporato codici QR geolocalizzati univoci nei display in negozio per ogni
negozio. Ha aperto la strada a un'esperienza di onboarding più rapida. Gli utenti scansionano i codici QR geolocalizzati stampati sul materiale di marketing presente nei negozi per accedere all'applicazione web Scan & Go.
In questo modo, possono evitare di digitare l'indirizzo web mishipay.shop per accedere al servizio.
Scansione dei prodotti
Una funzionalità principale dell'app MishiPay è la scansione dei codici a barre, che consente agli utenti di scansionare i propri acquisti e visualizzare il totale corrente prima ancora di raggiungere una cassa.
Per creare un'esperienza di scansione sul web, abbiamo identificato tre livelli principali.

Stream video
Con l'aiuto del metodo
getUserMedia(), possiamo
accedere alla videocamera posteriore dell'utente con i vincoli elencati di seguito. L'invocazione del metodo
attiva automaticamente una richiesta per gli utenti di accettare o negare l'accesso alla fotocamera. Una volta ottenuto l'accesso allo stream video, possiamo trasmetterlo a un elemento video come mostrato di seguito:
/**
* Video Stream Layer
* https://developer.mozilla.org/docs/Web/API/MediaDevices/getUserMedia
*/
const canvasEle = document.getElementById('canvas');
const videoEle = document.getElementById('videoElement');
const canvasCtx = canvasEle.getContext('2d');
fetchVideoStream();
function fetchVideoStream() {
let constraints = { video: { facingMode: 'environment' } };
if (navigator.mediaDevices !== undefined) {
navigator.mediaDevices
.getUserMedia(constraints)
.then((stream) => {
videoEle.srcObject = stream;
videoStream = stream;
videoEle.play();
// Initiate frame capture - Processing Layer.
})
.catch((error) => {
console.debug(error);
console.warn(`Failed to access the stream:${error.name}`);
});
} else {
console.warn(`getUserMedia API not supported!!`);
}
}
Livello di elaborazione
Per rilevare un codice a barre in un determinato stream video, dobbiamo acquisire periodicamente i frame e trasferirli
al livello del decodificatore. Per acquisire un frame, disegniamo gli stream da VideoElement su
un HTMLCanvasElement utilizzando il
metodo drawImage()
dell'API Canvas.
/**
* Processing Layer - Frame Capture
* https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas
*/
async function captureFrames() {
if (videoEle.readyState === videoEle.HAVE_ENOUGH_DATA) {
const canvasHeight = (canvasEle.height = videoEle.videoHeight);
const canvasWidth = (canvasEle.width = videoEle.videoWidth);
canvasCtx.drawImage(videoEle, 0, 0, canvasWidth, canvasHeight);
// Transfer the `canvasEle` to the decoder for barcode detection.
const result = await decodeBarcode(canvasEle);
} else {
console.log('Video feed not available yet');
}
}
Per i casi d'uso avanzati, questo livello esegue anche alcune attività di pre-elaborazione come il ritaglio,
la rotazione o la conversione in scala di grigi. Queste attività possono richiedere un utilizzo elevato della CPU e causare la mancata risposta dell'applicazione, dato che la scansione dei codici a barre è un'operazione a lunga esecuzione. Con l'aiuto dell'API
OffscreenCanvas, possiamo scaricare
l'attività che consuma molta CPU in un web worker. Sui dispositivi che supportano l'accelerazione grafica hardware, l'API WebGL e il relativo
WebGL2RenderingContext possono
ottimizzare i guadagni nelle attività di pre-elaborazione che richiedono un utilizzo elevato della CPU.
Livello del decodificatore
L'ultimo livello è il livello del decodificatore, responsabile della decodifica dei codici a barre dai frame
acquisiti dal livello di elaborazione. Grazie all'API Shape Detection (che non è ancora disponibile su tutti i browser), il browser stesso decodifica il codice a barre da un ImageBitmapSource, che può essere un elemento img, un elemento SVG image, un elemento video, un elemento canvas, un oggetto Blob, un oggetto ImageData o un oggetto ImageBitmap.

/**
* Barcode Decoder with Shape Detection API
* https://web.dev/shape-detection/
*/
async function decodeBarcode(canvas) {
const formats = [
'aztec',
'code_128',
'code_39',
'code_93',
'codabar',
'data_matrix',
'ean_13',
'ean_8',
'itf',
'pdf417',
'qr_code',
'upc_a',
'upc_e',
];
const barcodeDetector = new window.BarcodeDetector({
formats,
});
try {
const barcodes = await barcodeDetector.detect(canvas);
console.log(barcodes);
return barcodes.length > 0 ? barcodes[0]['rawValue'] : undefined;
} catch (e) {
throw e;
}
}
Per i dispositivi che non supportano ancora l'API Shape Detection, è necessaria una soluzione di riserva per decodificare
i codici a barre. L'API Shape Detection espone un metodo getSupportedFormats() che consente di passare dall'API Shape Detection alla soluzione di riserva.
// Feature detection.
if (!('BarceodeDetector' in window)) {
return;
}
// Check supported barcode formats.
BarcodeDetector.getSupportedFormats()
.then((supportedFormats) => {
supportedFormats.forEach((format) => console.log(format));
});

Soluzione di riserva
Sono disponibili diverse librerie di scansione open source e aziendali che possono essere facilmente integrate con qualsiasi applicazione web per implementare la scansione. Ecco alcune delle librerie consigliate da MishiPay.
Tutte queste librerie sono SDK completi che compongono tutti i livelli descritti. Inoltre, espongono interfacce per supportare varie operazioni di scansione. A seconda dei formati dei codici a barre e della velocità di rilevamento necessaria per lo scenario aziendale, la decisione può essere tra soluzioni Wasm e non Wasm. Nonostante il sovraccarico dovuto alla necessità di una risorsa aggiuntiva (Wasm) per decodificare il codice a barre, le soluzioni Wasm superano la soluzione non Wasm in termini di precisione.
Scandit è stata la nostra scelta principale. Supporta tutti i formati di codici a barre richiesti per i nostri casi d'uso aziendali e supera tutte le librerie open source disponibili in termini di velocità di scansione.
Il futuro della scansione
Una volta che l'API Shape Detection sarà completamente supportata da tutti i principali browser, potremmo avere un
nuovo elemento HTML <scanner> con le funzionalità necessarie per uno scanner di codici a barre. Il team di ingegneria di MishiPay ritiene che la funzionalità di scansione dei codici a barre possa essere un nuovo elemento HTML grazie al numero crescente di librerie open source e con licenza che consentono esperienze come Scan & Go e molte altre.
Conclusione
L'affaticamento delle app è un problema che gli sviluppatori devono affrontare quando i loro prodotti entrano nel mercato. Gli utenti spesso vogliono comprendere il valore che un'applicazione offre loro prima di scaricarla. In un negozio, dove MishiPay fa risparmiare tempo agli acquirenti e migliora la loro esperienza, è controintuitivo aspettare un download prima di poter utilizzare un'applicazione. È qui che entra in gioco la nostra PWA.
Eliminando la barriera all'ingresso, abbiamo aumentato le transazioni di 10 volte e consentito ai nostri utenti di risparmiare 2 anni e mezzo di attesa in coda.
Ringraziamenti
Questo articolo è stato rivisto da Joe Medley.