API RESTful para gerenciamento de pagamentos multi-gateway com fallback por prioridade, autenticacao, autorizacao por roles, CRUD de usuarios e produtos, compras assincronas em fila e fluxo de reembolso.
- Indice da documentacao
- Como rodar o projeto
- Migrations e seeds
- Testes
- Arquitetura
- Fluxo de execucao
- Variaveis de ambiente
- Rotas da API
Implementacao majoritariamente alinhada ao Nivel 3:
- valor da compra calculado no backend
- suporte a multiplos produtos por compra
- roles de usuario (ADMIN, MANAGER, FINANCE, USER)
- fallback entre gateways por prioridade
- Docker Compose com MySQL, Redis e mocks de gateway
- testes com Japa
- processamento de pagamentos assíncrono via fila (Redis + @adonisjs/queue)
flowchart LR
A["Cliente HTTP"] --> B["/api/v1/*"]
B --> C["Middlewares<br/>Auth + Roles"]
C --> D["Controller"]
D --> E["Contract / Port"]
E --> F["PurchaseAdapter"]
F --> DB[("MySQL<br/>Transaction pending")]
F --> Q["Redis Queue<br/>jobs::payments::pending"]
Q --> W["Worker<br/>ProcessPaymentJob"]
W --> P["PaymentProcessor"]
P --> GS["GatewaySelector"]
GS --> H1["GatewayOneAdapter"]
GS --> H2["GatewayTwoAdapter"]
H1 --> I1["Gateway Externo 1"]
H2 --> I2["Gateway Externo 2"]
W --> DB2[("MySQL<br/>Transaction update")]
- PaymentProcessor tenta os gateways em sequencia e retorna no primeiro sucesso.
- Em erro total dos gateways, o fluxo retorna falha consolidada.
- Contratos/ports e providers reduzem acoplamento e facilitam troca de implementacao.
- Repositories concentram acesso a dados e simplificam controllers.
- O processamento de pagamentos é assíncrono
(como grandes banco fazem): o request HTTP retorna imediatamente comstatus: pendingenquanto o job e processado pelo worker em background. - O job
ProcessPaymentJobgarante idempotencia: ignora transacoes que nao estejam comstatus: pending. - A biblioteca
sqidsoculta o id real protegendo indices do sistema - Retry com exponential backoff (ate 3 tentativas). Apos exaurir,
failed()marca a transacao comostatus: errorcomlastError: payment_processing_failed. QUEUE_DRIVER=syncpode ser usado em testes para processar jobs de forma sincrona sem Redis.
- Os dois gateways nao aceitam valores decimais no campo de valor/amount. O envio e feito em centavos (inteiro). Exemplo: amount 10000 representa R$ 100,00 cobrados do usuario.
- Não configurei um fallback caso o job não esteja em execuxao para processar de forma sincrona
- Tabelas solicitadas de
Usereclientestavam muito ambiguios, pesando em normalizaçaõ de dados defini apenas 1 tabela que contepla os dois - A documentacao deste arquivo descreve o estado atual da implementacao em AdonisJS.