Pular para o conteúdo principal

Códigos de Erro

Este documento lista todos os códigos de erro possíveis na API do OnnixPay, suas causas e como resolvê-los.

Estrutura de Erro

Todos os erros seguem o mesmo formato:

{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Descrição legível do erro",
"details": "Detalhes adicionais sobre o erro",
"field": "campo_com_erro" // Opcional
},
"meta": {
"requestId": "req_abc123",
"timestamp": "2025-11-14T10:30:00Z",
"version": "v1"
}
}

HTTP Status Codes

CódigoDescriçãoQuando Ocorre
200OKRequisição bem-sucedida
201CreatedRecurso criado com sucesso
204No ContentAção bem-sucedida sem conteúdo de resposta
400Bad RequestDados inválidos na requisição
401UnauthorizedAPI Key ausente ou inválida
403ForbiddenAPI Key válida mas sem permissão
404Not FoundRecurso não encontrado
409ConflictConflito (ex: duplicação)
422Unprocessable EntityDados válidos mas não processáveis
429Too Many RequestsRate limit excedido
500Internal Server ErrorErro interno do servidor
502Bad GatewayErro de comunicação com provedor
503Service UnavailableServiço temporariamente indisponível

Códigos de Erro por Categoria

Autenticação (4xx)

UNAUTHORIZED

{
"code": "UNAUTHORIZED",
"message": "API Key inválida ou ausente",
"details": "Verifique se o header X-API-Key está presente e correto"
}

Causa: API Key não foi fornecida ou está incorreta

Solução:

  • Verifique se está enviando o header X-API-Key
  • Confirme que a chave está correta
  • Verifique se não há espaços extras na chave

INSUFFICIENT_PERMISSIONS

{
"code": "INSUFFICIENT_PERMISSIONS",
"message": "API Key não possui as permissões necessárias",
"requiredScopes": ["pix.write"],
"currentScopes": ["pix.read"]
}

Causa: API Key não tem os scopes necessários

Solução:

  • Verifique os scopes da sua API Key
  • Crie uma nova chave com os scopes corretos
  • Use uma chave diferente com as permissões adequadas

API_KEY_EXPIRED

{
"code": "API_KEY_EXPIRED",
"message": "API Key expirada",
"expiredAt": "2025-10-01T00:00:00Z"
}

Causa: A API Key passou da data de validade

Solução:

  • Gere uma nova API Key no painel
  • Atualize suas credenciais

API_KEY_REVOKED

{
"code": "API_KEY_REVOKED",
"message": "API Key foi revogada",
"revokedAt": "2025-11-01T10:00:00Z"
}

Causa: A chave foi revogada manualmente

Solução:

  • Gere uma nova API Key
  • Entre em contato com o suporte se foi revogada inesperadamente

Validação de Dados (400)

INVALID_REQUEST

{
"code": "INVALID_REQUEST",
"message": "Dados inválidos na requisição",
"details": "Campo 'amount' é obrigatório",
"field": "amount"
}

Causa: Dados obrigatórios ausentes ou formato incorreto

Solução:

  • Revise os parâmetros enviados
  • Consulte a documentação do endpoint
  • Verifique tipos de dados

INVALID_AMOUNT

{
"code": "INVALID_AMOUNT",
"message": "Valor inválido",
"details": "O valor deve estar entre R$ 0,01 e R$ 50.000,00",
"field": "amount",
"min": 0.01,
"max": 50000.00
}

Causa: Valor fora dos limites permitidos

Solução:

  • Valor mínimo: R$ 0,01
  • Valor máximo: R$ 50.000,00
  • Use formato decimal (ex: 100.50)

INVALID_DOCUMENT

{
"code": "INVALID_DOCUMENT",
"message": "CPF ou CNPJ inválido",
"details": "O CPF '12345678901' não é válido",
"field": "document"
}

Causa: CPF ou CNPJ com formato ou dígitos verificadores inválidos

Solução:

  • Valide o CPF/CNPJ antes de enviar
  • Use apenas números (sem pontos, traços)
  • Verifique os dígitos verificadores

Exemplos válidos:

CPF:  12345678909 (11 dígitos)
CNPJ: 12345678000199 (14 dígitos)

INVALID_PIX_KEY

{
"code": "INVALID_PIX_KEY",
"message": "Chave PIX inválida",
"details": "O formato da chave PIX não corresponde a nenhum tipo válido",
"field": "pixKey"
}

Causa: Chave PIX com formato incorreto

Solução: Use um dos formatos válidos:

  • CPF: 12345678909
  • CNPJ: 12345678000199
  • Email: usuario@exemplo.com
  • Telefone: +5511999999999
  • Chave Aleatória: 123e4567-e89b-12d3-a456-426614174000

INVALID_DATE

{
"code": "INVALID_DATE",
"message": "Data inválida",
"details": "A data de vencimento deve ser no futuro",
"field": "dueDate"
}

Causa: Data com formato incorreto ou valor inválido

Solução:

  • Use formato ISO 8601: 2025-12-31T23:59:59Z
  • Datas de vencimento devem ser futuras
  • Respeite dias úteis para boletos

Recursos (404)

RESOURCE_NOT_FOUND

{
"code": "RESOURCE_NOT_FOUND",
"message": "Recurso não encontrado",
"details": "PIX 'pix_abc123' não encontrado",
"resourceType": "pix",
"resourceId": "pix_abc123"
}

Causa: ID fornecido não existe ou não pertence à sua conta

Solução:

  • Verifique se o ID está correto
  • Confirme que o recurso pertence à sua conta
  • Verifique se não foi deletado

TRANSACTION_NOT_FOUND

{
"code": "TRANSACTION_NOT_FOUND",
"message": "Transação não encontrada",
"transactionId": "txn_xyz789"
}

Causa: Transação não existe

Solução:

  • Confirme o ID da transação
  • Verifique se está usando a conta correta

Conflitos (409)

DUPLICATE_TRANSACTION

{
"code": "DUPLICATE_TRANSACTION",
"message": "Transação duplicada",
"details": "Já existe uma transação com este externalId",
"existingTransactionId": "txn_abc123",
"externalId": "order-12345"
}

Causa: Tentativa de criar transação com externalId já existente

Solução:

  • Use externalId únicos
  • Implemente X-Idempotency-Key nos headers
  • Consulte a transação existente

DUPLICATE_CUSTOMER

{
"code": "DUPLICATE_CUSTOMER",
"message": "Cliente já existe",
"details": "Já existe um cliente com este documento",
"existingCustomerId": "cust_xyz789",
"document": "12345678900"
}

Causa: Tentativa de criar cliente com documento já cadastrado

Solução:

  • Consulte o cliente existente
  • Atualize o cliente ao invés de criar novo

Limites e Restrições (422, 429)

INSUFFICIENT_BALANCE

{
"code": "INSUFFICIENT_BALANCE",
"message": "Saldo insuficiente",
"details": "Saldo disponível: R$ 50,00. Valor solicitado: R$ 100,00",
"availableBalance": 50.00,
"requestedAmount": 100.00,
"currency": "BRL"
}

Causa: Tentativa de pagamento sem saldo suficiente

Solução:

  • Adicione saldo à conta
  • Reduza o valor da transação
  • Considere a taxa da operação

RATE_LIMIT_EXCEEDED

{
"code": "RATE_LIMIT_EXCEEDED",
"message": "Limite de requisições excedido",
"details": "Máximo de 100 requisições por minuto",
"limit": 100,
"window": "1m",
"retryAfter": 45
}

Causa: Muitas requisições em curto período

Solução:

  • Implemente exponential backoff
  • Aguarde o tempo indicado em retryAfter
  • Considere fazer cache de respostas
  • Entre em contato para aumentar o limite

AMOUNT_LIMIT_EXCEEDED

{
"code": "AMOUNT_LIMIT_EXCEEDED",
"message": "Limite de valor excedido",
"details": "Valor máximo por transação: R$ 50.000,00",
"maxAmount": 50000.00,
"requestedAmount": 75000.00
}

Causa: Valor da transação acima do limite

Solução:

  • Divida em múltiplas transações
  • Entre em contato para aumentar o limite

PIX Específicos

PIX_EXPIRED

{
"code": "PIX_EXPIRED",
"message": "Cobrança PIX expirada",
"details": "Esta cobrança expirou em 2025-11-14T11:00:00Z",
"pixId": "pix_abc123",
"expiredAt": "2025-11-14T11:00:00Z"
}

Causa: Tentativa de pagar PIX após expiração

Solução:

  • Gere uma nova cobrança PIX
  • Configure prazo de expiração adequado

PIX_ALREADY_PAID

{
"code": "PIX_ALREADY_PAID",
"message": "PIX já foi pago",
"details": "Esta cobrança foi paga em 2025-11-14T10:30:00Z",
"pixId": "pix_abc123",
"paidAt": "2025-11-14T10:30:00Z"
}

Causa: Tentativa de pagar PIX já quitado

Solução:

  • Consulte o status antes de processar
  • Implemente idempotência

PIX_KEY_NOT_FOUND

{
"code": "PIX_KEY_NOT_FOUND",
"message": "Chave PIX não encontrada",
"details": "A chave PIX informada não está registrada no BACEN",
"pixKey": "usuario@exemplo.com"
}

Causa: Chave PIX não existe no sistema bancário

Solução:

  • Verifique se a chave está correta
  • Confirme com o destinatário

Boleto Específicos

BOLETO_EXPIRED

{
"code": "BOLETO_EXPIRED",
"message": "Boleto vencido",
"details": "Este boleto venceu em 2025-11-01",
"boletoId": "bol_abc123",
"dueDate": "2025-11-01"
}

Causa: Tentativa de pagar boleto vencido

Solução:

  • Gere um novo boleto
  • Configure multa/juros para pagamento após vencimento

BOLETO_ALREADY_PAID

{
"code": "BOLETO_ALREADY_PAID",
"message": "Boleto já foi pago",
"boletoId": "bol_abc123",
"paidAt": "2025-11-14T10:30:00Z"
}

Causa: Tentativa de pagar boleto já quitado

Solução:

  • Consulte o status antes de processar

BOLETO_CANCELED

{
"code": "BOLETO_CANCELED",
"message": "Boleto cancelado",
"boletoId": "bol_abc123",
"canceledAt": "2025-11-10T15:00:00Z"
}

Causa: Tentativa de usar boleto cancelado

Solução:

  • Gere um novo boleto

Erros de Provedor (502, 503)

PROVIDER_ERROR

{
"code": "PROVIDER_ERROR",
"message": "Erro no provedor de pagamento",
"details": "O provedor retornou um erro temporário",
"provider": "celcoin",
"providerCode": "ERR_123"
}

Causa: Erro no provedor bancário (Celcoin, Shipay, etc)

Solução:

  • Tente novamente em alguns segundos
  • Se persistir, entre em contato com o suporte

PROVIDER_TIMEOUT

{
"code": "PROVIDER_TIMEOUT",
"message": "Timeout ao comunicar com provedor",
"provider": "celcoin",
"timeout": 30000
}

Causa: Provedor demorou mais que o esperado

Solução:

  • Implemente retry com exponential backoff
  • Consulte o status da transação

PROVIDER_UNAVAILABLE

{
"code": "PROVIDER_UNAVAILABLE",
"message": "Provedor temporariamente indisponível",
"provider": "celcoin",
"estimatedRecovery": "2025-11-14T11:00:00Z"
}

Causa: Manutenção ou instabilidade do provedor

Solução:

  • Aguarde o tempo estimado
  • Tente com provedor alternativo se disponível

Erros Internos (500)

INTERNAL_ERROR

{
"code": "INTERNAL_ERROR",
"message": "Erro interno do servidor",
"details": "Ocorreu um erro inesperado. Nossa equipe foi notificada.",
"requestId": "req_abc123"
}

Causa: Erro inesperado no servidor

Solução:

  • Anote o requestId para referência
  • Entre em contato com o suporte
  • Tente novamente após alguns minutos

Tratamento de Erros - Boas Práticas

Exemplo Node.js/TypeScript

async function createPixCharge(data: CreatePixDto) {
try {
const response = await onnixpay.post('/sdk/pix', data);
return response.data;

} catch (error) {
if (error.response) {
const { code, message, details } = error.response.data.error;

switch (code) {
case 'INSUFFICIENT_BALANCE':
console.error('Saldo insuficiente:', details);
// Notificar usuário para adicionar saldo
break;

case 'INVALID_PIX_KEY':
console.error('Chave PIX inválida:', details);
// Solicitar chave PIX válida ao usuário
break;

case 'RATE_LIMIT_EXCEEDED':
const retryAfter = error.response.data.error.retryAfter;
console.log(`Aguardando ${retryAfter}s antes de tentar novamente`);
await sleep(retryAfter * 1000);
return createPixCharge(data); // Retry

case 'PROVIDER_TIMEOUT':
// Implementar retry com backoff
return retryWithBackoff(() => createPixCharge(data));

default:
console.error('Erro desconhecido:', code, message);
}
}
throw error;
}
}

Exemplo Python

from typing import Dict, Any
import time

def create_pix_charge(data: Dict[str, Any]):
try:
response = requests.post(
f'{BASE_URL}/sdk/pix',
headers=headers,
json=data
)
response.raise_for_status()
return response.json()

except requests.exceptions.HTTPError as e:
error_data = e.response.json()
code = error_data['error']['code']
message = error_data['error']['message']

if code == 'INSUFFICIENT_BALANCE':
print(f'Saldo insuficiente: {message}')
# Notificar usuário

elif code == 'RATE_LIMIT_EXCEEDED':
retry_after = error_data['error'].get('retryAfter', 60)
print(f'Rate limit. Aguardando {retry_after}s...')
time.sleep(retry_after)
return create_pix_charge(data) # Retry

elif code == 'PROVIDER_TIMEOUT':
# Retry com backoff
return retry_with_backoff(lambda: create_pix_charge(data))

else:
print(f'Erro: {code} - {message}')
raise

Exponential Backoff

async function retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (i === maxRetries - 1) throw error;

const delay = baseDelay * Math.pow(2, i);
console.log(`Tentativa ${i + 1} falhou. Aguardando ${delay}ms...`);
await sleep(delay);
}
}
}

Logs e Debugging

Sempre guarde o requestId para debugging:

try {
const response = await onnixpay.post('/sdk/pix', data);
} catch (error) {
const requestId = error.response?.data?.meta?.requestId;
console.error(`Erro na requisição ${requestId}:`, error.response?.data);

// Enviar para sistema de logs
logger.error('OnnixPay Error', {
requestId,
error: error.response?.data,
timestamp: new Date()
});
}

Próximos Passos