PWA MishiPay zwiększa liczbę transakcji 10 razy i pozwala zaoszczędzić 2,5 roku w kolejce

Dowiedz się, jak przejście na PWA pomogło firmie MishiPay.

MishiPay umożliwia kupującym skanowanie i płacenie za zakupy za pomocą smartfonów, dzięki czemu nie muszą tracić czasu na stanie w kolejce do kasy. Dzięki technologii Scan & Go dostępnej w MishiPay klienci mogą za pomocą własnego telefonu zeskanować kod kreskowy produktu i zapłacić za niego, a następnie po prostu wyjść ze sklepu. Badania pokazują, że kolejka w sklepach stacjonarnych pochłania ok. 200 miliardów dolarów rocznie w przypadku globalnego sektora handlu detalicznego.

Nasza technologia opiera się na możliwościach sprzętowych urządzenia, takich jak czujniki GPS i kamery, które umożliwiają użytkownikom znajdowanie sklepów obsługujących MishiPay, skanowanie kodów kreskowych produktów w sklepie stacjonarnym, a następnie płacenie za pomocą wybranej formy płatności cyfrowej. Początkowe wersje technologii Skanuj i jedź były aplikacjami na iOS i Androida. Na początku spodobały się one użytkownikom. Przeczytaj artykuł, aby dowiedzieć się, jak przejście na PWA zwiększyło liczbę transakcji 10-krotnie i zaoszczędziło 2,5 roku oczekiwania w kolejce.

    10×

    Wzrost liczby transakcji

    2,5 roku

    Kolejka została zapisana

Wyzwanie

Użytkownicy uważają, że nasza technologia jest bardzo przydatna, gdy czekają w kolejce lub przy kasie, ponieważ pozwala im pominąć kolejkę i płynnie poruszać się po sklepie. Jednak konieczność pobrania aplikacji na Androida lub iOS sprawiła, że użytkownicy nie wybrali naszej technologii, mimo jej wartości. Było to coraz większe wyzwanie dla MishiPay, ponieważ musieliśmy zwiększyć liczbę użytkowników przy jednoczesnym obniżeniu progu wejścia.

Rozwiązanie

Dzięki wysiłkom włożonym w stworzenie i uruchomienie aplikacji internetowej udało nam się wyeliminować problemy związane z instalacją. Zachęciliśmy nowych użytkowników do wypróbowania naszej technologii w sklepie stacjonarnym, pominięcia kolejki i skorzystania z bezproblemowego procesu zakupowego. Od momentu wprowadzenia tej usługi obserwujemy ogromny wzrost wykorzystania naszej aplikacji PWA w porównaniu z aplikacjami przeznaczonymi wyłącznie na tę platformę.

Porównanie bezpośredniego uruchamiania aplikacji PWA (po lewej, szybciej) z instalowaniem i uruchamianiem aplikacji na Androida (po prawej, wolniej).
Transakcje według platformy. ¡OS: 16397 (3,98%). Android: 13769 (3,34%). Internet: 382 184 (92,68%).
Większość transakcji jest realizowanych w internecie.

Szczegółowa analiza techniczna

Znajdowanie sklepów obsługujących MishiPay

Aby włączyć tę funkcję, korzystamy z interfejsu API getCurrentPosition() oraz rozwiązania zapasowego opartego na adresie 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,
);

Takie podejście sprawdzało się w wcześniejszych wersjach aplikacji, ale później okazało się, że jest bardzo uciążliwe dla użytkowników MishiPay z tych powodów:

  • niedokładne lokalizacje w przypadku rozwiązań zapasowych opartych na adresie IP;
  • Coraz większa liczba sklepów obsługujących MishiPay w poszczególnych regionach wymaga od użytkowników przewinięcia listy i zidentyfikowania odpowiedniego sklepu.
  • Czasami użytkownicy przypadkowo wybierają niewłaściwy sklep, co powoduje nieprawidłowe rejestrowanie zakupów.

Aby rozwiązać te problemy, w ramach każdego sklepu umieściliśmy na wyświetlaczach w sklepie stacjonarnym unikalne kody QR z lokalizacją. Dzięki temu proces wprowadzania w użycie jest szybszy. Użytkownicy skanują kody QR z lokalizacją geograficzną wydrukowane na materiałach marketingowych w sklepach, aby uzyskać dostęp do aplikacji internetowej Skanuj i idź. Dzięki temu nie muszą wpisywać adresu internetowego mishipay.shop, aby uzyskać dostęp do usługi.

Przebieg skanowania w sklepie za pomocą aplikacji PWA.

Skanowanie produktów

Podstawową funkcją aplikacji MishiPay jest skanowanie kodów kreskowych, ponieważ umożliwia użytkownikom skanowanie własnych zakupów i sprawdzanie łącznej kwoty jeszcze przed dotarciem do kasy.

Aby ułatwić skanowanie w internecie, zidentyfikowaliśmy 3 podstawowe warstwy.

Diagram przedstawiający 3 główne warstwy wątku: strumień wideo, warstwa przetwarzania i warstwa dekodera.

Strumień wideo

Za pomocą metody getUserMedia() możemy uzyskać dostęp do tylnej kamery użytkownika z ograniczeniami wymienionymi poniżej. Wywołanie tej metody automatycznie powoduje wyświetlenie użytkownikowi prośby o przyznanie lub odmowę dostępu do aparatu. Po uzyskaniu dostępu do strumienia wideo możemy przekazać go do elementu wideo w ten sposób:

/**
 * 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!!`);
  }
}

Warstwa przetwarzania

Aby wykryć kod kreskowy w strumieniu wideo, musimy okresowo rejestrować klatki i przesyłać je do warstwy dekodera. Aby uchwycić kadr, po prostu rysujemy strumień z VideoElement na HTMLCanvasElement za pomocą metody drawImage() interfejsu 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');
  }
}

W zaawansowanych przypadkach użycia ta warstwa wykonuje też niektóre zadania wstępnego przetwarzania danych, takie jak przycinanie, obracanie czy przekształcanie w skalę szarości. Te zadania mogą być wymagające pod względem procesora i mogą spowodować, że aplikacja przestanie odpowiadać, ponieważ skanowanie kodów kreskowych to długotrwała operacja. Za pomocą interfejsu OffscreenCanvas możemy przekazać zadanie mocno angażujące procesor do web workera. Na urządzeniach, które obsługują akcelerację graficzną sprzętową, interfejs WebGL API i WebGL2RenderingContext mogą optymalizować korzyści płynące z zadań wstępnych przetwarzania, które wymagają intensywnego wykorzystania procesora.

Warstwa dekodera

Ostatnią warstwą jest warstwa dekodera, która odpowiada za dekodowanie kodów kreskowych z klatek przechwycionych przez warstwę przetwarzania. Dzięki interfejsowi Shape Detection API (który nie jest jeszcze dostępny we wszystkich przeglądarkach) przeglądarka sama dekoduje kod kreskowy z elementu ImageBitmapSource, który może być elementem img, image, video, canvas, obiektem Blob, ImageData lub ImageBitmap.

Diagram przedstawiający 3 główne warstwy wątku: strumień wideo, warstwa przetwarzania i interfejs API wykrywania kształtów.

/**
 * 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;
  }
}

W przypadku urządzeń, które nie obsługują jeszcze interfejsu Shape Detection API, potrzebujemy rozwiązania zapasowego do dekodowania kodów kreskowych. Interfejs Machine Detection API udostępnia metodę getSupportedFormats(), która ułatwia przełączanie się między interfejsem Status Detection API a rozwiązaniem zastępczym.

// Feature detection.
if (!('BarceodeDetector' in window)) {
  return;
}
// Check supported barcode formats.
BarcodeDetector.getSupportedFormats()
.then((supportedFormats) => {
  supportedFormats.forEach((format) => console.log(format));
});

Schemat przepływu danych pokazujący, jak w zależności od obsługi detektorów kodów kreskowych i obsługiwanych formatów kodów kreskowych używany jest interfejs Shape Detection API lub rozwiązanie zastępcze.

Rozwiązanie zastępcze

Dostępnych jest kilka bibliotek skanowania open source i firmowych, które można łatwo zintegrować z dowolną aplikacją internetową, aby wdrożyć skanowanie. Oto niektóre z bibliotek rekomendowanych przez MishiPay.

Nazwa biblioteki Typ Rozwiązanie Wasm Formaty kodów kreskowych
QuaggaJs Oprogramowanie typu open source Nie 1D
ZxingJs Oprogramowanie typu open source Nie 1D i 2D (ograniczone)
CodeCorp Firma Tak 1D i 2D
Scandit Firma Tak 1D i 2D
Porównanie bibliotek skanowania kodów kreskowych open source i komercyjnych

Wszystkie powyższe biblioteki to w pełni funkcjonalne pakiety SDK, które składają się na wszystkie omówione powyżej warstwy. Udostępniają też interfejsy do obsługi różnych operacji skanowania. W zależności od formatów kodu kreskowego oraz szybkości wykrywania wymaganej w danym przypadku można podjąć decyzję o rozwiązaniach Wasm lub innych niż Wasm. Pomimo konieczności użycia dodatkowego zasobu (Wasm) do dekodowania kodu kreskowego, rozwiązania Wasm wygrywają z rozwiązaniami bez Wasm pod względem dokładności.

Naszym głównym wyborem był Scandit. Obsługuje wszystkie formaty kodów kreskowych wymagane w przypadku zastosowań biznesowych; pod względem szybkości skanowania przewyższa wszystkie dostępne biblioteki open source.

Przyszłość skanowania

Gdy interfejs Machine Detection API będzie w pełni obsługiwany przez wszystkie popularne przeglądarki, być może udostępnimy nowy element HTML <scanner> z funkcjami wymaganymi przez skaner kodów kreskowych. Zespół inżynierów w MishiPay uważa, że funkcja skanowania kodów kreskowych stanie się nowym elementem HTML ze względu na rosnącą liczbę bibliotek open source i licencjonowanych, które umożliwiają korzystanie z takich rozwiązań jak Scan &Go.

Podsumowanie

Zmęczenie aplikacjami to problem, z którym deweloperzy mierzą się, gdy ich produkty trafiają na rynek. Użytkownicy często chcą zrozumieć, co daje im aplikacja, zanim ją pobiorą. W sklepie, gdzie aplikacja MishiPay pozwala zaoszczędzić czas i poprawić wrażenia klientów, nielogicznym jest czekanie na pobranie aplikacji przed jej użyciem. Właśnie w tym przypadku przydatne są strony internetowe oparte na aplikacji internetowej. Dzięki usunięciu bariery wejścia liczba naszych transakcji wzrosła 10-krotnie, a użytkownicy zaoszczędzili 2,5 roku oczekiwania w kolejce.

Podziękowania

Ten artykuł został zrecenzowany przez Joe Medley.