Descubre cómo cambiarse a la AWP ayudó al negocio de MishiPay.
MishiPay permite que los compradores analicen y paguen sus compras con sus smartphones, en lugar de perder el tiempo haciendo fila en la confirmación de la compra. Con la tecnología Scan & Go de MishiPay, los compradores pueden usar su propio teléfono para escanear el código de barras de los artículos y pagarlos, y, luego, abandonar la tienda. Los estudios revelan que las colas en las tiendas le cuestan al sector global de venta minorista alrededor de $200,000 millones al año.
Nuestra tecnología se basa en capacidades de hardware del dispositivo, como sensores GPS y cámaras, que permiten a los usuarios ubicar las tiendas habilitadas para MishiPay, escanear códigos de barras de artículos dentro de las tiendas físicas y, luego, pagar con la forma de pago digital que prefieran. Las versiones iniciales de nuestra tecnología Scan & Go eran aplicaciones para iOS y Android específicas de la plataforma y a los usuarios pioneros les encanta esta tecnología. Continúa leyendo para descubrir cómo el cambio a una AWP aumentó 10 veces las transacciones y ahorró 2.5 años de espera en la fila.
10×
Aumento de las transacciones
2.5 años
Se guardó la fila
Desafío
Nuestra tecnología les resulta extremadamente útil a los usuarios cuando esperan en una fila o fila de salida, ya que les permite omitir la fila y tener una experiencia fluida en la tienda. Sin embargo, la molestia de descargar una aplicación para Android o iOS hizo que los usuarios no elijan nuestra tecnología a pesar de su valor. Fue un desafío creciente para MishiPay, y necesitábamos aumentar la adopción por parte de los usuarios con una barrera de entrada más baja.
Solución
Nuestros esfuerzos por compilar y lanzar la AWP nos ayudaron a quitar las complicaciones de la instalación y animamos a los usuarios nuevos a probar nuestra tecnología en una tienda física, omitir la fila y tener una experiencia de compra fluida. Desde el lanzamiento, observamos un aumento repentino en la adopción por parte de los usuarios con nuestra AWP en comparación con las aplicaciones específicas de nuestra plataforma.
![Transacciones por plataforma. ¡OS: 16397 (3.98%). Android: 13,769 (3.34%) Web: 382184 (92.68%).](https://web.dev/static/case-studies/mishipay/image/transactions-platform-3f29e33b0839e.png?authuser=7&hl=es)
Análisis técnico detallado
Ubica las tiendas habilitadas para MishiPay
Para habilitar esta función, usamos la API de getCurrentPosition()
junto con una solución de resguardo basada en 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,
);
Este enfoque funcionaba bien en las versiones anteriores de la app, pero más tarde se demostró que era un gran problema para los usuarios de MishiPay por los siguientes motivos:
- Inexactitudes de ubicación en las soluciones de resguardo basadas en IP.
- Una ficha en crecimiento de tiendas habilitadas para MishiPay por región requiere que los usuarios se desplacen por una lista y, luego, identifiquen la tienda correcta.
- A veces, los usuarios eligen una tienda incorrecta por accidente, lo que provoca que las compras se registren de manera incorrecta.
Para solucionar estos problemas, incorporamos códigos QR únicos con ubicación geográfica en las pantallas de cada tienda. Sirvió como precedente para una experiencia de incorporación más rápida. Los usuarios solo tienen que escanear los códigos QR ubicados geográficamente impresos en el material de marketing que se encuentra en las tiendas para acceder a la aplicación web Scan & Go.
De esta manera, pueden evitar escribir la dirección web mishipay.shop
para acceder al servicio.
Escaneo de productos
Una función principal de la app de MishiPay es el escaneo de códigos de barras, ya que permite a los usuarios escanear sus propias compras y ver el total acumulado incluso antes de que, de otro modo, se hubieran alcanzado a una caja registradora.
Para crear una experiencia de escaneo en la Web, identificamos tres capas principales.
Transmisión de video por Internet
Con la ayuda del método getUserMedia()
, podemos acceder a la cámara posterior del usuario con las restricciones que se indican a continuación. Cuando se invoca el método, se activa automáticamente un mensaje para que los usuarios acepten o rechacen el acceso a la cámara. Una vez que tengamos acceso a la transmisión de video por Internet, podemos retransmitirla a un elemento de video, como se muestra a continuación:
/**
* 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!!`);
}
}
Capa de procesamiento
Para detectar un código de barras en una transmisión de video por Internet determinada, necesitamos capturar fotogramas de forma periódica y transferirlos a la capa del decodificador. Para capturar un fotograma, simplemente dibujamos las transmisiones de VideoElement
en un HTMLCanvasElement
con el método drawImage()
de la API de Canvas.
/**
* 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');
}
}
Para casos de uso avanzados, esta capa también realiza algunas tareas de procesamiento previo, como recortar, rotar o convertir a escala de grises. Estas tareas pueden consumir mucha CPU y pueden hacer que la aplicación no responda, ya que el escaneo de códigos de barras es una operación de larga duración. Con la ayuda de la API de OffscreenCanvas, podemos descargar las tareas con uso intensivo de CPU a un trabajador web. En los dispositivos que admiten la aceleración de gráficos por hardware, la API de WebGL y su WebGL2RenderingContext
pueden optimizar las ganancias en las tareas de procesamiento previo que requieren mucha CPU.
Capa del decodificador
La capa final es la capa de decodificador que se encarga de decodificar los códigos de barras de los fotogramas que captura la capa de procesamiento. Gracias a la API de Shape Detection (que aún no está disponible en todos los navegadores), el propio navegador decodifica el código de barras de un ImageBitmapSource
, que puede ser img
, SVG image
, video
, canvas
, Blob
, ImageData
o 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;
}
}
En el caso de los dispositivos que aún no admiten la API de Shape Detection, necesitamos una solución de resguardo para decodificar los códigos de barras. La API de Shape Detection expone un método getSupportedFormats()
que ayuda a cambiar entre la API de Shape Detection y la solución de resguardo.
// Feature detection.
if (!('BarceodeDetector' in window)) {
return;
}
// Check supported barcode formats.
BarcodeDetector.getSupportedFormats()
.then((supportedFormats) => {
supportedFormats.forEach((format) => console.log(format));
});
Solución de resguardo
Hay varias bibliotecas de análisis empresarial y de código abierto disponibles que se pueden integrar fácilmente en cualquier aplicación web para implementar el análisis. Estas son algunas de las bibliotecas que recomienda MishiPay.
Todas las bibliotecas anteriores son SDKs completos que componen todas las capas que se analizaron anteriormente. También exponen interfaces que admiten varias operaciones de análisis. Según los formatos de códigos de barras y la velocidad de detección necesarias para el caso empresarial, la decisión puede determinarse entre las soluciones de Wasm y las que no son de Wasm. A pesar de la sobrecarga de requerir un recurso adicional (Wasm) para decodificar el código de barras, las soluciones de Wasm superan a la solución que no es de Wasm en términos de precisión.
Scandit fue nuestra elección principal. Es compatible con todos los formatos de códigos de barras necesarios para nuestros casos de uso empresariales y supera todas las bibliotecas de código abierto disponibles en cuanto a la velocidad de escaneo.
El futuro de la búsqueda
Una vez que la API de Shape Detection es completamente compatible con todos los navegadores principales, podríamos tener un nuevo elemento HTML <scanner>
con las capacidades necesarias para un escáner de código de barras. En Ingeniería en MishiPay, cree que existe un caso de uso sólido para que la funcionalidad de escaneo de códigos de barras sea un nuevo elemento HTML debido a la cantidad creciente de bibliotecas de código abierto y con licencia que habilitan experiencias como Scan & Go y muchas otras.
Conclusión
El cansancio de la app es un problema que enfrentan los desarrolladores cuando sus productos ingresan al mercado. A menudo, los usuarios quieren comprender el valor que les ofrece una aplicación antes de descargarla. En una tienda, en la que MishiPay les ahorra tiempo a los compradores y mejoran su experiencia, es contradictorio esperar a que se descargue una descarga antes de que puedan usar una aplicación. Aquí es donde nuestra AWP puede ser de ayuda. Cuando eliminamos la barrera de entrada, aumentamos 10 veces nuestras transacciones y permitimos a nuestros usuarios ahorrar 2.5 años de espera en la cola.
Agradecimientos
Joe Medley revisó este artículo.