novexFINTECH Docs

Referência

Erros

Formato dos erros, códigos HTTP e o que fazer em cada caso.

Todo erro vem no mesmo formato, com um code estável. Programe sempre em cima do code — a message é escrita para humanos e pode mudar sem aviso.

Formato do erro
{
  "error": {
    "code": "validation_error",
    "message": "2 campos estão inválidos. Veja "fields".",
    "fields": {
      "amount": "Informe o valor em CENTAVOS, como número inteiro (ex.: 1990 = R$ 19,90).",
      "customer.document": "CPF inválido."
    },
    "doc_url": "https://novexfinance.com.br/docs/erros",
    "request_id": "a3f1c09b7e42d85610fb2c7d9a4e5b83"
  }
}
CampoTipoDescrição
error.codeopcionalstringIdentificador estável do erro. É o que o seu código deve verificar.
error.messageopcionalstringExplicação em português. Não faça lógica em cima dela.
error.fieldsopcionalobjetoSó em validation_error: o problema de cada campo, pelo caminho completo (customer.email).
error.request_idopcionalstringIdentificador da requisição. Registre no seu log — é por ele que o suporte acha o que aconteceu.
error.doc_urlopcionalstringPágina da documentação que trata do assunto.

Códigos HTTP

HTTPSignificaRetentar?
200 · 201Deu certo.—
400Requisição malformada (JSON inválido, por exemplo).Não, sem corrigir.
401Credencial ausente, inválida ou revogada.Não, sem corrigir.
402Pagamento recusado pelo emissor.Não. Ofereça outro meio ao cliente.
403Autenticado, mas sem permissão para esta operação.Não, sem resolver a pendência.
404Recurso ou endpoint não encontrado.Não.
405Método HTTP errado para este caminho. Veja o header Allow.Não.
409Conflito com o estado atual do recurso.Depende do caso.
422JSON válido, mas os dados não passam nas regras.Não, sem corrigir.
429Limite de requisições excedido.Sim, após o Retry-After.
500Erro nosso.Sim, com a mesma Idempotency-Key.
502 · 503Serviço de processamento indisponível.Sim, com a mesma Idempotency-Key.

Todos os códigos de erro

Autenticação e acesso

CódigoHTTPO que fazer
missing_api_key401Enviar o header Authorization: Bearer. Se você já envia, verifique se o seu servidor não o está removendo.
invalid_api_key401Conferir a chave. Ela começa com nvx_live_.
revoked_api_key401Gerar uma chave nova no painel.
unauthorized401Requisição sem autenticação válida.
account_inactive403Conta suspensa ou bloqueada. Falar com o suporte.
kyc_required403Concluir a verificação de identidade no painel. Consultas funcionam; cobranças e saques, não.

Dados enviados

CódigoHTTPO que fazer
invalid_json400Corpo não é JSON válido. Confira o Content-Type: application/json.
validation_error422Ler fields e corrigir cada campo apontado.
resource_not_found404O ID não existe nesta conta. Conferir se não veio de outro ambiente.
not_found404Endpoint inexistente. Conferir o caminho.
method_not_allowed405Usar um dos verbos listados no header Allow.

Regras de negócio

CódigoHTTPO que fazer
payment_refused402O emissor não autorizou. Oferecer outro cartão ou outro meio.
insufficient_balance422Saldo menor que valor + taxa. A mensagem traz os três números.
amount_limit_exceeded403Valor acima do limite por transação da conta.
daily_limit_exceeded403Limite diário atingido. Tentar no dia seguinte ou pedir revisão do limite.
card_direct_not_enabled403Enviar dados de cartão pela API exige PCI-DSS. Usar checkout hospedado.
checkout_already_paid409Não dá para expirar um checkout já pago.
webhook_already_exists409Já existe endpoint com esta URL.
webhook_limit_reached409Máximo de 10 endpoints. Remover um antes de criar outro.

Idempotência e limites

CódigoHTTPO que fazer
idempotency_key_in_progress409A primeira requisição ainda está sendo processada. Aguardar e consultar antes de repetir.
idempotency_key_reused422A mesma chave foi usada com outro corpo. Usar uma chave nova.
rate_limit_exceeded429Esperar o Retry-After em segundos.

Do nosso lado

CódigoHTTPO que fazer
processing_error502Falha no processamento. Retentar com a mesma Idempotency-Key.
service_unavailable503Indisponibilidade temporária ou manutenção. Retentar com a mesma Idempotency-Key.
internal_error500Erro nosso. Retentar; se persistir, informar o request_id ao suporte.

Como tratar erros

A regra é simples: 4xx é problema do pedido — retentar sem mudar nada só repete o erro. 5xx e 429 são transitórios — retentar faz sentido, com espera crescente e sempre com a mesma Idempotency-Key.

Retentativa com backoff
function criarCobranca(array $payload, string $idemKey): array
{
    $espera = 1;

    for ($tentativa = 1; $tentativa <= 4; $tentativa++) {
        [$status, $body] = post('/charges', $payload, $idemKey);

        if ($status < 300) {
            return $body;
        }

        // 4xx (menos 429): o pedido está errado. Retentar não resolve.
        if ($status < 500 && $status !== 429) {
            throw new RuntimeException(
                $body['error']['code'] . ': ' . $body['error']['message']
            );
        }

        // Mesma Idempotency-Key: se a 1ª chegou a criar, recebemos ela de volta
        // em vez de uma segunda cobrança.
        sleep($espera);
        $espera *= 2;
    }

    throw new RuntimeException('Falha após 4 tentativas.');
}

Registre sempre o request_id junto com o erro no seu log. Sem ele, investigar uma falha vira uma busca por horário aproximado; com ele, o suporte localiza a requisição exata em segundos.

Timeout do seu lado

Criar cobrança envolve comunicação com o processador de pagamento. Use um timeout de pelo menos 40 segundos — um timeout curto derruba a conexão enquanto a cobrança está sendo criada de verdade, e você fica sem saber o resultado.

Se o timeout acontecer mesmo assim, não crie outra cobrança às cegas: repita a chamada com a mesma Idempotency-Key. Se a primeira tiver dado certo, você recebe ela de volta; se não, uma nova é criada. Nunca duas.