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

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

MishiPay позволяет покупателям сканировать и оплачивать покупки с помощью своих смартфонов, вместо того, чтобы тратить время на очереди на кассе. Благодаря технологии MishiPay Scan & Go покупатели могут использовать свой телефон для сканирования штрих-кода на товарах и оплаты их, а затем просто покинуть магазин. Исследования показывают, что очереди в магазинах обходятся мировому сектору розничной торговли примерно в 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() 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');
  }
}

В расширенных случаях использования этот слой также выполняет некоторые задачи предварительной обработки, такие как обрезка, вращение или преобразование в оттенки серого. Эти задачи могут быть ресурсоемкими и приводить к тому, что приложение перестанет отвечать на запросы, поскольку сканирование штрих-кода является длительной операцией. С помощью OffscreenCanvas API мы можем переложить задачу, нагружающую ЦП, на веб-работника. На устройствах, поддерживающих аппаратное ускорение графики, WebGL API и его 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));
});

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

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

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

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

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

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

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

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

Заключение

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

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

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