Pular para o conteúdo
LIQFYdocs
PTEN
Ir para o painel

Erros

Todo erro da Liqfy é um objeto JSON com formato estável — programe seu handler contra ele uma vez e pare de adivinhar. Toda resposta, de sucesso ou de erro, também traz o cabeçalho X-Request-Id (gerado quando você não manda um, devolvido igual quando você manda).

#Formato

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_amount",
    "message": "amount deve ser um inteiro positivo em centavos.",
    "param": "amount",
    "details": []
  },
  "request_id": "req_01J..."
}
CampoSempre presenteDescrição
error.typesimCategoria estável — uma de invalid_request_error, authentication_error, permission_error, not_found_error, conflict_error, rate_limit_error, api_error.
error.codesimCódigo de máquina estável, em snake_case. É nele que seu handler deve ramificar, não na message.
error.messagesimExplicação para humano. Pode logar; não é contrato para automação.
error.paramquando é de um campoIdentifica o campo que falhou, quando não há ambiguidade.
error.detailsem falha de validaçãoLista { param, message }[] para erro em vários campos.
request_idsimCite ao falar com o suporte — ele rastreia todo log, span e mensagem Kafka. Também vem no cabeçalho X-Request-Id.

Por que code e não message: a mensagem é escrita para gente ler e muda sem aviso — inclusive de idioma. O code é contrato. Um if (e.message === "Invalid API key") quebra na primeira vez que alguém melhorar a frase.

#Mapa de status

HTTPerror.typeO que o cliente deve fazer
200
201Guarde o id devolvido e siga.
400invalid_request_errorCorrija o corpo/cabeçalhos e tente de novo. Não repita às cegas.
401authentication_errorConfira se o cabeçalho apikey leva uma chave correta e ativa.
403permission_errorBloqueado por escopo ou pela guarda antifraude/velocidade. Revise o cliente ou fale com o suporte.
404not_found_errorConfira o id que você mandou.
409conflict_errorMesma Idempotency-Key usada com corpo diferente — use uma chave nova.
422invalid_request_errorViolação de regra de negócio — leia a message, corrija a entrada, não repita.
429rate_limit_errorReduza o ritmo. Repita com atraso exponencial + jitter; respeite o Retry-After quando vier.
5xxapi_errorSeguro repetir com a mesma Idempotency-Key — a idempotência é o que te protege de duplicar.

#Erros comuns

#400 Bad Request

Validação falhou — o error.code é invalid_request, a menos que exista um código mais específico (ex.: invalid_amount); o error.details lista cada campo que falhou.

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_request",
    "message": "Validation failed",
    "details": [
      { "param": "amount", "message": "must be a positive integer" },
      { "param": "payment_method", "message": "Invalid enum value" }
    ]
  },
  "request_id": "req_01J..."
}

Também dá 400 quando falta o cabeçalho Idempotency-Key numa escrita financeira (POST /v1/charges, POST /v1/pix/charges).

Ação Corrija a requisição e tente de novo. Nunca em laço.


#401 Unauthorized

json
{
  "error": {
    "type": "authentication_error",
    "code": "unauthorized",
    "message": "Invalid API key"
  },
  "request_id": "req_01J..."
}

Causas possíveis:

  • Cabeçalho ausente — confira se o apikey: lq_live_... está sendo enviado.
  • A chave foi girada — veja no painel.
  • Espaço em branco — a chave é comparada exatamente, sem espaço na frente ou atrás.

Ação Verifique a chave. Se ela estiver certa, pode ter sido desativada — fale com o suporte.


#403 Forbidden

A guarda de fraude/velocidade barra a cobrança antes de ela chegar no provedor — o error.code sempre começa com fraud.:

json
{
  "error": {
    "type": "permission_error",
    "code": "fraud.customer_velocity_exceeded",
    "message": "Too many payment attempts for this customer in a short window"
  },
  "request_id": "req_01J..."
}

Existe um segundo código fraud.* para o limite de velocidade da própria conta.

Ação Revise o cliente ou reduza o ritmo das tentativas. Se o bloqueio parecer errado, escreva para support@liqfy.com.br com o request_id.


#404 Not Found

json
{
  "error": {
    "type": "not_found_error",
    "code": "not_found",
    "message": "Charge ch_a1b2c3d4-0000-0000-0000-000000000009 not found"
  },
  "request_id": "req_01J..."
}

Ação Confira o id. Se você acabou de criar o recurso, espere 1 a 2 segundos e tente de novo.


#409 Conflict

json
{
  "error": {
    "type": "conflict_error",
    "code": "idempotency_key_reused",
    "message": "Idempotency key 'ORD-7821' already used with a different request body"
  },
  "request_id": "req_01J..."
}

Você reenviou uma Idempotency-Key com corpo diferente do original. A Liqfy recusa sobrescrever em silêncio.

Ação Use uma Idempotency-Key nova. Causa comum: reaproveitar o id do pedido depois que o cliente mexeu no carrinho.


#Recusa por regra de negócio

Falha de formato (campo faltando ou inválido) é 400 com error.type: "invalid_request_error". Algumas falhas de configuração mais abaixo — por exemplo, nenhum PSP configurado para o payment_method pedido — vêm repassadas do orquestrador interno com o status dele, normalmente 422 Unprocessable Entity:

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "unprocessable_entity",
    "message": "no provider for PIX"
  },
  "request_id": "req_01J..."
}

Ação Leia a message. Não repita — corrija a entrada, ou fale com o suporte se a conta deveria ter provedor configurado.


#429 Too Many Requests

json
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limited",
    "message": "Rate limit exceeded"
  },
  "request_id": "req_01J..."
}

Cabeçalhos nessa resposta (veja os limites atuais em Primeiros passos):

text
Retry-After: 12
X-RateLimit-Limit-Minute: 5000
X-RateLimit-Remaining-Minute: 0

Ação Reduza o ritmo — respeite o Retry-After quando vier, senão backoff exponencial com jitter.

js
async function comRetry(fn, tentativas = 5) {
  for (let i = 0; i < tentativas; i++) {
    try { return await fn(); }
    catch (err) {
      if (err.status !== 429 && err.status < 500) throw err;
      const base = Math.min(1000 * 2 ** i, 30_000);
      const jitter = Math.random() * 0.3 * base;
      await new Promise(r => setTimeout(r, base + jitter));
    }
  }
  throw new Error('tentativas esgotadas');
}

#5xx — do lado do servidor

json
{
  "error": {
    "type": "api_error",
    "code": "service_unavailable",
    "message": "Upstream unavailable"
  },
  "request_id": "req_01J..."
}

Seguro repetir. Use a mesma Idempotency-Key, para que uma cobrança duplicada nunca seja criada caso o processamento tenha dado certo e só a resposta tenha se perdido.

#Erros de entrega de webhook (servidor → seu endpoint)

Quando a Liqfy não consegue alcançar o seu endpoint, a falha aparece em GET /v1/webhooks/deliveries:

json
{
  "id": "wd_...",
  "status": "FAILED",
  "attempts": 3,
  "maxAttempts": 15,
  "lastStatusCode": 502,
  "lastError": "HTTP 502",
  "lastResponseBody": "Bad Gateway",
  "nextRetryAt": "2026-07-23T16:08:00.000Z"
}
lastStatusCode / lastErrorO que significa
2xxEntregue. Não retenta.
4xxSeu endpoint recusou o payload. A Liqfy ainda retenta até maxAttempts — corrija e reenvie se precisar.
5xxSeu endpoint está fora. A Liqfy retenta com backoff exponencial.
429 / Retry-AfterA Liqfy respeita o seu Retry-After e reagenda.
Connection timeout / ETIMEDOUTSeu endpoint levou mais de 30s. Responda 200 OK rápido e processe em fila.
getaddrinfo ENOTFOUNDSeu domínio não resolve. Atualize a URL registrada.
self signed certificateErro de TLS. A Liqfy exige certificado público válido.

Depois de maxAttempts (padrão 15), a entrega vai para a DLQ e pode ser reenviada manualmente. Veja Webhooks para a semântica completa.

#Lendo o error.details

O error.details é uma lista plana de { param, message } — renderizável direto:

jsx
{error.details.map(({ param, message }) => (
  <li key={param}>{param}: {message}</li>
))}

#Quando escrever para o suporte

Fale com integrations@liqfy.com.br se:

  • Um 5xx persistir por mais de 5 minutos
  • Uma entrega de webhook ficar presa em FAILED depois do maxAttempts
  • Um 403 Forbidden aparecer sem explicação
  • A mesma Idempotency-Key devolver cobranças diferentes em chamadas diferentes (isso é bug — não pode acontecer)

Sempre cite o request_id — ele nos deixa rastrear todo log, span e mensagem Kafka numa consulta só.