* @copyright 2007-2014 PrestaShop SA * @license http://addons.prestashop.com/en/content/12-terms-and-conditions-of-use * * International Registered Trademark & Property of PrestaShop SA * */ class AtosValidationModuleFrontController extends ModuleFrontController { /** * @see FrontController::__construct() */ public function __construct() { /* Force HTTP over HTTPS, because Atos doesn't support it * for the automatic response * ¯\_(ツ)_/¯ */ global $useSSL; $useSSL = false; parent::__construct(); } public function initContent() { // Test wether the controller is accessible from outside if (Tools::getValue('ping')) { die($this->ping()); } try { Db::getInstance()->insert( 'atos_validation_events', array( 'created_at' => date("Y-m-d H:i:s"), 'data' => Tools::jsonEncode($_GET + $_POST), ) ); } catch (PrestaShopDatabaseException $e) { $this->logAtosError($e->__toString()); } if (! Tools::getValue('DATA')) { header("HTTP/1.1 400 Bad Request"); echo "DATA parameter is missing"; die(); } $this->processValidation(); } public function ping() { echo "ping"; } private function processValidation() { $result = $this->decryptAtosResponse(); $mailMessage = ''; $orderMessage = ''; $totalPaid = 0; $orderState = _PS_OS_ERROR_; $merchantId = Configuration::get('ATOS_MERCHANT_ID'); $cart = new Cart(); $customer = new Customer(); $currencies = array(1 => '978'); $responseCode = 0; $errorBehavior = (int) Configuration::get('ATOS_ERROR_BEHAVIOR'); $order = new Order(); $orderPayment = new OrderPayment(); if (!count($result) || !isset($result[3]) || !isset($result[6])) { $mailMessage = $this->module->l('Error in atos module : cannot execute response binaries'); $this->sendNotificationMail($mailMessage); $this->logAtosError("Cannot execute response binaries"); header($_SERVER['SERVER_PROTOCOL'].' 500 Internal Server Error', true, 500); echo "Failed to parse DATA parameter"; die(); } if ($result[1] == -1) { $mailMessage = $this->module->l('Error in atos module : '.$result[2]); $this->sendNotificationMail($mailMessage); $this->logAtosError("Atos returned an error : ".$result[2]); header($_SERVER['SERVER_PROTOCOL'].' 500 Internal Server Error', true, 500); echo "Failed to parse DATA parameter"; die(); } $totalPaid = $result[5] / 100; $orderMessage = $this->module->l('Transaction ID:').' '.$result[6].'
'."\n". $this->module->l('Payment mean:').' '.$result[7].'
'."\n". $this->module->l('Payment has began at:').' '.$result[8].'
'."\n". $this->module->l('Payment received at:').' '.$result[10].' '.$result[9].'
'."\n". $this->module->l('Authorization ID:').' '.$result[13].'
'."\n". $this->module->l('Currency:').' '.$result[14].'
'."\n". $this->module->l('Customer IP address:').' '.$result[29].'
'."\n". $this->module->l('Cart ID:').' '.$result[22].'
'."\n\n". $this->module->l('Atos Real Paid:').' '.$totalPaid.'
'."\n\n". $this->module->l('Atos Version:').' '.$this->module->version.'
'."\n"; $orderState = _PS_OS_PAYMENT_; /* Checking whether merchant ID is OK */ if ($result[3] != $merchantId) { $orderState = _PS_OS_ERROR_; $msg = ' ('.$result[3].' '.$this->module->l('should be').' '.$merchantId.')'; $orderMessage .= ''.$this->module->l('Merchant ID is not valid: ').$msg.''."\n"; } /* Checking for currency */ if ($orderState == _PS_OS_PAYMENT_) { $cart = new Cart((int) $result[22]); if (isset($currencies[$cart->id_currency])) { if ($currencies[$cart->id_currency] != Tools::strtoupper($result[14])) { $orderState = _PS_OS_ERROR_; $orderMessage .= ''.$this->module->l('Currency is not the right one (should be ').$currencies[$cart->id_currency].')'."\n"; } } } /* Checking for bank code response */ if ($orderState == _PS_OS_PAYMENT_) { $responseCode = (int) $result[11]; switch ($responseCode) { case 3: $orderMessage .= ''.$this->module->l('Merchand ID is not valid').''."\n"; $orderState = _PS_OS_ERROR_; break; case 5: $orderMessage .= ''.$this->module->l('Bank has rejected payment').''."\n"; $orderState = _PS_OS_ERROR_; break; case 12: case 17: die; case 30: $orderMessage .= ''.$this->module->l('Format error').''."\n"; $orderState = _PS_OS_ERROR_; break; case 34: $orderMessage .= ''.$this->module->l('Bank said that transaction might be fraudulous').''."\n"; $orderState = _PS_OS_ERROR_; break; case 75: $orderMessage .= ''.$this->module->l('Customer has exceeded max tries for its card number').''."\n"; $orderState = _PS_OS_ERROR_; break; case 90: $orderMessage .= ''.$this->module->l('Bank server was unavailable').''."\n"; $orderState = _PS_OS_ERROR_; break; } } $customer = new Customer((int) $cart->id_customer); if ($orderState == _PS_OS_PAYMENT_ || $errorBehavior == 0) { $this->module->validateOrder( (int) $result[22], $orderState, $totalPaid, $this->module->displayName, $orderMessage, array(), null, false, $customer->secure_key ); if (version_compare(_PS_VERSION_, '1.5.0.0') >= '0') { $orderId = Order::getOrderByCartId((int) $result[22]); $order = new Order((int) $orderId); if ($orderState == _PS_OS_PAYMENT_) { $order->valid = 1; $order->save(); } $idOrderPayment = Db::getInstance()->getValue('SELECT id_order_payment FROM `'._DB_PREFIX_.'order_payment` WHERE `order_reference` LIKE \'%'.pSQL($order->reference).'%\''); if ($idOrderPayment == false) { $order->addOrderPayment($totalPaid, null, $result[6]); } else { $orderPayment = new OrderPayment((int) $idOrderPayment); $orderPayment->transaction_id = $result[6]; $orderPayment->save(); } } } elseif ($errorBehavior == 1) { $mailMessage = 'Order: '.$result[22].' / '.$orderMessage; $this->sendNotificationMail($mailMessage); } } private function decryptAtosResponse() { $encryptedData = Tools::getValue('DATA'); $isWin = (Tools::strtoupper(Tools::substr(PHP_OS, 0, 3)) === 'WIN'); $cmd = $this->module->bin_dir.'response'.(((int) $isWin === 1) ? '.exe' : ''); $cmd .= ' pathfile='.$this->module->getPathfilePath(); $cmd .= ' message='.preg_replace('#[^a-z0-9]#Ui', '', $encryptedData); return explode('!', exec($cmd)); } private function logAtosError($logMessage) { if (empty($logMessage)) { return; } if (version_compare(_PS_VERSION_, '1.6.0.3', '>=')) { PrestaShopLogger::addLog( $logMessage, 4, null, 'Atos', isset($this->module->id) ? $this->module->id : null, true ); } else { Logger::addLog( $logMessage, 4, null, 'Atos', isset($this->module->id) ? $this->module->id : null, true ); } } private function sendNotificationMail($message) { if (empty($message)) { return; } Mail::Send( Configuration::get('PS_LANG_DEFAULT'), 'notification', $this->module->l('Atos notification'), array('message' => $message), Configuration::get('ATOS_NOTIFICATION_EMAIL'), null, null, null, null, null, $this->module->getMailsPath() ); } } /* * * .-------.---------------------. * | INDEX | MEANING | * :-------+---------------------: * | 1 | code | * :-------+---------------------: * | 2 | error | * :-------+---------------------: * | 3 | merchant_id | * :-------+---------------------: * | 4 | merchant country | * :-------+---------------------: * | 5 | amount | * :-------+---------------------: * | 6 | transaction_id | * :-------+---------------------: * | 7 | payment_means | * :-------+---------------------: * | 8 | transmission_date | * :-------+---------------------: * | 9 | payment_time | * :-------+---------------------: * | 10 | payment_date | * :-------+---------------------: * | 11 | response_code | * :-------+---------------------: * | 12 | payment_certificate | * :-------+---------------------: * | 13 | authorisation_id | * :-------+---------------------: * | 14 | currency_code | * :-------+---------------------: * | 15 | card_number | * :-------+---------------------: * | 16 | cvv_flag | * :-------+---------------------: * | 17 | cvv_response_code | * :-------+---------------------: * | 18 | bank_response_code | * :-------+---------------------: * | 19 | complementary_code | * :-------+---------------------: * | 20 | complementary_info | * :-------+---------------------: * | 21 | return_context | * :-------+---------------------: * | 22 | caddie | * :-------+---------------------: * | 23 | receipt_complement | * :-------+---------------------: * | 24 | merchant_language | * :-------+---------------------: * | 25 | language | * :-------+---------------------: * | 26 | customer_id | * :-------+---------------------: * | 27 | order_id | * :-------+---------------------: * | 28 | customer_email | * :-------+---------------------: * | 29 | customer_ip_address | * :-------+---------------------: * | 30 | capture_day | * :-------+---------------------: * | 31 | capture_mode | * :-------+---------------------: * | 32 | data | * '-------'---------------------' */