Order Fraud Monitoring
Detect fraudulent orders in real time across online, in-store, and phone channels. Track anonymous user profiles, link devices, score every order for fraud risk, and monitor cashier behavior at POS terminals.
Overview
Order Fraud Monitoring provides:
- Anonymous profiles - Track users via a client-provided
external_idwithout storing PII - Real-time order scoring - Every order gets a risk score (0-100) with detailed signal breakdown
- Device linking - Map profiles to device fingerprints, detect multi-device and device-sharing anomalies
- POS cashier monitoring - Track voids, refunds, discount overrides, and off-shift activity
- Pattern-based alerts - Automatic detection of velocity spikes, impossible travel, and cross-org fraud
- Investigation workflow - Drill into alerts, review evidence, approve/reject orders
How It Works
Your App/POS Simplr API Dashboard
| | |
|-- identify(user) ----------->| Create/update profile |
| | Link device fingerprint |
| | |
|-- submitOrder(order) ------->| Score order in real-time |
|<-- { risk_score, flags } ----| Store order + signals |
| | |
| |-- Background jobs ---------> |
| | Update baselines |
| | Detect patterns |
| | Create alerts |
| | |
| | Investigate ->|
| | Approve/Reject|
Quick Start
1. Create a Profile
When a user signs up or logs in, identify them. Simplr creates an anonymous profile tied to your external_id.
curl -X POST https://api.simplr-ai.com/v1/profiles \
-H "X-API-Key: sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"external_id": "user-abc-123",
"profile_type": "customer",
"fingerprint_hash": "a1b2c3d4e5f6..."
}'
The external_id is your internal identifier (user ID, loyalty card number, etc.). Simplr never sees the user's name or email - only your opaque ID. You can trace back to the real user on your side.
2. Submit an Order
Every time a user places an order, submit it for fraud scoring:
curl -X POST https://api.simplr-ai.com/v1/orders \
-H "X-API-Key: sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"external_order_id": "ORD-2026-001",
"external_id": "user-abc-123",
"amount_cents": 15999,
"currency": "ZAR",
"order_type": "online",
"payment_method": "card",
"location_latitude": -33.92,
"location_longitude": 18.42,
"fingerprint_hash": "a1b2c3d4e5f6..."
}'
Response:
{
"success": true,
"content": {
"order": {
"id": "uuid",
"external_order_id": "ORD-2026-001",
"status": "pending"
},
"risk": {
"risk_score": 12,
"risk_level": "low",
"signals": {
"velocity": 0,
"amount_anomaly": 2,
"location_anomaly": 0,
"device_anomaly": 0,
"time_anomaly": 5,
"pattern": 0
},
"flags": [],
"flagged_for_review": false
}
}
}
Use the risk_score and risk_level to decide how to handle the order:
| Risk Level | Score | Suggested Action |
|---|---|---|
low | 0-24 | Auto-approve |
medium | 25-49 | Proceed with monitoring |
high | 50-69 | Hold for review, request additional verification |
critical | 70-100 | Block or escalate immediately |
3. In-Store Orders (POS)
For in-store orders, include the POS device and cashier:
curl -X POST https://api.simplr-ai.com/v1/orders \
-H "X-API-Key: sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"external_order_id": "POS-42-0891",
"order_type": "in_store",
"amount_cents": 8500,
"payment_method": "cash",
"edge_device_id": "pos-terminal-42",
"cashier_external_id": "cashier-jane",
"location_name": "Downtown Store"
}'
Note: external_id (customer) is optional for in-store orders. Unknown customers are tracked by device and location patterns only.
4. Track Cashier Actions
Submit cashier-specific actions for fraud monitoring:
curl -X POST https://api.simplr-ai.com/v1/cashier/actions \
-H "X-API-Key: sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"cashier_external_id": "cashier-jane",
"action_type": "void",
"edge_device_id": "pos-terminal-42",
"amount_cents": 4500,
"reason": "Customer changed mind"
}'
Action types: void, refund, discount_override, price_override, no_sale, cash_drop, cash_pickup, drawer_open, shift_start, shift_end
Using the SDKs
JavaScript SDK
import { SimplrProfiles } from '@simplr/sdk';
const profiles = new SimplrProfiles({ apiKey: 'pk_live_xxxxx' });
// Identify user (auto-collects device fingerprint)
await profiles.identify('user-abc-123');
// Submit order (auto-attaches fingerprint + geolocation)
const result = await profiles.submitOrder({
external_order_id: 'ORD-001',
external_id: 'user-abc-123',
amount_cents: 15999,
payment_method: 'card',
});
if (result.risk.risk_level === 'high' || result.risk.risk_level === 'critical') {
// Hold order, show verification step
}
Flutter SDK
final profiles = SimplrProfiles(
config: SimplrProfilesConfig(apiKey: 'pk_live_xxxxx'),
);
// Identify user (auto-collects device fingerprint)
await profiles.identify('user-abc-123');
// Submit order
final result = await profiles.submitOrder(OrderInput(
externalOrderId: 'ORD-001',
externalId: 'user-abc-123',
amountCents: 15999,
paymentMethod: 'card',
));
if (result.riskLevel == 'high' || result.riskLevel == 'critical') {
// Hold order, request additional verification
}
Fraud Signals Explained
Each order gets scored across six signal dimensions:
| Signal | Max Points | What It Detects |
|---|---|---|
| Velocity | 25 | Too many orders in a short time (>5/hour, >10/6h, >20/24h) |
| Amount Anomaly | 20 | Order amount deviates from profile baseline (>3x average) |
| Location Anomaly | 20 | Order from unusual location or impossible travel between orders |
| Device Anomaly | 20 | New device, >3 devices in 24h, many profiles sharing one device |
| Time Anomaly | 15 | Orders outside typical hours (especially 2-5am) |
| Pattern | 10 | Cross-org fraud flags, payment method changes on high amounts |
Cashier Fraud Patterns
| Pattern | Detection Method |
|---|---|
| Excessive voids | Void count >2 standard deviations above org average |
| Excessive refunds | Refund count >2 standard deviations above org average |
| Discount abuse | Cashier discount rate >2x the org average |
| Off-shift activity | Transactions outside the cashier's shift window |
| Rapid transactions | Orders processed <10 seconds apart |
| Drawer anomalies | >3 no-sale drawer opens per shift |
| Round-number refunds | Refunds at exact round amounts without matching orders |
Known vs Unknown Customers
| Scenario | How It Works |
|---|---|
| Known customer (online) | SDK calls identify() then submitOrder() with external_id. Full profile-level fraud scoring. |
| Known customer (in-store) | Loyalty card scan provides external_id. Order linked to profile. |
| Unknown customer (POS) | Order submitted with edge_device_id only, no external_id. Scored on device + location + cashier patterns. |
| Customer identifies later | When they scan loyalty card, update the order with their external_id to link it to their profile. |
Webhooks
Subscribe to fraud events for real-time notifications:
| Event | Trigger |
|---|---|
order.fraud.detected | An order scores 50+ risk |
order.fraud.alert | A pattern-based alert is created |
profile.risk.changed | A profile's risk level changes |
cashier.fraud.detected | A cashier action triggers fraud flags |
See the Webhooks guide for setup instructions.
Investigation Workflow
- Alert appears on the dashboard (e.g., "Impossible travel detected")
- Click Investigate to see why it was triggered and the evidence
- Drill into the profile to see the full activity timeline
- Expand orders to inspect individual fraud signals, flags, and device/location context
- Take action: Acknowledge (investigating), Resolve (handled), or False Positive (not fraud)
- Report profiles: Mark as fraud (flags for investigation) or legitimate (clears the flag)
All actions record the user who performed them and the timestamp.