Pular para o conteúdo principal

Visão Geral

Este guia apresenta o fluxo completo de integração para processar pagamentos com cartão de crédito, desde a captura dos dados até a confirmação da transação. O fluxo é otimizado para conversão e segurança, garantindo uma experiência fluida para o usuário final.

Fluxo de Etapas

1

Coleta de Dados do Cartão

Captura segura dos dados do cartão através de formulário validado
2

Validação Client-Side

Validações básicas (algoritmo de Luhn, CVV, data de validade)
3

Processamento da Transação

Envio dos dados para API FireBanking via HTTPS
4

Resposta Inicial

API retorna status inicial (PROCESSING, PAID ou DENIED)
5

Processamento pela Operadora

Validações de segurança, limite e autorização da transação
6

Confirmação Final

Webhook com resultado definitivo (PAID, DENIED ou REFUNDED)

Fluxo Detalhado

1. Coleta de Dados do Cartão

Implemente um formulário seguro para captura dos dados do cartão:
<form id="payment-form">
  <!-- Dados do Cartão -->
  <div class="card-section">
    <label for="card-number">Número do Cartão</label>
    <input type="text" id="card-number" placeholder="1234 5678 9012 3456" maxlength="19">

    <div class="card-row">
      <div>
        <label for="expiry">Validade</label>
        <input type="text" id="expiry" placeholder="MM/AA" maxlength="5">
      </div>
      <div>
        <label for="cvv">CVV</label>
        <input type="text" id="cvv" placeholder="123" maxlength="4">
      </div>
    </div>

    <label for="holder-name">Nome no Cartão</label>
    <input type="text" id="holder-name" placeholder="João Silva">
  </div>

  <!-- Dados do Comprador -->
  <div class="buyer-section">
    <label for="buyer-email">Email</label>
    <input type="email" id="buyer-email" placeholder="[email protected]">

    <label for="buyer-document">CPF</label>
    <input type="text" id="buyer-document" placeholder="123.456.789-01">
  </div>

  <button type="submit">Finalizar Pagamento</button>
</form>
Importante: Nunca armazene dados de cartão no seu servidor. Sempre processe os dados diretamente através da API FireBanking.

2. Validação Client-Side

Implemente validações básicas antes de enviar para a API:
function validateCardForm() {
  const cardNumber = document.getElementById('card-number').value.replace(/\s/g, '');
  const expiry = document.getElementById('expiry').value;
  const cvv = document.getElementById('cvv').value;
  const holderName = document.getElementById('holder-name').value;

  // Validação básica do número do cartão (algoritmo de Luhn)
  if (!isValidCardNumber(cardNumber)) {
    showError('Número do cartão inválido');
    return false;
  }

  // Validação da validade
  if (!isValidExpiry(expiry)) {
    showError('Data de validade inválida');
    return false;
  }

  // Validação CVV
  if (cvv.length < 3 || cvv.length > 4) {
    showError('CVV deve ter 3 ou 4 dígitos');
    return false;
  }

  // Validação nome
  if (holderName.trim().length < 2) {
    showError('Nome do portador é obrigatório');
    return false;
  }

  return true;
}

function isValidCardNumber(number) {
  let sum = 0;
  let isEven = false;

  for (let i = number.length - 1; i >= 0; i--) {
    let digit = parseInt(number[i]);

    if (isEven) {
      digit *= 2;
      if (digit > 9) {
        digit -= 9;
      }
    }

    sum += digit;
    isEven = !isEven;
  }

  return sum % 10 === 0;
}

3. Processamento da Transação

Envie os dados validados para a API FireBanking:
curl --request POST \
  --url https://api-gateway.firebanking.com.br/credit-card/v1/payment \
  --header 'x-api-key: sua_chave_api' \
  --header 'Content-Type: application/json' \
  --data '{
    "purchaseValue": 299.90,
    "installments": 3,
    "externalId": "pedido-98765",
    "purchaseTitle": "Compra online - Produto XYZ",
    "description": "Descrição da compra",
    "payment": {
      "chargeType": "FEE_TO_SELLER",
      "capture": true,
      "card": {
        "name": "João Silva",
        "number": "4111111111111111",
        "expiration": "12/2025",
        "securityCode": "123"
      }
    },
    "buyer": {
      "name": "João Silva",
      "document": "12345678901",
      "email": "[email protected]",
      "phone": "11999999999",
      "countryCode": "+55",
      "address": {
        "country": "BR",
        "state": "SP",
        "city": "São Paulo",
        "district": "Centro",
        "street": "Rua das Flores",
        "zipCode": "01000000",
        "number": "123"
      }
    }
  }'

4. Resposta Inicial

A API retorna uma resposta inicial com o status da transação: Resposta de Sucesso:
{
  "id": "070ab63a-5849-4f1b-ad10-a67b9136711f",
  "externalId": "pedido-98765",
  "status": "PROCESSING",
  "description": "Compra online - Produto XYZ",
  "amount": 299.90,
  "installments": 3,
  "createdAt": "2025-07-31T19:31:02.737Z"
}
Possíveis Status Iniciais:
  • PROCESSING - Transação em análise
  • PAID - Aprovada imediatamente
  • DENIED - Negada pelo emissor

5. Processamento pela Operadora

Durante esta etapa, a transação passa por validações:
  • 🔐 Autenticação: Verificação dos dados do cartão
  • 💰 Autorização: Validação de limite e saldo
  • 🛡️ Antifraude: Análise de risco da transação
  • ⏱️ Tempo médio: 2-5 segundos para resposta
O sistema realiza validações em tempo real com a operadora do cartão. Transações podem ser aprovadas instantaneamente ou passar por análise adicional.

6. Confirmação Final

Com base na análise, você receberá um webhook com o resultado final: Transação Aprovada - PAID:
{
  "product": "CREDIT_CARD",
  "paymentId": "070ab63a-5849-4f1b-ad10-a67b9136711f",
  "externalId": "pedido-98765",
  "status": "PAID",
  "processedAt": "2025-07-31T19:31:02.737Z",
  "additionalInfo": {
    "purchaseTitle": "Compra online - Produto XYZ",
    "description": "Compra online - Produto XYZ",
    "amount": 299.90,
    "installments": 3,
    "chargeType": "FEE_TO_SELLER",
    "cardBrand": "visa",
    "cardLastDigits": "1111",
    "metadata": {
      "orderId": "pedido-98765",
      "customerId": "cust-123456"
    }
  }
}
Transação Negada - DENIED:
{
  "product": "CREDIT_CARD",
  "paymentId": "070ab63a-5849-4f1b-ad10-a67b9136711f",
  "externalId": "pedido-98765",
  "status": "DENIED",
  "processedAt": "2025-07-31T19:31:02.737Z",
  "additionalInfo": {
    "purchaseTitle": "Compra online - Produto XYZ",
    "description": "Compra online - Produto XYZ",
    "amount": 299.90,
    "installments": 3,
    "cardBrand": "visa",
    "cardLastDigits": "1111",
    "denialReason": "Insufficient funds",
    "metadata": {
      "orderId": "pedido-98765"
    }
  }
}

Estados da Transação

StatusDescriçãoPróxima Ação
PROCESSINGTransação em análiseAguardar webhook final
PAIDPagamento aprovadoLiberar produto/serviço
DENIEDPagamento negadoInformar cliente e oferecer alternativa
CANCELEDTransação canceladaInformar cancelamento
REFUNDEDPagamento estornadoProcessar reembolso

Interface de Usuário

Feedback Visual Durante o Processamento

function handlePaymentProcess() {
  // Mostrar loading
  showLoadingState();

  // Processar pagamento
  processPayment(formData)
    .then(response => {
      if (response.status === 'PAID') {
        showSuccessMessage('Pagamento aprovado!');
        redirectToSuccess();
      } else if (response.status === 'PROCESSING') {
        showProcessingMessage('Processando pagamento...');
        waitForWebhook();
      } else if (response.status === 'DENIED') {
        showErrorMessage('Pagamento negado. Verifique os dados do cartão.');
        enableForm();
      }
    })
    .catch(error => {
      showErrorMessage('Erro no processamento. Tente novamente.');
      enableForm();
    });
}

function showLoadingState() {
  document.getElementById('submit-btn').disabled = true;
  document.getElementById('submit-btn').innerHTML =
    '<span class="spinner"></span> Processando...';
}

function showSuccessMessage(message) {
  document.getElementById('payment-status').innerHTML =
    `<div class="success-message">${message}</div>`;
}

function showErrorMessage(message) {
  document.getElementById('payment-status').innerHTML =
    `<div class="error-message">${message}</div>`;
}

Tratamento de Erros Comuns

function handlePaymentError(error) {
  const errorMessages = {
    'INVALID_CARD': 'Número do cartão inválido',
    'EXPIRED_CARD': 'Cartão vencido',
    'INSUFFICIENT_FUNDS': 'Saldo insuficiente',
    'INVALID_CVV': 'CVV inválido',
    'CARD_BLOCKED': 'Cartão bloqueado - entre em contato com seu banco',
    'GENERIC_ERROR': 'Erro no processamento - tente novamente'
  };

  const message = errorMessages[error.code] || errorMessages['GENERIC_ERROR'];
  showErrorMessage(message);

  // Sugerir alternativas
  if (error.code === 'INSUFFICIENT_FUNDS') {
    showAlternativePayments();
  }
}

function showAlternativePayments() {
  document.getElementById('alternatives').innerHTML = `
    <div class="alternatives">
      <h4>Outras formas de pagamento:</h4>
      <button onclick="showPixPayment()">Pagar com PIX</button>
      <button onclick="showBoletoPayment()">Gerar Boleto</button>
    </div>
  `;
}

Implementação de Webhook

Configure um endpoint robusto para receber confirmações:
app.post('/webhooks/credit-card', express.raw({type: 'application/json'}), (req, res) => {
  try {
    const payload = JSON.parse(req.body);

    // Verificar assinatura
    if (!verifyWebhookSignature(req.headers, req.body)) {
      return res.status(401).send('Unauthorized');
    }

    // Processar baseado no status
    switch (payload.status) {
      case 'PAID':
        handlePaymentSuccess(payload);
        break;

      case 'DENIED':
        handlePaymentDenied(payload);
        break;

      case 'REFUNDED':
        handlePaymentRefunded(payload);
        break;
    }

    res.status(200).send('OK');
  } catch (error) {
    console.error('Webhook error:', error);
    res.status(500).send('Internal Server Error');
  }
});

function handlePaymentSuccess(payload) {
  // Liberar produto/serviço
  fulfillOrder(payload.externalId);

  // Enviar confirmação para cliente
  sendConfirmationEmail(payload);

  // Atualizar sistema interno
  updatePaymentStatus(payload.paymentId, 'completed');
}

Segurança e Melhores Práticas

Validação de Dados Sensíveis

// Máscara para número do cartão
function formatCardNumber(value) {
  const v = value.replace(/\s+/g, '').replace(/[^0-9]/gi, '');
  const matches = v.match(/\d{4,16}/g);
  const match = matches && matches[0] || '';
  const parts = [];

  for (let i = 0, len = match.length; i < len; i += 4) {
    parts.push(match.substring(i, i + 4));
  }

  if (parts.length) {
    return parts.join(' ');
  } else {
    return v;
  }
}

// Validação CVV por bandeira
function validateCvv(cardNumber, cvv) {
  const brand = detectCardBrand(cardNumber);

  if (brand === 'amex') {
    return cvv.length === 4;
  } else {
    return cvv.length === 3;
  }
}

Rate Limiting

const rateLimit = require('express-rate-limit');

const paymentLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutos
  max: 5, // máximo 5 tentativas por IP
  message: 'Muitas tentativas de pagamento. Tente novamente em 15 minutos.',
  standardHeaders: true,
  legacyHeaders: false
});

app.use('/api/credit-card', paymentLimiter);

Monitoramento

Monitore métricas importantes:
  • 📊 Taxa de aprovação: PAID / Total de transações
  • ⏱️ Tempo de resposta: Tempo até confirmação
  • 🚫 Taxa de negação: Por motivo de recusa
  • 💳 Distribuição por bandeira: Visa, Mastercard, etc.
  • 🔄 Taxa de retry: Tentativas após negação

Próximos Passos