Skip to main content
POST
/
api
/
v1
/
cards
Criar Cartão
curl --request POST \
  --url https://zeus-sandbox.autorizou.dev/api/v1/cards \
  --header 'Authorization: Bearer <token>'
Este endpoint permite tokenizar e salvar um cartão de crédito de forma segura. O cartão é criptografado e associado a um cliente específico, permitindo seu uso em futuras transações.

Casos de Uso

  • 💾 Salvar cartão para pagamentos futuros
  • 🔒 Tokenização segura de dados sensíveis
  • 🔄 Reutilização em pagamentos recorrentes
  • 🛡️ Network Token automático (Visa/Mastercard)

Parâmetros Obrigatórios

customer_id
string
required
UUID do cliente ao qual o cartão será associado
encrypted
string
required
Dados do cartão criptografados usando nossa biblioteca de tokenização frontend

Estrutura dos Dados Criptografados

O parâmetro encrypted deve conter os dados do cartão criptografados usando AES-256-CBC. O Keranos envia o seguinte formato:
{
  "cardData": {
    "number": "4111111111111111",
    "holder": "JOAO SILVA",
    "expMonth": "12",
    "expYear": "2030",
    "securityCode": "123",
    "brand": "visa"
  },
  "cardHolder": {
    "name": "João Silva",
    "identification": {
      "type": "CPF",
      "number": "12345678900"
    }
  }
}
cardHolder Opcional: O objeto cardHolder é enviado pelo Keranos mas não é processado pela API de cartões. Ele é utilizado apenas em integrações com gateways específicos. Para salvar cartões, apenas o cardData é necessário.
Importante: Nunca envie dados de cartão em texto puro. Use sempre o Keranos (nossa biblioteca de tokenização frontend) para criptografar os dados antes de enviá-los para a API.
Criptografia: Os dados são criptografados no browser usando AES-256-CBC com a chave pública fornecida. O IV (Initialization Vector) é derivado do MD5 da chave secreta (primeiros 16 caracteres).

Exemplo de Requisição

curl -X POST https://zeus-sandbox.autorizou.dev/api/v1/cards \
  -H "Authorization: Bearer 4eC39HqLyjWDarjtT1zdp7dc" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cus_abc123def456ghi789",
    "encrypted": "eyJjYXJkRGF0YSI6eyJudW1iZXIiOiI0MTExMTExMTExMTExMTExIiwiaG9sZGVyIjoiSk9BTyBTSUxWQSIsImV4cE1vbnRoIjoiMTIiLCJleHBZZWFyIjoiMjAzMCIsInNlY3VyaXR5Q29kZSI6IjEyMyIsImJyYW5kIjoidmlzYSJ9fQ=="
  }'

Resposta de Sucesso

Cartão Novo (201 Created)

Quando um novo cartão é criado com sucesso:
{
  "id": "card_def456ghi789jkl012",
  "customer_id": "cus_abc123def456ghi789",
  "holder": "JOAO SILVA",
  "brand": "visa",
  "first_6": "411111",
  "last_4": "1111",
  "exp_month": "12",
  "exp_year": "30",
  "created_at": "15/01/2024 10:35:00",
  "updated_at": "15/01/2024 10:35:00"
}
Network Token: Para cartões Visa e Mastercard, um Network Token é automaticamente solicitado em segundo plano. O processo de tokenização acontece de forma assíncrona e não impacta a resposta inicial.

Cartão Duplicado (200 OK)

Se um cartão idêntico já existe para o cliente (mesmo número, nome, validade e bandeira) e já foi usado em uma transação autorizada:
{
  "id": "card_existing123456789abc",
  "customer_id": "cus_abc123def456ghi789",
  "holder": "JOAO SILVA",
  "brand": "visa",
  "first_6": "411111",
  "last_4": "1111",
  "exp_month": "12",
  "exp_year": "30",
  "created_at": "10/01/2024 08:20:00",
  "updated_at": "10/01/2024 08:20:00"
}
Detecção de Duplicatas: O sistema detecta cartões duplicados baseado em: mesmo cliente + mesmo número (first_6 + last_4) + mesmo nome + mesma validade + mesma bandeira + ter sido usado em pagamento autorizado.

Detalhes da Resposta

CampoTipoDescrição
idstringUUID único do cartão tokenizado
customer_idstringUUID do cliente proprietário
holderstringNome do portador do cartão
brandstringBandeira detectada automaticamente (visa, mastercard, elo, etc)
first_6stringPrimeiros 6 dígitos do cartão (BIN)
last_4stringÚltimos 4 dígitos do cartão
exp_monthstringMês de expiração (MM)
exp_yearstringAno de expiração (YY) - apenas 2 dígitos
created_atstringData de criação no formato DD/MM/YYYY HH:mm:ss
updated_atstringData da última atualização

Network Token (Visa e Mastercard)

Para cartões Visa e Mastercard, o sistema solicita automaticamente a criação de um Network Token através do VGS (Very Good Security). Este processo ocorre de forma assíncrona após a criação do cartão. Benefícios do Network Token:
  • Maior taxa de aprovação em transações
  • Melhor segurança (token dinâmico)
  • Atualização automática de dados de expiração
  • Redução de fraudes
Processo Assíncrono: A solicitação do Network Token não bloqueia a resposta da API. O token é gerado em segundo plano e associado ao cartão posteriormente.

Códigos de Erro

Erro de validação nos dados fornecidos
{
  "error": {
    "code": "validation_error",
    "message": "Os dados fornecidos são inválidos",
    "details": {
      "customer_id": ["Cliente não encontrado"],
      "encrypted": ["Dados criptografados inválidos"]
    }
  }
}
Dados criptografados malformados ou inválidos
{
  "error": {
    "code": "invalid_encrypted_card",
    "message": "Dados do cartão criptografados são inválidos"
  }
}
Possíveis causas:
  • Criptografia incorreta
  • Dados corrompidos
  • Formato JSON inválido nos dados descriptografados
Cliente não encontrado
{
  "error": {
    "code": "customer_not_found",
    "message": "Cliente não encontrado"
  }
}

Detecção de Duplicatas

O sistema detecta automaticamente cartões duplicados para evitar a criação de cartões redundantes. A duplicata é identificada quando todas as condições abaixo são atendidas: Critérios de Duplicata:
  • Mesmo cliente (customer_id)
  • Mesmo número (first_6 e last_4)
  • Mesmo portador (holder)
  • Mesma validade (exp_month e exp_year)
  • Mesma bandeira (brand_id)
  • Cartão já usado em pagamento autorizado (status AUTHORIZED)
Comportamento quando detectada duplicata:
  • Não cria novo cartão
  • Retorna cartão existente
  • Status HTTP 200 (em vez de 201)
Otimização: Esta verificação evita sobrecarga no banco de dados e no sistema de tokenização, além de simplificar a gestão de cartões para o usuário final.

Bandeiras Suportadas

BandeiraNetwork TokenDetecção Automática
Visa✅ Sim✅ Sim
Mastercard✅ Sim✅ Sim
Elo❌ Não✅ Sim
Hipercard❌ Não✅ Sim
Diners❌ Não✅ Sim
Discover❌ Não✅ Sim
JCB❌ Não✅ Sim
Amex❌ Não✅ Sim
Network Token: Apenas cartões Visa e Mastercard suportam Network Token. Para outras bandeiras, o cartão é tokenizado normalmente através do VGS.

Implementação Frontend com Keranos

Instalação da Biblioteca Keranos

O Keranos é a biblioteca oficial do Autorizou para criptografia de dados de cartão no frontend.
<!-- Incluir Keranos via CDN -->
<script src="https://js.autorizou.cloud/keranos/latest/embed.js"></script>
Ambiente de Teste: Para desenvolvimento, você pode usar a versão de sandbox. Configure a variável de ambiente NEXT_PUBLIC_APP_ENV para controlar o ambiente.

Exemplo Completo de Integração

<!DOCTYPE html>
<html>
<head>
  <title>Exemplo Keranos - Tokenização de Cartão</title>
  <!-- 1. Incluir biblioteca Keranos -->
  <script src="https://js.autorizou.cloud/keranos/latest/embed.js"></script>
</head>
<body>
  <!-- 2. Formulário de cartão -->
  <form id="card-form">
    <div>
      <label>Número do Cartão</label>
      <input type="text" id="card-number" placeholder="0000 0000 0000 0000" maxlength="19">
    </div>
    <div>
      <label>Nome no Cartão</label>
      <input type="text" id="card-holder" placeholder="NOME COMPLETO">
    </div>
    <div>
      <label>Validade (MM/AAAA)</label>
      <input type="text" id="card-month" placeholder="12" maxlength="2">
      <input type="text" id="card-year" placeholder="2030" maxlength="4">
    </div>
    <div>
      <label>CVV</label>
      <input type="text" id="card-cvv" placeholder="123" maxlength="4">
    </div>
    <button type="submit">Salvar Cartão</button>
  </form>

  <script>
    // 3. Handler do formulário
    document.getElementById('card-form').addEventListener('submit', async (e) => {
      e.preventDefault();

      // 4. Coletar dados do formulário
      const cardData = {
        number: document.getElementById('card-number').value.replace(/\s/g, ''),
        holder: document.getElementById('card-holder').value.toUpperCase(),
        expMonth: document.getElementById('card-month').value,
        expYear: document.getElementById('card-year').value,
        securityCode: document.getElementById('card-cvv').value
      };

      const cardHolder = {
        name: document.getElementById('card-holder').value,
        identification: {
          type: 'CPF',
          number: '00000000000' // Opcional: adicione campo no formulário se necessário
        }
      };

      try {
        // 5. Criptografar com Keranos usando callbacks
        await window.Autorizou.encryptCard(
          { cardData, cardHolder },
          {
            onSuccess: async (encryptResponse) => {
              // 6. Enviar para o backend
              const response = await fetch('https://zeus-sandbox.autorizou.dev/api/v1/cards', {
                method: 'POST',
                headers: {
                  'Authorization': 'Bearer 4eC39HqLyjWDarjtT1zdp7dc',
                  'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                  customer_id: 'cus_abc123def456ghi789',
                  encrypted: encryptResponse.token
                })
              });

              const result = await response.json();

              if (response.ok) {
                alert('Cartão salvo com sucesso! ID: ' + result.id);
                document.getElementById('card-form').reset();
              } else {
                alert('Erro ao salvar cartão: ' + (result.message || 'Erro desconhecido'));
              }
            },
            onError: (error) => {
              alert('Erro na criptografia: ' + (error.message || 'Erro desconhecido'));
            }
          }
        );

      } catch (error) {
        console.error('Erro:', error);
        alert('Erro ao processar cartão: ' + error.message);
      }
    });
  </script>
</body>
</html>

Integração React/Next.js

import { useState } from 'react';

export default function CardForm({ customerId }) {
  const [cardData, setCardData] = useState({
    number: '',
    holder: '',
    expMonth: '',
    expYear: '',
    securityCode: ''
  });
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const handleSubmit = async (e) => {
    e.preventDefault();
    setLoading(true);
    setError(null);

    try {
      // Verificar se o Keranos está disponível
      if (!window.Autorizou?.encryptCard) {
        throw new Error('Keranos não está carregado. Verifique se o script foi incluído.');
      }

      // Preparar cardHolder (opcional para salvar cartão)
      const cardHolder = {
        name: cardData.holder,
        identification: {
          type: 'CPF',
          number: '00000000000' // Opcional: adicione ao formulário se necessário
        }
      };

      // Criptografar dados do cartão usando callbacks
      await window.Autorizou.encryptCard(
        { cardData, cardHolder },
        {
          onSuccess: async (encryptResponse) => {
            try {
              // Enviar para a API
              const response = await fetch('https://zeus-sandbox.autorizou.dev/api/v1/cards', {
                method: 'POST',
                headers: {
                  'Authorization': `Bearer ${process.env.NEXT_PUBLIC_AUTORIZOU_API_KEY}`,
                  'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                  customer_id: customerId,
                  encrypted: encryptResponse.token
                })
              });

              const result = await response.json();

              if (!response.ok) {
                throw new Error(result.message || 'Erro ao salvar cartão');
              }

              alert('Cartão salvo com sucesso!');
              setCardData({ number: '', holder: '', expMonth: '', expYear: '', securityCode: '' });
            } catch (err) {
              setError(err.message);
              console.error('Erro ao salvar cartão:', err);
            } finally {
              setLoading(false);
            }
          },
          onError: (error) => {
            setError(error.message || 'Erro na criptografia');
            console.error('Erro na criptografia:', error);
            setLoading(false);
          }
        }
      );

    } catch (err) {
      setError(err.message);
      console.error('Erro:', err);
      setLoading(false);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        placeholder="Número do cartão"
        value={cardData.number}
        onChange={(e) => setCardData({ ...cardData, number: e.target.value })}
        required
      />
      <input
        type="text"
        placeholder="Nome no cartão"
        value={cardData.holder}
        onChange={(e) => setCardData({ ...cardData, holder: e.target.value.toUpperCase() })}
        required
      />
      <input
        type="text"
        placeholder="Mês (MM)"
        value={cardData.expMonth}
        onChange={(e) => setCardData({ ...cardData, expMonth: e.target.value })}
        maxLength="2"
        required
      />
      <input
        type="text"
        placeholder="Ano (AAAA)"
        value={cardData.expYear}
        onChange={(e) => setCardData({ ...cardData, expYear: e.target.value })}
        maxLength="4"
        required
      />
      <input
        type="text"
        placeholder="CVV"
        value={cardData.securityCode}
        onChange={(e) => setCardData({ ...cardData, securityCode: e.target.value })}
        maxLength="4"
        required
      />

      {error && <div style={{ color: 'red' }}>{error}</div>}

      <button type="submit" disabled={loading}>
        {loading ? 'Processando...' : 'Salvar Cartão'}
      </button>
    </form>
  );
}
// No seu _app.js ou layout.js
import Script from 'next/script';

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        {/* Carregar Keranos */}
        <Script
          src="https://js.autorizou.cloud/keranos/latest/embed.js"
          strategy="beforeInteractive"
        />
      </head>
      <body>{children}</body>
    </html>
  );
}

Segurança e Compliance

PCI DSS: Este endpoint atende aos requisitos PCI DSS. Dados sensíveis nunca trafegam em texto puro e são imediatamente tokenizados.
Criptografia End-to-End: Os dados são criptografados no browser do usuário e apenas descriptografados nos servidores seguros da Autorizou.

Próximos Passos

Após criar um cartão:
  1. Processar pagamento com o cartão
  2. Buscar detalhes do cartão
  3. Solicitar Network Token (Visa/Mastercard)
  4. Integração frontend com Keranos