Data Only: maximize a taxa de aprovação
Quick Reference
O que é Data Only?
Data Only usa a infraestrutura EMV 3DS para compartilhar dados de transação, dispositivo e comportamento com bandeiras e emissores — sem exibir desafio ao portador. O emissor recebe dados enriquecidos e decide a autorização com mais contexto.
O resultado: maior taxa de aprovação, zero abandono de carrinho por autenticação e sem redirect nem popup.
Por que o Data Only importa
Os números falam:
| Métrica | Valor | Fonte |
|---|---|---|
| Impacto de recusa indevida vs fraude | 3x maior — recusar um bom cliente custa 3x mais que fraude | Visa Global Client |
| Fraude em e-commerce nos EUA (projeção) | US$ 13 bilhões até 2026 | Visa |
| Taxa global de abandono de carrinho | 70% em média | Baymard Institute |
| Queda de conversão por atrito do 3DS | 2–15% conforme o mercado | Decta / US Payments Forum |
| Adoção de 3DS por lojistas nos EUA | Apenas ~3% das transações | US Payments Forum Brief #2 |
| Piloto Square (6M transações, 9 meses) | +23 a +646 pontos-base por instituição financeira | Estudo de caso Broadcom/Arcot |
| Melhora na taxa de estorno (mesmo piloto) | Redução de 6% | Estudo de caso Broadcom/Arcot |
Matriz de decisão
| Critério | 3DS completo | Data Only | Sem autenticação |
|---|---|---|---|
| Bandeiras | Todas suportadas | Somente Visa e Mastercard | Todas |
| Desafio ao portador | Sim, quando o emissor exige | Nunca | Nunca |
| Mudança de responsabilidade | Sim | Não | Não |
| Impacto na taxa de aprovação | Pode cair (atrito) | Sobe (dados enriquecidos) | Linha de base |
| Proteção contra estorno | Emissor assume (quando há mudança) | Lojista assume | Lojista assume |
| Dados enviados ao emissor | Dispositivo + comportamento + resultado do desafio | Dispositivo + comportamento (contexto mais rico) | Nenhum |
| Melhor para | Alto valor, regulado, PSD2/SCA | Alto volume, baixo risco, LATAM | Baixo risco, baixo valor |
| Mercados PSD2/SCA | Obrigatório | Indisponível (SCA tem prioridade) | Não conforme |
data_only e threeds_authentication não podem ser true na mesma cobrança. Se voce forçar autenticação 3DS completa (threeds_authentication: true), o sistema exige ECI 02 ou 05 (totalmente autenticado). Data Only gera ECI 06 ou 07, o que falha na validação de 3DS forçado.
Escolha uma estratégia por transação.
Como funciona
O ponto central: o emissor recebe dois sinais — a avaliação de risco da bandeira e os dados enriquecidos do seu device_info. Isso é mais informação do que uma autorização padrão, então o emissor pode aprovar com mais confiança.
Integração passo a passo
Coletar dados de dispositivo e navegador
Capture valores reais do navegador no cliente. Nunca invente esses dados — dados sintéticos aumentam recusas.
const deviceInfo = {
ip_address: await fetch('/api/ip').then(r => r.text()),
user_agent: navigator.userAgent,
http_accept_content: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
http_accept_browser_value: '*/*',
http_browser_language: navigator.language,
http_browser_java_enabled: navigator.javaEnabled?.() ?? false,
http_browser_javascript_enabled: true,
http_browser_color_depth: String(screen.colorDepth),
http_browser_screen_height: String(screen.height),
http_browser_screen_width: String(screen.width),
http_browser_time_difference: String(new Date().getTimezoneOffset()),
};
Envie deviceInfo ao seu backend na requisição de cobrança.
Autenticar e obter um token de acesso
- cURL
- Python
- Node.js
- Go
- Java
- PHP
curl -s -X POST "https://a55-auth.auth.us-east-1.amazoncognito.com/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET"
import os, requests
token_resp = requests.post(
"https://a55-auth.auth.us-east-1.amazoncognito.com/oauth2/token",
data={"grant_type": "client_credentials",
"client_id": os.environ["CLIENT_ID"],
"client_secret": os.environ["CLIENT_SECRET"]},
headers={"Content-Type": "application/x-www-form-urlencoded"},
)
access_token = token_resp.json()["access_token"]
const resp = await fetch(
"https://a55-auth.auth.us-east-1.amazoncognito.com/oauth2/token",
{
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "grant_type=client_credentials"
+ "&client_id=" + process.env.CLIENT_ID
+ "&client_secret=" + process.env.CLIENT_SECRET,
}
);
const { access_token } = await resp.json();
data := url.Values{
"grant_type": {"client_credentials"},
"client_id": {os.Getenv("CLIENT_ID")},
"client_secret": {os.Getenv("CLIENT_SECRET")},
}
resp, _ := http.PostForm(
"https://a55-auth.auth.us-east-1.amazoncognito.com/oauth2/token",
data,
)
defer resp.Body.Close()
var tok struct{ AccessToken string `json:"access_token"` }
json.NewDecoder(resp.Body).Decode(&tok)
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://a55-auth.auth.us-east-1.amazoncognito.com/oauth2/token"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(
"grant_type=client_credentials&client_id=" + CLIENT_ID
+ "&client_secret=" + CLIENT_SECRET))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
String accessToken = new JSONObject(resp.body()).getString("access_token");
$ch = curl_init("https://a55-auth.auth.us-east-1.amazoncognito.com/oauth2/token");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Content-Type: application/x-www-form-urlencoded"],
CURLOPT_POSTFIELDS => http_build_query([
"grant_type" => "client_credentials",
"client_id" => getenv("CLIENT_ID"),
"client_secret" => getenv("CLIENT_SECRET"),
]),
]);
$token = json_decode(curl_exec($ch))->access_token;
Criar cobrança com data_only: true
Defina data_only: true e inclua o objeto completo device_info do passo 1.
- cURL
- Python
- Node.js
- Go
- Java
- PHP
curl -sS -X POST "https://core-manager.a55.tech/api/v1/bank/wallet/charge/" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: dataonly_001" \
-d '{
"wallet_uuid": "00000000-0000-4000-8000-000000000001",
"merchant_id": "merchant_123",
"payer_name": "Jane Doe",
"payer_email": "jane@example.com",
"payer_cell_phone": "+5511999999999",
"payer_tax_id": "12345678901",
"items": [{"name": "Premium Plan", "quantity": 1, "value": 29900}],
"payer_address": {
"street": "Av. Paulista 1000", "city": "São Paulo",
"state": "SP", "zip_code": "01310100", "country": "BR"
},
"currency": "BRL",
"installment_value": 29900,
"installment_count": 1,
"due_date": "2026-12-31",
"description": "Premium subscription",
"type_charge": "credit_card",
"card_name": "JANE DOE",
"card_number": "4111111111111111",
"card_expiry_month": 12,
"card_expiry_year": 2030,
"card_cvv": "123",
"data_only": true,
"device_info": {
"ip_address": "203.0.113.10",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0",
"device_id": "dev_xyz",
"session_id": "sess_abc",
"http_accept_content": "text/html,application/xhtml+xml",
"http_accept_browser_value": "*/*",
"http_browser_language": "pt-BR",
"http_browser_java_enabled": false,
"http_browser_javascript_enabled": true,
"http_browser_color_depth": "24",
"http_browser_screen_height": "900",
"http_browser_screen_width": "1440",
"http_browser_time_difference": "180"
},
"reference_external_id": "dataonly_001",
"webhook_url": "https://merchant.example/webhooks/a55"
}'
import os, requests
payload = {
"wallet_uuid": "00000000-0000-4000-8000-000000000001",
"merchant_id": "merchant_123",
"payer_name": "Jane Doe",
"payer_email": "jane@example.com",
"payer_cell_phone": "+5511999999999",
"payer_tax_id": "12345678901",
"items": [{"name": "Premium Plan", "quantity": 1, "value": 29900}],
"payer_address": {
"street": "Av. Paulista 1000", "city": "São Paulo",
"state": "SP", "zip_code": "01310100", "country": "BR",
},
"currency": "BRL",
"installment_value": 29900,
"installment_count": 1,
"due_date": "2026-12-31",
"description": "Premium subscription",
"type_charge": "credit_card",
"card_name": "JANE DOE",
"card_number": "4111111111111111",
"card_expiry_month": 12,
"card_expiry_year": 2030,
"card_cvv": "123",
"data_only": True,
"device_info": {
"ip_address": "203.0.113.10",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0",
"device_id": "dev_xyz",
"session_id": "sess_abc",
"http_accept_content": "text/html,application/xhtml+xml",
"http_accept_browser_value": "*/*",
"http_browser_language": "pt-BR",
"http_browser_java_enabled": False,
"http_browser_javascript_enabled": True,
"http_browser_color_depth": "24",
"http_browser_screen_height": "900",
"http_browser_screen_width": "1440",
"http_browser_time_difference": "180",
},
"reference_external_id": "dataonly_001",
"webhook_url": "https://merchant.example/webhooks/a55",
}
r = requests.post(
"https://core-manager.a55.tech/api/v1/bank/wallet/charge/",
headers={
"Authorization": f"Bearer {os.environ['ACCESS_TOKEN']}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
print(r.status_code, r.json())
const payload = {
wallet_uuid: "00000000-0000-4000-8000-000000000001",
merchant_id: "merchant_123",
payer_name: "Jane Doe",
payer_email: "jane@example.com",
payer_cell_phone: "+5511999999999",
payer_tax_id: "12345678901",
items: [{ name: "Premium Plan", quantity: 1, value: 29900 }],
payer_address: {
street: "Av. Paulista 1000", city: "São Paulo",
state: "SP", zip_code: "01310100", country: "BR",
},
currency: "BRL",
installment_value: 29900,
installment_count: 1,
due_date: "2026-12-31",
description: "Premium subscription",
type_charge: "credit_card",
card_name: "JANE DOE",
card_number: "4111111111111111",
card_expiry_month: 12,
card_expiry_year: 2030,
card_cvv: "123",
data_only: true,
device_info: {
ip_address: "203.0.113.10",
user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0",
device_id: "dev_xyz",
session_id: "sess_abc",
http_accept_content: "text/html,application/xhtml+xml",
http_accept_browser_value: "*/*",
http_browser_language: "pt-BR",
http_browser_java_enabled: false,
http_browser_javascript_enabled: true,
http_browser_color_depth: "24",
http_browser_screen_height: "900",
http_browser_screen_width: "1440",
http_browser_time_difference: "180",
},
reference_external_id: "dataonly_001",
webhook_url: "https://merchant.example/webhooks/a55",
};
const res = await fetch(
"https://core-manager.a55.tech/api/v1/bank/wallet/charge/",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
}
);
console.log(await res.json());
payload := map[string]interface{}{
"wallet_uuid": "00000000-0000-4000-8000-000000000001",
"merchant_id": "merchant_123",
"payer_name": "Jane Doe",
"payer_email": "jane@example.com",
"payer_tax_id": "12345678901",
"currency": "BRL",
"installment_value": 29900,
"installment_count": 1,
"type_charge": "credit_card",
"card_name": "JANE DOE",
"card_number": "4111111111111111",
"card_expiry_month": 12,
"card_expiry_year": 2030,
"card_cvv": "123",
"data_only": true,
"device_info": map[string]interface{}{
"ip_address": "203.0.113.10",
"user_agent": "Mozilla/5.0",
"http_accept_content": "text/html",
"http_accept_browser_value": "*/*",
"http_browser_language": "pt-BR",
"http_browser_java_enabled": false,
"http_browser_javascript_enabled": true,
"http_browser_color_depth": "24",
"http_browser_screen_height": "900",
"http_browser_screen_width": "1440",
"http_browser_time_difference": "180",
},
"reference_external_id": "dataonly_001",
"webhook_url": "https://merchant.example/webhooks/a55",
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST",
"https://core-manager.a55.tech/api/v1/bank/wallet/charge/", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ACCESS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)
String json = """
{
"wallet_uuid": "00000000-0000-4000-8000-000000000001",
"type_charge": "credit_card",
"card_name": "JANE DOE",
"card_number": "4111111111111111",
"card_expiry_month": 12,
"card_expiry_year": 2030,
"card_cvv": "123",
"data_only": true,
"currency": "BRL",
"installment_value": 29900,
"installment_count": 1,
"device_info": {
"ip_address": "203.0.113.10",
"user_agent": "Mozilla/5.0",
"http_accept_content": "text/html",
"http_accept_browser_value": "*/*",
"http_browser_language": "pt-BR",
"http_browser_java_enabled": false,
"http_browser_javascript_enabled": true,
"http_browser_color_depth": "24",
"http_browser_screen_height": "900",
"http_browser_screen_width": "1440",
"http_browser_time_difference": "180"
},
"reference_external_id": "dataonly_001",
"webhook_url": "https://merchant.example/webhooks/a55"
}
""";
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://core-manager.a55.tech/api/v1/bank/wallet/charge/"))
.header("Authorization", "Bearer " + System.getenv("ACCESS_TOKEN"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
$payload = [
"wallet_uuid" => "00000000-0000-4000-8000-000000000001",
"type_charge" => "credit_card",
"card_name" => "JANE DOE",
"card_number" => "4111111111111111",
"card_expiry_month" => 12,
"card_expiry_year" => 2030,
"card_cvv" => "123",
"data_only" => true,
"currency" => "BRL",
"installment_value" => 29900,
"installment_count" => 1,
"device_info" => [
"ip_address" => "203.0.113.10",
"user_agent" => "Mozilla/5.0",
"http_accept_content" => "text/html",
"http_accept_browser_value" => "*/*",
"http_browser_language" => "pt-BR",
"http_browser_java_enabled" => false,
"http_browser_javascript_enabled" => true,
"http_browser_color_depth" => "24",
"http_browser_screen_height" => "900",
"http_browser_screen_width" => "1440",
"http_browser_time_difference" => "180",
],
"reference_external_id" => "dataonly_001",
"webhook_url" => "https://merchant.example/webhooks/a55",
];
$ch = curl_init("https://core-manager.a55.tech/api/v1/bank/wallet/charge/");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("ACCESS_TOKEN"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
echo curl_exec($ch);
Tratar a resposta
Cobranças Data Only resolvem na hora — sem redirect, sem url_3ds, sem esperar conclusão de desafio.
- Confirmado
- Recusado
- Erro de autenticação
{
"uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "confirmed",
"reference_external_id": "dataonly_001",
"data_only": true,
"eci": "07",
"authentication_status": "data_only_succeeded",
"amount": 29900,
"currency": "BRL",
"type_charge": "credit_card"
}
{
"uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "error",
"reference_external_id": "dataonly_001",
"data_only": true,
"message": [{"message": "Card declined by issuer"}],
"code": "CARD_DECLINED"
}
{
"uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "error",
"reference_external_id": "dataonly_001",
"data_only": true,
"message": [{"message": "Transaction not authenticated 3DS or DataOnly is required for debit card."}],
"code": "error_threeds_authentication"
}
Confirmar via webhook
A A55 envia um webhook ao seu webhook_url com o status final. Use sempre o webhook como fonte da verdade.
{
"charge_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "paid",
"transaction_reference": "txn_ref_001",
"webhook_url": "https://merchant.example/webhooks/a55"
}
Referência de device_info
Esses campos alimentam o modelo de risco do emissor. Mais dados = melhor avaliação de risco = maior taxa de aprovação.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
ip_address | string | Sim | IP público do cliente |
user_agent | string | Sim | Cabeçalho User-Agent do navegador |
http_accept_content | string | Sim | Valor do cabeçalho HTTP Accept |
http_accept_browser_value | string | Sim | Cabeçalho Accept do navegador |
http_browser_language | string | Sim | Idioma do navegador/SO (por exemplo, pt-BR) |
http_browser_java_enabled | boolean | Sim | Se o plugin Java está habilitado |
http_browser_javascript_enabled | boolean | Sim | Se JavaScript está habilitado |
http_browser_color_depth | string | Sim | Profundidade de cor da tela (por exemplo, "24") |
http_browser_screen_height | string | Sim | Altura da tela em pixels |
http_browser_screen_width | string | Sim | Largura da tela em pixels |
http_browser_time_difference | string | Sim | Offset em minutos em relação ao UTC (por exemplo, "180" para BRT) |
device_id | string | Não | Identificador estável do dispositivo |
session_id | string | Não | Identificador da sessão de checkout |
Diferenças de resposta Visa vs Mastercard
As duas bandeiras suportam Data Only, mas os campos da resposta de autenticação diferem:
| Campo | Visa Data Only | Mastercard Identity Check Insights |
|---|---|---|
| Nome do programa | Visa Data Only (VDO) | Identity Check Insights (IDCI) |
| ECI | 07 | 04 ou 06 (depende do adquirente) |
| Status da transação | I (informativo) | U (não autenticado) |
| CAVV/AAV | Presente | Presente |
| Challenge indicator enviado | 06 (somente dados) | 06 (somente dados) |
| Categoria da mensagem | Padrão | 80 (específico IDCI) |
| Mudança de responsabilidade | Não | Não |
Visa DCAP (Digital Commerce Authentication Program)
Para transações nos EUA e Canadá, a Visa oferece o programa DCAP — um caminho Data Only aprimorado que exige campos específicos para maximizar o ganho na taxa de aprovação.
Campos exigidos pelo DCAP
| Campo | Por que importa |
|---|---|
ip_address | Geolocalização e checagens de velocidade |
payer_email | Correlação de identidade entre lojistas |
payer_address (endereço de cobrança completo) | AVS e verificação de endereço |
Device fingerprint (device_info) | Reputação do dispositivo e análise comportamental |
Se voce envia cobranças cross-border para EUA ou Canadá, inclua todos esses campos para se qualificar aos dados de autorização aprimorados do DCAP.
Cartões de débito e Data Only
O Data Only também vale para transações com cartão de débito. O backend valida que cobranças de débito incluam autenticação 3DS completa ou Data Only:
| ECI | Aceito para débito |
|---|---|
02 | Sim (3DS completo — Mastercard) |
05 | Sim (3DS completo — Visa) |
06 | Sim (Data Only — Mastercard) |
07 | Sim (Data Only — Visa) |
Se uma cobrança de débito chega sem ECI válido de 3DS ou Data Only, é rejeitada com a mensagem: "Transaction not authenticated 3DS or DataOnly is required for debit card."
Testar com cartões de sandbox
| Card Number | Brand | Scenario | Expected Status |
|---|---|---|---|
4111 1111 1111 1111 | Visa | Data Only — confirmado | confirmed |
5500 0000 0000 0004 | Mastercard | Data Only — confirmado (IDCI) | confirmed |
4000 0000 0000 0002 | Visa | Data Only — recusado pelo emissor | declined |
4000 0000 0000 0069 | Visa | Data Only — erro de processamento | error |
No sandbox, cobranças Data Only são simuladas. A flag data_only é aceita e a resposta inclui eci e authentication_status, mas não há comunicação real com a rede. Use esses cartões de teste para validar a lógica da integração.
Parceiros A55: conversa de ativação
O Data Only está disponível na A55 hoje, mas exige alinhamento para ativar. Para começar:
- Confirmar suporte do adquirente — nem todos os adquirentes na sua tabela de roteamento suportam Data Only. Seu gestor de integração verifica quais provedores estão habilitados.
- Habilitar Data Only na configuração do lojista — a flag
authentication_dataonly_enabledprecisa estar ativa na conta. - Revisar qualidade do
device_info— dados incompletos ou sintéticos anulam o benefício. A A55 pode auditar seus payloads recentes. - Analisar o perfil de transações — seu gestor de integração pode estimar o ganho esperado na taxa de aprovação com base nos seus padrões de recusa atuais.
Fale com seu gestor de integração ou envie e-mail para tech.services@a55.tech para agendar uma revisão de ativação do Data Only.
Referências
Esta página se baseia em 17 fontes do setor:
- Visa Data Only for merchants and issuers
- CyberSource: Visa Data Only REST Example
- Adyen: Data-only flow
- Fiserv LATAM: Data Only — Mastercard and Visa
- PXP Kalixa: 3DS2 Data Only Flow
- PayPal: 3DS Data Only and authorization rates
- Square + Broadcom/Arcot: 6M transaction pilot case study
- US Payments Forum: 3DS Data Only Brief #2 (Aug 2025)
- Datos Insights: Lower Fraud, No Friction
- EMVCo: 3DS 2.2 specification — challengeInd "06"
- Mastercard: Identity Check Insights Program
- Stripe: Visa DCAP on Stripe
- Decta: 5 Optimization Tips for 3DS Approval Rates
- Cardinal/Verifi: Data Only
- Visa European EMV 3DS 2.2.0 Implementation Guide
- CyberSource: Visa Data Only Testing
- Merchant Advisory Group: Visa DCAP and VAMP Programs