Cobranças

Consultar QR Code

Como consultar cobranças Pix via API

A consulta de cobranças Pix é fundamental para acompanhar o status dos pagamentos e gerenciar transações em tempo real. Esta funcionalidade permite verificar se uma cobrança foi paga, cancelada ou expirou, além de obter informações detalhadas sobre a transação.

Conceitos Fundamentais

Estados de uma Cobrança Pix

Uma cobrança Pix pode estar em diferentes estados durante seu ciclo de vida:

ATIVA: Cobrança criada e aguardando pagamento

  • QR Code disponível para pagamento
  • Dentro do prazo de expiração
  • Pode ser paga a qualquer momento

EFETIVADO: Cobrança foi paga com sucesso

  • Pagamento confirmado e processado
  • Valor creditado na conta do recebedor
  • Transação finalizada

CANCELADO: Cobrança cancelada pelo recebedor

  • QR Code não é mais válido
  • Não pode ser paga
  • Ação manual do recebedor ou tempo de expiração

Informações Disponíveis na Consulta

Ao consultar uma cobrança, você obtém:

  • Status atual da cobrança
  • Dados do pagador (quando paga)
  • Valor e descrição da transação
  • Timestamps de criação e pagamento
  • QR Code para exibição
  • Informações de expiração

Implementação Técnica

Endpoint Oficial

GET /api/v2/cobranca/cob/{txid}

Características do Endpoint:

  • Método: GET (apenas leitura)
  • Parâmetro: TXID da cobrança a ser consultada
  • Resposta: Dados completos da cobrança
  • Cache: Pode ser consultada múltiplas vezes

Estrutura da Requisição

Headers Obrigatórios

Authorization: Bearer {access_token}
Accept: application/json

Parâmetros da URL

  • txid: Identificador único da cobrança (obrigatório)
  • Formato: UUID v4
  • Exemplo: 550e8400-e29b-41d4-a716-446655440000

Estrutura da Resposta

Resposta - Cobrança Ativa (sem pagamento)

{
    "txid": "JsI6bA0QTb42rycbB8u6UzULCJHR2lC7QZd",
    "revisao": 0,
    "status": "ATIVA",
    "calendario": {
        "criacao": "2024-10-04T21:42:56.000000Z",
        "expiracao": 86400
    },
    "devedor": [],
    "valor": {
        "original": "1.00",
        "modalidadeAlteracao": 0
    },
    "qrCode": "00020101021226730014br.gov.bcb.pix2554integrador.exemplo.com.br/pix/8b3da2f3-9a41-40d1-a91a-bd93113bd4415204000053039865802BR5920Fulano de Tal Exemplo6009Sao Paulo62070503***6304ABCD",
    "chave": "e3fe4462-4c8e-42c1-8360-b41b404ae557",
    "solicitacaoPagador": null,
    "pix": []
}

Resposta - Cobrança Paga (com pagamento confirmado)

Quando a cobrança é paga, o campo pix será preenchido com os dados da transação:

{
    "txid": "JsI6bA0QTb42rycbB8u6UzULCJHR2lC7QZd",
    "revisao": 0,
    "status": "EFETIVADO",
    "calendario": {
        "criacao": "2024-10-04T21:42:56.000000Z",
        "expiracao": 86400
    },
    "devedor": [],
    "valor": {
        "original": "1.00",
        "modalidadeAlteracao": 0
    },
    "qrCode": "00020101021226730014br.gov.bcb.pix2554integrador.exemplo.com.br/pix/8b3da2f3-9a41-40d1-a91a-bd93113bd4415204000053039865802BR5920Fulano de Tal Exemplo6009Sao Paulo62070503***6304ABCD",
    "chave": "e3fe4462-4c8e-42c1-8360-b41b404ae557",
    "solicitacaoPagador": null,
    "pix": [
        {
            "id": "001f7eb9-d3d0-41f5-922f-baf963c544f8",
            "endToEndId": "E3829737420250910193643362909064",
            "txid": "G8kSgU5AVIX1y4CZJaHdjb3lo",
            "status": "CONFIRMADO",
            "valor": 1.00,
            "horario": "2024-10-04T23:12:25.000000Z",
            "infoPagador": null,
            "bancoPagador": {
                "ispb": "38297374",
                "nome": "NUVENDE"
            },
            "bancoRecebedor": {
                "ispb": "38297374",
                "nome": "NUVENDE"
            },
            "devolucoes": []
        }
    ]
}

Nota: O campo pix será um array vazio quando a cobrança ainda não foi paga. Quando há pagamento confirmado, o array conterá objetos com informações detalhadas da transação, incluindo dados dos bancos pagador e recebedor.

Implementação em Código

Classe de Consulta de Cobranças

const axios = require('axios');

class ConsultaCobrancaService {
  constructor(baseUrl, accessToken) {
    this.baseUrl = baseUrl;
    this.accessToken = accessToken;
    this.cache = new Map();
    this.cacheTTL = 30000; // 30 segundos
  }

  /**
   * Consulta uma cobrança Pix pelo TXID
   * @param {string} txid - Identificador único da cobrança
   * @param {boolean} usarCache - Se deve usar cache (padrão: true)
   * @returns {Promise<Object>} Dados da cobrança
   */
  async consultarCobranca(txid, usarCache = true) {
    try {
      // Verificar cache primeiro
      if (usarCache && this.cache.has(txid)) {
        const cached = this.cache.get(txid);
        if (Date.now() - cached.timestamp < this.cacheTTL) {
          console.log(`Retornando cobrança ${txid} do cache`);
          return cached.data;
        }
        this.cache.delete(txid);
      }

      console.log(`Consultando cobrança Pix: ${txid}`);
      
      const response = await axios.get(
        `${this.baseUrl}/api/v2/cobranca/cob/${txid}`,
        {
          headers: {
            'Authorization': `Bearer ${this.accessToken}`,
            'Accept': 'application/json',
          }
        }
      );

      const cobranca = this.processarRespostaCobranca(response.data);
      
      // Armazenar no cache
      if (usarCache) {
        this.cache.set(txid, {
          data: cobranca,
          timestamp: Date.now()
        });
      }

      console.log(`Cobrança consultada: ${cobranca.status}`);
      return cobranca;
      
    } catch (error) {
      console.error('Erro ao consultar cobrança:', error.response?.data || error.message);
      throw this.tratarErroConsulta(error);
    }
  }

  /**
   * Processa a resposta da API para um formato mais amigável
   * @param {Object} dados - Dados brutos da API
   * @returns {Object} Dados processados
   */
  processarRespostaCobranca(dados) {
    return {
      txid: dados.txid,
      status: dados.status,
      valor: parseFloat(dados.valor.original),
      chave: dados.chave,
      solicitacaoPagador: dados.solicitacaoPagador,
      qrCode: dados.qrCode,
      criacao: new Date(dados.calendario.criacao),
      expiracao: dados.calendario.expiracao,
      devedor: dados.devedor || null,
      pagamento: dados.pix && dados.pix.length > 0 ? this.processarPagamento(dados.pix) : null,
      revisao: dados.revisao,
      modalidadeAlteracao: dados.valor.modalidadeAlteracao
    };
  }

  /**
   * Processa informações de pagamento quando disponíveis
   * @param {Array} pix - Array de pagamentos
   * @returns {Object} Dados do pagamento processados
   */
  processarPagamento(pix) {
    if (!pix || pix.length === 0) return null;

    const pagamento = pix[0]; // Primeiro pagamento
    return {
      endToEndId: pagamento.endToEndId,
      txid: pagamento.txid,
      valor: parseFloat(pagamento.valor),
      horario: new Date(pagamento.horario),
      infoPagador: pagamento.infoPagador || null
    };
  }

  /**
   * Verifica se uma cobrança está ativa
   * @param {string} txid - TXID da cobrança
   * @returns {Promise<boolean>} True se estiver ativa
   */
  async isCobrancaAtiva(txid) {
    try {
      const cobranca = await this.consultarCobranca(txid);
      return cobranca.status === 'ATIVA';
    } catch (error) {
      console.error('Erro ao verificar status da cobrança:', error.message);
      return false;
    }
  }

  /**
   * Verifica se uma cobrança foi paga
   * @param {string} txid - TXID da cobrança
   * @returns {Promise<boolean>} True se foi paga
   */
  async isCobrancaPaga(txid) {
    try {
      const cobranca = await this.consultarCobranca(txid);
      return cobranca.status === 'EFETIVADO';
    } catch (error) {
      console.error('Erro ao verificar pagamento da cobrança:', error.message);
      return false;
    }
  }

  /**
   * Obtém informações do pagador se a cobrança foi paga
   * @param {string} txid - TXID da cobrança
   * @returns {Promise<Object|null>} Dados do pagador ou null
   */
  async obterDadosPagador(txid) {
    try {
      const cobranca = await this.consultarCobranca(txid);
      return cobranca.pagamento ? {
        endToEndId: cobranca.pagamento.endToEndId,
        valor: cobranca.pagamento.valor,
        horario: cobranca.pagamento.horario,
        infoPagador: cobranca.pagamento.infoPagador
      } : null;
    } catch (error) {
      console.error('Erro ao obter dados do pagador:', error.message);
      return null;
    }
  }

  /**
   * Limpa o cache de consultas
   */
  limparCache() {
    this.cache.clear();
    console.log('Cache de consultas limpo');
  }

  /**
   * Trata erros específicos da consulta
   * @param {Error} error - Erro capturado
   * @returns {Error} Erro tratado
   */
  tratarErroConsulta(error) {
    const status = error.response?.status;
    const data = error.response?.data;

    switch (status) {
      case 400:
        return new Error('TXID inválido ou malformado');
      case 401:
        return new Error('Token de acesso inválido ou CANCELADO');
      case 403:
        return new Error('Permissões insuficientes para consultar cobranças');
      case 404:
        return new Error('Cobrança não encontrada');
      case 500:
        return new Error('Erro interno do servidor. Tente novamente mais tarde');
      default:
        return new Error(`Erro inesperado: ${error.message}`);
    }
  }
}

// Exemplo de uso prático
async function exemploConsultaCobranca() {
  const consultaService = new ConsultaCobrancaService(
    'https://api-h.nuvende.com.br',
    'seu_access_token');

  try {
    const txid = '550e8400-e29b-41d4-a716-446655440000';
    
    // Consultar cobrança
    const cobranca = await consultaService.consultarCobranca(txid);
    
    console.log('Status da cobrança:', cobranca.status);
    console.log('Valor:', cobranca.valor);
    console.log('Criada em:', cobranca.criacao);
    
    // Verificar se foi paga
    if (await consultaService.isCobrancaPaga(txid)) {
      console.log('Cobrança foi paga!');
      const pagador = await consultaService.obterDadosPagador(txid);
      console.log('Dados do pagador:', pagador);
    } else {
      console.log('Cobrança ainda não foi paga');
    }

  } catch (error) {
    console.error('Erro na consulta:', error.message);
  }
}

2025 © Nuvende - CNPJ 38.297.374/0001-93