MishiPay の PWA により、トランザクションが 10 倍に増加し、キューイングを 2 年半削減

PWA への切り替えが MishiPay のビジネスにどのように役立ったかをご覧ください。

MishiPay を使用すると、買い物客はレジで並ぶ時間を無駄にすることなく、スマートフォンで商品をスキャンして支払うことができます。MishiPay のScan & Go テクノロジーにより、買い物客は自分のスマートフォンを使用して商品のバーコードをスキャンし、支払いを済ませて、そのまま店舗を出ることができます。調査によると、店舗での待ち行列は、世界中の小売業界に年間約 2000 億ドルの費用を負担させています。

この技術は、GPS センサーやカメラなどのデバイスのハードウェア機能を利用して、ユーザーが MishiPay 対応の店舗を探し、実店舗で商品バーコードをスキャンして、任意のデジタル決済方法で支払うことを可能にします。スキャン&ゴー テクノロジーの初期バージョンは、プラットフォーム固有の iOS アプリと Android アプリでしたが、早期導入ユーザーに好評でした。PWA に切り替えることでトランザクションが 10 倍に増加し、キュー待ち時間が 2.5 年分削減された方法について、以下で詳しく説明します。

    10×

    取引の増加

    2 年半

    キューイングを保存しました

課題

ユーザーは、この技術がキューやレジ待ちの際に非常に役立つと考えています。キューをスキップしてスムーズに店舗での購入を完了できるためです。しかし、Android または iOS のアプリをダウンロードする手間があるため、ユーザーは価値にもかかわらず、このテクノロジーを採用しませんでした。これは MishiPay にとって大きな課題でした。ユーザーの利用を促進するために、参入障壁を下げる必要がありました。

解決策

PWA の構築とリリースにより、インストールの手間を省くことができ、新規ユーザーが実店舗でテクノロジーを試し、行列に並ばずにシームレスなショッピング体験を得られるようになりました。リリース以降、プラットフォーム固有のアプリと比較して、PWA のユーザーの利用が大幅に増加しています。

PWA を直接起動する(左、高速)場合と、Android アプリをインストールして起動する(右、低速)場合の比較。
プラットフォーム別の取引数。¡OS: 16,397(3.98%)。Android: 13,769 件(3.34%)。ウェブ: 382,184(92.68%)。
すべての取引の大部分はウェブ上で行われます。

技術的な詳細

MishiPay 対応の店舗の検索

この機能を有効にするには、IP ベースのフォールバック ソリューションとともに getCurrentPosition() API を使用します。

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 アプリのコア機能はバーコード スキャンです。これにより、ユーザーはレジに到達する前に購入品をスキャンして合計金額を確認できます。

ウェブでスキャン エクスペリエンスを構築するために、3 つのコアレイヤを特定しました。

動画ストリーム、処理レイヤ、デコーダ レイヤの 3 つのメインスレッドレイヤを示す図。

動画ストリーム

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

処理レイヤ

特定の動画ストリームでバーコードを検出するには、フレームを定期的にキャプチャしてデコーダレイヤに転送する必要があります。フレームをキャプチャするには、Canvas APIdrawImage() メソッドを使用して、VideoElement から HTMLCanvasElement にストリームを描画します。

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

高度なユースケースでは、このレイヤは切り抜き、回転、グレースケールへの変換などの前処理タスクも実行します。これらのタスクは CPU 使用率が高く、バーコード スキャンは長時間実行されるオペレーションであるため、アプリケーションが応答しなくなる可能性があります。OffscreenCanvas API を使用すると、CPU 使用率の高いタスクをウェブワーカーにオフロードできます。ハードウェア グラフィック アクセラレーションをサポートしているデバイスでは、WebGL API とその WebGL2RenderingContext を使用して、CPU 使用率の高い前処理タスクのゲインを最適化できます。

デコーダ レイヤ

最後のレイヤはデコーダ レイヤで、処理レイヤによってキャプチャされたフレームからバーコードをデコードします。Shape Detection API(一部のブラウザでは利用できない)により、ブラウザ自体が ImageBitmapSource からバーコードをデコードします。ImageBitmapSource は、img 要素、SVG image 要素、video 要素、canvas 要素、Blob オブジェクト、ImageData オブジェクト、ImageBitmap オブジェクトのいずれかです。

動画ストリーム、処理レイヤ、Shape Detection API の 3 つのメインスレッドレイヤを示す図。

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

Shape Detection API をまだサポートしていないデバイスの場合、バーコードをデコードするための代替ソリューションが必要です。Shape Detection API は、Shape Detection API と代替ソリューションの切り替えに役立つ getSupportedFormats() メソッドを公開します。

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

バーコード検出のサポートとサポートされているバーコードの形式に応じて、Shape Detection API またはフォールバック ソリューションのいずれが使用されるかを示すフロー図。

フォールバック ソリューション

オープンソースとエンタープライズのスキャン ライブラリがいくつかあり、任意のウェブ アプリケーションと簡単に統合してスキャンを実装できます。MishiPay が推奨するライブラリをいくつかご紹介します。

ライブラリ名 タイプ Wasm ソリューション バーコード形式
QuaggaJs オープンソース いいえ 1 日
ZxingJs オープンソース いいえ 1D と 2D(制限付き)
CodeCorp Enterprise はい 1D と 2D
Scandit Enterprise はい 1D と 2D
オープンソースと商用のバーコード スキャン ライブラリの比較

上記のライブラリはすべて、上記のすべてのレイヤを構成する本格的な SDK です。また、さまざまなスキャン操作をサポートするインターフェースも公開します。ビジネスケースに必要なバーコード形式と検出速度に応じて、Wasm ソリューションと非 Wasm ソリューションのどちらを選択するかを決定できます。バーコードをデコードするために追加のリソース(Wasm)が必要になるというオーバーヘッドがあるにもかかわらず、Wasm ソリューションは精度に関して Wasm 以外のソリューションよりも優れています。

主に Scandit を選択しました。ビジネスのユースケースに必要なすべてのバーコード形式をサポートし、スキャン速度では利用可能なすべてのオープンソース ライブラリを上回っています。

スキャンの未来

すべての主要ブラウザで Shape Detection API が完全にサポートされると、バーコード スキャナに必要な機能を備えた新しい HTML 要素 <scanner> が導入される可能性があります。MishiPay のエンジニアリングチームは、Scan & Go などのエクスペリエンスを可能にするオープンソース ライブラリやライセンス ライブラリの数が増えているため、バーコード スキャン機能を新しい HTML 要素にすることが有用なユースケースであると考えています。

まとめ

アプリの疲労は、デベロッパーがプロダクトを市場に投入する際に直面する問題です。多くのユーザーは、アプリをダウンロードする前に、そのアプリが提供する価値を理解したいと考えています。MishiPay が買い物客の時間を節約し、エクスペリエンスを向上させる店舗では、ダウンロードを待ってからアプリを使用できるようにするのは直感に反します。ここで PWA が役立ちます。参入障壁を排除することで、取引が 10 倍に増加し、ユーザーはキュー待ちで 2.5 年も節約できるようになりました。

謝辞

この記事は Joe Medley さんが確認しました。