Pular para o conteúdo principal
Versão: Guardian v0.1.0

Collect (Servidor para Servidor)

v0.2.1+

Dois caminhos de verificação

O Guardian SDK oferece duas formas de verificar dispositivos. Escolha com base na sua arquitetura:

verify()collect()
Quem chama a SurtO SDK (a partir do dispositivo)Seu backend (servidor para servidor)
Chamadas de rede do SDKSimNão
Seu backend envolvidoNãoSim
RespostaVerificationResult (permitido/negado)CollectResult (payload criptografado)
Ideal paraIntegração simples, decisões no frontendDecisões no backend, lógica personalizada, requisitos de auditoria

Fluxo de verify()

App → SDK.verify() → Surt backend → risk decision → App

O SDK chama a Surt diretamente e retorna allowed: true/false. Seu aplicativo age sobre a decisão imediatamente.

Fluxo de collect()

App → SDK.collect() → encrypted payload → App → Your backend → Surt /evaluate → Your backend → App

O SDK coleta dados do dispositivo e os criptografa localmente. Zero chamadas de rede para a Surt. Seu backend envia o payload para o endpoint de avaliação da Surt, recebe a avaliação de risco completa e decide o que retornar ao seu aplicativo.

Quando usar collect()

  • Seu backend precisa dos dados de risco antes de responder ao cliente
  • Você quer combinar o risco do dispositivo com sua própria lógica de negócio no lado do servidor
  • Você precisa de controle total sobre o que o cliente vê
  • Conformidade exige que todas as chamadas a terceiros se originem da sua infraestrutura

Uso

1. Coletar no dispositivo

import { useGuardian } from '@surtai/guardian-rn';

function PaymentScreen() {
const { collect, setCustomer } = useGuardian();

const handlePayment = async () => {
setCustomer('user_123', 'John Doe', 'john@example.com');

const { payload } = await collect('withdrawal', 'User Payment');

// Send payload to YOUR backend
const response = await fetch('https://your-api.com/verify-device', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
payload,
amount: 500,
currency: 'USD',
}),
});

const result = await response.json();
// Your backend already made the risk decision
};
}

2. Chamar a Surt a partir do seu backend

Seu backend recebe o payload criptografado do aplicativo e então chama o endpoint de avaliação da Surt:

POST https://api.surt.com/geolocation/transactions/evaluate
Content-Type: application/json
Authorization: Bearer YOUR_SURT_API_KEY
{
"customer_id": "user_123",
"transaction_type": "withdrawal",
"transaction_name": "User Payment",
"payload": {
"type": "encrypted",
"data": "<payload from SDK>"
},
"config": {
"response": {
"address": { "type": "include" }
}
}
}

Campos da requisição

CampoTipoObrigatórioDescrição
customer_idstringSimSeu identificador de usuário
transaction_typestringSimlogin, sign_up, deposit ou withdrawal
transaction_namestringNãoRótulo legível para humanos
payload.typestringSimSempre "encrypted"
payload.datastringSimO payload criptografado de collect()
config.response.addressobjectNão{ "type": "include" } para obter o endereço completo, omitido por padrão

Config

O objeto config controla quais dados opcionais são incluídos na resposta.

{
"config": {
"response": {
"address": { "type": "include" }
}
}
}
CampoValoresPadrãoDescrição
config.response.address.type"include" ou "omit""omit"Se o endereço completo de geocodificação reversa (rua, cidade, estado, país, código postal) deve ser incluído na resposta. Requer dados GPS no payload.

Quando address é omitido (padrão), o campo address na resposta será null mesmo se dados de localização foram coletados. Defina como "include" se seu backend precisa do endereço físico para conformidade, revisão de fraude ou exibição.

Autenticação

Use sua chave de API da Surt no cabeçalho Authorization como um token Bearer. Esta é uma chamada servidor para servidor - a chave de API nunca toca o dispositivo.

3. Tratar a resposta

O endpoint de avaliação retorna os mesmos dados que verify(), mas com detalhes completos:

{
"status_code": 200,
"message": "Transaction evaluated successfully",
"data": {
"transaction": {
"transaction_id": "1775514112-f2e3034b891e...",
"created_at": "2026-04-06T22:21:52Z",
"customer_id": "user_123",
"transaction_type": "withdrawal",
"transaction_name": "User Payment",
"status": {
"type": "completed",
"risk_level": "low",
"result": {
"status": "accepted",
"review": false
},
"address": {
"street": "123 Main St",
"city": "San Francisco",
"state": "California",
"country": "United States",
"postal_code": "94103",
"formatted_address": "123 Main St, San Francisco, CA 94103, USA"
},
"signals": [ ... ],
"triggered_scenarios": [ ... ]
},
"device": {
"device_id": "fingerprint_abc",
"manufacturer": "Apple",
"model": "iPhone 15",
"os_version": "18.0"
},
"metadata": {
"device_locations": [ ... ],
"ip_locations": [ ... ],
"device_ids": [ ... ]
},
"network_threat": {
"status": "not_analyzed"
},
"country": "United States",
"ip_address": "203.0.113.50"
}
}
}

Seu backend pode usar status.risk_level, status.result.status, signals, triggered_scenarios e address para tomar sua própria decisão antes de responder ao cliente.

Substituição de localização

Assim como verify(), você pode substituir a coleta de localização por chamada:

// Coletar com localização
const { payload } = await collect('login', 'Login', { collectLocation: true });

// Coletar sem localização
const { payload } = await collect('login', 'Login', { collectLocation: false });

CollectResult

interface CollectResult {
/** Base64-encoded encrypted payload. Pass as payload.data in the evaluate request. */
payload: string;
}

O payload é criptografado e só pode ser descriptografado pelo backend da Surt. Ele contém a impressão digital do dispositivo, dados de atestação, sinais de segurança e opcionalmente localização.

Exemplo de backend

app.post('/verify-device', async (req, res) => {
const { payload, userId } = req.body;

const surtResponse = await fetch(
'https://api.surt.com/geolocation/transactions/evaluate',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.SURT_API_KEY}`,
},
body: JSON.stringify({
customer_id: userId,
transaction_type: 'login',
payload: { type: 'encrypted', data: payload },
config: { response: { address: { type: 'include' } } },
}),
}
);

const { data } = await surtResponse.json();
const risk = data.transaction.status.risk_level;
const accepted = data.transaction.status.result.status === 'accepted';

res.json({ allowed: accepted, risk });
});