Saiba como a mudança para o PWA ajudou os negócios da MishiPay.
O MishiPay permite que os compradores digitalizem e paguem pelas compras com smartphones, em vez de perdendo tempo na fila do caixa. Com os métodos Scan & Go, os compradores podem usar o próprio smartphone para ler o código de barras dos itens e pagar, da loja. Os estudos revelam que o processo de filas na loja custa ao setor de varejo global cerca de US $200 bilhões por ano.
Nossa tecnologia depende de recursos de hardware do dispositivo, como câmeras e sensores de GPS que permitem os usuários localizarem lojas que usam o MishiPay, lerem códigos de barras de itens na loja física e pagarem usando a forma de pagamento digital que preferirem. As versões iniciais da nossa biblioteca Tecnologia Go eram aplicativos iOS e Android específicos da plataforma, e os primeiros usuários adoraram a tecnologia. Lida para saber como mudar para um PWA aumentou as transações em 10 vezes e economizou 2,5 anos na fila.
10×
Mais transações
2,5 anos
Fila salva
Desafio
Os usuários acham nossa tecnologia extremamente útil ao esperar em uma fila ou fila de check-out, pois permite a pular a fila e ter uma experiência tranquila na loja. Mas o incômodo de fazer o download O aplicativo Android ou iOS fez com que os usuários não escolhessem nossa tecnologia, apesar do valor. Foi um crescimento para o MishiPay, e precisávamos aumentar a adoção dos usuários com uma barreira menor de entrada.
Solução
Nossos esforços na criação e lançamento do PWA nos ajudaram a eliminar a complicação da instalação e encorajamos novos usuários a testar nossa tecnologia em uma loja física, pular a fila e ter um uma experiência de compra perfeita. Desde o lançamento, vimos um grande pico na adoção dos usuários com nosso PWA em comparação com nossos aplicativos específicos da plataforma.
![Transações por plataforma. SO: 16.397 (3,98%). Android: 13.769 (3,34%). Web: 382184 (92,68%).](https://web.dev/static/case-studies/mishipay/image/transactions-platform-3f29e33b0839e.png?authuser=9&hl=pt)
Detalhes técnicos
Localização de lojas que aceitam o MishiPay
Para ativar esse recurso, contamos com o
getCurrentPosition()
com uma solução substituta baseada em 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,
);
Essa abordagem funcionou bem nas versões anteriores do aplicativo, mas foi comprovadamente um grande problema para os usuários do MishiPay pelos seguintes motivos:
- Imprecisões de localização nas soluções de substituição baseadas em IP.
- A lista crescente de lojas compatíveis com o MishiPay por região exige que os usuários rolem a lista e identificar a loja correta.
- Às vezes, os usuários escolhem acidentalmente a loja errada, fazendo com que as compras sejam registradas. de forma incorreta.
Para resolver esses problemas, incorporamos códigos QR exclusivos geolocalizados nas vitrines das lojas para cada
loja on-line. Isso abriu caminho para uma experiência de integração mais rápida. Os usuários só precisam ler o QR code geolocalizado
impressos em materiais de marketing presentes nas lojas para acessar o recurso Aplicativo da Web Go.
Assim, eles não precisam digitar o endereço da Web mishipay.shop
para acessar o serviço.
Como verificar produtos
Um recurso importante do app MishiPay é a leitura de código de barras, que permite que nossos usuários leiam os próprios suas próprias compras e ver o total das compras antes mesmo que elas atingissem o dinheiro se registrar.
Para criar uma experiência de digitalização na Web, identificamos três camadas principais.
Stream de vídeo
Com a ajuda da
método getUserMedia()
,
pode acessar a câmera traseira do usuário com as restrições listadas abaixo. Como invocar o método
aciona automaticamente uma solicitação para os usuários aceitarem ou negarem o acesso à câmera. Assim que tivermos
acesso ao stream de vídeo, podemos retransmiti-lo para um elemento de vídeo, conforme mostrado abaixo:
/**
* 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!!`);
}
}
Camada de processamento
Para detectar um código de barras em um stream de vídeo, precisamos capturar periodicamente quadros e transferir
para a camada decodificador. Para capturar um frame, simplesmente desenhamos os streams de VideoElement
para
um HTMLCanvasElement
usando o
drawImage()
da API 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 avançados, essa camada também realiza algumas tarefas de pré-processamento, como corte,
rotação ou conversão para escala de cinza. Essas tarefas podem consumir muita CPU e resultar
não responde, já que a leitura do código de barras é uma operação de longa duração. Com a ajuda da
OffscreenCanvas, podemos descarregar
a tarefa com uso intensivo de CPU a um web worker. Em dispositivos com suporte
a aceleração gráfica de hardware,
A API WebGL e seus
WebGL2RenderingContext
pode
otimizar os ganhos nas tarefas de pré-processamento com uso intensivo da CPU.
Camada do decodificador
A camada final é a camada decodificadora, responsável por decodificar os códigos de barras dos frames
são capturados pela camada de processamento. Graças à
API Shape Detection (que é
ainda não está disponível em todos os navegadores), o próprio navegador decodifica o código de barras a partir de uma
ImageBitmapSource
, que pode ser um elemento img
, um elemento image
SVG, um elemento video
, um
canvas
, um objeto Blob
, um objeto ImageData
ou um 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 dispositivos que ainda não têm suporte à API Shape Detection, precisamos de uma solução substituta para decodificar
os códigos de barras. A API Shape Detection expõe uma
getSupportedFormats()
que ajuda a alternar entre a API Shape Detection e a solução substituta.
// Feature detection.
if (!('BarceodeDetector' in window)) {
return;
}
// Check supported barcode formats.
BarcodeDetector.getSupportedFormats()
.then((supportedFormats) => {
supportedFormats.forEach((format) => console.log(format));
});
Solução substituta
Várias bibliotecas de código aberto e de varredura empresarial estão disponíveis e podem ser facilmente integradas com qualquer aplicativo da Web para implementar a verificação. Estas são algumas das bibliotecas que o MishiPay que recomendamos.
Todas as bibliotecas acima são SDKs completos que compõem todas as camadas discutidas acima. Eles também expor interfaces para dar suporte a várias operações de verificação. Dependendo dos formatos de código de barras e de detecção do caso de negócios, é possível decidir entre soluções Wasm e não Wasm. Apesar da sobrecarga de exigir um recurso adicional (Wasm) para decodificar o código de barras, o Wasm em termos de acurácia, as soluções superam as soluções não Wasm.
O Scandit foi nossa principal escolha. Compatível com todos os códigos de barras formatos necessários para nossos casos de uso comerciais; ele supera todas as bibliotecas de código aberto disponíveis em e a velocidade de leitura.
O futuro da verificação
Depois que a API Shape Detection tiver suporte total em todos os principais navegadores, poderemos ter
novo elemento HTML <scanner>
que tem os recursos necessários para um leitor de código de barras. Engenharia
da MishiPay acredita que há um bom caso de uso para que a funcionalidade de leitura de código de barras seja uma nova
Elemento HTML, devido ao crescente número de bibliotecas de código aberto e licenciadas que estão permitindo
experiências como Scan & Go e muitos outros.
Conclusão
O desgaste do app é um problema que os desenvolvedores enfrentam quando seus produtos entram no mercado. Os usuários muitas vezes querem para entender o valor que um aplicativo oferece antes de fazer o download. Em uma loja, onde O MishiPay economiza e melhorar a experiência, não é intuitivo esperar fazer o download antes de usar um aplicativo. É aqui que nosso PWA ajuda. Ao eliminar a barreira do Google, aumentamos nossas transações em 10 vezes e permitimos que nossos usuários economizassem 2,5 anos de esperando na fila.
Agradecimentos
Este artigo foi revisado por Joe Medley.