Pular para o conteúdo principal
POST
/
bank-slip
/
v1
/
payment
/
{id}
/
generate-pdf
Gerar PDF do Boleto
curl --request POST \
  --url https://api-gateway.firebanking.dev/bank-slip/v1/payment/{id}/generate-pdf \
  --header 'x-api-key: <api-key>'
{
  "pdfAccessUrl": "https://s3.us-east-1.amazonaws.com/dev...."
}

Visão Geral

Gere o arquivo PDF de um boleto bancário registrado. Este endpoint retorna uma URL temporária para download do arquivo PDF formatado com todos os dados necessários para pagamento em agências bancárias, lotéricas ou para impressão.
O PDF gerado segue o padrão FEBRABAN e é aceito em toda rede bancária nacional.

Parâmetros da URL

id
string
required
ID do boleto ou externalId para gerar o PDF

Exemplo de Requisição

curl --request POST \
  --url 'https://api-gateway.firebanking.com.br/bank-slip/v1/payment/<id>/generate-pdf' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <sua-chave-api>'

Exemplo de Resposta

{
  "pdfAccessUrl": "https://s3.us-east-1.amazonaws.com/dev...."
}

Implementação Frontend

Interface de Download

<div class="boleto-pdf-section">
  <h4>📄 Arquivo do Boleto</h4>

  <div class="pdf-actions">
    <button id="download-btn" class="btn btn-primary" onclick="downloadPDF()">
      ⬇️ Baixar PDF
    </button>

    <button id="view-btn" class="btn btn-secondary" onclick="viewPDF()">
      👁️ Visualizar
    </button>

    <button id="email-btn" class="btn btn-info" onclick="sendByEmail()">
      📧 Enviar por Email
    </button>
  </div>

  <div id="pdf-preview" class="pdf-preview" style="display: none;">
    <iframe id="pdf-iframe" width="100%" height="600"></iframe>
  </div>

  <div class="pdf-instructions">
    <p>💡 <strong>Dica:</strong> Você pode pagar este boleto em:</p>
    <ul>
      <li>Qualquer agência bancária</li>
      <li>Internet banking do seu banco</li>
      <li>App do banco pelo celular</li>
      <li>Lotéricas e casas lotéricas</li>
    </ul>
  </div>
</div>

JavaScript para Manipular PDF

class BoletoPDFManager {
  constructor(boletoId) {
    this.boletoId = boletoId;
    this.currentPdfUrl = null;
    this.setupEventListeners();
  }

  setupEventListeners() {
    document.getElementById('download-btn').addEventListener('click', () => this.downloadPDF());
    document.getElementById('view-btn').addEventListener('click', () => this.viewPDF());
    document.getElementById('email-btn').addEventListener('click', () => this.sendByEmail());
  }

  async generatePDF(format = 'url') {
    try {
      this.setLoadingState(true);

      const response = await fetch(`/api/boleto/${this.boletoId}/pdf`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ format })
      });

      if (!response.ok) {
        throw new Error('Erro ao gerar PDF');
      }

      const result = await response.json();
      return result;
    } catch (error) {
      console.error('Erro ao gerar PDF:', error);
      this.showError('Erro ao gerar PDF. Tente novamente.');
      throw error;
    } finally {
      this.setLoadingState(false);
    }
  }

  async downloadPDF() {
    try {
      const pdfData = await this.generatePDF('url');

      // Criar link de download
      const link = document.createElement('a');
      link.href = pdfData.pdf_url;
      link.download = `boleto-${this.boletoId}.pdf`;

      // Trigger download
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);

      this.showSuccess('PDF baixado com sucesso!');
    } catch (error) {
      this.showError('Erro ao baixar PDF');
    }
  }

  async viewPDF() {
    try {
      const pdfData = await this.generatePDF('url');

      // Mostrar preview
      const iframe = document.getElementById('pdf-iframe');
      iframe.src = pdfData.pdf_url;

      const preview = document.getElementById('pdf-preview');
      preview.style.display = 'block';

      // Scroll para o preview
      preview.scrollIntoView({ behavior: 'smooth' });
    } catch (error) {
      this.showError('Erro ao visualizar PDF');
    }
  }

  async sendByEmail() {
    try {
      const response = await fetch(`/api/boleto/${this.boletoId}/send-email`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        }
      });

      if (response.ok) {
        this.showSuccess('PDF enviado por email!');
      } else {
        throw new Error('Erro ao enviar email');
      }
    } catch (error) {
      this.showError('Erro ao enviar email');
    }
  }

  setLoadingState(loading) {
    const buttons = ['download-btn', 'view-btn', 'email-btn'];
    buttons.forEach(btnId => {
      const btn = document.getElementById(btnId);
      btn.disabled = loading;

      if (loading) {
        btn.classList.add('loading');
        btn.textContent = 'Gerando...';
      } else {
        btn.classList.remove('loading');
        // Restaurar texto original baseado no ID
        const originalTexts = {
          'download-btn': '⬇️ Baixar PDF',
          'view-btn': '👁️ Visualizar',
          'email-btn': '📧 Enviar por Email'
        };
        btn.textContent = originalTexts[btnId];
      }
    });
  }

  showSuccess(message) {
    this.showNotification(message, 'success');
  }

  showError(message) {
    this.showNotification(message, 'error');
  }

  showNotification(message, type) {
    const notification = document.createElement('div');
    notification.className = `notification notification-${type}`;
    notification.textContent = message;

    document.body.appendChild(notification);

    // Auto-remove após 3 segundos
    setTimeout(() => {
      if (notification.parentNode) {
        notification.parentNode.removeChild(notification);
      }
    }, 3000);
  }
}

// Inicializar quando a página carregar
document.addEventListener('DOMContentLoaded', () => {
  const boletoId = document.querySelector('[data-boleto-id]')?.dataset.boletoId;
  if (boletoId) {
    new BoletoPDFManager(boletoId);
  }
});

Compartilhamento por WhatsApp

function shareViaWhatsApp(boletoData) {
  const phone = boletoData.buyer.phone;
  const pdfUrl = boletoData.pdf_url;

  const message = `🧾 *Seu Boleto Bancário*\n\n` +
    `💰 Valor: R$ ${(boletoData.amount / 100).toFixed(2)}\n` +
    `📅 Vencimento: ${formatDate(boletoData.due_date)}\n\n` +
    `📎 Link do PDF:\n${pdfUrl}\n\n` +
    `📱 Você pode pagar pelo app do seu banco escaneando o código de barras ou usar a linha digitável:\n\n` +
    `${boletoData.digitable_line}\n\n` +
    `💡 Também pode pagar em qualquer agência bancária ou lotérica.`;

  const whatsappUrl = `https://wa.me/55${phone.replace(/\D/g, '')}?text=${encodeURIComponent(message)}`;
  window.open(whatsappUrl, '_blank');
}

Backend - Implementação

Endpoint para Gerar PDF

// Node.js/Express
app.post('/api/boleto/:id/pdf', async (req, res) => {
  try {
    const { id } = req.params;
    const { format = 'url' } = req.body;

    // Validar formato
    if (!['url', 'base64'].includes(format)) {
      return res.status(400).json({
        error: 'Formato inválido. Use "url" ou "base64"'
      });
    }

    // Chamar API da FireBanking
    const response = await fetch(
      `https://api-gateway.firebanking.com.br/bank-slip/v1/payment/${id}/generate-pdf?format=${format}`,
      {
        method: 'POST',
        headers: {
          'x-api-key': process.env.FIREBANKING_API_KEY
        }
      }
    );

    const result = await response.json();

    if (response.ok) {
      res.json(result);
    } else {
      res.status(response.status).json(result);
    }
  } catch (error) {
    console.error('Erro ao gerar PDF:', error);
    res.status(500).json({ error: 'Erro interno do servidor' });
  }
});

Envio por Email

app.post('/api/boleto/:id/send-email', async (req, res) => {
  try {
    const { id } = req.params;

    // Buscar dados do boleto
    const boleto = await getBoletoById(id);

    if (!boleto) {
      return res.status(404).json({ error: 'Boleto não encontrado' });
    }

    // Gerar PDF
    const pdfData = await generateBoletoPDF(id, 'base64');

    // Enviar email
    await sendBoletoEmail({
      to: boleto.buyer.email,
      boleto: boleto,
      pdfBase64: pdfData.pdf_base64
    });

    res.json({ message: 'Email enviado com sucesso' });
  } catch (error) {
    console.error('Erro ao enviar email:', error);
    res.status(500).json({ error: 'Erro ao enviar email' });
  }
});

async function sendBoletoEmail({ to, boleto, pdfBase64 }) {
  const emailData = {
    to: to,
    subject: `Seu Boleto - ${boleto.description}`,
    html: `
      <h2>Seu Boleto Bancário</h2>

      <p>Olá! Segue em anexo seu boleto para pagamento.</p>

      <div style="background: #f5f5f5; padding: 20px; border-radius: 8px;">
        <h3>Detalhes do Boleto:</h3>
        <p><strong>Valor:</strong> R$ ${(boleto.amount / 100).toFixed(2)}</p>
        <p><strong>Vencimento:</strong> ${formatDate(boleto.due_date)}</p>
        <p><strong>Código de Barras:</strong> ${boleto.digitable_line}</p>
      </div>

      <h4>Como Pagar:</h4>
      <ul>
        <li>📱 App do banco: escaneie o código de barras</li>
        <li>💻 Internet banking: use a linha digitável</li>
        <li>🏪 Agência ou lotérica: apresente o boleto impresso</li>
      </ul>

      <p>Obrigado!</p>
    `,
    attachments: [
      {
        filename: `boleto-${boleto.id}.pdf`,
        content: pdfBase64,
        encoding: 'base64',
        contentType: 'application/pdf'
      }
    ]
  };

  return await sendEmail(emailData);
}

Cache e Performance

Cache de PDFs

const pdfCache = new Map();
const CACHE_TTL = 60 * 60 * 1000; // 1 hora

async function getCachedPDF(boletoId) {
  const cacheKey = `pdf-${boletoId}`;
  const cached = pdfCache.get(cacheKey);

  if (cached && (Date.now() - cached.timestamp) < CACHE_TTL) {
    return cached.data;
  }

  // Gerar novo PDF
  const pdfData = await generateBoletoPDF(boletoId);

  // Cachear resultado
  pdfCache.set(cacheKey, {
    data: pdfData,
    timestamp: Date.now()
  });

  return pdfData;
}

Processamento Assíncrono

// Queue para processar PDFs pesados
const pdfQueue = [];
let processing = false;

async function processPDFQueue() {
  if (processing || pdfQueue.length === 0) return;

  processing = true;

  while (pdfQueue.length > 0) {
    const task = pdfQueue.shift();
    try {
      await task.execute();
      task.resolve();
    } catch (error) {
      task.reject(error);
    }
  }

  processing = false;
}

Códigos de Erro

CódigoDescrição
BOLETO_NOT_FOUNDBoleto não encontrado
BOLETO_NOT_GENERATEDBoleto deve estar registrado para gerar PDF
PDF_GENERATION_FAILEDFalha na geração do PDF
INVALID_FORMATFormato de retorno inválido
PDF_TOO_LARGEArquivo PDF muito grande

Próximos Passos

Authorizations

x-api-key
string
header
required

Chave de API para autenticação

Path Parameters

id
string
required

ID do boleto

Response

PDF do boleto gerado

pdfAccessUrl
string<uri>

URL para download do PDF do boleto

Example:

"https://s3.us-east-1.amazonaws.com/dev..."