Aplicativo Android nativo desenvolvido em Kotlin e Jetpack Compose para venda de ingressos de eventos locais, com suporte a carrinho multieventos, emissão de bilhetes digitais com QR Code e integração transacional completa com Emulador Cielo via protocolo Deep Link.
- Listagem responsiva de eventos em cards com detalhes (título, categoria, data, horário, local e preço).
- Isolamento de clique: navegação acionada exclusivamente pelo botão "Visualizar evento".
- Barra superior com contador/badge dinâmica do carrinho (com formatação inteligente
99+) e botão de acesso aos Ingressos Comprados.
- Informações completas do evento selecionado.
- Seletor de ingressos com reset automático em 1 ingresso a cada abertura e limites de 1 a 10 unidades.
- Botão compacto para adicionar ao carrinho ou botão "Pagar" para compra imediata consolidada no carrinho.
- Gerenciamento de múltiplos itens com ajuste unitário (+ e -) e cálculo de subtotal em tempo real.
- Modais de confirmação bloqueantes para exclusão individual ou limpeza total do carrinho (
dismissOnClickOutside = false). - Estado vazio ilustrado com botão CTA de retorno ao catálogo.
- Rodapé seguro com respeito aos insets do sistema Android (
navigationBarsPadding).
- Resumo financeiro consolidado de todos os ingressos adquiridos.
- Seletor moderno de pagamento Material 3 (
ExposedDropdownMenuBox) com ícones para:- Cartão de Crédito (
CREDITO_AVISTA) - Cartão de Débito (
DEBITO_AVISTA) - Pix (
PIX)
- Cartão de Crédito (
- Idempotência Garantida: Todo pedido gera ou reutiliza um
orderId(UUID) gravado comoPENDINGno banco Room local antes de disparar o terminal de pagamento. - Trava de UI: Controle estrito de concorrência com
AtomicBooleanpara prevenir duplos cliques ou disparos paralelos. - Suporte a pagamento direto de pedidos pendentes preservando a referência original.
- Exibição pós-sucesso com dados completos da transação (ID do Pedido, NSU, Código de Autorização, Forma de Pagamento e Data/Hora).
- Geração de QR Code multi-linha escaneável contendo o payload estruturado do bilhete (identificador, evento, quantidade e código de autorização).
- Limpeza automática do carrinho após conclusão da compra.
- Fonte da Verdade da Cielo: Consulta em tempo real das ordens processadas pelo terminal da Cielo via Deep Link (
lio://orders). - Enriquecimento Local: Cruzamento dos pedidos retornados pela Cielo com o banco de dados Room local (
OrderEntity.paymentMethod), garantindo a exibição exata da modalidade escolhida (CRÉDITO À VISTA,DÉBITO,PIX). - Pagamento de Pendentes: Pedidos com status
PENDENTEexibem o botão "Pagar" para quitação imediata mantendo a chave de idempotência. - Estorno & Cancelamento: Pedidos
PAGOexibem o botão de cancelamento, abrindo modal de confirmação bloqueante e disparando o fluxo de estorno da Cielo (lio://payment-reversal). - Visualização de Ingresso: Modal dedicado não-descartável por toque externo para visualização do QR Code do ingresso.
Assista ao vídeo demonstrando o fluxo completo do aplicativo (Catálogo de eventos, Carrinho multieventos, Checkout com deep link, Pagamento no Emulador Cielo, Comprovante com QR Code, Histórico de compras e Estorno):
📹 Demo (arquivo local disponível em docs/demo_cielo.mp4)
- Android Studio Ladybug (2024.2+) ou superior / IntelliJ IDEA.
- JDK 17 configurado.
- Dispositivo Físico ou Emulador Android com o APK do Emulador Cielo instalado.
-
Clonar o repositório:
git clone https://github.com/thideoli/cielo-test.git cd CieloTest -
Executar a suíte de testes unitários:
./gradlew testDebugUnitTest
-
Compilar e instalar o app no dispositivo/emulador:
./gradlew installDebug
-
Baixar o Emulador Oficial da Cielo:
curl -LO https://s3-sa-east-1.amazonaws.com/cielo-lio-store/apps/lio-emulator/1.61.8/lio-emulator.apk
-
Instalar o Emulador Oficial da Cielo:
adb install -r lio-emulator.apk
- Clean Architecture + MVVM: Separação clara entre Camada de Apresentação (Compose + ViewModels), Domínio (Modelos, Contratos e Casos de Uso) e Dados (Room DAOs, Entidades e Repositórios).
- Única Fonte da Verdade: O
CartRepositoryem memória gerencia o estado global do carrinho viaStateFlow<Cart>, enquanto oOrderRepositorypersiste pedidos e ingressos no Room Database. - Valores Monetários em Centavos (
Long): Prevenção de erros de arredondamento de ponto flutuante; todos os cálculos e payloads transitam em centavos inteiros (amountInCents). - Tratamento Resiliente do Ciclo de Vida Android: Disparo de Deep Links da Cielo via
Intent(Intent.ACTION_VIEW)com esquema de callback dedicado (cielotest://), interceptado viaonNewIntentnaMainActivitye repassado aos ViewModels correspondentes. - Navegação Contextual com
BackHandler: Cada tela controla o fluxo de retorno de acordo com sua origem (from = "detail",from = "cart"oufrom = "purchased").
| Biblioteca | Finalidade |
|---|---|
| Jetpack Compose & Material 3 | Construção da interface declarativa e responsiva. |
| Compose Navigation | Gerenciamento de rotas e navegação entre telas. |
| Room Database (SQLite) | Persistência local de pedidos, status e ingressos emitidos. |
| Kotlin Coroutines & Flow | Programação assíncrona reativa e gerenciamento de estado (StateFlow). |
| ZXing Android Embedded | Geração e renderização de QR Codes em alta definição. |
| JUnit 4, MockK & Turbine | Testes unitários com mock estático e validação reativa de fluxos de coroutines. |
A comunicação com o emulador Cielo ocorre via Deep Links codificados em Base64:
| Operação | Endpoint Cielo | Endpoint de Retorno (Callback) |
|---|---|---|
| Pagamento | lio://payment?request={BASE64}&urlCallback={CALLBACK} |
cielotest://payment_result |
| Listar Pedidos | lio://orders?request={BASE64}&urlCallback={CALLBACK} |
cielotest://orders_result |
| Estorno / Cancelamento | lio://payment-reversal?request={BASE64}&urlCallback={CALLBACK} |
cielotest://reversal_result |
Para documentação técnica aprofundada de payloads JSON, mapeamento de códigos e respostas, consulte: 👉 Guia Técnico de Deep Links Cielo.
- Consulta Cielo vs. Banco Local:
- Decisão: A tela de Ingressos Comprados usa o serviço da Cielo (
lio://orders) como fonte primária para status transacional e histórico fiscal, mas complementa as informações com o banco Room local (OrderEntity) para garantir fidelidade das formas de pagamento escolhidas pelo usuário, contornando limitações de mock estático de emuladores.
- Decisão: A tela de Ingressos Comprados usa o serviço da Cielo (
- Carrinho em Memória vs. Persistência:
- Decisão: O carrinho ativo é mantido em memória via
StateFlowpara máxima velocidade de interação durante a montagem do pedido. Apenas no momento do Checkout o pedido é formalizado no Room comoPENDING, garantindo idempotência antes de acionar a Cielo.
- Decisão: O carrinho ativo é mantido em memória via
- Modais Críticos Não-Descartáveis:
- Decisão: Diálogos de exclusão, estorno financeiro e visualização de QR Code utilizam
dismissOnClickOutside = falseedismissOnBackPress = falsepara evitar cancelamentos ou fechamentos acidentais por toque na tela.
- Decisão: Diálogos de exclusão, estorno financeiro e visualização de QR Code utilizam
- 🎟️ QR Code Individual por Ingresso Comprado:
- Emissão de ingressos com identificadores e QR Codes exclusivos para cada unidade adquirida (mesmo dentro de compras multieventos ou de múltiplos ingressos), viabilizando validação e leitura individual na catraca/portaria do evento.
- 📄 Paginação do Histórico de Pedidos (
lio://orderscom Infinite Scroll):- Implementação de paginação reativa via Android Jetpack Paging 3 consumindo os parâmetros
pageepageSizedo contrato da Cielo, permitindo carregamento contínuo e sob demanda em pontos de venda com alto volume diário de transações.
- Implementação de paginação reativa via Android Jetpack Paging 3 consumindo os parâmetros
- 💳 Expansão de Formas de Pagamento (Crédito Parcelado):
- Suporte a parcelamento de compras no cartão de crédito (
CREDITO_PARCELADO_LOJAeCREDITO_PARCELADO_ADM), com seletor de número de parcelas (2x a 12x), cálculo de valor por parcela e repasse do campoinstallmentsno payload transacional da Cielo.
- Suporte a parcelamento de compras no cartão de crédito (
- 🧪 Testes de UI Instrumentados & Regressão Visual:
- Construção de suíte de testes de UI instrumentados com
createComposeRulepara validação de fluxos de ponta a ponta (E2E) e testes de regressão visual (Screenshot Testing com Roborazzi ou Paparazzi).
- Construção de suíte de testes de UI instrumentados com
- 🖨️ Impressão (
lio://print):- Disparo do deep link de impressão para emissão do comprovante físico com QR Code após a confirmação do pagamento.
A base de código possui 59 testes automatizados com 100% de aprovação:
CieloPaymentParserTest: Validação de retornos transacionais da Cielo (Sucesso, Erro, Cancelamento).CieloOrdersParserTest: Validação de listagem de ordens, paginação e decodificação Base64.CieloReversalParserTest: Validação de cancelamento e estorno.CheckoutViewModelTest: Idempotência, concorrência e fluxos de pagamento.PurchasedTicketsViewModelTest: Consolidação de duplicatas, priorização de status e enriquecimento com repositório local.CartViewModelTest&CartRepositoryTest: Lógica de adição, incremento, decremento e limpeza do carrinho.EventDetailViewModelTest&EventListViewModelTest: Estados de UI e catálogo.OrderRepositoryTest: Persistência Room e transição de status.