بیاموزید که چگونه تغییر به PWA به کسب و کار MishiPay کمک کرد.
میشیپی به خریداران این امکان را میدهد که به جای اتلاف وقت در صف صندوق، با تلفنهای هوشمند خود خرید خود را اسکن و پرداخت کنند. با فناوری اسکن و برو میشیپی، خریداران میتوانند از تلفن خود برای اسکن بارکد روی اقلام و پرداخت هزینه آنها استفاده کنند و سپس فروشگاه را ترک کنند. مطالعات نشان میدهد که صف کشیدن در فروشگاه سالانه ۲۰۰ میلیارد دلار برای بخش خردهفروشی جهانی هزینه دارد .
فناوری ما به قابلیتهای سختافزاری دستگاه مانند حسگرهای GPS و دوربینها متکی است که به کاربران امکان میدهد فروشگاههای دارای قابلیت MishiPay را پیدا کنند، بارکد اقلام را در فروشگاه فیزیکی اسکن کنند و سپس با استفاده از روش پرداخت دیجیتال مورد نظر خود پرداخت را انجام دهند. نسخههای اولیه فناوری Scan & Go ما، برنامههای iOS و اندروید مخصوص پلتفرم بودند و کاربران اولیه عاشق این فناوری شدند. برای یادگیری نحوه افزایش 10 برابری تراکنشها و صرفهجویی 2.5 ساله در صف، ادامه مطلب را بخوانید!
۱۰ ×
افزایش تراکنشها
۲.۵ سال
صفبندی ذخیره شد
چالش
کاربران هنگام انتظار در صف یا صف صندوق، فناوری ما را بسیار مفید میدانند، زیرا به آنها امکان میدهد از صف عبور کنند و تجربهای روان در فروشگاه داشته باشند. اما دردسر دانلود اپلیکیشن اندروید یا iOS باعث شد کاربران با وجود ارزش، فناوری ما را انتخاب نکنند. این یک چالش رو به رشد برای MishiPay بود و ما باید پذیرش کاربران را با مانع ورود کمتر افزایش میدادیم.
راه حل
تلاشهای ما در ساخت و راهاندازی PWA به ما کمک کرد تا دردسر نصب را از بین ببریم و کاربران جدید را تشویق کنیم تا فناوری ما را در یک فروشگاه فیزیکی امتحان کنند، از صف انتظار عبور کنند و یک تجربه خرید بینقص داشته باشند. از زمان راهاندازی، شاهد افزایش چشمگیر پذیرش کاربران با PWA خود در مقایسه با برنامههای مختص پلتفرم خود بودهایم.

بررسی عمیق فنی
پیدا کردن فروشگاههای فعال شده با 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 با موقعیت جغرافیایی چاپ شده روی مواد بازاریابی موجود در فروشگاهها را اسکن میکنند تا به برنامه وب Scan & Go دسترسی پیدا کنند. به این ترتیب، آنها میتوانند از تایپ کردن آدرس وب mishipay.shop برای دسترسی به سرویس اجتناب کنند.
اسکن محصولات
یکی از ویژگیهای اصلی برنامه 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 با استفاده از متد drawImage() از API Canvas روی یک 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 را بهینه کنند.
لایه رمزگشا
لایه آخر، لایه رمزگشا است که مسئول رمزگشایی بارکدها از فریمهای ضبطشده توسط لایه پردازش است. به لطف API تشخیص شکل (که هنوز در همه مرورگرها در دسترس نیست)، خود مرورگر بارکد را از یک ImageBitmapSource رمزگشایی میکند، که میتواند یک عنصر img ، یک عنصر image SVG، یک عنصر 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;
}
}
برای دستگاههایی که هنوز از API تشخیص شکل (Shape Detection API) پشتیبانی نمیکنند، به یک راهحل جایگزین برای رمزگشایی بارکدها نیاز داریم. API تشخیص شکل، متدی به نام getSupportedFormats() ارائه میدهد که به جابجایی بین API تشخیص شکل و راهحل جایگزین کمک میکند.
// 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 انتخاب اصلی ما بود. این نرمافزار از تمام فرمتهای بارکد مورد نیاز برای موارد استفاده تجاری ما پشتیبانی میکند و از نظر سرعت اسکن، از تمام کتابخانههای متنباز موجود پیشی میگیرد.
آینده اسکن
زمانی که API تشخیص شکل به طور کامل توسط همه مرورگرهای اصلی پشتیبانی شود، میتوانیم یک عنصر HTML جدید <scanner> داشته باشیم که قابلیتهای مورد نیاز برای یک اسکنر بارکد را داشته باشد. مهندسی در MishiPay معتقد است که به دلیل افزایش تعداد کتابخانههای متنباز و دارای مجوز که تجربیاتی مانند Scan & Go و بسیاری دیگر را امکانپذیر میکنند، یک مورد استفاده قوی برای عملکرد اسکن بارکد به عنوان یک عنصر HTML جدید وجود دارد.
نتیجهگیری
خستگی از اپلیکیشن مشکلی است که توسعهدهندگان هنگام ورود محصولاتشان به بازار با آن مواجه میشوند. کاربران اغلب میخواهند قبل از دانلود یک اپلیکیشن، ارزش آن را درک کنند. در یک فروشگاه اینترنتی، جایی که MishiPay در زمان خریداران صرفهجویی میکند و تجربه آنها را بهبود میبخشد، انتظار برای دانلود اپلیکیشن قبل از استفاده از آن، خلاف عقل سلیم است. اینجاست که PWA ما به کمک میآید.
با حذف موانع ورود، تراکنشهای خود را 10 برابر افزایش دادهایم و به کاربران خود این امکان را دادهایم که 2.5 سال از انتظار در صف را صرفهجویی کنند.
تقدیرنامهها
این مقاله توسط جو مدلی بررسی شده است.