root@construct:~/projects/yooga$
<-- voltar para /projects

Yooga Pagamentos & SmartPOS

Pagamentos para 2.100+ lojistas numa plataforma com 7.000+ restaurantes

KotlinAndroidStone SDKJavaQuarkusKafka

>Contexto

A Yooga é um sistema operacional para restaurantes, com 7.000+ restaurantes. Pagamentos é a área que recebe o dinheiro das vendas e repassa ao lojista: 2.100+ lojistas estavam integrados na solução de pagamentos.

Entrei em setembro de 2023 como Senior Software Engineer em Pagamentos. Construí os fluxos centrais de transação do lojista, ciclos de cobrança e conciliação financeira, enquanto o domínio saía de um monólito para serviços. Em maio de 2025 fui promovido a Tech Lead e liderei o time de 5 engenheiros até agosto de 2026: arquitetura, roadmap com produto, suporte e comercial, padrões de code review e onboarding de quem chegava.

O bug que mais importava era o comum: o mesmo webhook entregue duas vezes, ou o cliente tocando em pagar de novo. Boa parte do trabalho foi tornar cada transação segura para rodar duas vezes, em dois provedores.

Também arquitetei e construí o SmartPOS, que leva a Yooga para dentro da maquininha: o app roda a Yooga no terminal e integra com o pagamento da própria maquininha pelo SDK da Stone.

>Arquitetura (HLD)

Os pagamentos rodavam em serviços Java 21 e Quarkus, em contêineres no Kubernetes, na AWS. Os serviços usavam MySQL e MongoDB. A observabilidade era New Relic, Prometheus/Grafana e OpenTelemetry.

Uma cobrança sai dos canais da Yooga, entra no serviço de pagamentos com chave de idempotência e vai ao provedor por drivers plugáveis: Pix direto com o Itaú; cartões, Apple Pay e Google Pay via Tuna e Pagar.me, com antifraude. O status volta por webhooks assinados de Tuna e Pagar.me, validados antes de mudar estado e seguros para chegar duas vezes. O SmartPOS é um app Kotlin/Android na própria maquininha: usa as APIs da Yooga e cobra pelo SDK da Stone.

Fora do caminho da cobrança, o trabalho é assíncrono. Jobs agendados montam os lotes de saque, calculam a data do repasse com feriados e fins de semana, pagam por Pix via Itaú, rodam a conciliação e mandam um relatório diário no Slack. A camada de eventos em Kafka leva pedidos e status entre os microsserviços e os conectores de delivery (iFood e parceiros), com SASL/SSL, ordenação, replay e consumo idempotente. Mudanças iam para produção atrás de feature toggles, com liberação gradual.

Passe o mouse ou foque uma peça: ela acende com as ligações.
MaquininhaBackend da Yoogaserviços externosPagamentos · AWS + Kubernetes2 SmartPOS1 Canais da Yooga4 Serviços da Yooga6 Serviço de pagamentos9 Drivers e webhooks3 SDK da Stone11 Tuna7 MySQL e MongoDB13 Itaú5 Kafka12 Pagar.me8 Conectores de delivery14 iFood e parceiros10 Repasse e conciliação
14 peças13 ligações4 áreas

Componentes

  • Serviço de pagamentos :: Serviço Java 21/Quarkus no Kubernetes da AWS que registra cada cobrança com chave de idempotência e chama o provedor pelo driver certo.
  • Drivers de provedor :: Pix direto com o Itaú e cartões, Apple Pay e Google Pay via Tuna e Pagar.me, com antifraude que coleta dados da sessão no início da transação e usa os motores dos dois provedores.
  • Handlers de webhook :: Validam a assinatura de Tuna e Pagar.me antes de processar e tratam a reentrega como caso normal, sem cobrança duplicada nem estado inconsistente.
  • Repasse automatizado :: Jobs agendados montam lotes de saque por lojista, calculam a data com feriados e fins de semana, pagam por Pix via Itaú, conciliam e mandam o relatório diário no Slack.
  • Credenciamento self-service :: Cadastro do lojista com validação de CPF/CNPJ, verificação da conta bancária e integração direta com a API de lojistas da Tuna.
  • Camada de eventos em Kafka :: Eventos de pedido e status entre os microsserviços e os conectores de delivery (iFood e parceiros), com SASL/SSL, ordenação, replay e consumo idempotente.
  • SmartPOS :: App Kotlin/Android com Clean Architecture e Jetpack Compose que roda a Yooga em maquininhas Sunmi, Positivo e Tectoy, usa as APIs da Yooga e cobra pelo SDK da Stone.

>Trade-offs

Tratar a segunda entrega como caso normal: chave de idempotência em cada transação e webhook assinado validado antes de mudar estado.

Alternativa descartada: Confiar que o provedor entrega cada webhook uma vez e que o cliente toca em pagar uma vez só.

Por quê: O bug que mais importava era o mesmo webhook chegando duas vezes ou o cliente tocando em pagar de novo. Nos dois provedores, foi a idempotência que acabou com cobrança duplicada, corrida e estado inconsistente.

Drivers plugáveis por provedor dentro do serviço de pagamentos.

Alternativa descartada: Concentrar todos os métodos de pagamento num único provedor.

Por quê: O Pix, com 98% do volume de transações, ia direto pelo Itaú, e os cartões passavam por Tuna e Pagar.me, todos atrás da mesma arquitetura de drivers plugáveis.

Consumo idempotente com replay na camada de Kafka.

Alternativa descartada: Assumir que o broker entrega cada evento exatamente uma vez.

Por quê: Em sistema orientado a eventos qualquer passo pode rodar duas vezes. Com o handler desenhado para a segunda entrega desde o início, um incidente no broker nunca gerou pedido duplicado ou perdido.

>Destaques

  • >US$70M+ processados em 6M+ transações para 2.100+ lojistas
  • >Pix com integração direta ao Itaú: 98% do volume de transações
  • >800+ testes automatizados cobrindo fluxos de pagamento e webhooks
  • >SmartPOS em maquininhas de 3 fabricantes: Sunmi, Positivo e Tectoy
  • >Time de 5 engenheiros liderado por 1 ano e 4 meses
  • >Claude Code e Cursor como ferramentas centrais: velocidade de entrega do time 3x maior
Yooga Pagamentos & SmartPOS | The Broad Way | Kinho.dev