Pular para o conteúdo
xFlow Payments

Blog

Erros da API Pix

Na API Pix da xFlow, todo erro volta em JSON com error (o código), message e request_id. O status HTTP diz a família do problema: 400 corpo inválido, 401 credencial, 403 conta ou modo, 404 recurso inexistente, 409 idempotência, 422 recusa de negócio, 429 limite e 502 falha no provedor. O request_id localiza a chamada em Integrações > Logs da API.

Atualizado em · Equipe xFlow Payments · 5 min de leitura

Os erros da API Pix da xFlow seguem um formato único: o status HTTP indica a família do problema e o corpo JSON traz o código exato em error, uma explicação em message e o request_id da chamada. Ler o error, e não só o status, é o que permite tratar cada caso no código. Abaixo estão todos os códigos listados na documentação da API, com causa e solução. Para o panorama da integração, veja o guia da API Pix.

Formato de um erro

json
{
  "error": "validation",
  "message": "...",
  "request_id": "req_kJ2m9..."
}

O request_id também vem no header x-request-id. Ele existe em toda resposta, inclusive nas de sucesso. Nos erros 400 validation, confira também o campo details, que aponta o que está errado no corpo.

Use error para decidir o que fazer no código e message para o log: o texto foi escrito para leitura humana. Um if (erro.code === "insufficient_balance") é mais claro e mais seguro do que procurar palavras na mensagem.

Sobre o 401: além do HTTP Basic com pk_live_...:sk_live_..., a API ainda aceita o formato legado Authorization: Bearer sk_live_..., só com o segredo. Ele aceita apenas segredos sk_live_ e sk_test_. Se a chamada usa outro formato, a resposta é 401 unauthorized.

Tabela de erros da API Pix

HTTP Código Quando acontece Como resolver
400 validation Corpo inválido: campo obrigatório ausente, tipo errado ou valor fora do mínimo e do máximo da conta. Leia details e corrija. Os limites de valor ficam no painel, em Empresa > Limites e taxas.
400 invalid_url URL de webhook inacessível ou apontando para rede interna. Use uma URL https:// pública.
400 endpoint_limit A conta já tem 20 endpoints de webhook. Remova um endpoint com DELETE /api/v1/webhooks/{id}.
401 unauthorized Chave ausente, inválida ou revogada, ou IP fora da allowlist. Confira as chaves e a allowlist em Chaves de API.
403 account_inactive Conta em análise ou bloqueada. Confira o cadastro no painel. Enquanto isso, integre com chave de teste.
403 api_withdrawal_disabled Saque via API desabilitado para a conta. Fale com o suporte.
403 test_mode_unsupported Recurso indisponível com chave de teste, como saques. Teste esse fluxo com chave de produção.
403 test_mode_only Endpoint de simulação chamado com chave de produção. Use a chave pk_test_ em POST /test/charges/{id}/pay.
404 not_found Cobrança ou saque não encontrado. Confira o id enviado na URL.
409 idempotency_conflict Idempotency-Key já usada com um corpo diferente. Gere uma chave nova por pedido.
422 transfer_failed Saque recusado, por exemplo por saldo insuficiente ou QR Code não aceito pelo provedor. Confira o saldo em GET /balance. Com QR não aceito, nada é debitado: use chave Pix.
422 charge_not_refundable Estorno de cobrança que não está paid. Estorne só cobranças pagas.
422 refund_window_expired Estorno pedido mais de 90 dias após o pagamento. O estorno pela API não está mais disponível.
422 insufficient_balance Saldo disponível não cobre o estorno. O corpo traz shortfallCents. Aguarde saldo e tente de novo.
422 refund_not_supported O provedor da cobrança não oferece estorno via API. Fale com o suporte, citando o request_id.
429 rate_limited Muitas requisições. O limite é por conta. Espere o retry-after e use backoff.
502 charge_failed Falha ao gerar a cobrança no provedor. Tente de novo com backoff.
502 refund_failed O PSP recusou ou não respondeu ao estorno. A retenção foi liberada. Peça o estorno de novo mais tarde.

Dois casos respondem 400 sem código próprio na lista: splits enviados com chave de teste e split inválido em produção. Os detalhes de estorno e saque estão em estorno Pix por API e API de saque Pix.

Quais erros vale repetir

Nem todo erro melhora com retentativa. Separe em três grupos:

  1. Repita com espera: 429 rate_limited (depois do retry-after), 502 charge_failed e 502 refund_failed.
  2. Corrija antes de repetir: 400, 401, 404 e 409. Repetir o mesmo pedido dá o mesmo erro.
  3. Depende de algo fora do código: 403 e 422. Conta, configuração, saldo ou prazo precisam mudar primeiro.

Ao repetir uma criação de cobrança ou de saque, mantenha a mesma Idempotency-Key. É ela que garante que um retry não gere um segundo Pix nem debite o saldo duas vezes. O mecanismo está explicado em idempotência em API de pagamento.

js
async function comRetentativa(chamada, tentativas = 3) {
  for (let i = 0; ; i++) {
    try {
      return await chamada();
    } catch (erro) {
      const repetivel = erro.status === 429 || erro.status === 502;
      if (!repetivel || i === tentativas - 1) throw erro;
      const espera = erro.retryAfter ? erro.retryAfter * 1000 : 2 ** i * 1000;
      await new Promise((r) => setTimeout(r, espera));
    }
  }
}

A função espera um erro com status e retryAfter, como o do cliente em API Pix em Node.js.

Limite de requisições

Toda resposta autenticada traz três headers:

  • x-ratelimit-limit: o limite da sua conta.
  • x-ratelimit-remaining: quanto ainda resta.
  • x-ratelimit-reset: quando o contador zera, em epoch (segundos).

Monitore x-ratelimit-remaining para desacelerar antes do 429. A causa mais comum de estouro é polling em laço de GET /api/v1/charges/{id}. Troque o polling pelo webhook Pix, que avisa quando a cobrança é paga.

request_id e Logs da API

O request_id (req_...) é a ferramenta principal de depuração. Grave esse valor no seu log em toda chamada que falhar:

python
resp = requests.post(url, auth=auth, json=corpo, timeout=30)
if resp.status_code >= 400:
    erro = resp.json()
    logger.error("xflow %s %s request_id=%s", resp.status_code, erro.get("error"), resp.headers.get("x-request-id"))

No painel, em Integrações > Logs da API, cada requisição autenticada aparece com status, duração e código de erro. A retenção é de 30 dias. Com o request_id, você acha a chamada exata sem abrir chamado. Se precisar do suporte, cite o mesmo request_id: é por ele que a chamada é localizada.

Problemas que não aparecem como código de erro

  • Assinatura do webhook não confere. Quase sempre o corpo foi convertido em JSON antes da validação. O HMAC-SHA256 do header x-webhook-signature é calculado sobre o corpo cru.
  • Pedido real baixado por evento de teste. Eventos gerados com chave de teste trazem livemode: false no data. Filtre por esse campo.
  • QR Code de teste não paga. No sandbox, o pix.copyPaste é um marcador que não pode ser pago. Simule com POST /api/v1/test/charges/{id}/pay, como mostra o sandbox da API Pix.
  • Entrega de webhook repetida. Sem resposta 2xx, o mesmo evento é reenviado até 3 vezes. Se o seu sistema não tratar repetição, um pedido pode ser processado duas vezes.

Perguntas frequentes

O que significa 401 unauthorized na API Pix?

A chave está ausente, inválida ou revogada, ou o IP do servidor está fora da allowlist configurada na conta. Com allowlist ativa, o 401 aparece mesmo com a credencial certa.

Como resolver o erro 409 idempotency_conflict?

Ele aparece quando a mesma Idempotency-Key é enviada com um corpo diferente. Use a mesma chave só para repetir exatamente o mesmo pedido. Para uma cobrança ou saque novo, gere uma chave nova.

Onde vejo o histórico das minhas requisições à API?

No painel, em Integrações > Logs da API. Cada requisição autenticada aparece com status, duração e código de erro, com retenção de 30 dias. Busque pelo request_id que veio na resposta.

O que fazer quando a API responde 429?

Espere o número de segundos do header retry-after e tente de novo com backoff. O limite é por conta, e os headers x-ratelimit-limit, x-ratelimit-remaining e x-ratelimit-reset mostram quanto ainda resta.

Continue lendo