Pular para o conteúdo principal

Visão Geral de Status

Um pagamento passa por várias fases desde a criação até a liquidação final. Cada fase tem três status — Pendente, Em Processamento e Concluído — oferecendo visibilidade granular em cada etapa do pipeline.

Fluxo de Status

Durante a fase de Cash In, FAILED e ERROR são status terminais — nenhum fundo foi coletado, portanto nenhum reembolso é emitido. Para todas as fases seguintes (KYT Out, Cash Out), FAILED e ERROR são transitórios: o pagamento segue para o fluxo de reembolso (REFUND_PENDINGREFUND_PROCESSINGREFUNDED). REJECTED também aciona o fluxo de reembolso, pois ocorre apenas após o Cash In.

Descrição dos Status

StatusFaseDescriçãoMensagem Sugerida
CREATEDInicialO pagamento foi recebido e persistido, aguardando entrada na fila”Pagamento enviado”
CASH_IN_PENDINGCash InColeta de fundos recebidos na fila”Processando pagamento”
CASH_IN_PROCESSINGCash InColetando fundos do saldo pré-financiado”Coletando fundos”
CASH_IN_COMPLETEDCash InFundos coletados com sucesso”Fundos coletados”
KYT_OUT_PENDINGKYT OutTransação de saída na fila para verificação de conformidade”Verificação de saída pendente”
KYT_OUT_PROCESSINGKYT OutRevisão de conformidade em andamento (saída)“Verificação de saída em andamento”
KYT_OUT_COMPLETEDKYT OutVerificação de conformidade de saída aprovada”Pronto para transferência”
CASH_OUT_PENDINGCash OutDesembolso ao beneficiário na fila”Transferência na fila”
CASH_OUT_PROCESSINGCash OutFundos submetidos ao provedor de pagamentos”Transferência em andamento”
CASH_OUT_COMPLETEDCash OutProvedor de pagamentos confirmou a entrega”Transferência entregue”
COMPLETEDTerminalPagamento totalmente liquidado”Pagamento entregue!”
REVIEW_NEEDEDRevisãoTransação sinalizada para revisão manual de conformidade”Em revisão — notificaremos você”
FAILEDEstado de ErroOperação falhou. Terminal durante Cash In (nenhum fundo coletado). Inicia fluxo de reembolso se ocorrer em fase posterior.”Transferência falhou — verifique os dados do beneficiário”
REJECTEDEstado de ErroPagamento bloqueado por revisão de conformidade. Sempre aciona o fluxo de reembolso, pois ocorre apenas após o Cash In.”Transferência rejeitada — problema de conformidade”
ERROREstado de ErroErro interno do sistema. Terminal durante Cash In (nenhum fundo coletado). Inicia fluxo de reembolso se ocorrer em fase posterior.”Erro interno — contate o suporte”
REFUND_PENDINGReembolsoReembolso ao saldo pré-financiado na fila”Reembolso iniciado”
REFUND_PROCESSINGReembolsoReembolso em andamento”Reembolso em andamento”
REFUNDEDTerminalFundos devolvidos ao saldo pré-financiado”Fundos reembolsados ao saldo”

Obter Status do Pagamento

GET /api/v2/payouts/{id}
const obterStatusPagamento = async (payoutId) => {
  const response = await fetch(
    `https://sandbox.killb.app/api/v2/payouts/${payoutId}`,
    {
      headers: { 'Authorization': `Bearer ${token}` }
    }
  );

  const pagamento = await response.json();
  return pagamento.status;
};

Polling de Status

Use polling como fallback quando webhooks não estiverem disponíveis:
const aguardarPagamento = async (payoutId, timeoutMs = 300000) => {
  const statusTerminais = ['COMPLETED', 'FAILED', 'REJECTED', 'ERROR', 'REFUNDED'];
  const inicio = Date.now();

  while (Date.now() - inicio < timeoutMs) {
    const response = await fetch(
      `https://sandbox.killb.app/api/v2/payouts/${payoutId}`,
      { headers: { 'Authorization': `Bearer ${token}` } }
    );

    const pagamento = await response.json();
    console.log('Status:', pagamento.status);

    if (statusTerminais.includes(pagamento.status)) {
      return pagamento;
    }

    // Aguardar 15 segundos antes da próxima verificação
    await new Promise(resolve => setTimeout(resolve, 15000));
  }

  throw new Error(`Pagamento ${payoutId} não liquidou dentro do timeout`);
};

const resultado = await aguardarPagamento('payout-abc123');

if (resultado.status === 'COMPLETED') {
  console.log('Fundos entregues com sucesso');
} else {
  console.error('Pagamento encerrado com status:', resultado.status);
}
Use webhooks como método de notificação principal. Polling a cada 15–30 segundos é apropriado como backup.

Webhooks para Atualizações de Status

Assine o tipo de evento PAYOUT para receber notificações em tempo real a cada mudança de status:
// Assinar eventos de pagamento
await fetch('/api/v2/webhooks', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    url: 'https://seu-app.com/webhooks/killb',
    secret: 'seu-segredo-webhook',
    events: ['PAYOUT'],
    active: true
  })
});
Gerencie os eventos webhook de pagamento recebidos:
app.post('/webhooks/killb', (req, res) => {
  const { event, data } = req.body;

  switch (event) {
    // Eventos de progresso de fase — atualize o indicador de status da sua interface
    case 'payout.cash_in_pending':
    case 'payout.cash_in_processing':
    case 'payout.cash_in_completed':
    case 'payout.kyt_out_pending':
    case 'payout.kyt_out_processing':
    case 'payout.kyt_out_completed':
    case 'payout.cash_out_pending':
    case 'payout.cash_out_processing':
    case 'payout.cash_out_completed':
    case 'payout.refund_pending':
    case 'payout.refund_processing': {
      const status = event.replace('payout.', '').toUpperCase();
      atualizarStatusPagamento(data.id, status);
      break;
    }

    case 'payout.completed':
      atualizarStatusPagamento(data.id, 'COMPLETED');
      notificarDestinatario(data);
      break;

    case 'payout.review_needed':
      // Transação sinalizada para revisão manual — nenhuma ação necessária
      atualizarStatusPagamento(data.id, 'REVIEW_NEEDED');
      alertarEquipeConformidade(data);
      break;

    case 'payout.error':
      // Erro interno do sistema — nenhum fundo desembolsado
      atualizarStatusPagamento(data.id, 'ERROR');
      alertarEquipeOps(data);
      break;

    case 'payout.failed':
      // Dados de conta do beneficiário inválidos ou incorretos
      atualizarStatusPagamento(data.id, 'FAILED');
      notificarBeneficiarioInvalido(data);
      break;

    case 'payout.rejected':
      // Bloqueado por revisão de conformidade
      atualizarStatusPagamento(data.id, 'REJECTED');
      escalarParaConformidade(data);
      break;

    case 'payout.refunded':
      // Fundos devolvidos ao saldo pré-financiado
      atualizarStatusPagamento(data.id, 'REFUNDED');
      reconciliarSaldo(data);
      break;
  }

  res.status(200).json({ received: true });
});

Boas Práticas

Sempre configure um endpoint webhook para eventos PAYOUT. Isso fornece atualizações instantâneas de status sem sobrecarga de polling e reduz chamadas desnecessárias à API.
Se a entrega do webhook falhar, consulte GET /api/v2/payouts/{id} a cada 15–30 segundos. Defina um timeout razoável (ex.: 5 minutos) e alerte sua equipe se um pagamento permanecer em qualquer estado de processamento por mais tempo que o esperado.
Cada status de falha tem uma causa distinta e a fase em que ocorre determina se haverá reembolso:
  • FAILED / ERROR durante Cash In — Terminal. Nenhum fundo foi coletado, portanto nenhum reembolso é emitido. Para ERROR, contate o suporte se persistir.
  • FAILED / ERROR após Cash In (KYT Out, Cash Out) — Transitório. Como os fundos já foram coletados, o pagamento segue automaticamente para REFUND_PENDINGREFUND_PROCESSINGREFUNDED.
  • REJECTED — Bloqueado por revisão de conformidade. Não retentar automaticamente; escalar internamente. Sempre aciona o fluxo de reembolso, pois os fundos já foram coletados.
  • REVIEW_NEEDED — Uma verificação KYT sinalizou a transação para revisão manual. O pagamento é retomado automaticamente ou passa para REJECTED; nenhuma ação necessária da sua parte.
Obtenha todos os pagamentos do dia anterior via GET /api/v2/payouts e reconcilie com seu livro-razão interno. Compare os status terminais esperados vs. reais para detectar discrepâncias antecipadamente.
const { payouts } = await listarPagamentos({ limit: 100 });
const precisamAtencao = payouts.filter(p =>
  ['ERROR', 'FAILED', 'REJECTED'].includes(p.status)
);

if (precisamAtencao.length > 0) {
  console.warn(`${precisamAtencao.length} pagamentos precisam de atenção`, precisamAtencao);
}

Próximos Passos

Configurar Webhooks

Configure e proteja notificações webhook

Tratamento de Erros

Gerencie falhas da API com elegância