Skip to main content
O PIX OUT permite enviar transferências instantâneas para qualquer chave PIX de forma programática. Ideal para pagamentos a fornecedores, transferências para afiliados, estornos e qualquer situação onde você precisa enviar dinheiro.

🎯 Como Funciona

O PIX OUT funciona através do envio direto para chaves PIX, sem necessidade de dados bancários complexos:

🔑 Chave PIX

Use qualquer tipo de chave: CPF, CNPJ, email, telefone ou aleatória

⚡ Transferência Instantânea

Dinheiro é transferido instantaneamente, 24/7

🔒 Segurança Total

Validação automática de chaves e dados

📊 Confirmação Imediata

Receba confirmação via webhook em tempo real

🛠️ Implementação Rápida

1. Enviar Transferência PIX

curl -X POST 'https://api.avanttifinance.com/v1/pix/out/transfer' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <seu_token>' \
  -H 'X-Idempotency-Key: transfer_20241201_001' \
  -d '{
    "pixKey": "[email protected]",
    "amount": 300,
    "password": "111111"
}'

2. Resposta de Sucesso

{
    "success": true,
    "data": {
        "id": "cmij05x240000ubhwgb0dd365",
        "companyId": "cmiivyxev0000hww1j9l4ckc8",
        "adquirenceId": 1,
        "status": "pending_analysis",
        "pixKey": "[email protected]",
        "amount": 300,
        "netAmount": 275,
        "fees": 25,
        "providerFees": 0,
        "requestSource": "api",
        "type": "send_analysis",
        "method": "manual",
        "idempotencyKey": "local-cmij05x240000ubhwgb0dd365",
        "companyIdempotencyKey": "idempotencykey222222ssssssssssss2",
        "debtorAccount": null,
        "creditorAccount": null,
        "externalId": null,
        "endToendId": null,
        "requestedBy": null,
        "approvedBy": null,
        "refusedBy": null,
        "message": null,
        "description": "Transferência de R$3.00 para [email protected]",
        "createdAt": "2025-11-28T15:13:45.629Z",
        "updatedAt": "2025-11-28T15:13:45.629Z",
        "processedAt": null
    }
}

3. Confirmação via Webhook

{
  "id": "wh_75g9b3c2d4e5f6g7h8i9j0k1",
  "type": "transfer",
  "event": "transfer_completed",
  "scope": "user",
  "transfer": {
    "id": "cln1a2b3c4567890defghijk",
    "amount": 150000,
    "status": "completed",
    "pix": {
      "endToEndId": "E87654321202412011145543210ZY987X",
      "creditorAccount": {
        "bank": "341",
        "branch": "1234",
        "account": "567890"
      }
    }
  }
}

🔑 Tipos de Chave PIX Suportados

CPF e CNPJ

# CPF (apenas números)
"pixKey": "12345678901"

# CNPJ (apenas números)  
"pixKey": "12345678000195"

Email

# Email válido
"pixKey": "[email protected]"
"pixKey": "[email protected]"

Telefone

# Formato: +5511999999999
"pixKey": "+5511987654321"
"pixKey": "+5521988888888"

Chave Aleatória (EVP)

# UUID gerado pelo banco
"pixKey": "123e4567-e89b-12d3-a456-426614174000"
"pixKey": "a1b2c3d4-e5f6-7890-1234-567890abcdef"

📊 Parâmetros Detalhados

Campos Obrigatórios

CampoTipoDescrição
pixKeystringChave PIX de destino
amountnumberValor em centavos
passwordstringsenha de transação

Headers Importantes

HeaderObrigatórioDescrição
AuthorizationToken Bearer
Content-Typeapplication/json
X-Idempotency-Key🔶Chave única para evitar duplicação
Importante: Use sempre o header X-Idempotency-Key para evitar transferências duplicadas acidentais.

📋 Status das Transferências

StatusDescriçãoTempo EsperadoPróximo Passo
createdTransferência criada e validadaImediatoAguardar processamento
processingEm processamento pelo sistema1-3 segundosAguardar conclusão
completedTransferência concluída3-10 segundosTransferência realizada
canceledCancelada pelo sistemaImediatoVerificar motivo
refusedRecusada pela instituição5-15 segundosVerificar dados

🛡️ Segurança e Boas Práticas

Validação de Chaves PIX

function validarChavePIX(chave) {
  // Remover espaços e caracteres especiais
  chave = chave.trim()
  
  // CPF (11 dígitos)
  if (/^\d{11}$/.test(chave)) {
    return validarCPF(chave)
  }
  
  // CNPJ (14 dígitos)
  if (/^\d{14}$/.test(chave)) {
    return validarCNPJ(chave)
  }
  
  // Email
  if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(chave)) {
    return true
  }
  
  // Telefone (+5511999999999)
  if (/^\+55\d{10,11}$/.test(chave)) {
    return true
  }
  
  // Chave aleatória (UUID)
  if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(chave)) {
    return true
  }
  
  return false
}

Controle de Concorrência

// Cache para evitar transferências duplicadas
const transferenciasEmAndamento = new Map()

async function enviarComControle(dados) {
  const chaveControle = `${dados.pixKey}_${dados.amount}`
  
  if (transferenciasEmAndamento.has(chaveControle)) {
    throw new Error('Transferência similar já em andamento')
  }
  
  try {
    transferenciasEmAndamento.set(chaveControle, true)
    const resultado = await enviarTransferencia(dados)
    return resultado
  } finally {
    transferenciasEmAndamento.delete(chaveControle)
  }
}

Auditoria e Logs

function logarTransferencia(transferencia, status, detalhes = {}) {
  const logEntry = {
    timestamp: new Date().toISOString(),
    transferId: transferencia.id,
    pixKey: transferencia.pixKey,
    amount: transferencia.amount,
    status: status,
    userId: transferencia.userId,
    ...detalhes
  }
  
  // Salvar no sistema de auditoria
  console.log('Transfer Log:', JSON.stringify(logEntry))
  
  // Enviar para sistema de monitoramento
  if (status === 'refused' || status === 'canceled') {
    alertSystem.notify('transfer_failed', logEntry)
  }
}

🚨 Tratamento de Erros

Códigos de Erro Comuns

CódigoErroCausaSolução
400Chave PIX inválidaFormato incorretoValidar formato da chave
402Saldo insuficienteNão há saldo na contaVerificar saldo disponível
422Valor inválidoFora dos limitesVerificar limites operacionais
429Rate limitMuitas requisiçõesImplementar retry com delay

Exemplo de Tratamento

async function enviarComTratamento(dados) {
  try {
    return await enviarTransferencia(dados)
  } catch (error) {
    switch (error.status) {
      case 400:
        throw new Error('Verifique os dados da transferência')
      case 402:
        throw new Error('Saldo insuficiente para realizar a transferência')
      case 422:
        throw new Error('Valor fora dos limites permitidos')
      case 429:
        // Aguardar e tentar novamente
        await new Promise(resolve => setTimeout(resolve, 1000))
        return await enviarTransferencia(dados)
      default:
        throw new Error('Erro interno. Tente novamente em alguns minutos.')
    }
  }
}

📊 Casos de Uso Comuns

Pagamento a Fornecedores

async function pagarFornecedor(fornecedor, valorNota, numeroNF) {
  const transferencia = {
    pixKey: fornecedor.chavePix,
    amount: valorNota,
    description: `Pagamento NF ${numeroNF} - ${fornecedor.nome}`
  }
  
  return await enviarTransferencia(transferencia)
}

Transferência para Afiliados

async function pagarAfiliado(afiliado, comissao, periodo) {
  const transferencia = {
    pixKey: afiliado.chavePix,
    amount: comissao,
    description: `Comissão ${periodo} - Afiliado ${afiliado.id}`
  }
  
  return await enviarTransferencia(transferencia)
}

Estorno para Cliente

async function estornarCliente(cliente, valorEstorno, motivo) {
  const transferencia = {
    pixKey: cliente.chavePix,
    amount: valorEstorno,
    description: `Estorno: ${motivo}`
  }
  
  return await enviarTransferencia(transferencia)
}

🎯 Próximos Passos