2016-01-04 12:49:26 +01:00
|
|
|
<?php
|
|
|
|
if (!defined('_PS_VERSION_'))
|
|
|
|
exit;
|
|
|
|
|
|
|
|
include_once dirname(__FILE__).'/models/FraudCore.php';
|
|
|
|
|
|
|
|
class Fraud extends Module {
|
|
|
|
|
|
|
|
public function __construct() {
|
|
|
|
$this->name = 'fraud';
|
|
|
|
$this->tab = 'payments_gateways';
|
|
|
|
$this->version = 1.0;
|
|
|
|
$this->author = 'Antadis';
|
|
|
|
$this->need_instance = 0;
|
|
|
|
|
|
|
|
parent::__construct();
|
|
|
|
|
|
|
|
$this->displayName = $this->l('Fraud');
|
|
|
|
$this->description = $this->l('Check fraud orders.');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function install() {
|
2017-05-04 11:35:59 +02:00
|
|
|
if(!(parent::install()
|
2016-01-04 12:49:26 +01:00
|
|
|
&& $this->installDB()
|
|
|
|
&& $this->registerHook('adminOrder')
|
|
|
|
&& $this->registerHook('backBeforePayment')
|
|
|
|
&& $this->registerHook('afterChangeStatus'))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function installDB() {
|
|
|
|
return Db::getInstance()->Execute('
|
|
|
|
CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'reputation` (
|
|
|
|
`id_customer` INTEGER UNSIGNED NOT NULL,
|
|
|
|
`ip_address` VARCHAR(15) NOT NULL,
|
|
|
|
`score` INTEGER NOT NULL,
|
|
|
|
`date_upd` DATETIME NOT NULL,
|
|
|
|
PRIMARY KEY (`id_customer`),
|
|
|
|
INDEX (`ip_address`)
|
|
|
|
) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8;
|
|
|
|
') && Db::getInstance()->Execute('
|
|
|
|
CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'reputation_ip` (
|
|
|
|
`ip_address` VARCHAR(15) NOT NULL,
|
|
|
|
PRIMARY KEY (`ip_address`)
|
|
|
|
) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8;
|
|
|
|
') && Db::getInstance()->Execute('
|
|
|
|
CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'order_reputation` (
|
|
|
|
`id_cart` INTEGER NOT NULL,
|
|
|
|
`score` INTEGER NOT NULL,
|
|
|
|
`pass` BOOLEAN NOT NULL,
|
|
|
|
`report` TEXT,
|
|
|
|
PRIMARY KEY (`id_cart`)
|
|
|
|
) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8;
|
|
|
|
');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hookbackBeforePayment($params) {
|
|
|
|
FraudCore::CartFraudConnexion($params['cart']);
|
|
|
|
}
|
2017-05-04 11:35:59 +02:00
|
|
|
|
2016-01-04 12:49:26 +01:00
|
|
|
public function hookAdminOrder($params) {
|
|
|
|
global $currentIndex;
|
|
|
|
|
|
|
|
if (Tools::getIsset('validFraud')) {
|
|
|
|
$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>';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$reputation = FraudCore::getReputationOrder((int) $params['id_order']);
|
|
|
|
if ($reputation) {
|
|
|
|
if ($reputation['score'] >= 100) {
|
|
|
|
$info = json_decode($reputation['report']);
|
|
|
|
$data = '<br />
|
|
|
|
<fieldset style="width: 400px">
|
2017-05-04 11:35:59 +02:00
|
|
|
<p class="alert" style="width:300px">
|
2016-01-04 12:49:26 +01:00
|
|
|
<b>'.$this->l('Suspect Order').'</b>
|
|
|
|
<br />
|
2017-05-04 11:35:59 +02:00
|
|
|
'.$this->l('Score : ').' <strong style="color:red">'.$reputation['score'].'</strong>
|
2016-01-04 12:49:26 +01:00
|
|
|
</p>
|
|
|
|
<h4>'.$this->l('Details : ').'</h4>
|
|
|
|
<p>'.implode('<br />', $info).'</p>';
|
2017-05-04 11:35:59 +02:00
|
|
|
|
2016-01-04 12:49:26 +01:00
|
|
|
if ($reputation['pass'] == 0) {
|
|
|
|
$data .= '<a onclick="if(!confirm(\'Voulez-vous valider la commande ? \')) return false;" href="'.$_SERVER['REQUEST_URI'].'&validFraud=1" class="button">'.$this->l('Valid Order').'</a>';
|
|
|
|
} else {
|
|
|
|
$data .= $this->l('Order validate manually');
|
|
|
|
}
|
|
|
|
$data .= '</fieldset>';
|
|
|
|
echo $data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-04 11:35:59 +02:00
|
|
|
/* This method is called after the response returned by paybox */
|
|
|
|
public function testPaybox($id_order, $ip_country)
|
|
|
|
{
|
|
|
|
$order = new Order($id_order);
|
|
|
|
$authorized = array('ESP','DEU','ITA','NLD','SWE','GBR','PRT','CHE','LUX','POL','AUT','BEL');
|
|
|
|
|
2017-05-04 11:53:47 +02:00
|
|
|
$authorized_ip = array(
|
|
|
|
'88.163.22.99',
|
|
|
|
'90.63.178.63',
|
|
|
|
'217.64.63.215'
|
|
|
|
);
|
|
|
|
if (in_array($_SERVER['REMOTE_ADDR'], $authorized_ip)) {
|
|
|
|
mail('marion@antadis.com', '[BBB] Fraud test', $id_order.' '.$ip_country); // dev
|
|
|
|
}
|
|
|
|
|
2017-05-04 11:35:59 +02:00
|
|
|
if(!in_array($ip_country, $authorized)) {
|
|
|
|
$total_score = 110;
|
|
|
|
$fraud_report = array();
|
|
|
|
$fraud_report[] = 'Pays de paiement hors EU (+110)';
|
|
|
|
|
|
|
|
Db::getInstance()->ExecuteS('
|
|
|
|
INSERT INTO `'._DB_PREFIX_.'order_reputation`
|
|
|
|
VALUES (
|
|
|
|
'.(int) $order->id_cart.',
|
|
|
|
'.(int) $total_score.',
|
|
|
|
'.((int) $total_score < 100? 1: 0).',
|
|
|
|
"'.pSQL(json_encode($fraud_report)).'"
|
|
|
|
)
|
|
|
|
');
|
|
|
|
$this->_changeStatutFraud($order->id);
|
|
|
|
}
|
|
|
|
}
|
2016-01-04 12:49:26 +01:00
|
|
|
|
2016-05-02 15:30:12 +02:00
|
|
|
/* This method is called when a customer use account's paypal on a different address from previously */
|
|
|
|
public function testPaypalBilling($id_order)
|
|
|
|
{
|
|
|
|
$order = new Order($id_order);
|
|
|
|
$id_billing = Db::getInstance()->getValue('
|
|
|
|
SELECT `is_billing`
|
2017-05-04 11:35:59 +02:00
|
|
|
FROM `'._DB_PREFIX_.'paypal_order`
|
2016-05-02 15:30:12 +02:00
|
|
|
WHERE `id_order` = '.(int) $order->id
|
|
|
|
);
|
|
|
|
|
|
|
|
if ($id_billing !=0) {
|
|
|
|
$address = new Address($order->id_address_delivery);
|
|
|
|
$address_paypal = Db::getInstance()->getRow('
|
|
|
|
SELECT `city`, `address`
|
|
|
|
FROM `'._DB_PREFIX_.'paypal_customer_agreement`
|
|
|
|
WHERE id_paypal_agreement = '.(int) $id_billing.'
|
|
|
|
');
|
|
|
|
|
|
|
|
$new_address = false;
|
|
|
|
if ($address->city != $address_paypal['city']) {
|
|
|
|
$new_address = true;
|
|
|
|
} else if ($address->address1 != $address_paypal['address']) {
|
|
|
|
$new_address = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($new_address) {
|
|
|
|
$total_score = 110;
|
|
|
|
$fraud_report = array();
|
|
|
|
$fraud_report[] = 'Compte paypal enregistré utilisé sur une nouvelle adresse (+110)';
|
|
|
|
|
|
|
|
Db::getInstance()->ExecuteS('
|
|
|
|
INSERT INTO `'._DB_PREFIX_.'order_reputation`
|
|
|
|
VALUES (
|
|
|
|
'.(int) $order->id_cart.',
|
|
|
|
'.(int) $total_score.',
|
|
|
|
'.((int) $total_score < 100? 1: 0).',
|
|
|
|
"'.pSQL(json_encode($fraud_report)).'"
|
|
|
|
)
|
|
|
|
');
|
|
|
|
$this->_changeStatutFraud($order->id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-01-04 12:49:26 +01:00
|
|
|
public function hookafterChangeStatus($params) {
|
|
|
|
if($params['newOrderState'] == 2) {
|
|
|
|
$order = new Order($params['order']['id']);
|
|
|
|
if ( Validate::isLoadedObject($order) ) {
|
2017-05-04 11:35:59 +02:00
|
|
|
|
2016-01-04 12:49:26 +01:00
|
|
|
if ($order->module != 'paybox') {
|
|
|
|
return FALSE;
|
|
|
|
}
|
2017-05-04 11:35:59 +02:00
|
|
|
|
2016-01-04 12:49:26 +01:00
|
|
|
// commande déjà test
|
|
|
|
$already_test = Db::getInstance()->getValue('
|
|
|
|
SELECT `id_cart`
|
|
|
|
FROM `ps_order_reputation`
|
|
|
|
WHERE `id_cart` ='.(int)$order->id_cart
|
|
|
|
);
|
|
|
|
if(!empty($already_test)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
$fraud_detection = new FraudCore($order);
|
|
|
|
$fraud_detection->setFraudScore();
|
|
|
|
$fraud_score = $fraud_detection->getFraudScore();
|
|
|
|
$fraud_report = $fraud_detection->getFraudReport();
|
|
|
|
|
2016-05-02 15:30:12 +02:00
|
|
|
$current_reputation = 0;
|
2016-01-04 12:49:26 +01:00
|
|
|
$i = 0;
|
|
|
|
$query = Db::getInstance()->ExecuteS('
|
|
|
|
SELECT *
|
|
|
|
FROM `'._DB_PREFIX_.'reputation`
|
|
|
|
WHERE `id_customer` = '.(int) $order->id_customer);
|
|
|
|
|
|
|
|
if($query && count($query) > 0) {
|
|
|
|
foreach($query as $r) {
|
|
|
|
$current_reputation += $r['score'] - floor((time() - strtotime($r['date_upd'])) / (86400 * 7)) * 20;
|
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
}
|
2017-05-04 11:35:59 +02:00
|
|
|
// paiement ok
|
2016-01-04 12:49:26 +01:00
|
|
|
$reputation_change = 0;
|
|
|
|
if ($i) {
|
|
|
|
$current_reputation = floor($current_reputation / $i);
|
|
|
|
}
|
|
|
|
$final_reputation = max($current_reputation + $reputation_change, 0);
|
|
|
|
$total_score = max($fraud_score, 0) + $final_reputation;
|
2017-05-04 11:35:59 +02:00
|
|
|
|
2016-01-04 12:49:26 +01:00
|
|
|
$cart_info = Db::getInstance()->getRow('
|
2017-05-04 11:35:59 +02:00
|
|
|
SELECT *
|
2016-01-04 12:49:26 +01:00
|
|
|
FROM ps_cart_fraud
|
|
|
|
WHERE id_cart = '. (int)$order->id_cart);
|
|
|
|
|
|
|
|
Db::getInstance()->ExecuteS('
|
|
|
|
INSERT INTO `'._DB_PREFIX_.'order_reputation`
|
|
|
|
VALUES (
|
|
|
|
'.(int) $order->id_cart.',
|
|
|
|
'.(int) $total_score.',
|
|
|
|
'.((int) $total_score < 100? 1: 0).',
|
|
|
|
"'.pSQL(json_encode($fraud_report)).'"
|
|
|
|
)
|
|
|
|
');
|
|
|
|
|
|
|
|
// check fraud score
|
|
|
|
if($total_score < 100) {
|
|
|
|
Db::getInstance()->ExecuteS('
|
|
|
|
INSERT INTO `'._DB_PREFIX_.'reputation`
|
|
|
|
VALUES (
|
|
|
|
'.(int) $order->id_customer.',
|
|
|
|
"'.pSQL($cart_info['ip_cart']).'",
|
|
|
|
0,
|
|
|
|
NOW()
|
|
|
|
)
|
|
|
|
ON DUPLICATE KEY
|
|
|
|
UPDATE
|
|
|
|
`score` = 0,
|
|
|
|
`ip_address` = "'.pSQL(Tools::getRemoteAddr()).'",
|
|
|
|
`date_upd` = NOW()
|
|
|
|
');
|
|
|
|
} else {
|
|
|
|
$reputation_change += 50;
|
|
|
|
Db::getInstance()->ExecuteS('
|
|
|
|
INSERT INTO `'._DB_PREFIX_.'reputation`
|
|
|
|
VALUES (
|
|
|
|
'.(int) $order->id_customer.',
|
|
|
|
"'.pSQL($cart_info['ip_cart']).'",
|
|
|
|
'.(int) $reputation_change.',
|
|
|
|
NOW()
|
|
|
|
)
|
|
|
|
ON DUPLICATE KEY
|
|
|
|
UPDATE
|
|
|
|
`score` = `score` + '.(int) $reputation_change.',
|
|
|
|
`ip_address` = "'.pSQL($cart_info['ip_cart']).'",
|
|
|
|
`date_upd` = NOW()
|
|
|
|
');
|
|
|
|
|
|
|
|
$this->_changeStatutFraud($order->id);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function _changeStatutFraud($order_id) {
|
|
|
|
$history = new OrderHistory();
|
|
|
|
$history->id_order = $order_id;
|
|
|
|
$history->changeIdOrderState(18, $order_id);
|
|
|
|
$history->addWithemail();
|
|
|
|
}
|
|
|
|
}
|