Este projeto é uma implementação do desafio backend do PicPay, construída com Java 21 e Spring Boot, seguindo a Arquitetura Limpa (Clean Architecture).
A API permite transferências financeiras entre usuários, garantindo:
✔ Autenticação JWT para segurança
✔ Validação de saldo antes da transação
✔ Autorização de transações via serviço externo
✔ Notificações de pagamento ao recebedor
✔ Modelo transacional para evitar inconsistências
Este projeto segue a Arquitetura Limpa, garantindo:
- Separação de responsabilidades entre camadas (
domain,application,infrastructure,adapters) - Código modular e testável, facilitando manutenção e evolução
- Baixo acoplamento, permitindo troca de tecnologias sem afetar a lógica de negócio
- Java 21 com Spring Boot
- Arquitetura Limpa (Clean Architecture)
- Spring Security (Autenticação e JWT)
- Spring Data JPA (Persistência)
- PostgreSQL (Banco de Dados)
- Docker & Docker Compose (Containerização)
- Feign Client (Integração com serviços externos)
- Swagger (Documentação da API)
git clone https://github.com/seu-repositorio/picpay-backend.git
cd picpay-backendA aplicação utiliza autenticação JWT com chaves pública e privada.
Para gerar essas chaves, basta rodar o seguinte script:
chmod +x ./scripts/generate-ssh-keys.sh
./scripts/generate-ssh-keys.shIsso criará as chaves na pasta ./keys/.
Crie um arquivo .env na raiz do projeto e configure as variáveis de ambiente:
# DATABASE
DB_HOST=localhost
DB_PORT=5432
DB_NAME=java
DB_USERNAME=postgres
DB_PASSWORD=root12345
# SERVER
SERVER_PORT=8080O docker-compose já contém API + Banco de Dados.
Para rodar tudo, basta usar:
docker-compose up -dIsso iniciará:
- PostgreSQL na porta 5432
- API Spring Boot na porta 8080
Caso não use Docker, a API pode ser iniciada manualmente com:
./mvnw spring-boot:runA API estará disponível em http://localhost:8080.
Para facilitar os testes, aqui estão alguns usuários pré-cadastrados:
[
{
"fullName": "João Silva",
"document": "123.456.789-09",
"email": "joao.silva@example.com",
"password": "senha123",
"userType": "COMUM"
},
{
"fullName": "Maria Oliveira",
"document": "529.982.247-25",
"email": "maria.oliveira@example.com",
"password": "senha123",
"userType": "COMUM"
},
{
"fullName": "Carlos Santos",
"document": "111.444.777-35",
"email": "carlos.santos@example.com",
"password": "senha123",
"userType": "COMUM"
},
][
{
"fullName": "Loja Exemplo 1",
"document": "12.345.678/0001-95",
"email": "loja1@example.com",
"password": "senha123",
"userType": "LOGISTA"
},
{
"fullName": "Supermercado Exemplo 2",
"document": "04.252.011/0001-10",
"email": "supermercado2@example.com",
"password": "senha123",
"userType": "LOGISTA"
},
{
"fullName": "Empresa Exemplo 3",
"document": "20.392.287/0001-80",
"email": "empresa3@example.com",
"password": "senha123",
"userType": "LOGISTA"
}
]
A API segue os padrões REST e os endpoints principais são:
Rota: POST /api/v1/auth/login
Corpo da requisição:
{
"email": "joao.silva@example.com",
"password": "senha123"
}Resposta:
{
"token": "eyJhbGciOi...",
"expiresIn": 86400
}Rota: POST /api/v1/users
Corpo da requisição:
{
"fullName": "Novo Usuário",
"document": "987.654.321-00",
"email": "novo.usuario@example.com",
"password": "novaSenha123",
"userType": "COMUM"
}Resposta: 201 Created
Rota: GET /api/v1/wallet
Headers:
Authorization: Bearer SEU_TOKEN_JWTResposta:
{
"walletId": "123e4567-e89b-12d3-a456-426614174000",
"userId": "e2f2b256-1c3e-4d78-840e-c128abe918bf",
"balance": 1000.00
}Rota: POST /api/v1/wallet/deposit?amount=500
Headers:
Authorization: Bearer SEU_TOKEN_JWTResposta:
Depósito de R$ 500 realizado com sucesso!
Rota: POST /api/v1/transfer
Headers:
Authorization: Bearer SEU_TOKEN_JWTCorpo da requisição:
{
"value": 100.0,
"payeeDocument": "529.982.247-25"
}Resposta: 200 OK
Transferência de R$ 100 para Maria Oliveira realizada com sucesso!
✅ Usuários COMUNS podem enviar dinheiro.
❌ Usuários LOJISTAS NÃO podem enviar dinheiro.
✅ Antes da transferência, verificamos se há saldo suficiente.
✅ A transferência só acontece se o serviço externo autorizar.
✅ Após a transferência, o recebedor recebe uma notificação.
✅ Se houver erro, o dinheiro é estornado automaticamente.
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "joao.silva@example.com", "password": "senha123"}'http://localhost:8080/swagger-ui.htmlEste projeto está licenciado sob a MIT License.
Para mais detalhes, veja o arquivo LICENSE.