Verificar transacciones
Llama a verify() en momentos sensibles de seguridad. El SDK recopila señales del dispositivo, ejecuta verificaciones de integridad del dispositivo y devuelve la decisión de riesgo del backend.
verify() requiere un JWT fresco que genera tu backend. El SDK nunca maneja una clave de API de Surt; tu backend maneja la clave sp_live_* (solo del lado del servidor) y la intercambia por un JWT de corta duración.
Uso básico
Primero, obtén un JWT fresco desde tu propio backend y luego pásalo a verify():
import { useGuardian } from '@surtai/guardian-rn';
// Tu backend llama al POST /geolocation/preflight de Surt con la
// clave de API sp_live_* y devuelve el JWT generado al cliente.
async function fetchVerifyJwt(): Promise<string> {
const res = await fetch('https://your-api.com/guardian/jwt', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
transaction_type: 'withdrawal',
transaction_name: 'User Payment',
}),
});
const { token } = await res.json();
return token;
}
function PaymentScreen() {
const { verify } = useGuardian();
const handlePayment = async () => {
try {
const jwt = await fetchVerifyJwt();
const result = await verify(jwt);
if (result.allowed) {
// Proceder con el pago
} else {
// Transacción denegada - revisa result.riskLevel
}
} catch (error) {
// Manejar error del SDK (red, no inicializado, jwt inválido, etc.)
}
};
return <Button onPress={handlePayment} title="Pay" />;
}
Obtén siempre un JWT fresco justo antes de cada llamada a verify(). Cada JWT es de un solo uso; reutilizar uno es rechazado por el backend.
De dónde provienen el contexto de cliente y de transacción
En la v0.3.0 el cliente ya no llama a setCustomer() ni pasa un tipo de transacción a verify(). En su lugar, tu backend establece todo este contexto al generar el JWT.
Cuando tu backend llama a POST /geolocation/preflight, incluye customer_id, transaction_type y, opcionalmente, transaction_name, name y email. Esos valores quedan incorporados en el JWT, por lo que el cliente solo necesita pasar el token:
const jwt = await fetchVerifyJwt(); // el backend estableció el contexto de cliente + transacción
const result = await verify(jwt);
Tipos de transacción
Estos valores los envía tu backend en el campo transaction_type del preflight. No se pasan a verify() en el cliente.
| Tipo | Caso de uso |
|---|---|
login | Inicio de sesión del usuario |
sign_up | Creación de cuenta nueva |
deposit | Agregar fondos |
withdrawal | Retirar fondos |
Anulación de ubicación por llamada
Anula el valor predeterminado de collectLocation para una sola llamada:
// Omitir ubicación para esta llamada
const result = await verify(jwt, { collectLocation: false });
// Solicitar ubicación para esta llamada
const result = await verify(jwt, { collectLocation: true });
// Usar el valor predeterminado de inicialización
const result = await verify(jwt);
La anulación es de un solo uso. Solo afecta esa única llamada a verify().
Cómo se decide la recopilación de ubicación
La recopilación de ubicación tiene dos niveles de control, evaluados en conjunto. Ambos deben coincidir para que se recopilen datos GPS:
1. Panel de Surt: GPS habilitado (mayor prioridad)
La recopilación GPS debe estar habilitada en tu panel de cliente de Surt. Si el GPS está deshabilitado en el panel, la ubicación nunca se recopila, sin importar lo que establezcas en el código. Habilítalo en Settings > Developer o contacta a tu gerente de cuenta de Surt.
2. Configuración del lado del cliente (tu código)
Esto se resuelve como: anulación por llamada > valor predeterminado de inicialización.
- Si pasas
{ collectLocation: true }averify(), eso prevalece sobre el valor de inicialización. - Si pasas
{ collectLocation: false }averify(), el GPS se omite incluso si la inicialización eratrue. - Si lo omites, se usa el valor predeterminado de inicialización de
GuardianProvider/initialize().
En la práctica, esto significa:
| GPS en panel | Tu código dice | Resultado |
|---|---|---|
| habilitado | true (init o anulación) | GPS recopilado |
| habilitado | false (init o anulación) | Sin GPS: optaste por no participar |
| deshabilitado | true (init o anulación) | Sin GPS: el panel lo tiene desactivado |
| deshabilitado | false (init o anulación) | Sin GPS |
Tu configuración collectLocation del lado del cliente solo puede desactivar la recopilación de ubicación. No puede forzar la recopilación GPS si el panel lo tiene deshabilitado. Para habilitar la recopilación GPS, actívalo primero en tu panel de cliente de Surt y luego establece collectLocation: true en tu código.
Resultado de la verificación
interface VerificationResult {
allowed: boolean; // Decisión del backend - true = continuar
riskLevel: RiskLevel; // 'low' | 'medium' | 'high' | 'blocked' | 'unknown'
sessionId: string; // ID de transacción para referencia de soporte
errors?: string[]; // Mensajes de error del backend, si los hay
timestamp: number; // Marca de tiempo de la respuesta (ms)
metadata?: Record<string, any>; // Metadatos adicionales del backend
}
Para detalles sobre niveles de riesgo, consulta Niveles de riesgo.
Ejemplo completo
import React, { useState } from 'react';
import { View, Button, Text, Alert } from 'react-native';
import {
GuardianProvider,
useGuardian,
type VerificationResult,
} from '@surtai/guardian-rn';
// Tu backend llama al POST /geolocation/preflight de Surt con la
// clave de API sp_live_* y devuelve el JWT generado al cliente.
async function fetchVerifyJwt(): Promise<string> {
const res = await fetch('https://your-api.com/guardian/jwt', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
transaction_type: 'login',
transaction_name: 'User Login',
}),
});
const { token } = await res.json();
return token;
}
function HomeScreen() {
const { verify, collect, isInitialized } = useGuardian();
const [result, setResult] = useState<VerificationResult | null>(null);
const handleLogin = async () => {
try {
const jwt = await fetchVerifyJwt();
const res = await verify(jwt);
setResult(res);
Alert.alert(res.allowed ? 'Approved' : 'Denied', `Risk: ${res.riskLevel}`);
} catch (e: any) {
Alert.alert('Error', e.message);
}
};
return (
<View style={{ padding: 20 }}>
<Text>SDK Ready: {isInitialized ? 'Yes' : 'No'}</Text>
<Button title="Login & Verify" onPress={handleLogin} />
{result && <Text>Allowed: {result.allowed ? 'Yes' : 'No'}</Text>}
</View>
);
}
export default function App() {
return (
<GuardianProvider environment="production" collectLocation={true}>
<HomeScreen />
</GuardianProvider>
);
}
Diagnósticos del resultado
El resultado de verify() incluye un objeto opcional diagnostics (location, networkIntel, warnings y, solo en Android a partir de v0.5.2, timings con milisegundos por fase) para que sepas qué ocurrió en el dispositivo.
const result = await verify(jwt);
if (result.diagnostics?.location === 'denied') {
// pide al usuario que active la ubicación
}
Consulta Códigos de error para la referencia completa.