PWA への切り替えが MishiPay のビジネスにどのように役立ったかをご覧ください。
MishiPay を利用すると、買い物客はレジに並ぶ時間を無駄にすることなく、スマートフォンで商品をスキャンして支払うことができます。MishiPay の Scan & Go テクノロジーにより、買い物客は自分のスマートフォンを使用して商品のバーコードをスキャンして支払い、そのまま店を出ることができます。調査によると、店舗での行列待ちによって、世界の小売業界は年間 2, 000 億ドルの損失を被っています。
この技術は、GPS センサーやカメラなどのデバイスのハードウェア機能を利用して、MishiPay 対応の店舗を特定したり、実店舗内で商品のバーコードをスキャンしたり、選択したデジタル決済方法で支払ったりできるようにします。スキャン&ゴー テクノロジーの初期バージョンは、iOS と Android のプラットフォーム固有のアプリケーションでしたが、早期導入者には好評でした。PWA に切り替えることで、トランザクションが 10 倍に増加し、キューイングの時間が 2 年半も短縮された方法について、続きをお読みください。
10×
取引が増加
2 年半
キューイングを保存しました
課題
ユーザーは、キューやチェックアウトの列で待っているときに、このテクノロジーが非常に役立つと感じています。キューをスキップして、スムーズな店内体験を実現できるからです。しかし、Android または iOS アプリケーションをダウンロードする手間がかかるため、ユーザーは価値があるにもかかわらず、このテクノロジーを選択しませんでした。これは MishiPay にとって大きな課題であり、参入障壁を低くしてユーザーの導入を増やす必要がありました。
解決策
PWA の構築とリリースにより、インストールの手間を省き、実店舗で新しいテクノロジーを試して、列に並ばずにシームレスなショッピング体験を楽しめるようになりました。リリース以来、プラットフォーム固有のアプリケーションと比較して、PWA のユーザー導入が大幅に増加しています。
技術的な詳細
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 を入力しなくてもサービスにアクセスできるようになります。
商品をスキャンする
MishiPay アプリのコア機能はバーコード スキャンです。これにより、ユーザーは購入商品を自分でスキャンし、レジにたどり着く前に合計金額を確認できます。
ウェブでスキャン エクスペリエンスを構築するために、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 からバーコードをデコードします。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 のエンジニアリング部門は、Scan & Go などのエクスペリエンスを可能にするオープンソース ライブラリやライセンス ライブラリの数が増加しているため、バーコード スキャン機能が新しい HTML 要素になることには確かなユースケースがあると考えています。
まとめ
アプリ疲れは、デベロッパーが製品を市場に投入する際に直面する問題です。ユーザーは、アプリをダウンロードする前に、アプリが自分にもたらす価値を把握したいと考えています。MishiPay は、店舗で買い物客の時間を節約し、エクスペリエンスを向上させるものですが、アプリを使用する前にダウンロードを待つのは、直感に反します。ここで PWA が役立ちます。
参入障壁をなくすことで、取引が 10 倍に増え、ユーザーはキューでの待ち時間を 2 年半短縮できました。
謝辞
この記事は Joe Medley によってレビューされました。