אפליקציית MishiPay' מגדילה את מספר העסקאות פי 10 וחוסכת 2.5 שנים של המתנה בתור

איך המעבר לאפליקציית PWA עזר לעסק של MishiPay?

MishiPay מאפשרת לקונים לסרוק את הפריטים ולשלם עליהם באמצעות הסמארטפונים שלהם, במקום לבזבז זמן בתור בקופה. בעזרת הטכנולוגיה של MishiPay לסריקה ויציאה, הקונים יכולים לסרוק את הברקוד של הפריטים בטלפון שלהם, לשלם עליהם ולצאת מהחנות. מחקרים מראים שהמתנה בתור בחנות פיזית עולה לתעשיית הקמעונאות העולמית כ-200 מיליארד דולר בשנה.

הטכנולוגיה שלנו מתבססת על יכולות החומרה של המכשיר, כמו חיישני GPS ומצלמות, שמאפשרות למשתמשים לאתר חנויות שתומכות ב-MishiPay, לסרוק את הקודים הביומטריים של הפריטים בחנות הפיזית ואז לשלם באמצעות אמצעי התשלום הדיגיטלי שבחרתם. הגרסאות הראשונות של הטכנולוגיה שלנו ל'סריקה ורכישה' היו אפליקציות ספציפיות לפלטפורמות iOS ו-Android, והמשתמשים הראשונים אהבו את הטכנולוגיה. בהמשך תוכלו לקרוא איך המעבר ל-PWA הגדיל את מספר העסקאות פי 10 וחסך 2.5 שנים של תורים!

    10×

    יותר עסקאות

    שנתיים וחצי

    שמירת הנתונים בתור

האתגר

המשתמשים מוצאים את הטכנולוגיה שלנו מועילה מאוד כשהם ממתינים בתור או בתור לקופה, כי היא מאפשרת להם לדלג על התור וליהנות מחוויית קנייה חלקה בחנות. אבל הטרחה של הורדת אפליקציה ל-Android או ל-iOS גרמה למשתמשים לא לבחור בטכנולוגיה שלנו למרות הערך. זה היה אתגר הולך וגדל עבור MishiPay, והיינו צריכים להגדיל את השימוש בשירות על ידי הפחתת חסמי הכניסה.

פתרון

המאמצים שלנו לפתח ולהשיק את אפליקציית ה-PWA עזרו לנו להסיר את הטרחה של ההתקנה, ועודדו משתמשים חדשים לנסות את הטכנולוגיה שלנו בחנות פיזית, לדלג על התור וליהנות מחוויית קנייה חלקה. מאז ההשקה, ראינו עלייה משמעותית בשימוש של המשתמשים באפליקציית ה-PWA שלנו בהשוואה לאפליקציות הספציפיות לפלטפורמות.

השוואה מפורטת בין הפעלה ישירה של ה-PWA (שמאל, מהיר יותר) לבין התקנה והפעלה של האפליקציה ל-Android (ימינה, איטית יותר).
עסקאות לפי פלטפורמה. סטרOS: 16397 (3.98%). Android:‏ 13,769 (3.34%). אינטרנט: 382,184 (92.68%).
רוב העסקאות מתבצעות באינטרנט.

ניתוח מעמיק של הנתונים הטכניים

איתור חנויות שתומכות ב-MishiPay

כדי להפעיל את התכונה הזו, אנחנו מסתמכים על ה-API של getCurrentPosition() יחד עם פתרון חלופי מבוסס-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 ייחודיים עם מיקום גיאוגרפי במסכים בחנות של כל חנות. הוא סלל את הדרך לתהליך הצטרפות מהיר יותר. כדי לגשת לאפליקציית האינטרנט של 'סריקה ורכישה', המשתמשים פשוט סורקים את קודי ה-QR הממוקמים גיאוגרפית שמודפסים על חומרים שיווקיים בחנויות. כך הם יוכלו להימנע מהקלדה של כתובת האינטרנט mishipay.shop כדי לגשת לשירות.

חוויית הסריקה בחנות באמצעות אפליקציית ה-PWA.

סריקה של מוצרים

סריקת ברקוד היא תכונה עיקרית באפליקציית MishiPay, שעוזרת למשתמשים לסרוק את הרכישות שלהם ולראות את הסכום הכולל עוד לפני שהם היו מגיעים לפקודת מזומן.

כדי ליצור חוויית סריקה באינטרנט, זיהינו שלוש שכבות ליבה.

תרשים שמציג את שלוש שכבות ה-thread הראשיות: זרם וידאו, שכבת עיבוד ושכבת המפענח.

וידאו בסטרימינג

בעזרת השיטה getUserMedia(), אנחנו יכולים לגשת למצלמת התצוגה האחורית של המשתמש בכפוף למגבלות שמפורטות בהמשך. קריאה ל-method מפעילה באופן אוטומטי הודעה למשתמשים לאשר או לדחות את הגישה למצלמה שלהם. אחרי שנקבל גישה לסטרימינג של הסרטון, נוכל להעביר אותו אל רכיב וידאו, כפי שמוצג בהמשך:

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

בתרחישי שימוש מתקדמים, השכבה הזו מבצעת גם כמה משימות של עיבוד מקדים, כמו חיתוך, כיוון או המרה לגווני אפור. המשימות האלה יכולות להיות עתירות מעבד, וכתוצאה מכך האפליקציה לא תגיב, כי סריקת ברקודים היא פעולה ממושכת. בעזרת ה-API של OffscreenCanvas, אנחנו יכולים להעביר את המשימה שמשתמשת ב-CPU באופן אינטנסיבי ל-web worker. במכשירים שתומכים בהאצת גרפיקה באמצעות חומרה, ה-WebGL API וה-WebGL2RenderingContext שלו יכולים לייעל את העבודה על משימות עיבוד אינטנסיביות לפני העיבוד (CPU).

שכבת המפענח

השכבה האחרונה היא שכבת המפענח, שאחראית לפענוח ברקודים מהפריימים ששכבת העיבוד תיעדה. בעזרת Shape Detection API (שעדיין לא זמין בכל הדפדפנים), הדפדפן עצמו מפענח את הברקוד מ-ImageBitmapSource, שיכול להיות אלמנט img, אלמנט SVG image, אלמנט video, אלמנט canvas, אובייקט Blob, אובייקט ImageData או אובייקט ImageBitmap.

תרשים שבו מוצגות שלוש השכבות העיקריות של ה-thread: שידור הווידאו, שכבת העיבוד ו-Form Detection API (ממשק ה-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, אנחנו צריכים פתרון חלופי לפענוח הברקודים. ממשק ה-API לזיהוי צורה חושף method getSupportedFormats() שעוזר לעבור בין ה- לנהל את ה-API של זיהוי הצורה לבין הפתרון החלופי.

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

תרשים תהליך שבו מוצג איך, בהתאם לתמיכה ב-Barcode Detector ולפורמטים הנתמכים של ברקודים, נעשה שימוש ב-Shape Detection API או בפתרון החלופי.

פתרון חלופי

יש כמה ספריות סריקה של קוד פתוח וארגונים שאפשר לשלב בקלות עם כל אפליקציית אינטרנט כדי להטמיע סריקה. ריכזנו כאן כמה מהספריות שמומלצות על ידי MishiPay.

שם הספרייה סוג פתרון Wasm פורמטים של ברקוד
QuaggaJs קוד פתוח לא יום
ZxingJs קוד פתוח לא 1D ו-2D (מוגבלת)
CodeCorp ארגונים כן 1D ו-2D
Scandit ארגונים כן 1D ו-2D
השוואה בין ספריות קוד פתוח לספריות מסחריות לסריקה של ברקודים

כל הספריות שלמעלה הן ערכות SDK מלאות שמכילות את כל השכבות שצוינו למעלה. הם גם חושפים ממשקים שתומכים בפעולות סריקה שונות. בהתאם לפורמטים של הברקוד ולמהירות הזיהוי שנדרשים למקרה העסקי, ההחלטה יכולה להיות בין פתרונות Wasm לבין פתרונות שאינם Wasm. למרות התקורה שדורשת משאב נוסף (Wasm) לפענוח הברקוד, ביצועי הפתרון של Wasm טובים יותר מהפתרון שאינו Wasm.

Scandit הייתה הבחירה הראשית שלנו. היא תומכת בכל הפורמטים של קודי מ barras הנדרשים לתרחישי השימוש העסקיים שלנו, והיא מהירה יותר מכל הספריות הזמינות בקוד פתוח.

העתיד של הסריקה

אחרי ש-Shape Detection API יקבל תמיכה מלאה בכל הדפדפנים העיקריים, יכול להיות שיהיה לנו רכיב HTML חדש <scanner> עם היכולות הנדרשות לסורק ברקודים. מהנדסי MishiPay סבורים שיש תרחיש לדוגמה שבו הפונקציונליות של סריקת ברקודים יכולה להיות רכיב HTML חדש, בגלל מספר ההולך וגדל של ספריות קוד פתוח ורישיונות שמאפשרות חוויות כמו 'סריקה ורכישה' ועוד רבות.

סיכום

מפתחים נתקלים בבעיה של 'תשישות מאפליקציות' כשהמוצרים שלהם נכנסים לשוק. לרוב, משתמשים רוצים להבין מה הערך שהאפליקציה מספקת להם לפני שהם מורידים אותה. בחנות, שבה הקונים חוסכים זמן על ידי MishiPay ומשפרים את החוויה שלהם, לא הגיוני להמתין להורדה לפני שיוכלו להשתמש באפליקציה. כאן נכנסת לתמונה אפליקציית ה-PWA שלנו. בעקבות הסרת מחסום הכניסה, הגדילנו את מספר העסקאות פי 10 והמשתמשים שלנו חוסכים 2.5 שנים של המתנה בתור.

תודות

המאמר הזה נבדק על ידי Joe Medley.