Criar Cartão
curl --request POST \
--url https://pay.autorizou.dev/api/v1/cards \
--header 'Authorization: Bearer <token>'import requests
url = "https://pay.autorizou.dev/api/v1/cards"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://pay.autorizou.dev/api/v1/cards', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://pay.autorizou.dev/api/v1/cards",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://pay.autorizou.dev/api/v1/cards"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://pay.autorizou.dev/api/v1/cards")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://pay.autorizou.dev/api/v1/cards")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyCartões
Criar Cartão
POST
/
api
/
v1
/
cards
Criar Cartão
curl --request POST \
--url https://pay.autorizou.dev/api/v1/cards \
--header 'Authorization: Bearer <token>'import requests
url = "https://pay.autorizou.dev/api/v1/cards"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://pay.autorizou.dev/api/v1/cards', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://pay.autorizou.dev/api/v1/cards",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://pay.autorizou.dev/api/v1/cards"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://pay.autorizou.dev/api/v1/cards")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://pay.autorizou.dev/api/v1/cards")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyEste 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 futuros pagamentos.
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
string
required
UUID do cliente ao qual o cartão será associado
string
required
Dados do cartão criptografados usando nossa biblioteca de tokenização frontend
Estrutura dos Dados Criptografados
O parâmetroencrypted deve conter os dados do cartão criptografados usando AES-256-CBC. O SDK 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 SDK 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 SDK (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://pay.autorizou.dev/api/v1/cards \
-H "Authorization: Bearer 4eC39HqLyjWDarjtT1zdp7dc" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "46e9d3d9-afb2-4d19-9a29-43b739f859a5",
"encrypted": "eyJjYXJkRGF0YSI6eyJudW1iZXIiOiI0MTExMTExMTExMTExMTExIiwiaG9sZGVyIjoiSk9BTyBTSUxWQSIsImV4cE1vbnRoIjoiMTIiLCJleHBZZWFyIjoiMjAzMCIsInNlY3VyaXR5Q29kZSI6IjEyMyIsImJyYW5kIjoidmlzYSJ9fQ=="
}'
// 1. Incluir o SDK (biblioteca de criptografia do Autorizou)
// <script src="https://sdk.autorizou.dev/embed/gateway.js"></script>
// 2. Preparar dados do cartão
const cardData = {
number: '4111111111111111',
holder: 'JOAO SILVA',
expMonth: '12',
expYear: '2030',
securityCode: '123'
};
// 3. Preparar dados do portador (opcional para salvar cartão)
const cardHolder = {
name: 'João Silva',
identification: {
type: 'CPF',
number: '12345678900'
}
};
// 4. Criptografar usando o SDK
await window.Autorizou.encryptCard(
{ cardData, cardHolder },
{
onSuccess: async (response) => {
// 5. Enviar token criptografado para a API
const apiResponse = await fetch('https://pay.autorizou.dev/api/v1/cards', {
method: 'POST',
headers: {
'Authorization': 'Bearer 4eC39HqLyjWDarjtT1zdp7dc',
'Content-Type': 'application/json'
},
body: JSON.stringify({
customer_id: 'cus_abc123def456ghi789',
encrypted: response.token
})
});
const card = await apiResponse.json();
console.log('Cartão tokenizado:', card);
},
onError: (error) => {
console.error('Erro na criptografia:', error);
}
}
);
<?php
// Assumindo que os dados já foram criptografados no frontend
$encryptedCardData = 'eyJjYXJkRGF0YSI6eyJudW1iZXIiOiI0MTExMTExMTExMTExMTExIiwiaG9sZGVyIjoiSk9BTyBTSUxWQSIsImV4cE1vbnRoIjoiMTIiLCJleHBZZWFyIjoiMjAzMCIsInNlY3VyaXR5Q29kZSI6IjEyMyIsImJyYW5kIjoidmlzYSJ9fQ==';
$data = [
'customer_id' => 'cus_abc123def456ghi789',
'encrypted' => $encryptedCardData
];
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://pay.autorizou.dev/api/v1/cards',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer 4eC39HqLyjWDarjtT1zdp7dc',
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => json_encode($data)
]);
$response = curl_exec($curl);
$card = json_decode($response, true);
curl_close($curl);
echo "Cartão criado: " . json_encode($card, JSON_PRETTY_PRINT);
?>
Resposta de Sucesso
Cartão Novo (201 Created)
Quando um novo cartão é criado com sucesso:{
"id": "3f7d2a91-8c4e-4b6f-9a2d-5e8c1f4b7a30",
"customer_id": "46e9d3d9-afb2-4d19-9a29-43b739f859a5",
"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 um pagamento autorizado:{
"id": "b96e2d54-7a3c-4f8e-91d6-4e7a2c5f8b19",
"customer_id": "46e9d3d9-afb2-4d19-9a29-43b739f859a5",
"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
| Campo | Tipo | Descrição |
|---|---|---|
id | string | UUID único do cartão tokenizado |
customer_id | string | UUID do cliente proprietário |
holder | string | Nome do portador do cartão |
brand | string | Bandeira detectada automaticamente (visa, mastercard, elo, etc) |
first_6 | string | Primeiros 6 dígitos do cartão (BIN) |
last_4 | string | Últimos 4 dígitos do cartão |
exp_month | string | Mês de expiração (MM) |
exp_year | string | Ano de expiração (YY) - apenas 2 dígitos |
created_at | string | Data de criação no formato DD/MM/YYYY HH:mm:ss |
updated_at | string | Data 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 pagamentos
- 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
422 - Validation Error
422 - Validation Error
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"]
}
}
}
400 - Invalid Encrypted Data
400 - Invalid Encrypted Data
Dados criptografados malformados ou inválidosPossíveis causas:
{
"error": {
"code": "invalid_encrypted_card",
"message": "Dados do cartão criptografados são inválidos"
}
}
- Criptografia incorreta
- Dados corrompidos
- Formato JSON inválido nos dados descriptografados
404 - Customer Not Found
404 - Customer Not Found
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_6elast_4) - Mesmo portador (
holder) - Mesma validade (
exp_montheexp_year) - Mesma bandeira (
brand_id) - Cartão já usado em pagamento autorizado (status
AUTHORIZED)
- 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
| Bandeira | Network Token | Detecçã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 SDK
Instalação do SDK
O SDK é a biblioteca oficial do Autorizou para criptografia de dados de cartão no frontend.<!-- Incluir SDK via CDN -->
<script src="https://sdk.autorizou.dev/embed/gateway.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 SDK - Tokenização de Cartão</title>
<!-- 1. Incluir SDK -->
<script src="https://sdk.autorizou.dev/embed/gateway.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 o SDK usando callbacks
await window.Autorizou.encryptCard(
{ cardData, cardHolder },
{
onSuccess: async (encryptResponse) => {
// 6. Enviar para o backend
const response = await fetch('https://pay.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 SDK está disponível
if (!window.Autorizou?.encryptCard) {
throw new Error('SDK 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://pay.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 SDK */}
<Script
src={`https://sdk.autorizou.${
process.env.NEXT_PUBLIC_AUTORIZOU_ENVIRONMENT === 'live' ? 'cloud' : 'dev'
}/embed/gateway.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.