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

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

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

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

    10×

    取引の増加

    2 年半

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

課題

ユーザーは、この技術がキューやレジ待ちの際に非常に役立つと考えています。キューをスキップしてスムーズに店舗での購入を完了できるためです。ところが、Android や iOS のアプリをダウンロードする手間がかかるため、その価値にもかかわらず、ユーザーは Google のテクノロジーを選んではいませんでした。これは MishiPay にとって大きな課題でした。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 コードをスキャンするだけで、スキャン &ゴー ウェブ アプリケーションにアクセスできます。これにより、サービスにアクセスする際にウェブアドレス 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 年半も節約できるようになりました。

謝辞

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