MishiPay';PWA 提升了交易 10 倍,並省下 2.5 年的佇列

瞭解改用 PWA 對 MishiPay 的助益。

MishiPay 可讓購物者使用智慧型手機掃描並付款,而不必使用 結帳流程會浪費時間MishiPay 的掃描與圍繞過去採用的技術 購物者可以使用自己的手機掃描商品條碼,並付款 。研究: 121 億美元在店內排完後,全球零售部門每年花費約 $2,000 億美元。

我們的技術仰賴裝置硬體功能,例如允許連線的 GPS 感應器和攝影機 使用者尋找支援 MishiPay 的商店,掃描實體商店內的商品條碼,然後付款 選擇數位付款方式最初版本的掃描與Go 技術 是特定平台專用的 iOS 和 Android 應用程式,早期採用者也很喜歡這項技術。已讀 ,瞭解改用 PWA 如何使交易量增加 10 倍,並省下 2.5 年 排隊中!

    10×

    交易量增加

    2.5 年

    已儲存待播清單

挑戰

使用者在排隊或退房時,覺得我們的技術非常實用,因為 這樣就能略過等候名單,享有順暢的店內消費體驗。而且下載起來十分簡單 儘管 Android 或 iOS 應用程式如此實用,使用者卻無法選擇我們的技術。它持續成長 面臨了 MishiPay 的挑戰,因此我們需要降低進入門檻,以提高使用者採用率。

解決方案

我們建構並推出 PWA 所付出的心力,都讓我們不必再費心安裝 PWA, 鼓勵新使用者在實體商店中試用我們的技術、跳過排隊程序, 順暢無阻的購物體驗自這項功能推出以來,我們就發現使用者採用率大幅提升 進一步改善 PWA。

並排比較直接啟動 PWA (較左側、較快) 與安裝/啟動 Android 應用程式 (右側速度較慢) 的差異。
,瞭解如何調查及移除這項存取權。
交易 (依平台)。KatOS:16397 (3.98%)。Android:13769 (3.34%)。網頁:382184 (92.68%)。
所有交易都是在網路上進行。

技術深入解析

尋找支援 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 的商店清單不斷增加,因此使用者必須捲動清單 找出正確的分店
  • 使用者不小心選錯商店,導致系統記錄購買交易 不正確。

為解決這些問題,我們在店內展示器上嵌入了不重複的地理位置 QR code, 也就是經過處理且會導入模型的資料 接著再透過特徵儲存庫與他人分享有助於加快新手上路速度。使用者只要掃描地理位置的 QR code 印在商店的行銷文宣上,以存取掃描和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');
  }
}

針對進階用途,此層也會執行一些預先處理工作,例如裁剪、 旋轉或轉換為灰階這些工作可能耗用大量 CPU 資源,且可能導致應用程式 條碼掃描是一項長時間執行的作業,因此尚未回應。我們使用 OffscreenCanvas API 網路工作站。而在支援硬體圖形加速功能的裝置上 WebGL API 及其 WebGL2RenderingContext 可以 針對耗用大量 CPU 的預先處理工作進行最佳化,進一步提升效能。

解碼器層

最後一層是解碼器層 負責解碼影格中的條碼 從處理層擷取到的這都要歸功於 Shape Detection API ( 並非所有瀏覽器都支援這項功能),瀏覽器本身會自行將條碼 ImageBitmapSource,可以是 img 元素、SVG image 元素、video 元素、 canvas 元素、Blob 物件、ImageData 物件或 ImageBitmap 物件。

這張圖表顯示三個主要執行緒層:影片串流、處理層和 Shape Detection 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;
  }
}

如果裝置尚未支援 Shape Detection API,我們需要一種備用解決方案才能解碼 也不必擔心Shape Detection API 提供 getSupportedFormats()敬上 方法,有助於在 Shape Detection API 和備用解決方案之間切換。

// 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。支援所有條碼 符合業務用途所需的格式這打敗了目前所有 Google 提供的開放原始碼程式庫 或是掃描速度

掃描的未來趨勢

一旦所有主要瀏覽器完全支援 Shape Detection API,我們或許就能 具備條碼掃描器所需功能的新 HTML 元素 <scanner>。工程 MishiPay 認為,條碼掃描功能確實一項新用途 HTML 元素,因為可啟用的開放原始碼和授權程式庫數量與日俱增 提供掃描與再接再厲。

結論

應用程式疲勞是指開發人員在產品上市時面臨的問題。使用者通常希望 在應用程式下載前 瞭解應用程式能帶來什麼價值商店內有 MishiPay 省去購物者消費的麻煩縮短時間並改善他們的使用體驗,這不符合直覺 使用者才能使用應用程式而 PWA 就能派上用場。消除障礙 交易量增加 10 倍,使用者也能省下 2.5 年 排入佇列中。

特別銘謝

本文經過 Joe Medley