PWA от MishiPay увеличивает количество транзакций в 10 раз и экономит 2,5 года ожидания в очереди

Узнайте, как переход на PWA помог бизнесу MishiPay.

MishiPay позволяет покупателям сканировать и оплачивать покупки с помощью смартфонов, вместо того чтобы тратить время на очереди на кассе. Благодаря технологии Scan & Go от MishiPay покупатели могут использовать свой телефон для сканирования штрихкода на товарах и оплаты, а затем покинуть магазин. Исследования показывают, что ежегодные очереди в магазинах обходятся мировому розничному сектору в 200 миллиардов долларов .

Наша технология основана на возможностях аппаратного обеспечения устройств, таких как GPS-датчики и камеры, которые позволяют пользователям находить магазины, поддерживающие MishiPay, сканировать штрих-коды товаров в физическом магазине, а затем оплачивать покупки с помощью выбранного ими способа цифровой оплаты. Первые версии нашей технологии Scan & Go представляли собой приложения для платформ iOS и Android, и первые пользователи были в восторге от этой технологии. Читайте дальше, чтобы узнать, как переход на PWA увеличил количество транзакций в 10 раз и сэкономил 2,5 года ожидания в очередях!

    10 ×

    Увеличение количества транзакций

    2,5 года

    Очередь сохранена

Испытание

Пользователи считают нашу технологию чрезвычайно полезной при ожидании в очереди или на кассе, поскольку она позволяет им избежать очереди и получить удобный опыт покупок в магазине. Однако неудобство загрузки приложения для Android или iOS отталкивало пользователей от нашей технологии, несмотря на ее преимущества. Это стало растущей проблемой для MishiPay, и нам нужно было увеличить число пользователей, снизив порог входа.

Решение

Наши усилия по созданию и запуску PWA помогли нам упростить установку и побудили новых пользователей опробовать нашу технологию в реальном магазине, избежать очередей и получить удобный процесс покупок. С момента запуска мы наблюдаем значительный рост числа пользователей нашего PWA по сравнению с нашими приложениями, разработанными специально для этой платформы.

Сравнительный анализ прямого запуска PWA (слева, быстрее) и установки и запуска приложения для Android (справа, медленнее).
Транзакции по платформам. ОС: 16397 (3,98%). Android: 13769 (3,34%). Веб: 382184 (92,68%).
Большинство транзакций совершается в интернете.

Технический подробный анализ

Поиск магазинов, поддерживающих MishiPay.

Для активации этой функции мы используем API getCurrentPosition() в сочетании с резервным решением на основе 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,
);

Этот подход хорошо работал в ранних версиях приложения, но позже оказался огромной проблемой для пользователей MishiPay по следующим причинам:

  • Неточности определения местоположения в резервных решениях на основе IP-адресов.
  • По мере увеличения количества магазинов, поддерживающих MishiPay в каждом регионе, пользователям приходится прокручивать список и искать нужный магазин.
  • Пользователи иногда случайно выбирают не тот магазин, из-за чего покупки регистрируются некорректно.

Для решения этих проблем мы разместили уникальные QR-коды с геолокацией на информационных стендах в каждом магазине. Это ускорило процесс регистрации. Пользователи сканируют QR-коды с геолокацией, напечатанные на рекламных материалах в магазинах, чтобы получить доступ к веб-приложению Scan & Go. Таким образом, им не нужно вводить веб-адрес mishipay.shop для доступа к сервису.

Опыт сканирования товаров в магазине с использованием PWA.

Сканирующие продукты

Ключевой функцией приложения MishiPay является сканирование штрихкодов, позволяющее пользователям сканировать свои покупки и видеть итоговую сумму еще до того, как они подошли бы к кассе.

Для создания удобного веб-интерфейса для сканирования мы выделили три основных уровня.

Диаграмма, показывающая три основных уровня потоков: видеопоток, уровень обработки и уровень декодирования.

Видеопоток

С помощью метода getUserMedia() мы можем получить доступ к камере заднего вида пользователя с ограничениями, указанными ниже. Вызов метода автоматически запускает запрос пользователю на принятие или отклонение доступа к своей камере. Получив доступ к видеопотоку, мы можем передать его на видеоэлемент, как показано ниже:

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

Слой обработки

Для обнаружения штрихкода в заданном видеопотоке нам необходимо периодически захватывать кадры и передавать их на слой декодера. Для захвата кадра мы рисуем потоки из VideoElement на HTMLCanvasElement , используя метод drawImage() из 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');
  }
}

Для сложных сценариев использования этот слой также выполняет некоторые задачи предварительной обработки, такие как обрезка, поворот или преобразование в оттенки серого. Эти задачи могут быть ресурсоемкими для ЦП и приводить к зависанию приложения, поскольку сканирование штрих-кодов — это длительная операция. С помощью API OffscreenCanvas мы можем переложить ресурсоемкую задачу на веб-воркер. На устройствах, поддерживающих аппаратное ускорение графики, API WebGL и его WebGL2RenderingContext могут оптимизировать вычислительные ресурсы при выполнении ресурсоемких задач предварительной обработки.

Слой декодера

Последний слой — это слой декодирования, отвечающий за расшифровку штрихкодов из кадров, захваченных слоем обработки. Благодаря API распознавания форм (который пока доступен не во всех браузерах) браузер сам декодирует штрихкод из объекта ImageBitmapSource , который может быть элементом img , элементом image SVG, элементом video , элементом canvas , объектом Blob , объектом ImageData или объектом ImageBitmap .

Диаграмма, показывающая три основных уровня потоков: видеопоток, уровень обработки и 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;
  }
}

Для устройств, которые еще не поддерживают API распознавания форм, нам необходимо резервное решение для декодирования штрихкодов. API распознавания форм предоставляет метод getSupportedFormats() , который позволяет переключаться между API распознавания форм и резервным решением.

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

Блок-схема, показывающая, как в зависимости от поддержки Barcode Detector и поддерживаемых форматов штрихкодов используется либо API распознавания форм, либо резервное решение.

Резервное решение

Существует несколько библиотек для сканирования с открытым исходным кодом и корпоративных решений, которые легко интегрируются с любым веб-приложением для реализации сканирования. Вот некоторые из библиотек, которые рекомендует MishiPay.

Название библиотеки Тип Решение Wasm Форматы штрихкодов
QuaggaJs Открытый исходный код Нет 1D
ZxingJs Открытый исходный код Нет 1D и 2D (ограниченный прокат)
CodeCorp Предприятие Да 1D и 2D
Скандит Предприятие Да 1D и 2D
Сравнение библиотек сканирования штрих-кодов с открытым исходным кодом и коммерческих библиотек.

Все эти библиотеки представляют собой полноценные SDK, которые включают в себя все обсуждаемые уровни. Они также предоставляют интерфейсы для поддержки различных операций сканирования. В зависимости от форматов штрихкодов и требуемой скорости обнаружения для конкретного бизнес-задачи, выбор может стоять между решениями на основе Wasm и решениями без Wasm. Несмотря на дополнительные затраты, связанные с необходимостью использования дополнительного ресурса (Wasm) для декодирования штрихкода, решения на основе Wasm превосходят решения без Wasm по точности.

Scandit был нашим основным выбором. Он поддерживает все форматы штрихкодов, необходимые для наших бизнес-задач; по скорости сканирования он превосходит все доступные библиотеки с открытым исходным кодом.

Будущее сканирования

Как только API распознавания форм будет полностью поддерживаться всеми основными браузерами, у нас потенциально может появиться новый HTML-элемент <scanner> , обладающий необходимыми возможностями для сканирования штрих-кодов. Инженеры MishiPay считают, что существует веская причина для использования функции сканирования штрих-кодов в качестве нового HTML-элемента, поскольку растет число библиотек с открытым исходным кодом и лицензионных библиотек, которые позволяют реализовать такие функции, как Scan & Go и многие другие.

Заключение

Усталость от приложений — это проблема, с которой сталкиваются разработчики, когда их продукты выходят на рынок. Пользователи часто хотят понять ценность приложения, прежде чем его загрузить. В магазине, где MishiPay экономит время покупателей и улучшает их опыт, ждать загрузки, прежде чем они смогут использовать приложение, нелогично. Именно здесь на помощь приходит наше PWA.

Устранив барьер для входа, мы увеличили количество транзакций в 10 раз и позволили нашим пользователям сэкономить 2,5 года ожидания в очереди.

Благодарности

Данная статья была проверена Джо Медли .