Saltar al contenido principal
Version: Guardian v0.1.0

Collect (Servidor a servidor)

v0.2.1+

Dos rutas de verificación

El Guardian SDK ofrece dos formas de verificar dispositivos. Elija según su arquitectura:

verify()collect()
Quién llama a SurtEl SDK (desde el dispositivo)Su backend (servidor a servidor)
Llamadas de red desde el SDKNo
Su backend involucradoNo
RespuestaVerificationResult (permitido/denegado)CollectResult (payload cifrado)
Ideal paraIntegración simple, decisiones en el frontendDecisiones en el backend, lógica personalizada, requisitos de auditoría

Flujo de verify()

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

El SDK llama a Surt directamente y devuelve allowed: true/false. Su aplicación actúa sobre la decisión inmediatamente.

Flujo de collect()

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

El SDK recopila datos del dispositivo y los cifra localmente. Cero llamadas de red a Surt. Su backend envía el payload al endpoint de evaluación de Surt, recibe la evaluación de riesgo completa y decide qué devolver a su aplicación.

Cuándo usar collect()

  • Su backend necesita los datos de riesgo antes de responder al cliente
  • Desea combinar el riesgo del dispositivo con su propia lógica de negocio del lado del servidor
  • Necesita control total sobre lo que el cliente ve
  • El cumplimiento requiere que todas las llamadas a terceros se originen desde su infraestructura

Uso

1. Recopilar en el 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. Llamar a Surt desde su backend

Su backend recibe el payload cifrado de la aplicación y luego llama al endpoint de evaluación de 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 de la solicitud

CampoTipoRequeridoDescripción
customer_idstringSu identificador de usuario
transaction_typestringlogin, sign_up, deposit o withdrawal
transaction_namestringNoEtiqueta legible para humanos
payload.typestringSiempre "encrypted"
payload.datastringEl payload cifrado de collect()
config.response.addressobjectNo{ "type": "include" } para obtener la dirección completa, omitido por defecto

Config

El objeto config controla qué datos opcionales se incluyen en la respuesta.

{
"config": {
"response": {
"address": { "type": "include" }
}
}
}
CampoValoresPor defectoDescripción
config.response.address.type"include" o "omit""omit"Si se incluye la dirección completa de geocodificación inversa (calle, ciudad, estado, país, código postal) en la respuesta. Requiere datos GPS en el payload.

Cuando address se omite (por defecto), el campo address en la respuesta será null incluso si se recopilaron datos de ubicación. Establezca en "include" si su backend necesita la dirección física para cumplimiento, revisión de fraude o visualización.

Autenticación

Use su clave de API de Surt en el encabezado Authorization como un token Bearer. Esta es una llamada servidor a servidor - la clave de API nunca toca el dispositivo.

3. Manejar la respuesta

El endpoint de evaluación devuelve los mismos datos que verify(), pero con detalle completo:

{
"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"
}
}
}

Su backend puede usar status.risk_level, status.result.status, signals, triggered_scenarios y address para tomar su propia decisión antes de responder al cliente.

Anulación de ubicación

Igual que verify(), puede anular la recopilación de ubicación por llamada:

// Recopilar con ubicación
const { payload } = await collect('login', 'Login', { collectLocation: true });

// Recopilar sin ubicación
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;
}

El payload está cifrado y solo puede ser descifrado por el backend de Surt. Contiene la huella digital del dispositivo, datos de atestación, señales de seguridad y opcionalmente ubicación.

Ejemplo 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 });
});