Erros & Status HTTP

4 min de leitura

A API retorna erros em formato padronizado via GlobalExceptionHandler. Todos os erros incluem os campos timestamp (Unix ms), status, error, message e path — definidos pela classe StandardError.

Estrutura StandardError
Todos os erros retornados pela API seguem este contrato exato. O campo timestamp é um Long em milissegundos Unix, útil para correlacionar com logs internos via System.currentTimeMillis().
2xx — Sucesso
201 Created Pagamento criado com sucesso. O PaymentController retorna ResponseEntity.status(HttpStatus.CREATED).body(response).
200 OK Retornado quando o idempotencyKey já existe com status APPROVED ou FAILED — o payload original é devolvido sem reprocessamento.
4xx — Erro do cliente
400 Bad Request Lançado pelo GlobalExceptionHandler ao capturar MethodArgumentNotValidException. Ocorre quando campos @NotNull, @NotBlank ou @DecimalMin falham na validação do PaymentRequestDTO.
401 Unauthorized O header x-api-key está ausente ou contém uma chave que não existe no banco (hash SHA-256 não encontrado). Retornado pelo ApiKeyAuthFilter antes de qualquer processamento de negócio. Verifique se a chave está correta e incluída em todas as requisições.
403 Forbidden A x-api-key é válida, mas o tenant associado está com status INACTIVE no banco. O GlobalExceptionHandler mapeia TenantInactiveException403. Diferente do 401: a chave existe, mas o acesso foi bloqueado administrativamente.
404 Not Found Recurso solicitado não encontrado. O GlobalExceptionHandler mapeia ResourceNotFoundException404.
409 Conflict O idempotencyKey enviado já está associado a uma transação com status PROCESSING. O GlobalExceptionHandler mapeia IdempotencyConflictException409.
429 Too Many Requests Limite de requisições excedido para a x-api-key. Ver Rate Limiting.
5xx — Erro do servidor
500 Server Error Exceção não tratada capturada pelo handler genérico handleGenericException(Exception). Inclua path e timestamp ao reportar problemas via suporte.

Exemplos de Resposta de Erro

// MethodArgumentNotValidException — campo obrigatório ausente // Gerado quando "amount" ou "currency" não são enviados no body { "timestamp": 1740161400000, "status": 400, "error": "Dados inválidos", "message": "amount: não deve ser nulo; currency: não deve ser vazio", "path": "/v1/payments" }
// ApiKeyAuthFilter — header ausente ou chave não encontrada // Retornado ANTES de qualquer lógica de negócio { "timestamp": 1740161380000, "status": 401, "error": "Nao autorizado", "message": "API key ausente ou invalida.", "path": "/v1/payments" }
// TenantInactiveException — chave válida mas tenant desativado // Diferente do 401: a chave existe, mas o acesso foi bloqueado { "timestamp": 1740161450000, "status": 403, "error": "Acesso negado", "message": "Tenant inativo. Entre em contato com o suporte.", "path": "/v1/payments" }
// IdempotencyConflictException — pagamento já em processamento { "timestamp": 1740161400000, "status": 409, "error": "Conflito de Idempotencia", "message": "Pagamento já está em processamento ativo.", "path": "/v1/payments" }
// handleGenericException — exceção não prevista { "timestamp": 1740161500000, "status": 500, "error": "Erro interno do servidor", "message": "Ocorreu um erro inesperado. Tente novamente em instantes.", "path": "/v1/payments" }
Dica de depuração
O campo timestamp é um Long Unix em milissegundos (gerado via System.currentTimeMillis()). Use-o para correlacionar a chamada com os logs internos. Ao abrir um suporte, inclua sempre o timestamp e o path exatos da resposta de erro.
401 vs 403 — qual a diferença?
401 significa que a identidade é desconhecida — o header x-api-key está ausente ou a chave não existe no sistema. 403 significa que a identidade é conhecida, mas o acesso foi negado — a chave existe, mas o tenant foi desativado. Trate os dois de forma diferente: 401 geralmente indica um bug de configuração; 403 requer contato com o suporte.