> ## Documentation Index
> Fetch the complete documentation index at: https://docs.turbofypay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Erros e estados do Pix Out

> Interprete erros de criação de lote e motivos públicos por item de payout Pix.

Ao criar um lote, consulte `error.code` na resposta HTTP. Depois da criação, acompanhe o `status` do lote e de cada item junto dos campos `lastErrorCode` e `statusReasonCode`. Um motivo de processamento pendente pode aparecer em uma consulta HTTP `200`.

## Erros ao criar um lote

Envie uma criação de lote por vez por conta e aguarde a resposta HTTP antes da próxima. O HTTP `201` confirma a criação do lote. Os Pix do lote são processados depois e devem ser acompanhados por consulta.

A rota permite até 10 solicitações de criação por minuto. Espaçar os envios por um segundo pode reduzir a concorrência, mas não substitui a espera pela resposta nem a cota da rota.

| HTTP | Código | Significado | Ação segura |
| - | - | - | - |
| `400` | `INSUFFICIENT_AVAILABLE_BALANCE` | O saldo disponível da conta não cobre o valor total do lote e as tarifas aplicáveis. | Consulte o saldo disponível e revise os valores antes de enviar o lote novamente. |
| `409` | `PAYOUT_BATCH_BUSY` | A criação não conseguiu obter acesso exclusivo às operações financeiras da conta naquele momento. | Aguarde a requisição em andamento responder e espere pelo menos um segundo antes de repetir. Se o conflito persistir, aumente o intervalo entre tentativas. Reenvie com o mesmo payload e a mesma chave de idempotência, usando uma nova assinatura. |
| `409` | `PIX_UNAVAILABLE` | A criação do Pix não está disponível naquele momento. Nesta rota, o código também pode indicar uma pausa temporária de saques Pix para a conta. | Consulte o lote se recebeu um `batchId`. Se repetir a mesma solicitação, mantenha o payload e a chave de idempotência; gere uma assinatura válida para a nova requisição. |
| `429` | Limite de requisições | A requisição atingiu uma cota de chamadas. | Aguarde o prazo indicado em `Retry-After`, quando disponível, antes de tentar de novo. |
| `500` | `P2028` | A transação de criação expirou ou foi encerrada durante o processamento no servidor. | Se recebeu um `batchId`, consulte o lote. Se precisar repetir a criação, use o mesmo payload e a mesma chave de idempotência, com uma nova assinatura. |
| Sem resposta HTTP | Timeout de rede ou do cliente, por exemplo `timeout of 10000ms exceeded` | A integração parou de esperar e o resultado da criação ficou desconhecido. | Consulte o lote se já tiver o `batchId`. Caso contrário, repita apenas a solicitação original, com o mesmo payload e a mesma chave de idempotência, gerando uma nova assinatura. |

## Exemplo de nova tentativa sem duplicar o Pix

Antes do primeiro envio, gere uma `idempotencyKey` para o lote e salve o corpo JSON completo no seu sistema. Use esse mesmo corpo nas novas tentativas, inclusive depois de reiniciar a aplicação. Se já tiver o `batchId`, [consulte o lote](https://docs.turbofypay.com/pages/reference/payouts/consultar-lote-payouts.md).

Por exemplo, se o primeiro envio usou `"idempotencyKey": "payout-pedido-8472"`, mantenha `payout-pedido-8472` e todos os campos do JSON nas tentativas seguintes. Carregue esse JSON como texto e passe-o para `enviarLote(corpoOriginal)`.

O exemplo em Node.js recebe o JSON original já salvo. Ele aguarda cada resposta, tenta novamente em caso de `PAYOUT_BATCH_BUSY`, `P2028` ou timeout do cliente e recalcula a [assinatura HMAC](https://docs.turbofypay.com/pages/integracao/autenticacao.md) a cada envio.

```js theme={null}
import { createHmac } from 'node:crypto';
import { setTimeout as sleep } from 'node:timers/promises';

export async function enviarLote(corpoOriginal) {
  const path = '/v1/payouts/batches';
  const clientId = process.env.TURBOFY_CLIENT_ID;
  const clientSecret = process.env.TURBOFY_CLIENT_SECRET;

  for (let tentativa = 1; tentativa <= 3; tentativa++) {
    const timestamp = Date.now().toString();
    const signature = createHmac('sha256', clientSecret)
      .update(`${timestamp}.POST.${path}.${corpoOriginal}`)
      .digest('hex');
    const signal = AbortSignal.timeout(15_000);

    try {
      const response = await fetch(`https://api.turbofypay.com${path}`, {
        method: 'POST',
        headers: {
          'content-type': 'application/json',
          'x-client-id': clientId,
          'x-client-secret': clientSecret,
          'x-turbofy-timestamp': timestamp,
          'x-turbofy-signature': signature,
        },
        body: corpoOriginal,
        signal,
      });

      if (response.status === 429) {
        throw new Error(`HTTP 429. Retry-After: ${response.headers.get('retry-after') ?? 'ausente'}`);
      }

      const resultado = await response.json();
      if (response.status === 201 || response.status === 200) return resultado;

      const code = resultado?.error?.code;
      const busy = response.status === 409 && code === 'PAYOUT_BATCH_BUSY';
      const timeout = response.status === 500 && code === 'P2028';
      if (!busy && !timeout) throw new Error(`HTTP ${response.status}: ${code ?? 'sem código'}`);
    } catch (error) {
      if (error.name !== 'TimeoutError' && !(error.name === 'AbortError' && signal.aborted)) {
        throw error;
      }
    }

    if (tentativa < 3) await sleep(tentativa * 1000);
  }

  throw new Error('Lote sem confirmação. Preserve o corpo original e a chave de idempotência.');
}
```

HTTP `201` confirma a criação do lote. HTTP `200` indica que o lote já existia e retorna o mesmo `batchId`. Em ambos os casos, acompanhe os Pix pela consulta do lote. Se as tentativas se esgotarem, preserve a solicitação original para conciliação. Gerar uma chave nova pode criar outro lote.

## Motivos no status de um item

| Código | Significado | Ação segura |
| - | - | - |
| `PIX_RESULT_PENDING` | O resultado ainda está sendo confirmado. A consulta pode retornar HTTP `200` enquanto o item continua pendente ou em processamento. | Continue consultando o mesmo lote e item. Não crie outro Pix nem use uma nova chave de idempotência enquanto o desfecho não estiver confirmado. |
| `PIX_KEY_NOT_FOUND` | O item terminou em falha e a chave não foi encontrada. | Confirme a chave com o destinatário. Só envie uma solicitação corrigida depois de verificar que o item anterior está em estado final. |
| `INVALID_PIX_KEY` | A chave Pix é inválida. Em um item, este código é apresentado quando o estado já é final. | Confira a chave com o destinatário. Antes de criar outro pagamento, confirme que o item anterior terminou em falha. |
| `PIX_FAILED` | O item terminou sem sucesso e a API não tem um motivo público mais específico para apresentar. | Consulte o estado final e o histórico da conta antes de iniciar outro pagamento. |

Na [consulta de saldo](https://docs.turbofypay.com/pages/reference/saldo/consultar-saldo.md), HTTP `503` com `BALANCE_UNAVAILABLE` indica uma falha na leitura do saldo. Tente novamente apenas a consulta `GET`.

> [!WARNING]
>
> Não trate `PIX_RESULT_PENDING` como falha. Uma nova chave de idempotência pode criar uma segunda operação enquanto o primeiro resultado ainda está sendo confirmado.

Consulte o [lote](https://docs.turbofypay.com/pages/reference/payouts/consultar-lote-payouts.md) ou [liste os itens](https://docs.turbofypay.com/pages/reference/payouts/listar-itens-payouts.md) para acompanhar o desfecho.

## Avisos de revisão manual

| Código relatado | Significado | Ação segura |
| - | - | - |
| `MANUAL_REVIEW_PIX_UNAVAILABLE` | Código relatado em integrações para uma indisponibilidade de Pix associada a revisão manual. O retorno pode variar conforme a integração. | Se houver `batchId`, consulte o lote e o item já existentes. Se o resultado estiver em aberto, aguarde a confirmação antes de criar outro Pix. Se o aviso persistir, informe ao suporte o horário, o status HTTP e o `x-request-id`, quando disponíveis. |

Em ações sobre um lote existente, a API pode responder `PIX_UNAVAILABLE` com a mensagem “Lote indisponível para novas operações; revisão necessária.” Use o estado do item para confirmar se o Pix foi concluído, falhou ou segue em análise.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.