Descubre cómo cambiar a la AWP ayudó a la empresa de MishiPay.
MishiPay permite a los compradores escanear y pagar sus compras con sus smartphones, en lugar de perder tiempo haciendo cola 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 salir de la tienda. Los estudios revelan que las filas en las tiendas le cuestan al sector minorista global alrededor de USD 200,000 millones anuales.
Nuestra tecnología se basa en las capacidades de hardware de los dispositivos, como los sensores GPS y las cámaras, que permiten a los usuarios ubicar tiendas compatibles con MishiPay, escanear los códigos de barras de los artículos dentro de la tienda física y, luego, pagar con la forma de pago digital que elijan. Las versiones iniciales de nuestra tecnología de Scan & Go eran aplicaciones específicas de iOS y Android, y a los usuarios pioneros les encantó. Sigue leyendo para descubrir cómo cambiar a una AWP aumentó las transacciones 10 veces y ahorró 2.5 años de colas.
10×
Aumento de las transacciones
2.5 años
Se guardaron las filas
Desafío
Los usuarios encuentran nuestra tecnología muy útil cuando esperan en una cola o en una fila para pagar, ya que les permite evitar la cola 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 eligieran nuestra tecnología a pesar del valor. Era un desafío creciente para MishiPay, y necesitábamos aumentar la adopción de los usuarios con una barrera de entrada más baja.
Solución
Nuestros esfuerzos para crear y lanzar la AWP nos ayudaron a quitar las molestias de la instalación y a motivar a los usuarios nuevos a probar nuestra tecnología en una tienda física, omitir la cola y tener una experiencia de compra sin inconvenientes. Desde el lanzamiento, observamos un aumento significativo en la adopción de usuarios con nuestra AWP en comparación con nuestras aplicaciones específicas de la plataforma.
Análisis técnico detallado
Cómo encontrar 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 funcionó bien en las versiones anteriores de la app, pero más adelante 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 lista creciente de tiendas compatibles con MishiPay por región requiere que los usuarios se desplacen por una lista y identifiquen la tienda correcta.
- En ocasiones, los usuarios eligen accidentalmente la tienda incorrecta, lo que hace que las compras se registren de forma incorrecta.
Para abordar estos problemas, incorporamos códigos QR geolocalizados únicos en las pantallas de cada tienda. Abrió el camino para una experiencia de integración más rápida. Los usuarios solo deben escanear los códigos QR geolocalizados impresos en el material de marketing presente en las tiendas para acceder a la aplicación web de Scan & Go.
De esta manera, puede evitar escribir la dirección web mishipay.shop
para acceder al servicio.
Escanea 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 en curso incluso antes de llegar a un registro de caja.
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 retrovisora del usuario con las restricciones que se indican a continuación. Invocar el método activa automáticamente un mensaje para que los usuarios acepten o rechacen el acceso a su cámara. Una vez que tengamos acceso al flujo de video, podremos retransmitirlo 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 determinada, debemos capturar marcos 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');
}
}
En el caso de los casos de uso avanzados, esta capa también realiza algunas tareas de procesamiento previo, como recortar, girar o convertir a escala de grises. Estas tareas pueden ser intensivas en la CPU y provocar que la aplicación
deje de responder, 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 transferir la tarea intensiva de la 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 mucho uso de la CPU.
Capa de decodificación
La capa final es la capa de decodificación, que se encarga de decodificar los códigos de barras de las tramas que captura la capa de procesamiento. Gracias a la API de Shape Detection (que aún no está disponible en todos los navegadores), el navegador decodifica el código de barras de un ImageBitmapSource
, que puede ser un elemento img
, un elemento image
SVG, un elemento video
, un elemento canvas
, un objeto Blob
, un objeto ImageData
o un objeto 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;
}
}
Para 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
Existen varias bibliotecas de análisis empresariales y de código abierto que se pueden integrar fácilmente con 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 mencionadas anteriormente. También exponen interfaces para admitir varias operaciones de escaneo. Según los formatos de códigos de barras y la velocidad de detección necesarios para el caso de éxito, se puede tomar una decisión entre las soluciones Wasm y no 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 las que no son de Wasm en términos de precisión.
Scandit fue nuestra primera opción. Admite todos los formatos de código de barras necesarios para nuestros casos de uso comerciales y supera a todas las bibliotecas de código abierto disponibles en velocidad de escaneo.
El futuro del escaneo
Una vez que la API de Shape Detection sea compatible por completo con todos los navegadores principales, es posible que tengamos un nuevo elemento HTML <scanner>
que tenga las capacidades necesarias para un escáner de códigos de barras. El equipo de Ingeniería de MishiPay cree que hay 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 creciente cantidad de bibliotecas de código abierto y con licencia que permiten experiencias como Scan & Go y muchas otras.
Conclusión
El cansancio por apps es un problema que enfrentan los desarrolladores cuando sus productos ingresan al mercado. A menudo, los usuarios quieren comprender el valor que les brinda una aplicación antes de descargarla. En una tienda, donde MishiPay ahorra tiempo a los compradores y mejora su experiencia, no es intuitivo esperar una descarga antes de poder usar una aplicación. Aquí es donde nuestra AWP puede ayudar. Cuando eliminamos la barrera de entrada, aumentamos nuestras transacciones 10 veces y permitimos que nuestros usuarios ahorraran 2.5 años de espera en la cola.
Agradecimientos
Joe Medley revisó este artículo.