Voltar aos projetos
Em desenvolvimento

Payment Service Multi-Provider

Plataforma de pagamentos em Spring Boot com arquitetura gateway-agnostic: o core de cobrança, assinatura, checkout, créditos e webhooks é independente do provedor, com Asaas como primeiro adapter real e suporte arquitetural para novos gateways sem reescrever regras de negócio.

JavaSpring BootMySQLDockerAWSReactTerraformSwagger

O Problema

Sistemas de pagamento costumam nascer acoplados ao primeiro provedor integrado. Isso espalha regras específicas do gateway pelo domínio, dificulta testes, trava migrações futuras e torna webhooks, erros, status e fluxos de cobrança difíceis de manter quando o produto cresce.

A Solução

  • Arquitetura modular por capacidades de negócio, com cada domínio isolado em seu próprio módulo e fronteiras explícitas
  • Core de aplicação protegido por ports e adapters, isolando regras de negócio dos detalhes do provedor de pagamento
  • Asaas implementado como primeiro adapter concreto, sem transformar o domínio em uma extensão da API do provedor
  • Webhooks externos traduzidos para fluxos internos normalizados, com idempotência, rastreabilidade e tolerância a reentregas
  • Fluxos críticos desenhados para evitar transações longas envolvendo chamadas externas ao gateway
  • Contratos de erro padronizados com ProblemDetail e separação clara entre API, application, domain e infra

Arquitetura

  • Modular Monolith

    Java 21 / Spring Boot / Maven

    O sistema é organizado por módulos de negócio, não por camadas globais genéricas. Cada módulo concentra sua API, aplicação, domínio, infraestrutura, testes e contratos.

  • Core

    Ports & Adapters

    Casos de uso dependem de portas de saída por fronteira, como gateway, repository, cliente, assinatura, notificação e fiscal, mantendo detalhes externos fora das regras centrais.

  • Adapter Asaas

    Asaas API

    Primeiro provedor real da plataforma, responsável por cobranças, assinaturas, Pix, boleto, cartão, tokenização, webhooks, clientes e integrações fiscais.

  • Persistência

    MySQL / Flyway

    Modelo relacional versionado por migrations, com atenção a idempotência, histórico de processamento, status financeiros e rastreabilidade operacional.

  • Eventos

    Outbox / Mensageria / SQS

    Fluxos assíncronos são usados para efeitos colaterais e integração interna/externa, reduzindo acoplamento entre módulos e evitando processamento frágil em cadeia síncrona.

  • Observabilidade

    OpenTelemetry, métricas e logs estruturados

    Operações críticas são rastreadas com correlationId, métricas por fluxo e logs úteis para diagnóstico de falhas parciais, webhooks duplicados e inconsistências de gateway.

Serviços Utilizados

  • Asaas
  • Amazon SQS
  • Amazon S3

Testes

  • JUnit 5
  • ArchUnit
  • Testcontainers

Desafios & Decisões

Como manter o sistema independente do gateway sem cair em abstrações genéricas demais?

A solução foi criar portas orientadas às necessidades reais do domínio, e não simplesmente espelhar a API do provedor. O adapter Asaas traduz comandos e respostas externas para objetos internos mais estáveis.

Como lidar com webhooks enviados várias vezes ou fora de ordem?

Os eventos recebidos passam por controle de idempotência, validação e normalização antes de alterar estados internos. O sistema trata reentregas como comportamento esperado, não como exceção.

Como evitar inconsistência entre banco local e gateway externo?

Fluxos críticos evitam manter transação de banco aberta durante chamadas externas. A persistência local, sincronização de status e tratamento de falhas são separados para melhorar rastreabilidade e recuperação.

Como evoluir assinatura, cobrança, crédito, cupom e fiscal sem criar um serviço gigante e acoplado?

Cada capacidade foi isolada em módulo próprio, com fronteiras explícitas. Comunicação síncrona acontece via ports quando há necessidade de resposta imediata; efeitos colaterais podem ser tratados por eventos ou processamento assíncrono.

Como preparar o sistema para novos gateways sem implementar todos no início?

O projeto nasceu gateway-agnostic por arquitetura, mas com entrega incremental. O Asaas é o primeiro provider real; novos provedores entram como adapters quando houver demanda concreta.

Resultados

  • Core financeiro desacoplado do provedor inicial de pagamento
  • Asaas integrado como adapter real sem contaminar domínio e casos de uso com DTOs externos
  • Fluxos de assinatura, cobrança, checkout, créditos e webhooks organizados por módulos de negócio
  • Processamento mais seguro contra reentregas, retentativas e falhas parciais
  • Base preparada para múltiplos gateways sem reescrever regras centrais
  • Arquitetura testável, documentada e adequada para evolução incremental

Screenshots

Screenshot 1
Screenshot 2
Screenshot 3
Screenshot 4

Lições Aprendidas

  • Ser gateway-agnostic não significa implementar vários provedores no começo; significa impedir que o primeiro provedor vire o centro da arquitetura
  • Ports devem representar fronteiras reais do sistema, não interfaces decorativas criadas por padrão
  • Webhooks precisam ser tratados como fonte assíncrona, duplicável e eventualmente fora de ordem
  • Idempotência em pagamento não é detalhe técnico, é regra fundamental de arquitetura
  • Modular monolith é uma escolha mais pragmática do que microserviços quando o time precisa evoluir rápido mantendo consistência transacional e baixa complexidade operacional
  • Separar API, application, domain e infra evita que DTOs externos, entidades JPA e contratos de gateway vazem para o núcleo do sistema