How to Implement a Custom Fraud Detection System in Magento 2

Why You Need Custom Fraud Detection in Magento 2
Fraud is a growing concern for eCommerce stores, and Magento 2 is no exception. While the platform offers basic fraud prevention tools, they might not be enough to catch sophisticated scams. A custom fraud detection system helps you:
- Reduce chargebacks and financial losses
- Flag suspicious orders before they're processed
- Improve customer trust by preventing fraudulent transactions
- Adapt to new fraud patterns with custom rules
Let’s dive into how you can build your own fraud detection system in Magento 2.
Understanding Magento 2’s Built-in Fraud Tools
Before building a custom solution, it’s good to know what Magento already offers:
- Basic Fraud Filters: Simple checks like AVS (Address Verification System) and CVV validation.
- Payment Gateway Fraud Detection: Some payment providers (like PayPal or Stripe) have their own fraud screening.
- Third-Party Extensions: Tools like Signifyd or Riskified integrate with Magento for advanced fraud protection.
But if you need more control, a custom solution is the way to go.
Step 1: Setting Up a Custom Module
First, create a new module for your fraud detection system. Here’s how:
app/code/Magefine/CustomFraudDetection/
├── etc/
│ ├── module.xml
│ └── events.xml
├── Model/
│ └── FraudChecker.php
└── registration.php
1. registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Magefine_CustomFraudDetection',
__DIR__
);
2. module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Magefine_CustomFraudDetection" setup_version="1.0.0">
<sequence>
<module name="Magento_Sales"/>
<module name="Magento_Checkout"/>
</sequence>
</module>
</config>
3. events.xml (to trigger fraud checks)
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_order_place_before">
<observer name="magefine_customfraud_check" instance="Magefine\CustomFraudDetection\Model\FraudChecker"/>
</event>
</config>
Step 2: Building the Fraud Detection Logic
Now, let’s create the core fraud detection logic in FraudChecker.php:
<?php
namespace Magefine\CustomFraudDetection\Model;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Magento\Sales\Model\Order;
class FraudChecker implements ObserverInterface
{
public function execute(Observer $observer)
{
$order = $observer->getEvent()->getOrder();
// Example Rule 1: High-Value Orders from New Customers
if ($order->getGrandTotal() > 1000 && $order->getCustomerIsGuest()) {
$order->setState(Order::STATE_HOLDED)
->setStatus(Order::STATE_HOLDED)
->addCommentToStatusHistory("Fraud Check: Suspicious high-value guest order.");
}
// Example Rule 2: Multiple Shipping/Billing Mismatches
if ($order->getBillingAddress()->getPostcode() != $order->getShippingAddress()->getPostcode()) {
$order->setState(Order::STATE_HOLDED)
->setStatus(Order::STATE_HOLDED)
->addCommentToStatusHistory("Fraud Check: Billing/Shipping mismatch detected.");
}
// Add more custom rules as needed
}
}
Step 3: Adding Advanced Fraud Detection Methods
To make your system smarter, consider adding:
1. IP Geolocation Checks
public function checkIPLocation(Order $order)
{
$ip = $order->getRemoteIp();
$geoData = file_get_contents("http://ip-api.com/json/{$ip}");
$geoData = json_decode($geoData);
if ($geoData->country != $order->getBillingAddress()->getCountryId()) {
return true; // Flag as suspicious
}
return false;
}
2. Velocity Checking (Multiple Orders in Short Time)
public function checkOrderVelocity(Order $order)
{
$customerEmail = $order->getCustomerEmail();
$lastHourOrders = $this->orderCollectionFactory->create()
->addFieldToFilter('customer_email', $customerEmail)
->addFieldToFilter('created_at', ['gte' => date('Y-m-d H:i:s', strtotime('-1 hour'))]);
if ($lastHourOrders->count() > 3) {
return true; // Too many orders in short time
}
return false;
}
3. BIN (Bank Identification Number) Validation
public function checkCardBIN(Order $order)
{
$payment = $order->getPayment();
$cardNumber = $payment->getCcNumber();
$firstSix = substr($cardNumber, 0, 6);
$binData = file_get_contents("https://lookup.binlist.net/{$firstSix}");
$binData = json_decode($binData);
if ($binData->country->alpha2 != $order->getBillingAddress()->getCountryId()) {
return true; // Card country doesn't match billing
}
return false;
}
Step 4: Storing Fraud Rules in Database (Optional)
For more flexibility, you can store fraud rules in the database:
CREATE TABLE magefine_fraud_rules (
rule_id INT AUTO_INCREMENT PRIMARY KEY,
rule_name VARCHAR(255),
condition VARCHAR(255),
action VARCHAR(50),
is_active BOOLEAN DEFAULT 1
);
Then modify your FraudChecker to load rules dynamically:
public function execute(Observer $observer)
{
$order = $observer->getEvent()->getOrder();
$rules = $this->fraudRulesFactory->create()->getActiveRules();
foreach ($rules as $rule) {
if (eval($rule->getCondition())) {
$order->setState($rule->getAction())
->addCommentToStatusHistory("Fraud Check: Triggered rule {$rule->getName()}");
}
}
}
Step 5: Testing Your Fraud Detection System
Before going live, test with:
- Legitimate orders (should pass)
- High-risk orders (should flag)
- Edge cases (mixed data)
Use Magento's developer tools to simulate orders or create test payment methods.
Step 6: Monitoring & Improving Over Time
Track effectiveness with:
- Fraud detection rate (how many fraud attempts caught)
- False positive rate (legitimate orders flagged)
- Chargeback rates before/after implementation
Adjust rules based on real data to minimize false positives while catching more fraud.
Final Thoughts
Building a custom fraud detection system in Magento 2 gives you control over security while adapting to your store's unique risks. Start with basic rules, then expand as needed. For stores handling high volumes, consider combining this with third-party services for maximum protection.
Need help implementing this? Check out Magefine's Magento security extensions or optimized Magento hosting for enhanced protection.