
Carteira Digital Desenvolvimento Back-end / Engenharia de Software
API REST para gerenciamento seguro de carteiras em BRL, com autenticação, depósitos, transferências, reversões administrativas, ledger imutável, idempotência e proteção contra concorrência.
Feito com
- PHP
- Laravel
- PostgresSQL
- Docker
- Nginx
- OpenAPI
- Sanctum
Contexto
Operações financeiras exigem mais do que a simples atualização de um campo de saldo. Requisições repetidas, acessos concorrentes, falhas durante transferências e alterações indevidas no histórico podem provocar duplicidade de operações ou inconsistências contábeis.
O projeto foi desenvolvido como uma API REST de carteira digital em BRL, com o objetivo de explorar esses problemas por meio de garantias aplicadas tanto no código quanto no banco de dados.
Objetivo
O objetivo foi construir uma API segura e previsível para o cadastro de usuários, a consulta de saldo, a realização de depósitos e transferências e o processamento de reversões administrativas. A solução deveria impedir o gasto duplo, processar requisições repetidas de maneira idempotente, preservar todo o histórico financeiro e disponibilizar um ambiente local reproduzível e documentado.
Processo
A implementação começou pela modelagem das entidades centrais, como usuários, carteiras, transações, lançamentos contábeis e chaves de idempotência. As regras de negócio foram organizadas em Actions, enquanto Controllers, Form Requests e DTOs ficaram responsáveis pelo transporte e pela validação dos dados. As operações financeiras foram executadas dentro de transações do PostgreSQL, utilizando bloqueios pessimistas e restrições de integridade para proteger os dados.
Em seguida, foram adicionados autenticação com Laravel Sanctum, permissões específicas para cada operação, autorização administrativa, eventos publicados somente após a confirmação das transações, logs estruturados, reconciliação de saldo, documentação OpenAPI e uma suíte automatizada de testes. Os valores monetários foram armazenados como números inteiros em centavos para evitar erros de ponto flutuante, enquanto cada alteração de saldo passou a gerar lançamentos contendo os valores anterior e posterior.
O histórico financeiro foi estruturado como um ledger append-only, protegido por gatilhos do PostgreSQL contra alterações, exclusões e truncamentos. Depósitos, transferências e reversões passaram a exigir uma chave de idempotência. As transferências também foram implementadas com o bloqueio das carteiras em uma ordem determinística, reduzindo a possibilidade de deadlocks. Além disso, as reversões foram modeladas como novas transações compensatórias, preservando integralmente as operações originais.
Decisões técnicas
O projeto adota valores monetários representados em centavos inteiros para evitar erros de ponto flutuante. Utiliza transações e bloqueios pessimistas do PostgreSQL para garantir a consistência em situações de concorrência e mantém um ledger imutável, protegido por constraints e triggers, como fonte de verdade das movimentações.
Depósitos, transferências e reversões são idempotentes, impedindo o processamento duplicado de operações. As reversões geram lançamentos compensatórios sem apagar ou modificar o histórico original.
A arquitetura separa as responsabilidades entre Controllers, Form Requests, DTOs e Actions. Além disso, combina o Laravel Sanctum com roles e abilities para controlar a autorização, publica eventos somente após a confirmação da transação e utiliza o Docker Compose para disponibilizar um ambiente local reproduzível.
Desafios
O principal desafio foi garantir a consistência quando duas operações tentavam movimentar o mesmo saldo simultaneamente. Esse problema foi tratado com transações, bloqueios pessimistas e uma ordem determinística para bloquear as carteiras envolvidas. Outro ponto importante foi assegurar que a repetição de uma requisição não movimentasse dinheiro duas vezes. Para isso, a solução associou a chave de idempotência ao usuário e ao conteúdo da solicitação, permitindo reproduzir a resposta original e rejeitar a reutilização da mesma chave com dados diferentes.
As reversões também exigiram atenção especial. Em vez de apagar ou modificar uma operação anterior, o sistema passou a criar lançamentos opostos, mantendo toda a trilha de auditoria. A autorização administrativa combinou as permissões do token com o papel persistido no banco de dados, enquanto os eventos financeiros foram publicados somente após a confirmação definitiva da transação.
Resultados e aprendizados
O resultado foi uma API com autenticação, depósitos, transferências, histórico financeiro, reversões administrativas, reconciliação e documentação reproduzível em OpenAPI e Postman. O ambiente local foi organizado com Docker Compose, reunindo aplicação, worker, Nginx, PostgreSQL e Redis. As regras financeiras críticas ficaram protegidas em múltiplas camadas, envolvendo aplicação, transações, restrições de integridade e gatilhos do banco de dados.
A suíte automatizada de testes passou a abranger autenticação, autorização, consulta e movimentação de saldo, idempotência, rollback, concorrência, publicação de eventos e integridade do ledger. O projeto reforçou que sistemas financeiros devem tratar o histórico como fonte de verdade, representar valores monetários sem ponto flutuante e considerar a concorrência, as falhas e a repetição de requisições desde o início da arquitetura.
Galeria
6 imagens
Captura da documentação interativa da API. Diagrama de entidades do banco de dados. Serviços do Docker. Captura da execução dos testes. Exemplo do histórico de transações retornado pela API (Request). Exemplo do histórico de transações retornado pela API (Response).