Skip to main content

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_id without 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 LevelScoreSuggested Action
low0-24Auto-approve
medium25-49Proceed with monitoring
high50-69Hold for review, request additional verification
critical70-100Block 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:

SignalMax PointsWhat It Detects
Velocity25Too many orders in a short time (>5/hour, >10/6h, >20/24h)
Amount Anomaly20Order amount deviates from profile baseline (>3x average)
Location Anomaly20Order from unusual location or impossible travel between orders
Device Anomaly20New device, >3 devices in 24h, many profiles sharing one device
Time Anomaly15Orders outside typical hours (especially 2-5am)
Pattern10Cross-org fraud flags, payment method changes on high amounts

Cashier Fraud Patterns

PatternDetection Method
Excessive voidsVoid count >2 standard deviations above org average
Excessive refundsRefund count >2 standard deviations above org average
Discount abuseCashier discount rate >2x the org average
Off-shift activityTransactions outside the cashier's shift window
Rapid transactionsOrders processed <10 seconds apart
Drawer anomalies>3 no-sale drawer opens per shift
Round-number refundsRefunds at exact round amounts without matching orders

Known vs Unknown Customers

ScenarioHow 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 laterWhen 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:

EventTrigger
order.fraud.detectedAn order scores 50+ risk
order.fraud.alertA pattern-based alert is created
profile.risk.changedA profile's risk level changes
cashier.fraud.detectedA cashier action triggers fraud flags

See the Webhooks guide for setup instructions.

Investigation Workflow

  1. Alert appears on the dashboard (e.g., "Impossible travel detected")
  2. Click Investigate to see why it was triggered and the evidence
  3. Drill into the profile to see the full activity timeline
  4. Expand orders to inspect individual fraud signals, flags, and device/location context
  5. Take action: Acknowledge (investigating), Resolve (handled), or False Positive (not fraud)
  6. Report profiles: Mark as fraud (flags for investigation) or legitimate (clears the flag)

All actions record the user who performed them and the timestamp.