Merge branch 'ticket-14959-fraud' into develop
This commit is contained in:
commit
9c8625b389
@ -202,7 +202,7 @@ abstract class AdminTabCore
|
||||
*
|
||||
* @param mixed $string term or expression in english
|
||||
* @param string $class
|
||||
* @param boolan $addslashes if set to true, the return value will pass through addslashes(). Otherwise, stripslashes().
|
||||
* @param boolean $addslashes if set to true, the return value will pass through addslashes(). Otherwise, stripslashes().
|
||||
* @param boolean $htmlentities if set to true(default), the return value will pass through htmlentities($string, ENT_QUOTES, 'utf-8')
|
||||
* @return string the translation if available, or the english default text.
|
||||
*/
|
||||
@ -227,8 +227,8 @@ abstract class AdminTabCore
|
||||
}
|
||||
|
||||
/**
|
||||
* ajaxDisplay is the default ajax return sytem
|
||||
*
|
||||
* ajaxDisplay is the default ajax return sytem
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function displayAjax()
|
||||
@ -357,7 +357,6 @@ abstract class AdminTabCore
|
||||
{
|
||||
switch ($action)
|
||||
{
|
||||
|
||||
case 'submitAdd1':
|
||||
if (Tools::getValue('submitAdd'.$adminTab->table))
|
||||
$ok_inc = true;
|
||||
@ -452,7 +451,7 @@ abstract class AdminTabCore
|
||||
|
||||
/* Checking for fields validity */
|
||||
foreach ($rules['validate'] AS $field => $function)
|
||||
if (($value = Tools::getValue($field)) !== false AND !empty($value) AND ($field != 'passwd'))
|
||||
if (($value = Tools::getValue($field)) !== false AND !empty($value) AND ($field != 'passwd'))
|
||||
if (!Validate::$function($value))
|
||||
$this->_errors[] = $this->l('the field').' <b>'.call_user_func(array($className, 'displayFieldName'), $field, $className).'</b> '.$this->l('is invalid');
|
||||
|
||||
@ -506,8 +505,8 @@ abstract class AdminTabCore
|
||||
}
|
||||
|
||||
/**
|
||||
* ajaxPreProcess is a method called in ajax-tab.php before displayConf().
|
||||
*
|
||||
* ajaxPreProcess is a method called in ajax-tab.php before displayConf().
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxPreProcess()
|
||||
@ -516,7 +515,7 @@ abstract class AdminTabCore
|
||||
|
||||
/**
|
||||
* ajaxProcess is the default handle method for request with ajax-tab.php
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxProcess()
|
||||
@ -1240,7 +1239,7 @@ abstract class AdminTabCore
|
||||
echo '<form method="post" action="'.$currentIndex;
|
||||
if (Tools::getIsset($this->identifier))
|
||||
echo '&'.$this->identifier.'='.(int)(Tools::getValue($this->identifier));
|
||||
echo '&token='.$token;
|
||||
echo '&token='.$token;
|
||||
if (Tools::getIsset($this->table.'Orderby'))
|
||||
echo '&'.$this->table.'Orderby='.urlencode($this->_orderBy).'&'.$this->table.'Orderway='.urlencode(strtolower($this->_orderWay));
|
||||
echo '#'.$this->table.'" class="form">
|
||||
|
@ -4,9 +4,10 @@ if (!defined('_PS_VERSION_'))
|
||||
|
||||
include_once dirname(__FILE__).'/models/FraudCore.php';
|
||||
|
||||
class Fraud extends Module {
|
||||
|
||||
public function __construct() {
|
||||
class Fraud extends Module
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->name = 'fraud';
|
||||
$this->tab = 'payments_gateways';
|
||||
$this->version = 1.0;
|
||||
@ -19,18 +20,20 @@ class Fraud extends Module {
|
||||
$this->description = $this->l('Check fraud orders.');
|
||||
}
|
||||
|
||||
public function install() {
|
||||
public function install()
|
||||
{
|
||||
if(!(parent::install()
|
||||
&& $this->installDB()
|
||||
&& $this->registerHook('adminOrder')
|
||||
&& $this->registerHook('backBeforePayment')
|
||||
&& $this->registerHook('afterChangeStatus'))) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function installDB() {
|
||||
public function installDB()
|
||||
{
|
||||
return Db::getInstance()->Execute('
|
||||
CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'reputation` (
|
||||
`id_customer` INTEGER UNSIGNED NOT NULL,
|
||||
@ -56,22 +59,29 @@ class Fraud extends Module {
|
||||
');
|
||||
}
|
||||
|
||||
public function hookbackBeforePayment($params) {
|
||||
public function hookbackBeforePayment($params)
|
||||
{
|
||||
FraudCore::CartFraudConnexion($params['cart']);
|
||||
}
|
||||
|
||||
public function hookAdminOrder($params) {
|
||||
|
||||
public function hookAdminOrder($params)
|
||||
{
|
||||
global $currentIndex;
|
||||
|
||||
if (Tools::getIsset('validFraud')) {
|
||||
$token = Tools::getValue('token');
|
||||
$id_order = Tools::getValue('id_order');
|
||||
if (!FraudCore::validOrder($id_order)) {
|
||||
echo '<br /><p class="alert" style="width:300px">'.$this->l('Update impossible').'</p>';
|
||||
} else {
|
||||
echo '<br /><p class="conf">'.$this->l('Valid order with success').'</p>';
|
||||
Tools::redirectAdmin($currentIndex.'&id_order='.$id_order.'&vieworder&hookconf=1&token='.$token);
|
||||
}
|
||||
}
|
||||
|
||||
if (Tools::getIsset('hookconf')) {
|
||||
echo '<br /><p class="conf">'.$this->l('Valid order with success').'</p>';
|
||||
}
|
||||
|
||||
$reputation = FraudCore::getReputationOrder((int) $params['id_order']);
|
||||
if ($reputation) {
|
||||
if ($reputation['score'] >= 100) {
|
||||
@ -97,8 +107,10 @@ class Fraud extends Module {
|
||||
}
|
||||
}
|
||||
|
||||
public function hookAdminOrderNew($params) {
|
||||
public function hookAdminOrderNew($params)
|
||||
{
|
||||
global $currentIndex;
|
||||
|
||||
$data .= '';
|
||||
$reputation = FraudCore::getReputationOrder((int) $params['id_order']);
|
||||
if ($reputation) {
|
||||
@ -110,28 +122,36 @@ class Fraud extends Module {
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="panel-content">';
|
||||
if (Tools::getIsset('validFraud')) {
|
||||
$id_order = Tools::getValue('id_order');
|
||||
if (!FraudCore::validOrder($id_order)) {
|
||||
$data .= '<br /><p class="alert">'.$this->l('Update impossible').'</p>';
|
||||
} else {
|
||||
$data .= '<br /><p class="conf">'.$this->l('Valid order with success').'</p>';
|
||||
}
|
||||
}
|
||||
if ($reputation['score'] >= 100) {
|
||||
$info = json_decode($reputation['report']);
|
||||
$data .= '
|
||||
<a class="btn btn-danger" role="button" data-toggle="collapse" href="#collapseFraudModule">
|
||||
<b>'.$this->l('Score : ').'</b> <span class="badge">'.$reputation['score'].'</span>
|
||||
</a>
|
||||
<div class="collapse" id="collapseFraudModule">
|
||||
<h4>'.$this->l('Details : ').'</h4>
|
||||
<p>'.implode('<br />', $info).'</p>
|
||||
</div>';
|
||||
if ($reputation['pass'] == 0) {
|
||||
$data .= '<a class="pull-right btn btn-primary btn-sm" onclick="if(!confirm(\'Voulez-vous valider la commande ? \')) return false;" href="'.$_SERVER['REQUEST_URI'].'&validFraud=1" class="button">'.$this->l('Valid Order').'</a>';
|
||||
}
|
||||
}
|
||||
|
||||
if (Tools::getIsset('validFraud')) {
|
||||
$token = Tools::getValue('token');
|
||||
$id_order = Tools::getValue('id_order');
|
||||
if (!FraudCore::validOrder($id_order)) {
|
||||
$data .= '<br /><p class="alert">'.$this->l('Update impossible').'</p>';
|
||||
} else {
|
||||
Tools::redirectAdmin($currentIndex.'&id_order='.$id_order.'&vieworder&hookconf=1&token='.$token);
|
||||
}
|
||||
}
|
||||
|
||||
if (Tools::getIsset('hookconf')) {
|
||||
$data .= '<br /><p class="conf">'.$this->l('Valid order with success').'</p>';
|
||||
}
|
||||
|
||||
if ($reputation['score'] >= 100) {
|
||||
$info = json_decode($reputation['report']);
|
||||
$data .= '
|
||||
<a class="btn btn-danger" role="button" data-toggle="collapse" href="#collapseFraudModule">
|
||||
<b>'.$this->l('Score : ').'</b> <span class="badge">'.$reputation['score'].'</span>
|
||||
</a>
|
||||
<div class="collapse" id="collapseFraudModule">
|
||||
<h4>'.$this->l('Details : ').'</h4>
|
||||
<p>'.implode('<br />', $info).'</p>
|
||||
</div>';
|
||||
if ($reputation['pass'] == 0) {
|
||||
$data .= '<a class="pull-right btn btn-primary btn-sm" onclick="if(!confirm(\'Voulez-vous valider la commande ? \')) return false;" href="'.$_SERVER['REQUEST_URI'].'&validFraud=1" class="button">'.$this->l('Valid Order').'</a>';
|
||||
}
|
||||
}
|
||||
|
||||
$data .= '</div>
|
||||
</div>
|
||||
</div>';
|
||||
@ -145,13 +165,13 @@ class Fraud extends Module {
|
||||
$order = new Order($id_order);
|
||||
$authorized = array('FRA','ESP','DEU','ITA','NLD','SWE','GBR','PRT','CHE','LUX','POL','AUT','BEL');
|
||||
|
||||
if(!in_array($ip_country, $authorized)) {
|
||||
if (!in_array($ip_country, $authorized)) {
|
||||
$total_score = 110;
|
||||
$fraud_report = array();
|
||||
$fraud_report[] = 'Pays de paiement hors EU (+110)';
|
||||
|
||||
$order_reputation = FraudCore::getReputationOrder((int)$id_order);
|
||||
if($order_reputation) {
|
||||
if ($order_reputation) {
|
||||
$fraud_report = array_merge($fraud_report, json_decode($order_reputation['report']));
|
||||
$total_score += (int)$order_reputation['score'];
|
||||
}
|
||||
@ -217,11 +237,11 @@ class Fraud extends Module {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function hookafterChangeStatus($params) {
|
||||
if($params['newOrderState'] == 2) {
|
||||
public function hookafterChangeStatus($params)
|
||||
{
|
||||
if ($params['newOrderState'] == 2) {
|
||||
$order = new Order($params['order']['id']);
|
||||
if ( Validate::isLoadedObject($order) ) {
|
||||
if (Validate::isLoadedObject($order)) {
|
||||
|
||||
if ($order->module != 'paybox') {
|
||||
return FALSE;
|
||||
@ -233,7 +253,7 @@ class Fraud extends Module {
|
||||
FROM `ps_order_reputation`
|
||||
WHERE `id_cart` ='.(int)$order->id_cart
|
||||
);
|
||||
if(!empty($already_test)) {
|
||||
if (!empty($already_test)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -249,7 +269,7 @@ class Fraud extends Module {
|
||||
FROM `'._DB_PREFIX_.'reputation`
|
||||
WHERE `id_customer` = '.(int) $order->id_customer);
|
||||
|
||||
if($query && count($query) > 0) {
|
||||
if ($query && count($query) > 0) {
|
||||
foreach($query as $r) {
|
||||
$current_reputation += $r['score'] - floor((time() - strtotime($r['date_upd'])) / (86400 * 7)) * 20;
|
||||
$i++;
|
||||
@ -279,7 +299,7 @@ class Fraud extends Module {
|
||||
');
|
||||
|
||||
// check fraud score
|
||||
if($total_score < 100) {
|
||||
if ($total_score < 100) {
|
||||
Db::getInstance()->ExecuteS('
|
||||
INSERT INTO `'._DB_PREFIX_.'reputation`
|
||||
VALUES (
|
||||
@ -318,7 +338,8 @@ class Fraud extends Module {
|
||||
}
|
||||
}
|
||||
|
||||
private function _changeStatutFraud($order_id) {
|
||||
private function _changeStatutFraud($order_id)
|
||||
{
|
||||
$history = new OrderHistory();
|
||||
$history->id_order = $order_id;
|
||||
$history->changeIdOrderState(18, $order_id);
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
class FraudCore {
|
||||
|
||||
class FraudCore
|
||||
{
|
||||
public $order;
|
||||
public $cart;
|
||||
public $customer;
|
||||
@ -11,8 +11,9 @@ class FraudCore {
|
||||
private $delivery_country;
|
||||
private $invoice_country;
|
||||
|
||||
public function __construct(Order $order) {
|
||||
if( !Validate::isLoadedObject($order) ) {
|
||||
public function __construct(Order $order)
|
||||
{
|
||||
if (!Validate::isLoadedObject($order)) {
|
||||
return false;
|
||||
} else {
|
||||
$this->order = $order;
|
||||
@ -23,7 +24,8 @@ class FraudCore {
|
||||
}
|
||||
}
|
||||
|
||||
public function setFraudScore() {
|
||||
public function setFraudScore()
|
||||
{
|
||||
if( !Validate::isLoadedObject($this->order) ) {
|
||||
throw new Exception("this->order is not an object");
|
||||
return false;
|
||||
@ -37,17 +39,21 @@ class FraudCore {
|
||||
$this->alreadyInFraud();
|
||||
}
|
||||
|
||||
public function getFraudScore() {
|
||||
public function getFraudScore()
|
||||
{
|
||||
return $this->fraud_score;
|
||||
}
|
||||
public function getFraudReport() {
|
||||
|
||||
public function getFraudReport()
|
||||
{
|
||||
return $this->fraud_report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tools fraud
|
||||
**/
|
||||
private function fraudAccount() {
|
||||
private function fraudAccount()
|
||||
{
|
||||
$account_today = time() - strtotime($this->customer->date_add) < 86400;
|
||||
$time_warn = in_array(date('H'), array('23', '00', '01', '02', '03', '04', '05'));
|
||||
$lower_warn = (mb_strtolower($this->customer->firstname) === $this->customer->firstname) && (mb_strtolower($this->customer->lastname) === $this->customer->lastname);
|
||||
@ -62,7 +68,8 @@ class FraudCore {
|
||||
$this->fraud_score = $account_today * 50 + $time_warn * 20 + $lower_warn * 20 + $name_warn * 100;
|
||||
}
|
||||
|
||||
private function fraudAdresses() {
|
||||
private function fraudAdresses()
|
||||
{
|
||||
$this->delivery_country = (int) Db::getInstance()->getValue('
|
||||
SELECT `id_country`
|
||||
FROM `'._DB_PREFIX_.'address`
|
||||
@ -111,7 +118,8 @@ class FraudCore {
|
||||
$this->fraud_score += $foreign_delivery * 50 + $foreign_invoice * 50 + $delivery_warn * 20;
|
||||
}
|
||||
|
||||
private function fraudEmail() {
|
||||
private function fraudEmail()
|
||||
{
|
||||
$freemail_warn = preg_match('/^(.*)@(yahoo|hotmail|gmail|yopmail|mail|mail2web|fastmail|mailinator|jetable|msn)\.(.*)$/i', $this->customer->email);
|
||||
$cctldmail_warn = preg_match('/^(.*)@(.*)\.(cn|cc|in|tw|ru|pl|ua|bg|bj|br|by|ci|dj|dz|eg|et|fj|hk|it|ma|si|tn|zw)$/i', $this->customer->email);
|
||||
|
||||
@ -121,8 +129,8 @@ class FraudCore {
|
||||
$this->fraud_score += $freemail_warn * 20 + $cctldmail_warn * 100;
|
||||
}
|
||||
|
||||
private function fraudConnexion() {
|
||||
|
||||
private function fraudConnexion()
|
||||
{
|
||||
$data = Db::getInstance()->getRow('
|
||||
SELECT *
|
||||
FROM `ps_cart_fraud`
|
||||
@ -141,11 +149,12 @@ class FraudCore {
|
||||
|
||||
$this->fraud_score += $proxy * 20 + $ip_foreign * 200 + $ip_alert * 50 + $freewifi * 50;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function fraudCountData() {
|
||||
$count_addresses = Db::getInstance()->getValue('
|
||||
private function fraudCountData()
|
||||
{
|
||||
// Adresses count
|
||||
$count_addresses = Db::getInstance()->getValue('
|
||||
SELECT COUNT(*)
|
||||
FROM `'._DB_PREFIX_.'address`
|
||||
WHERE `id_customer` = '.(int) $this->customer->id.'
|
||||
@ -156,10 +165,11 @@ class FraudCore {
|
||||
$this->fraud_report[] = 'Compte à plus de 2 adresses (+'.(5 * ((int) $count_addresses - 2)).')';
|
||||
}
|
||||
|
||||
// Orders count last 7 days
|
||||
$count_orders = Db::getInstance()->getRow('
|
||||
SELECT COUNT(*) AS `total`
|
||||
FROM `ps_orders`
|
||||
WHERE `id_customer` = '.(int) $this->customer->id.'
|
||||
WHERE `id_customer` = '.(int)$this->customer->id.'
|
||||
AND `date_add` >= DATE_SUB(NOW(), INTERVAL 7 DAY)
|
||||
');
|
||||
if($count_orders['total'] + 1 > 3) {
|
||||
@ -167,31 +177,53 @@ class FraudCore {
|
||||
$this->fraud_report[] = 'Compte origine de plus de 3 commandes ces 7 derniers jours (+100)';
|
||||
}
|
||||
|
||||
$count_products = Db::getInstance()->getRow('
|
||||
SELECT COUNT(*) AS `total`
|
||||
FROM `ps_cart_product`
|
||||
WHERE `id_cart` = '.(int) $this->cart->id.'
|
||||
');
|
||||
// Products and Total Paid
|
||||
$count_total_paid = $this->cart->getOrderTotal();
|
||||
|
||||
if($count_products['total'] > 7 && $count_total_paid > 250) {
|
||||
$this->fraud_score += 100;
|
||||
$this->fraud_report[] = 'Plus de 7 produits dans le panier et total de plus de 250€ (+100)';
|
||||
if ($count_total_paid > 250) {
|
||||
$count_products = Db::getInstance()->getRow('
|
||||
SELECT COUNT(*) AS `total`
|
||||
FROM `ps_cart_product`
|
||||
WHERE `id_cart` = '.(int)$this->cart->id.'
|
||||
');
|
||||
if ($count_products['total'] > 7) {
|
||||
$this->fraud_score += 100;
|
||||
$this->fraud_report[] = 'Plus de 7 produits dans le panier et total de plus de 250€ (+100)';
|
||||
}
|
||||
}
|
||||
$count_oldorders = Db::getInstance()->getValue('
|
||||
SELECT COUNT(*)
|
||||
FROM `'._DB_PREFIX_.'orders`
|
||||
WHERE `id_customer` = '.(int) $this->customer->id.'
|
||||
AND `valid` = 1
|
||||
AND `date_add` < DATE_SUB(NOW(), INTERVAL 30 DAY)
|
||||
');
|
||||
if($count_oldorders > 3) {
|
||||
$this->fraud_score -= 50;
|
||||
$this->fraud_report[] = 'Compte avec plus de 3 commandes valides de plus de 30 jours (-50)';
|
||||
|
||||
// Orders delivered and valid
|
||||
$count_delivered = Db::getInstance()->getValue('
|
||||
SELECT COUNT(*)
|
||||
FROM `'._DB_PREFIX_.'orders`
|
||||
WHERE `id_customer` = '.(int)$this->customer->id.'
|
||||
AND `valid` = 1 AND `delivery_date` != 0
|
||||
');
|
||||
if ($count_delivered > 10) {
|
||||
$this->fraud_score -= 100;
|
||||
$this->fraud_report[] = 'Compte avec plus de 10 commandes valides expédiées (-100)';
|
||||
}
|
||||
elseif ($count_delivered > 5) {
|
||||
$this->fraud_score -= 50;
|
||||
$this->fraud_report[] = 'Compte avec plus de 5 commandes valides expédiées (-50)';
|
||||
}
|
||||
else {
|
||||
// Old Orders
|
||||
$count_oldorders = Db::getInstance()->getValue('
|
||||
SELECT COUNT(*)
|
||||
FROM `'._DB_PREFIX_.'orders`
|
||||
WHERE `id_customer` = '.(int)$this->customer->id.'
|
||||
AND `valid` = 1
|
||||
AND `date_add` < DATE_SUB(NOW(), INTERVAL 30 DAY)
|
||||
');
|
||||
if($count_oldorders > 3) {
|
||||
$this->fraud_score -= 50;
|
||||
$this->fraud_report[] = 'Compte avec plus de 3 commandes valides de plus de 30 jours (-50)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function fraudInvite() {
|
||||
private function fraudInvite()
|
||||
{
|
||||
$has_order = (bool) (int) Db::getInstance()->getValue('
|
||||
SELECT `id_order`
|
||||
FROM `'._DB_PREFIX_.'orders`
|
||||
@ -282,7 +314,8 @@ class FraudCore {
|
||||
}
|
||||
|
||||
|
||||
public static function getReputationOrder($id_order) {
|
||||
public static function getReputationOrder($id_order)
|
||||
{
|
||||
$id_cart = Order::getCartIdStatic($id_order);
|
||||
return Db::getInstance()->getRow('
|
||||
SELECT *
|
||||
@ -292,7 +325,8 @@ class FraudCore {
|
||||
}
|
||||
|
||||
|
||||
public static function validOrder($id_order) {
|
||||
public static function validOrder($id_order)
|
||||
{
|
||||
$id_cart = Order::getCartIdStatic($id_order);
|
||||
$order = new Order($id_order);
|
||||
|
||||
@ -333,7 +367,8 @@ class FraudCore {
|
||||
}
|
||||
}
|
||||
|
||||
public static function cidr_match($ip, $range) {
|
||||
public static function cidr_match($ip, $range)
|
||||
{
|
||||
list ($subnet, $bits) = explode('/', $range);
|
||||
$ip = ip2long($ip);
|
||||
$subnet = ip2long($subnet);
|
||||
@ -342,9 +377,8 @@ class FraudCore {
|
||||
return ($ip & $mask) == $subnet;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function CartFraudConnexion(Cart $cart) {
|
||||
public static function CartFraudConnexion(Cart $cart)
|
||||
{
|
||||
if (!Validate::isLoadedObject($cart)) {
|
||||
return false;
|
||||
}
|
||||
@ -436,5 +470,4 @@ class FraudCore {
|
||||
`ip_cart` = "'.Tools::getRemoteAddr().'"
|
||||
');
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user