Profiles & Order Fraud (JavaScript)
The SimplrProfiles class provides anonymous user profile management and real-time order fraud scoring.
Setup
import { SimplrProfiles } from '@simplr/sdk';
const profiles = new SimplrProfiles({
apiKey: 'pk_live_xxxxx',
// baseUrl: 'https://api.simplr-ai.com' // optional, defaults to production
});
Auto-collect device fingerprints
To automatically attach device fingerprints to identify() and submitOrder() calls, connect the fingerprint collector:
import { SimplrFraud, SimplrProfiles } from '@simplr/sdk';
const fraud = new SimplrFraud({ apiKey: 'pk_live_xxxxx' });
const profiles = new SimplrProfiles({ apiKey: 'pk_live_xxxxx' });
// Connect the device signal collector
profiles.setDeviceSignalCollector(() => fraud.collectDeviceSignals());
Identify a User
Call identify() when a user signs up, logs in, or is otherwise known. This creates (or updates) an anonymous profile and links the current device.
const result = await profiles.identify('user-abc-123', {
profileType: 'customer', // 'customer' | 'cashier' | 'employee'
});
console.log(result.is_new); // true if first time
console.log(result.device_linked); // true if device was attached
console.log(result.device_anomaly); // null or anomaly description
The external_id you pass ('user-abc-123') is your internal identifier. Simplr stores it as-is but never knows the user's real identity.
Submit an Order
const result = await profiles.submitOrder({
external_order_id: 'ORD-2026-001',
external_id: 'user-abc-123', // links to profile
amount_cents: 15999,
currency: 'ZAR',
order_type: 'online', // 'online' | 'in_store' | 'phone' | 'other'
payment_method: 'card', // 'card' | 'cash' | 'mobile' | 'crypto' | 'other'
// Optional location
location_latitude: -33.92,
location_longitude: 18.42,
// Optional: for POS orders
// edge_device_id: 'pos-terminal-42',
// cashier_external_id: 'cashier-jane',
// Optional: line items for item-level fraud detection
items: [
{
item_category: 'electronics',
quantity: 1,
unit_price_cents: 15999,
total_price_cents: 15999,
},
],
});
// Use the risk assessment
console.log(result.risk.risk_score); // 0-100
console.log(result.risk.risk_level); // 'low' | 'medium' | 'high' | 'critical'
console.log(result.risk.flags); // ['high_velocity', 'amount_anomaly', ...]
console.log(result.risk.flagged_for_review); // true if score >= 50
// Act on the result
if (result.risk.risk_level === 'critical') {
blockOrder();
} else if (result.risk.risk_level === 'high') {
holdForReview();
} else {
approveOrder();
}
If setDeviceSignalCollector is configured, submitOrder() automatically attaches the device fingerprint. It also requests browser geolocation (with a 3-second timeout) if no location is provided.
Get Profile Risk
const risk = await profiles.getProfileRisk('user-abc-123');
console.log(risk.profile.risk_score);
console.log(risk.profile.signals); // { velocity, device_diversity, location_anomaly, ... }
console.log(risk.profile.total_orders);
console.log(risk.profile.flagged_orders);
Report Fraud / Mark Legitimate
Feed back investigation outcomes to improve fraud detection:
// Flag a profile for investigation
await profiles.reportOutcome('user-abc-123', 'fraud');
// Clear a profile after investigation
await profiles.reportOutcome('user-abc-123', 'legitimate');
TypeScript Types
interface OrderInput {
external_order_id: string;
external_id?: string;
order_type?: 'online' | 'in_store' | 'phone' | 'other';
amount_cents: number;
currency?: string;
payment_method?: 'card' | 'cash' | 'mobile' | 'crypto' | 'other';
location_latitude?: number;
location_longitude?: number;
edge_device_id?: string;
cashier_external_id?: string;
ordered_at?: string;
items?: OrderItemInput[];
}
interface OrderFraudResult {
order: { id: string; external_order_id: string; status: string };
risk: {
risk_score: number;
risk_level: 'low' | 'medium' | 'high' | 'critical';
signals: Record<string, number>;
flags: string[];
flagged_for_review: boolean;
};
}