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.

Dzięki MishiPay kupujący mogą skanować zakupy i opłacać je za pomocą smartfonów, zamiast tracić czas w kolejce do kasy. Dzięki technologii Scan & Go firmy MishiPay kupujący mogą za pomocą telefonu zeskanować kod kreskowy na produktach, zapłacić za produkty, a następnie po prostu opuścić sklep. Badania pokazują, że pozycja w kolejkach w sklepie kosztuje w globalnym sektorze handlu detalicznego około 200 miliardów dolarów rocznie.

Nasza technologia opiera się na możliwościach sprzętowych urządzeń, takich jak czujniki GPS i aparaty fotograficzne, które pozwalają użytkownikom zlokalizować sklepy obsługujące MishiPay, skanować kody kreskowe produktów w sklepach i płacić za pomocą wybranej przez siebie cyfrowej formy płatności. Początkowe wersje naszej technologii Scan & Go były przeznaczone na konkretne platformy na iOS i Androida, a początki byli zachwyceni tą technologią. Czytaj dalej, aby dowiedzieć się, jak przejście na PWA zwiększyło 10-krotnie liczbę transakcji i zaoszczędziło 2,5 roku w kolejce.

    10×

    Większa liczba transakcji

    2,5 roku

    Kolejka została zapisana

Wyzwanie

Nasza technologia jest niezwykle przydatna dla użytkowników, którzy oczekują w kolejce lub przy kasie, ponieważ pozwalają im pominąć kolejkę i bezproblemowo płacić za zakupy w sklepach. Ale kłopotliwy pobieranie aplikacji na Androida lub iOS sprawił, że użytkownicy nie wybrali naszej technologii pomimo korzyści. Dla MishiPay było to coraz większe wyzwanie, dlatego musieliśmy zwiększyć liczbę użytkowników, ograniczając barierę dostępu.

Rozwiązanie

Wysiłki związane z opracowaniem i uruchomieniem aplikacji PWA pozwoliły nam wyeliminować kłopoty z instalacją i zachęciły nowych użytkowników do wypróbowania naszej technologii w sklepie stacjonarnym, ominięcia kolejki i sprawnego dokonywania zakupów. Od tego czasu zaobserwowaliśmy ogromny wzrost liczby użytkowników naszej progresywnej aplikacji internetowej w porównaniu z aplikacjami na poszczególnych platformach.

Porównanie bezpośredniego uruchamiania PWA (w lewo, szybciej) z instalacją i uruchamianiem aplikacji na Androida (prawa, wolniej).
Transakcje według platformy. safetys: 16397 (3,98%). Android: 13769 (3,34%). internet: 382184 (92,68%).
Większość transakcji ma miejsce w internecie.

Szczegóły techniczne

Znajduję sklepy obsługujące MishiPay

Do włączania tej funkcji służy interfejs API getCurrentPosition() oraz rozwiązanie zastępcze oparte 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,
);

To podejście sprawdzało się we wcześniejszych wersjach aplikacji, ale później okazało się dużym problemem dla użytkowników MishiPay z tych powodów:

  • Niedokładności lokalizacji w rozwiązaniach zastępczych opartych na adresie IP.
  • Coraz większa liczba sklepów obsługujących MishiPay w danym regionie wymaga od użytkowników przewijania listy i wyboru odpowiedniego sklepu.
  • Użytkownicy czasami przypadkowo wybierają niewłaściwy sklep, przez co zakupy są rejestrowane nieprawidłowo.

Aby rozwiązać te problemy, umieściliśmy unikalne kody QR z lokalizacją geograficzną na ekranach w każdym sklepie. Utorował on drogę do szybszego wdrożenia. Aby uzyskać dostęp do aplikacji internetowej Scan & Go, użytkownicy muszą po prostu skanować geolokalizowane kody QR wydrukowane w materiałach marketingowych dostępnych w sklepach. Dzięki temu nie będą musieli wpisywać adresu mishipay.shop, aby uzyskać dostęp do usługi.

Skanowanie w sklepie z wykorzystaniem aplikacji PWA.

Skanuję produkty

Podstawową funkcją aplikacji MishiPay jest skanowanie kodów kreskowych, ponieważ pozwala to użytkownikom skanować własne zakupy i sprawdzać ich łączną kwotę, jeszcze zanim dotrą oni do kasy.

Aby umożliwić użytkownikom skanowanie w internecie, zidentyfikowaliśmy 3 główne warstwy.

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

Strumień wideo

Za pomocą metody getUserMedia() mamy dostęp do kamery tylnej kamery użytkownika (z ograniczeniami wymienionymi poniżej). Wywołanie metody powoduje automatyczne wyświetlenie prośby o zaakceptowanie lub odmowę dostępu do kamery. Gdy mamy dostęp 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

W przypadku wykrywania kodu kreskowego w strumieniu wideo musimy co jakiś czas przechwytywać klatki i przesyłać je do warstwy dekodera. Aby przechwycić klatkę, rysujemy po prostu strumienie z VideoElement w elemencie 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ż pewne wstępne przetwarzanie, takie jak przycinanie, obracanie i przetwarzanie w trybie szarości. Te zadania mogą być obciążające procesor i powodować, że aplikacja nie będzie reagować, ponieważ skanowanie kodów kreskowych jest procesem trwającym długo. Interfejs API OffscreenCanvas pozwala przeciążyć zadanie pracochłonne przez pracowników sieciowych. Na urządzeniach obsługujących sprzętową akcelerację graficzną interfejs WebGL API i jego WebGL2RenderingContext mogą optymalizować korzyści wynikające z zadań wstępnego przetwarzania intensywnie obciążających procesor.

Warstwa dekodera

Ostatnia warstwa to warstwa dekodera, która odpowiada za dekodowanie kodów kreskowych z ramek przechwyconych przez warstwę przetwarzania. Interfejs shape Detection API (który nie jest jeszcze dostępny we wszystkich przeglądarkach) pozwala samodzielnie dekodować kod kreskowy z pliku ImageBitmapSource, który może być elementem img, elementem SVG image, elementem video, elementem canvas, obiektem Blob, obiektem ImageData lub obiektem ImageBitmap.

Diagram przedstawiający 3 główne warstwy nici: strumień wideo, warstwa przetwarzania i interfejs Percent Detection API.

/**
 * 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 Percent Detection API, potrzebujemy rozwiązania zastępczego, aby dekodować kody kreskowe. Interfejs Character Detection API ujawnia metodę getSupportedFormats(), która ułatwia przełączanie się między Character 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 procesu pokazujący, jak (w zależności od obsługi czytnika kodów kreskowych i obsługiwanych formatów kodu kreskowego) używany jest interfejs Character Detection API lub zastępcze rozwiązanie

Rozwiązanie zastępcze

Dostępnych jest kilka bibliotek open source i dla firm, które można łatwo zintegrować z dowolną aplikacją internetową w celu wdrożenia skanowania. Oto niektóre biblioteki polecane przez MishiPay.

Nazwa biblioteki Typ Roztwór Wasm Formaty kodów kreskowych
QuaggaJs Oprogramowanie typu open source Nie 1D
ZxingJs Oprogramowanie typu open source Nie 1D i 2D (z ograniczeniami)
CodeCorp Enterprise Tak 1D i 2D
Scandit Enterprise Tak 1D i 2D
Porównanie komercyjnych bibliotek do skanowania kodów kreskowych na licencji open source

Wszystkie powyższe biblioteki to w pełni funkcjonalne pakiety SDK, które składają się ze wszystkich omówionych powyżej warstw. Udostępniają też interfejsy do obsługi różnych operacji skanowania. W zależności od formatów kodu kreskowego i szybkości wykrywania wymaganych w danej firmie dostępne są rozwiązania Wasm i inne niż Wasm. Mimo że dekodowanie kodu kreskowego wymaga dodatkowych zasobów (Wasm), rozwiązania Wasm pod względem dokładności są lepsze od rozwiązań innych niż Wasm.

Głównym wyborem był Scandit. Obsługuje wszystkie formaty kodów kreskowych wymagane w naszych firmach i pod względem szybkości skanowania przewyższa wszystkie dostępne biblioteki open source.

Przyszłość skanowania

Gdy wszystkie najpopularniejsze przeglądarki będą w pełni obsługiwać interfejs shape Detection API, możemy opracować nowy element HTML <scanner> z funkcjami wymaganymi przez skanery kodów kreskowych. Dział techniczny MishiPay uważa, że funkcja skanowania kodów kreskowych może zostać nowym elementem HTML ze względu na rosnącą liczbę bibliotek open source i licencjonowanych bibliotek, które umożliwiają takie rozwiązania jak Scan & Go i wiele innych.

Podsumowanie

Zmęczenie aplikacją to problem, z którym borykają się deweloperzy, gdy ich produkty wkraczają na rynek. Przed pobraniem aplikacji użytkownicy często chcą poznać korzyści, jakie daje im aplikacja. W sklepie, w którym MishiPay oszczędza czas kupujących i zwiększa ich wygodę, czekanie na pobranie aplikacji przed użyciem aplikacji jest sprzeczne z intuicją. Z pomocą przychodzi nam nasza aplikacja PWA. Dzięki wyeliminowaniu bariery wejścia na rynek zwiększyliśmy liczbę transakcji dziesięciokrotnie, a użytkownikom nie trzeba czekać 2,5 roku w kolejce.

Podziękowania

Autor artykułu: Joe Medley.