bebeboutik/modules/fraud/fraud.php
Marion Muszynski fff250224a fix testPaxbox
2017-05-04 14:03:15 +02:00

286 lines
8.1 KiB
PHP
Executable File

<?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() {
if(!(parent::install()
&& $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']);
}
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">
<p class="alert" style="width:300px">
<b>'.$this->l('Suspect Order').'</b>
<br />
'.$this->l('Score : ').' <strong style="color:red">'.$reputation['score'].'</strong>
</p>
<h4>'.$this->l('Details : ').'</h4>
<p>'.implode('<br />', $info).'</p>';
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;
}
}
}
/* This method is called after the response returned by paybox */
public function testPaybox($id_order, $ip_country)
{
$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)) {
$total_score = 110;
$fraud_report = array();
$fraud_report[] = 'Pays de paiement hors EU (+110)';
$order_reputation = FraudCore::getReputationOrder((int)$id_order);
if($order_reputation) {
$fraud_report = array_merge($fraud_report, json_decode($order_reputation['report']));
$total_score += (int)$order_reputation['score'];
}
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)).'"
)
ON DUPLICATE KEY UPDATE
`score` = '.(int) $total_score.',
`report` = "'.pSQL(json_encode($fraud_report)).'",
`pass` = '.((int) $total_score < 100? 1: 0).'
');
$this->_changeStatutFraud($order->id);
}
}
/* 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`
FROM `'._DB_PREFIX_.'paypal_order`
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);
}
}
}
public function hookafterChangeStatus($params) {
if($params['newOrderState'] == 2) {
$order = new Order($params['order']['id']);
if ( Validate::isLoadedObject($order) ) {
if ($order->module != 'paybox') {
return FALSE;
}
// 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();
$current_reputation = 0;
$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++;
}
}
// paiement ok
$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;
$cart_info = Db::getInstance()->getRow('
SELECT *
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();
}
}