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

Verificar Transações

Chame verify() em momentos sensíveis à segurança. O SDK coleta sinais do dispositivo, executa verificações de integridade do dispositivo e retorna a decisão de risco do backend.

verify() requer um JWT novo que o seu backend gera. O SDK nunca guarda uma chave de API da Surt - o seu backend guarda a chave sp_live_* (somente no lado do servidor) e a troca por um JWT de curta duração.

Uso Básico​

Primeiro, obtenha um JWT novo do seu próprio backend e então passe-o para verify():

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

// Seu backend chama o POST /geolocation/preflight da Surt com a
// chave de API sp_live_* e retorna o JWT gerado para o 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) {
// Prosseguir com o pagamento
} else {
// Transação negada - verifique result.riskLevel
}
} catch (error) {
// Tratar erro do SDK (rede, não inicializado, jwt inválido, etc.)
}
};

return <Button onPress={handlePayment} title="Pay" />;
}
aviso

Sempre obtenha um JWT novo imediatamente antes de cada chamada verify(). Cada JWT é de uso único - reutilizar um JWT é rejeitado pelo backend.

Diagnóstico do resultado​

O resultado de verify() inclui um objeto diagnostics opcional que descreve o que o SDK observou durante a transação. É aditivo - leia-o para mais visibilidade ou ignore-o.

const result = await verify(jwt);
if (result.diagnostics?.location === 'denied') {
// peça ao usuário para ativar a localização
}

diagnostics.location é collected · denied · unavailable · timeout · not_requested; diagnostics.networkIntel é collected · unavailable; diagnostics.warnings é um array de { code, signal }; diagnostics.timings (somente Android, v0.5.2+) traz milissegundos por fase mais total. Veja Códigos de Erro → Diagnóstico do resultado.

De Onde Vem o Contexto de Cliente e Transação​

Na v0.3.0 o cliente não chama mais setCustomer() e não passa mais um tipo de transação para verify(). Em vez disso, o seu backend define todo esse contexto quando gera o JWT.

Quando o seu backend chama POST /geolocation/preflight, ele inclui customer_id, transaction_type e, opcionalmente, transaction_name, name e email. Esses valores são embutidos no JWT, então o cliente só precisa passar o token:

const jwt = await fetchVerifyJwt(); // backend definiu o contexto de cliente + transação
const result = await verify(jwt);

Tipos de Transação​

Estes valores são enviados pelo seu backend no campo transaction_type do preflight. Eles não são passados para verify() no cliente.

TipoCaso de uso
loginLogin do usuário
sign_upCriação de nova conta
depositAdição de fundos
withdrawalSaque de fundos

Substituição de Localização por Chamada​

Substitua o padrão collectLocation para uma única chamada:

// Ignorar localização para esta chamada
const result = await verify(jwt, { collectLocation: false });

// Solicitar localização para esta chamada
const result = await verify(jwt, { collectLocation: true });

// Usar padrão de inicialização
const result = await verify(jwt);

A substituição é única. Ela afeta apenas aquela chamada verify().

Como a Coleta de Localização É Decidida​

A coleta de localização tem dois níveis de controle, avaliados em conjunto. Ambos devem concordar para que os dados de GPS sejam coletados:

1. Painel Surt: GPS habilitado (maior prioridade)

A coleta de GPS deve estar habilitada no seu painel de cliente Surt. Se o GPS estiver desabilitado no painel, a localização nunca é coletada, independentemente do que você definir no código. Habilite-o em Configurações > Desenvolvedor ou entre em contato com o gerente da sua conta Surt.

2. Configuração do lado do cliente (seu código)

Isso é resolvido como: substituição por chamada > padrão de inicialização.

  • Se você passar { collectLocation: true } para verify(), isso prevalece sobre o valor de inicialização.
  • Se você passar { collectLocation: false } para verify(), o GPS é ignorado mesmo se a inicialização estava true.
  • Se você omiti-lo, o padrão de inicialização do GuardianProvider / initialize() é usado.

Na prática, isso significa:

GPS no PainelSeu código dizResultado
habilitadotrue (init ou substituição)GPS coletado
habilitadofalse (init ou substituição)Sem GPS: você optou por sair
desabilitadotrue (init ou substituição)Sem GPS: o painel está desativado
desabilitadofalse (init ou substituição)Sem GPS
Conclusão principal

Sua configuração collectLocation no lado do cliente só pode optar por sair da coleta de localização. Ela não pode forçar a coleta de GPS se o painel a tiver desabilitada. Para habilitar a coleta de GPS, ative-a primeiro no seu painel de cliente Surt e então defina collectLocation: true no seu código.

Resultado da Verificação​

interface VerificationResult {
allowed: boolean; // Decisão do backend - true = prosseguir
riskLevel: RiskLevel; // 'low' | 'medium' | 'high' | 'blocked' | 'unknown'
sessionId: string; // ID da transação para referência de suporte
errors?: string[]; // Mensagens de erro do backend, se houver
timestamp: number; // Timestamp da resposta (ms)
metadata?: Record<string, any>; // Metadados adicionais do backend
}

Para detalhes sobre níveis de risco, consulte Níveis de Risco.

Exemplo Completo​

App.tsx
import React, { useState } from 'react';
import { View, Button, Text, Alert } from 'react-native';
import {
GuardianProvider,
useGuardian,
type VerificationResult,
} from '@surtai/guardian-rn';

// Seu backend chama o POST /geolocation/preflight da Surt com a
// chave de API sp_live_* e retorna o JWT gerado para o 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>
);
}