ดูว่าการเปลี่ยนไปใช้ PWA ช่วยธุรกิจของ MishiPay ได้อย่างไร
MishiPay ช่วยให้ผู้เลือกซื้อสแกนและชำระเงินเพื่อช็อปปิ้งด้วยสมาร์ทโฟน แทนที่จะต้องเสียเวลาเข้าคิวที่จุดชำระเงิน เทคโนโลยี Scan & Go ของ MishiPay ช่วยให้ผู้เลือกซื้อสามารถใช้โทรศัพท์ของตนเองสแกนบาร์โค้ดบนสินค้าและชำระเงิน จากนั้นจึงออกจากร้านค้า การศึกษาเผยให้เห็นว่าการจัดคิวในร้านค้ามีค่าใช้จ่ายภาคการค้าปลีกทั่วโลกประมาณ 2 แสนล้านดอลลาร์ต่อปี
เทคโนโลยีของเราอาศัยความสามารถของฮาร์ดแวร์ของอุปกรณ์ เช่น เซ็นเซอร์และกล้อง GPS ที่ช่วยให้ผู้ใช้ค้นหาร้านค้าที่เปิดใช้ MishiPay, สแกนบาร์โค้ดสินค้าในหน้าร้านจริง แล้วชำระเงินโดยใช้วิธีการชำระเงินแบบดิจิทัลที่ต้องการ เทคโนโลยี Scan & Go เวอร์ชันเริ่มต้นของเราคือแอปพลิเคชัน iOS และ Android เฉพาะแพลตฟอร์ม ซึ่งลูกค้ารายแรกสุดที่เปิดรับนวัตกรรมนั้นชื่นชอบเทคโนโลยีนี้ อ่านต่อเพื่อดูวิธีที่การเปลี่ยนไปใช้ PWA ช่วยให้ธุรกรรมเพิ่มขึ้นถึง 10 เท่าและช่วยให้อยู่ในคิวได้ถึง 2.5 ปี
10×
ธุรกรรมที่เพิ่มขึ้น
2.5 ปี
บันทึกการจัดคิวแล้ว
ชาเลนจ์
ผู้ใช้พบว่าเทคโนโลยีของเรามีประโยชน์อย่างมากขณะต่อคิวหรือชำระเงิน เนื่องจากช่วยให้ผู้ใช้ไม่ต้องต่อคิวและได้รับประสบการณ์การใช้งานในร้านค้าที่ราบรื่น แต่ความยุ่งยากในการดาวน์โหลดแอปพลิเคชัน Android หรือ iOS ทำให้ผู้ใช้ไม่เลือกเทคโนโลยีของเราแม้จะมีประโยชน์ ถือเป็นความท้าทายมากขึ้นเรื่อยๆ สำหรับ MishiPay และเราจำเป็นต้องเพิ่มการรับไปใช้งานของผู้ใช้ด้วยอุปสรรคที่ต่ำลงในการเข้าใช้งาน
โซลูชัน
ความพยายามของเราในการสร้างและเปิดตัว PWA ช่วยลดความยุ่งยากในการติดตั้ง และกระตุ้นให้ผู้ใช้ใหม่ลองใช้เทคโนโลยีภายในกิจการที่มีหน้าร้านจริง โดยไม่ต้องต่อคิว และได้รับประสบการณ์การช็อปปิ้งที่ราบรื่น นับตั้งแต่เปิดตัว เราพบว่าการใช้งานของผู้ใช้ด้วย PWA มีจำนวนเพิ่มขึ้นอย่างมากเมื่อเทียบกับแอปพลิเคชันเฉพาะแพลตฟอร์ม
![ธุรกรรมตามแพลตฟอร์ม ¡OS: 16397 (3.98%) Android: 13769 (3.34%) เว็บ: 382184 (92.68%)](https://web.dev/static/case-studies/mishipay/image/transactions-platform-3f29e33b0839e.png?authuser=6&hl=th)
เจาะลึกทางเทคนิค
การค้นหาร้านค้าที่เปิดใช้ 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 ซึ่งมีจำนวนมากขึ้นเรื่อยๆ ในแต่ละภูมิภาคทำให้ผู้ใช้ต้องเลื่อนดูรายการและระบุร้านค้าที่ถูกต้อง
- ผู้ใช้เลือกร้านค้าผิดในบางครั้งโดยไม่ตั้งใจ ทำให้บันทึกการซื้อไม่ถูกต้อง
เพื่อแก้ไขปัญหาเหล่านี้ เราได้ฝังคิวอาร์โค้ดที่มีตำแหน่งทางภูมิศาสตร์ที่ไม่ซ้ำกันบนจอแสดงผลในร้านค้าของแต่ละร้าน โดยได้กรุยทางไปสู่ประสบการณ์การเริ่มต้นใช้งานที่เร็วขึ้น ผู้ใช้เพียงสแกนคิวอาร์โค้ดตำแหน่งทางภูมิศาสตร์ที่พิมพ์ลงในสื่อการตลาดที่มีอยู่ในร้านค้าเพื่อเข้าถึงเว็บแอปพลิเคชัน Scan & Go
ซึ่งจะช่วยให้ผู้ใช้ไม่ต้องพิมพ์ที่อยู่เว็บ 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!!`);
}
}
เลเยอร์การประมวลผล
สำหรับการตรวจจับบาร์โค้ดในสตรีมวิดีโอหนึ่งๆ เราจำเป็นต้องจับภาพเฟรมและโอนไปยังเลเยอร์ตัวถอดรหัสเป็นระยะๆ ในการจับภาพเฟรม เพียงวาดสตรีมจาก 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 ทำให้ระบบทำงานที่ใช้ 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 จะแสดงเมธอด 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));
});
โซลูชันสำรอง
มีไลบรารีการสแกนแบบโอเพนซอร์สและระดับองค์กรจำนวนมากซึ่งผสานรวมได้อย่างง่ายดายกับเว็บแอปพลิเคชันต่างๆ เพื่อใช้การสแกน นี่คือห้องสมุดบางส่วนที่ MishiPay แนะนำ
ไลบรารีข้างต้นทั้งหมดเป็น SDK เต็มรูปแบบซึ่งประกอบขึ้นเป็นเลเยอร์ทั้งหมดที่กล่าวถึงข้างต้น และยังมีอินเทอร์เฟซที่รองรับการดำเนินการสแกนต่างๆ ด้วย การตัดสินใจอาจอยู่ระหว่างโซลูชัน Wasm กับโซลูชันที่ไม่ใช่ Wasm ทั้งนี้ขึ้นอยู่กับรูปแบบบาร์โค้ดและความเร็วในการตรวจจับที่จำเป็นสำหรับกรณีทางธุรกิจ แม้ว่าจะมีค่าใช้จ่ายที่ต้องใช้ทรัพยากรเพิ่มเติม (Wasm) ในการถอดรหัสบาร์โค้ด แต่โซลูชัน Wasm ก็มีประสิทธิภาพมากกว่าโซลูชันที่ไม่ใช่ Wasm ในแง่ของความถูกต้อง
Scandit คือตัวเลือกหลักของเรา รองรับรูปแบบบาร์โค้ดทั้งหมดที่จำเป็นสำหรับกรณีการใช้งานทางธุรกิจของเรา ซึ่งเหนือกว่าไลบรารีโอเพนซอร์สทั้งหมดที่มีอยู่ในด้านความเร็วในการสแกน
อนาคตของการสแกน
เมื่อเบราว์เซอร์หลักๆ ทั้งหมดรองรับ Shape Detection API อย่างเต็มรูปแบบ เราอาจมีองค์ประกอบ HTML ใหม่ <scanner>
ที่มีความสามารถที่จำเป็นสำหรับเครื่องสแกนบาร์โค้ด ฝ่ายวิศวกรรมของ MishiPay เชื่อว่าฟังก์ชันการใช้งานการสแกนบาร์โค้ดเป็นองค์ประกอบ HTML ใหม่ที่ดี เนื่องจากมีไลบรารีโอเพนซอร์สและไลบรารีที่ได้รับอนุญาตจำนวนมากขึ้นเรื่อยๆ ซึ่งเปิดใช้ประสบการณ์การใช้งาน เช่น Scan & Go และอื่นๆ อีกมากมาย
บทสรุป
ความล้าของแอปเป็นปัญหาที่นักพัฒนาแอปพบเมื่อผลิตภัณฑ์เข้าสู่ตลาด ผู้ใช้มักต้องการเข้าใจคุณค่าที่แอปพลิเคชันมอบให้ก่อนที่จะดาวน์โหลด ในร้านค้าที่ MishiPay ประหยัดเวลาและปรับปรุงประสบการณ์การใช้งานของผู้เลือกซื้อ การรอดาวน์โหลดก่อนจึงจะใช้แอปพลิเคชันได้ ซึ่ง PWA ของเราสามารถช่วยได้ การขจัดอุปสรรคในการเข้าใช้งาน ทำให้เราได้รับธุรกรรมเพิ่มขึ้นถึง 10 เท่า และช่วยให้ผู้ใช้ประหยัดเวลาในการรอคิวได้นานถึง 2.5 ปี
ข้อความแสดงการยอมรับ
บทความนี้ได้รับการตรวจสอบโดย Joe Medley