Découvrez comment le passage à une PWA a aidé MishiPay à développer son activité.
MishiPay permet aux clients de scanner et de payer leurs achats avec leur smartphone, au lieu de perdre du temps à faire la queue à la caisse. Grâce à la technologie Scan & Go de MishiPay, les clients peuvent utiliser leur propre téléphone pour scanner le code-barres des articles et les payer, puis quitter le magasin. Des études révèlent que les files d'attente en magasin coûtent chaque année 200 milliards de dollars au secteur mondial de la vente au détail.
Notre technologie repose sur les capacités matérielles des appareils, telles que les capteurs GPS et les caméras, qui permettent aux utilisateurs de localiser les magasins compatibles avec MishiPay, de scanner les codes-barres des articles dans le magasin physique, puis de payer avec le mode de paiement numérique de leur choix. Les premières versions de notre technologie Scan & Go étaient des applications iOS et Android spécifiques à une plate-forme. Les premiers utilisateurs ont adoré cette technologie. Lisez la suite pour découvrir comment le passage à une PWA a multiplié les transactions par 10 et permis d'économiser 2,5 ans de temps d'attente !
10×
Augmentation du nombre de transactions
2,5 ans
File d'attente enregistrée
Défi
Les utilisateurs trouvent notre technologie extrêmement utile lorsqu'ils font la queue ou attendent à la caisse, car elle leur permet de passer devant tout le monde et de profiter d'une expérience fluide en magasin. Cependant, la difficulté de télécharger une application Android ou iOS a dissuadé les utilisateurs de choisir notre technologie malgré sa valeur. C'était un défi de plus en plus difficile pour MishiPay, et nous devions augmenter l'adoption par les utilisateurs avec un seuil d'entrée plus bas.
Solution
Nos efforts pour créer et lancer la PWA nous ont aidés à supprimer les tracas liés à l'installation et ont encouragé de nouveaux utilisateurs à essayer notre technologie dans un magasin physique, à éviter la file d'attente et à profiter d'une expérience d'achat fluide. Depuis le lancement, nous avons constaté une augmentation massive de l'adoption par les utilisateurs de notre PWA par rapport à nos applications spécifiques à la plate-forme.
Détails techniques
Trouver les magasins compatibles avec MishiPay
Pour activer cette fonctionnalité, nous nous appuyons sur l'API getCurrentPosition() ainsi que sur une solution de secours basée sur l'adresse 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,
);
Cette approche fonctionnait bien dans les premières versions de l'application, mais s'est avérée être un énorme point sensible pour les utilisateurs de MishiPay pour les raisons suivantes :
- Imprécisions de la localisation dans les solutions de secours basées sur l'adresse IP.
- La liste des magasins compatibles avec MishiPay par région étant de plus en plus longue, les utilisateurs doivent la faire défiler et identifier le bon magasin.
- Il arrive que les utilisateurs choisissent le mauvais magasin par erreur, ce qui entraîne un enregistrement incorrect des achats.
Pour résoudre ces problèmes, nous avons intégré des codes QR géolocalisés uniques sur les présentoirs en magasin pour chaque magasin. Cela a permis d'accélérer l'intégration. Les utilisateurs scannent les codes QR géolocalisés imprimés sur les supports marketing présents dans les magasins pour accéder à l'application Web Scan & Go.
Ils n'ont ainsi pas besoin de saisir l'adresse Web mishipay.shop pour accéder au service.
Scanner des produits
La fonctionnalité principale de l'application MishiPay est la lecture de codes-barres, qui permet à nos utilisateurs de scanner leurs propres achats et de voir le total en cours avant même d'avoir atteint une caisse.
Pour créer une expérience de lecture sur le Web, nous avons identifié trois couches principales.

Flux vidéo
Grâce à la méthode getUserMedia(), nous pouvons accéder à la caméra de recul de l'utilisateur avec les contraintes listées ci-dessous. L'appel de la méthode déclenche automatiquement une invite demandant aux utilisateurs d'accepter ou de refuser l'accès à leur caméra. Une fois que nous avons accès au flux vidéo, nous pouvons le relayer vers un élément vidéo, comme indiqué ci-dessous :
/**
* 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!!`);
}
}
Couche de traitement
Pour détecter un code-barres dans un flux vidéo donné, nous devons capturer régulièrement des images et les transférer vers la couche de décodage. Pour capturer un frame, nous dessinons les flux de VideoElement sur un HTMLCanvasElement à l'aide de la méthode drawImage() de l'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');
}
}
Pour les cas d'utilisation avancés, cette couche effectue également des tâches de prétraitement telles que le recadrage, la rotation ou la conversion en niveaux de gris. Ces tâches peuvent être gourmandes en ressources processeur et rendre l'application non réactive, car la lecture de codes-barres est une opération de longue durée. Grâce à l'API OffscreenCanvas, nous pouvons décharger la tâche gourmande en ressources processeur sur un Web Worker. Sur les appareils compatibles avec l'accélération graphique matérielle, l'API WebGL et son WebGL2RenderingContext peuvent optimiser les gains sur les tâches de prétraitement gourmandes en ressources processeur.
Couche de décodage
La dernière couche est la couche de décodage, qui est chargée de décoder les codes-barres à partir des frames capturées par la couche de traitement. Grâce à l'API Shape Detection (qui n'est pas encore disponible sur tous les navigateurs), le navigateur lui-même décode le code-barres à partir d'un ImageBitmapSource, qui peut être un élément img, un élément SVG image, un élément video, un élément canvas, un objet Blob, un objet ImageData ou un objet 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;
}
}
Pour les appareils qui ne sont pas encore compatibles avec l'API Shape Detection, nous avons besoin d'une solution de secours pour décoder les codes-barres. L'API Shape Detection expose une méthode getSupportedFormats() qui permet de basculer entre l'API Shape Detection et la solution de secours.
// Feature detection.
if (!('BarceodeDetector' in window)) {
return;
}
// Check supported barcode formats.
BarcodeDetector.getSupportedFormats()
.then((supportedFormats) => {
supportedFormats.forEach((format) => console.log(format));
});

Solution de remplacement
Plusieurs bibliothèques d'analyse Open Source et d'entreprise sont disponibles et peuvent être facilement intégrées à n'importe quelle application Web pour implémenter l'analyse. Voici quelques-unes des bibliothèques recommandées par MishiPay.
Toutes ces bibliothèques sont des SDK à part entière qui composent toutes les couches abordées. Ils exposent également des interfaces pour prendre en charge diverses opérations d'analyse. Selon les formats de codes-barres et la vitesse de détection nécessaires pour le cas d'utilisation, la décision peut se faire entre les solutions Wasm et non-Wasm. Malgré la surcharge liée à la nécessité d'une ressource supplémentaire (Wasm) pour décoder le code-barres, les solutions Wasm surpassent la solution non-Wasm en termes de précision.
Nous avons principalement choisi Scandit. Il est compatible avec tous les formats de codes-barres requis pour nos cas d'utilisation professionnels et surpasse toutes les bibliothèques Open Source disponibles en termes de vitesse de lecture.
L'avenir de l'analyse
Une fois que l'API Shape Detection sera entièrement compatible avec tous les principaux navigateurs, nous pourrions potentiellement disposer d'un nouvel élément HTML <scanner> doté des fonctionnalités requises pour un lecteur de codes-barres. L'équipe d'ingénierie de MishiPay estime que la fonctionnalité de lecture de codes-barres constitue un cas d'utilisation solide pour un nouvel élément HTML, en raison du nombre croissant de bibliothèques Open Source et sous licence qui permettent des expériences telles que le Scan & Go et bien d'autres.
Conclusion
La lassitude des applications est un problème auquel les développeurs sont confrontés lorsque leurs produits sont mis sur le marché. Les utilisateurs souhaitent souvent comprendre la valeur qu'une application leur apporte avant de la télécharger. Dans un magasin, où MishiPay permet aux clients de gagner du temps et d'améliorer leur expérience, il est illogique de devoir attendre un téléchargement avant de pouvoir utiliser une application. C'est là que notre PWA peut vous aider.
En éliminant la barrière à l'entrée, nous avons multiplié nos transactions par 10 et permis à nos utilisateurs de gagner 2,5 ans d'attente dans la file d'attente.
Remerciements
Cet article a été examiné par Joe Medley.