Erfahren Sie, wie die Umstellung auf eine PWA MishiPay geholfen hat.
Mit MishiPay können Kunden ihre Einkäufe mit dem Smartphone scannen und bezahlen, anstatt an der Kasse anzustehen. Mit der Scan & Go-Technologie von MishiPay können Kunden mit ihrem eigenen Smartphone den Barcode auf Artikeln scannen und bezahlen. Anschließend können sie das Geschäft einfach verlassen. Studien zeigen, dass das Anstehen im Geschäft den globalen Einzelhandel jährlich etwa 200 Milliarden $kostet.
Unsere Technologie basiert auf der Hardware von Geräten, z. B. GPS-Sensoren und Kameras, mit denen Nutzer Geschäfte finden können, die MishiPay unterstützen, Artikelbarcodes im Geschäft scannen und dann mit der digitalen Zahlungsmethode ihrer Wahl bezahlen können. Die ersten Versionen unserer Scan & Go-Technologie waren plattformspezifische iOS- und Android-Anwendungen, die bei den ersten Nutzern sehr gut ankamen. Lesen Sie weiter, um zu erfahren, wie durch die Umstellung auf eine PWA die Anzahl der Transaktionen verzehnfacht und 2,5 Jahre Wartezeit eingespart werden konnten.
10×
Mehr Transaktionen
2,5 Jahre
Warteschlange gespeichert
Herausforderung
Nutzer finden unsere Technologie sehr hilfreich, wenn sie in einer Warteschlange oder an der Kasse warten müssen, da sie die Warteschlange überspringen und einen reibungslosen Einkauf im Geschäft genießen können. Da es aber so umständlich war, eine Android- oder iOS-App herunterzuladen, entschieden sich die Nutzer trotz des Mehrwerts nicht für unsere Technologie. Das war eine wachsende Herausforderung für MishiPay. Wir mussten die Nutzerakzeptanz mit einer niedrigeren Einstiegshürde steigern.
Lösung
Die Entwicklung und Einführung der PWA hat uns geholfen, die Installation zu vereinfachen und neue Nutzer zu ermutigen, unsere Technologie in einem Ladengeschäft auszuprobieren, die Warteschlange zu überspringen und ein reibungsloses Einkaufserlebnis zu genießen. Seit der Einführung haben wir im Vergleich zu unseren plattformspezifischen Anwendungen einen massiven Anstieg der Nutzerzahlen unserer PWA verzeichnet.

Technische Details
MishiPay-fähige Geschäfte finden
Für diese Funktion nutzen wir die getCurrentPosition()
API sowie eine IP-basierte Fallback-Lösung.
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,
);
Dieses Vorgehen hat in den früheren Versionen der App gut funktioniert, erwies sich aber später aus den folgenden Gründen als großes Problem für die Nutzer von MishiPay:
- Ungenauigkeiten bei der Standortbestimmung in den IP-basierten Fallback-Lösungen.
- Eine wachsende Liste von MishiPay-fähigen Geschäften pro Region erfordert, dass Nutzer eine Liste durchscrollen und das richtige Geschäft identifizieren.
- Nutzer wählen gelegentlich versehentlich das falsche Geschäft aus, wodurch die Käufe falsch erfasst werden.
Um diese Probleme zu beheben, haben wir eindeutige geolokalisierte QR-Codes in die Displays für jedes Geschäft eingebettet. Das Onboarding wurde dadurch beschleunigt. Nutzer scannen einfach die geolokalisierten QR-Codes, die auf Marketingmaterialien in den Geschäften aufgedruckt sind, um auf die Scan & Go-Webanwendung zuzugreifen.
So müssen sie nicht die Webadresse mishipay.shop
eingeben, um auf den Dienst zuzugreifen.
Produkte scannen
Eine Kernfunktion der MishiPay App ist das Scannen von Barcodes. So können unsere Nutzer ihre Einkäufe selbst scannen und den laufenden Gesamtbetrag sehen, noch bevor sie eine Kasse erreicht haben.
Um das Scannen im Web zu ermöglichen, haben wir drei grundlegende Ebenen definiert.
Videostream
Mithilfe der Methode getUserMedia()
können wir unter den unten aufgeführten Einschränkungen auf die Rückfahrkamera des Nutzers zugreifen. Durch den Aufruf der Methode wird automatisch eine Aufforderung für Nutzer ausgelöst, den Zugriff auf ihre Kamera zu akzeptieren oder abzulehnen. Sobald wir Zugriff auf den Videostream haben, können wir ihn an ein Videoelement weiterleiten, wie unten dargestellt:
/**
* 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!!`);
}
}
Verarbeitungsebene
Um einen Barcode in einem bestimmten Videostream zu erkennen, müssen wir regelmäßig Frames erfassen und an die Decodierungsebene übertragen. Um einen Frame zu erfassen, zeichnen wir die Streams aus VideoElement
einfach auf ein HTMLCanvasElement
mit der Methode drawImage()
der Canvas API.
/**
* 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');
}
}
Für erweiterte Anwendungsfälle werden in dieser Ebene auch einige Vorverarbeitungsaufgaben wie Zuschneiden, Drehen oder Konvertieren in Graustufen ausgeführt. Diese Aufgaben können CPU-intensiv sein und dazu führen, dass die Anwendung nicht mehr reagiert, da das Scannen von Barcodes ein langwieriger Vorgang ist. Mithilfe der OffscreenCanvas-API können wir die CPU-intensive Aufgabe an einen Web-Worker auslagern. Auf Geräten, die hardwarebeschleunigte Grafikdarstellung unterstützen, können mit der WebGL API und ihrem WebGL2RenderingContext
die CPU-intensiven Vorverarbeitungsaufgaben optimiert werden.
Decoderebene
Die letzte Ebene ist die Decodierungsebene, die für das Decodieren von Barcodes aus den von der Verarbeitungsebene erfassten Frames verantwortlich ist. Dank der Shape Detection API (die noch nicht in allen Browsern verfügbar ist) decodiert der Browser den Barcode aus einem ImageBitmapSource
, das ein img
-Element, ein SVG-image
-Element, ein video
-Element, ein canvas
-Element, ein Blob
-Objekt, ein ImageData
-Objekt oder ein ImageBitmap
-Objekt sein kann.
/**
* 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;
}
}
Für Geräte, die die Shape Detection API noch nicht unterstützen, benötigen wir eine Fallback-Lösung zum Decodieren der Barcodes. Die Shape Detection API stellt eine getSupportedFormats()
-Methode zur Verfügung, mit der zwischen der Shape Detection API und der Fallback-Lösung gewechselt werden kann.
// Feature detection.
if (!('BarceodeDetector' in window)) {
return;
}
// Check supported barcode formats.
BarcodeDetector.getSupportedFormats()
.then((supportedFormats) => {
supportedFormats.forEach((format) => console.log(format));
});
Fallback-Lösung
Es sind mehrere Open-Source- und Enterprise-Scanning-Bibliotheken verfügbar, die sich einfach in jede Webanwendung einbinden lassen, um das Scannen zu implementieren. Hier sind einige der Bibliotheken, die MishiPay empfiehlt.
Alle oben genannten Bibliotheken sind vollwertige SDKs, die alle oben beschriebenen Ebenen umfassen. Außerdem werden Schnittstellen für verschiedene Scanvorgänge bereitgestellt. Je nach den für den Anwendungsfall erforderlichen Barcodeformaten und der Erkennungsgeschwindigkeit kann zwischen Wasm- und Nicht-Wasm-Lösungen entschieden werden. Trotz des zusätzlichen Aufwands, der durch die erforderliche zusätzliche Ressource (Wasm) zum Decodieren des Barcodes entsteht, sind Wasm-Lösungen in Bezug auf die Genauigkeit der Nicht-Wasm-Lösung überlegen.
Scandit war unsere erste Wahl. Es unterstützt alle Barcodeformate, die für unsere Anwendungsfälle erforderlich sind, und ist schneller als alle verfügbaren Open-Source-Bibliotheken.
Die Zukunft des Scannens
Sobald die Shape Detection API von allen wichtigen Browsern vollständig unterstützt wird, könnte es ein neues HTML-Element <scanner>
geben, das die für einen Barcodescanner erforderlichen Funktionen bietet. Das Engineering-Team von MishiPay ist der Meinung, dass es einen soliden Anwendungsfall für die Barcode-Scanning-Funktion als neues HTML-Element gibt, da die Anzahl der Open-Source- und lizenzierten Bibliotheken, die Funktionen wie „Scan & Go“ und viele andere ermöglichen, stetig wächst.
Fazit
App-Müdigkeit ist ein Problem, mit dem Entwickler konfrontiert werden, wenn ihre Produkte auf den Markt kommen. Nutzer möchten oft wissen, welchen Nutzen eine App für sie hat, bevor sie sie herunterladen. In einem Geschäft, in dem MishiPay den Kunden Zeit spart und das Einkaufserlebnis verbessert, ist es kontraintuitiv, auf einen Download zu warten, bevor sie eine Anwendung nutzen können. Hier kann unsere PWA helfen. Durch die Beseitigung der Einstiegshürde haben wir die Anzahl unserer Transaktionen verzehnfacht und unseren Nutzern 2, 5 Jahre Wartezeit erspart.
Danksagungen
Dieser Artikel wurde von Joe Medley überprüft.