[Avg. reading time: 8 minutes]

Fraud Detection

Step 1: Graph Data Modeling

Financial entities are modeled as Nodes (e.g., :Customer, :Account, :Transaction, :IPAddress, :PhoneNumber).

The connections between them are modeled as Relationships (e.g., :OWNS, :PERFORMED, :USED, :REGISTERED_AT).

Properties (attributes) are stored on both nodes and relationships (e.g., Customer.name, Transaction.amount, Transaction.timestamp).

This creates an explicit map of "who is connected to whom, and how."

Step 2: Data Ingestion

Data from various sources (customer records, transactions, application logs) is imported into Neo4j, creating the graph structure defined above.

Example: API, CSV, Streaming (Kafka)

Step 3: Pattern Detection via Cypher

Cypher queries to look for suspicious patterns that are indicators of fraud.

Common patterns include:

Shared Attributes: Multiple customers/accounts sharing non-unique identifiers (like an IP address or phone number) but having different personal details.6 This is a classic indicator of a "fraud ring" or synthetic identity fraud.

Circular Money Flow: Transactions forming a loop (money moving from A > B > C > A), often seen in money laundering.

Rapid Activity: A new account performing an unusually large number of transactions in a short time.

Step 4: Visualization and Action

The results are visualized using tools BI Tools.

The queries are executed as soon a new Transaction is added using Triggers.


// 1. Create a Shared IP Address - The fraud indicator
CREATE (ip:IPAddress {ip_address: '103.45.67.89'})

// 2. Create two suspicious customers and their accounts
CREATE (c1:Customer {id: 'C1001', name: 'Rachel'})
CREATE (a1:Account {account_number: 'A9001'})
CREATE (c1)-[:OWNS]->(a1)
CREATE (c1)-[:USED_IP {timestamp: 1730304000}]->(ip) // Rachel uses shared IP

CREATE (c2:Customer {id: 'C1002', name: 'Ross'})
CREATE (a2:Account {account_number: 'A9002'})
CREATE (c2)-[:OWNS]->(a2)
CREATE (c2)-[:USED_IP {timestamp: 1730304100}]->(ip) // Ross uses shared IP, close in time

// 3. Create a legitimate customer
CREATE (c3:Customer {id: 'C1003', name: 'Chandler'})
CREATE (a3:Account {account_number: 'A9003'})
CREATE (ip_c3:IPAddress {ip_address: '201.1.2.3'})
CREATE (c3)-[:OWNS]->(a3)
CREATE (c3)-[:USED_IP {timestamp: 1730304200}]->(ip_c3) // Chandler uses a unique IP
MATCH (c1:Customer)-[:USED_IP]->(ip:IPAddress)<-[:USED_IP]-(c2:Customer)
WHERE c1.id < c2.id // Ensures we only look at unique pairs (c1, c2)
WITH ip, collect(c1.name) + collect(c2.name) AS users, count(DISTINCT c1)+count(DISTINCT c2) AS connectedUsers
WHERE connectedUsers >= 2 // Find IP addresses shared by 2 or more distinct customers
RETURN ip.ip_address AS Shared_IP, users, connectedUsers

Very useful and informative video

Neo4J Transaction Graph DemoVer 5.5.9

Last change: 2025-12-03