PWA への移行が MishiPay のビジネスにどのように役立ったかをご覧ください。
MishiPay を使用すると、買い物客はスマートフォンでショッピングをスキャンして支払いができるようになり、購入手続きで時間を浪費する必要がなくなります。MishiPay のスキャン&ゴー テクノロジーを使用すると、買い物客は自分のスマートフォンで商品のバーコードをスキャンし、支払いをするだけで済みます。調査によると、世界中の小売業界が店頭での待機に要する費用は年間約 2,000 億ドルにのぼることがわかっています。
当社のテクノロジーは、GPS センサーやカメラなどのデバイス ハードウェア機能に依存しています。これらの機能により、ユーザーは MishiPay 対応店舗を見つけ、実店舗内で商品のバーコードをスキャンし、選択したデジタル決済方法で支払いを行うことができます。Scan & Go テクノロジーの初期バージョンは、プラットフォーム固有の iOS および Android アプリで提供されていましたが、先行ユーザーがこのテクノロジーを愛用していました。ここでは、PWA への切り替えによってトランザクションが 10 倍に増加し、キューイングを 2.5 年削減した方法をご覧ください。
10×
取引の増加
2 年半
キューを保存しました
課題
当社のテクノロジーは、列に並ぶことなくスムーズに店内を体験できるため、列に並ぶときに非常に便利です。しかし、Android や iOS のアプリをダウンロードするという面倒な作業のため、Google のテクノロジーの価値にもかかわらず、ユーザーは Google のテクノロジーを選んではなりませんでした。これは MishiPay にとっての課題の増大を招き、参入障壁を低くしてユーザーへの導入を増やす必要がありました。
解決策
PWA の構築とリリースに関する取り組みにより、インストールの手間が省け、新規ユーザーは実店舗で当社のテクノロジーを試し、キューをスキップし、シームレスなショッピング体験を得ることができました。リリース以来、Google の PWA は、プラットフォーム固有のアプリケーションと比較して、ユーザーによる PWA の導入が大幅に急増しました。
技術的な詳細
MishiPay 対応店舗を探す
この機能を有効にするには、getCurrentPosition()
API と 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 対応の店舗が地域ごとに増えていくと、ユーザーはリストをスクロールして正しい店舗を特定する必要があります。
- ユーザーが誤って間違った店舗を選択すると、購入が正しく記録されないことがあります。
こうした問題に対処するため、Google は位置情報が表示された一意の QR コードを店舗ごとに店舗内のディスプレイに組み込みました。これにより、オンボーディング エクスペリエンスの迅速化への道が開かれました。ユーザーは、店舗にあるマーケティング資料に印刷されている位置情報付きの QR コードをスキャンするだけで、Scan & Go ウェブ アプリケーションにアクセスできます。こうすることで、サービスにアクセスするときにウェブアドレス mishipay.shop
を入力する手間を省くことができます。
商品のスキャン
MishiPay アプリのコア機能はバーコード スキャンです。これにより、ユーザーはレジに届く前に購入内容をスキャンし、累計を確認できます。
ウェブでスキャン機能を構築するために、Google は 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 API の drawImage()
メソッドを使用して、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
(img
要素、SVG image
要素、video
要素、canvas
要素、Blob
オブジェクト、ImageData
オブジェクト、ImageBitmap
オブジェクトなど)からバーコードをデコードします。
/**
* 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));
});
代替ソリューション
複数のオープンソース ライブラリとエンタープライズ スキャン ライブラリが用意されています。これらのライブラリは、ウェブ アプリケーションと簡単に統合してスキャンを実装できます。MishiPay が推奨するライブラリの一部を以下に示します。
上記のライブラリはすべて、前述のすべてのレイヤを構成する本格的な SDK です。また、さまざまなスキャン オペレーションをサポートするインターフェースも公開します。ビジネスケースに必要なバーコード形式と検出速度に応じて、Wasm または Wasm 以外のソリューションを選択できます。バーコードのデコードに追加のリソース(Wasm)が必要になるオーバーヘッドにもかかわらず、Wasm ソリューションは精度の点で Wasm 以外のソリューションより優れています。
一番の選択肢は Scandit です。当社のビジネス ユースケースに必要なすべてのバーコード形式をサポートしており、スキャン速度の点では、利用可能なすべてのオープンソース ライブラリより優れています。
スキャンの未来
Shape Detection API がすべての主要なブラウザで完全にサポートされるようになると、バーコード スキャナに必要な機能を備えた新しい HTML 要素 <scanner>
が作成される可能性があります。MishiPay のエンジニアリング チームは、バーコード スキャン機能を新しい HTML 要素にするという確固たるユースケースがあると考えています。Scan & Go などのエクスペリエンスを可能にするオープンソース ライブラリやライセンス付きライブラリは増加の一途をたどっています。
おわりに
アプリ疲れは、デベロッパーが製品を市場に投入する際に直面する問題です。ユーザーは、アプリケーションをダウンロードする前に、アプリケーションが提供する価値を理解したいと思うことがよくあります。MishiPay は買い物客の時間を節約し、エクスペリエンスを向上させている店舗では、アプリがダウンロードされる前にアプリを使用できるのを待つのは直感的ではありません。ここで役立つのが PWA です。導入の障壁がなくなったことで、トランザクションが 10 倍に増加し、ユーザーがキューで待つ時間を 2.5 年短縮できました。
謝辞
この記事は Joe Medley によってレビューされました。