private function _processWebhook()
 {
     $webhook = new \beGateway\Webhook();
     if ($webhook->isAuthorized() && ($webhook->isSuccess() || $webhook->isFailed())) {
         $Status = $webhook->getStatus();
         $Currency = $webhook->getResponse()->transaction->currency;
         $Amount = new \beGateway\Money();
         $Amount->setCurrency($Currency);
         $Amount->setCents($webhook->getResponse()->transaction->amount);
         $TransId = $webhook->getUid();
         $orderno = $webhook->getTrackingId();
         $cart = new Cart((int) $orderno);
         if (!Validate::isLoadedObject($cart)) {
             Logger::addLog($this->l('Webhook: error to load cart'), 4);
             die($this->l('Critical error to load order cart'));
         }
         $customer = new Customer((int) $cart->id_customer);
         if (!Validate::isLoadedObject($customer)) {
             Logger::addLog($this->l('Webhook: error to load customer details'), 4);
             die($this->l('Critical error to load customer'));
         }
         $shop_ptype = trim(Configuration::get('BEGATEWAY_SHOP_PAYTYPE'));
         $payment_status = $webhook->isSuccess() ? Configuration::get('PS_OS_PAYMENT') : Configuration::get('PS_OS_ERROR');
         $this->be_gateway->validateOrder((int) $orderno, $payment_status, $Amount->getAmount(), $this->be_gateway->displayName, $webhook->getMessage(), array('transaction_id' => $TransId), NULL, false, $customer->secure_key);
         $order_new = empty($this->be_gateway->currentOrder) ? $orderno : $this->be_gateway->currentOrder;
         Db::getInstance()->Execute('
     INSERT INTO ' . _DB_PREFIX_ . 'begateway_transaction (type, id_begateway_customer, id_cart, id_order,
       uid, amount, status, currency, date_add)
       VALUES ("' . $shop_ptype . '", ' . $cart->id_customer . ', ' . $orderno . ', ' . $order_new . ', "' . $TransId . '", ' . $Amount->getAmount() . ', "' . $Status . '", "' . $Currency . '", NOW())');
         die('OK');
     }
 }
 private function verifyResponse()
 {
     if (!$this->verified) {
         Logger::addLog('PayPal response NOT verified');
         exit(0);
     }
     $errmsg = '';
     //        if ($_POST['receiver_email'] != $this->paypalEmailAddress) {
     //            $errmsg .= "'receiver_email' does not match: ";
     //            $errmsg .= $_POST['receiver_email']."\n";
     //        }
     if (!empty($errmsg)) {
         throw new Exception("IPN failed fraud checks: \n" . $errmsg . "\n\n");
     }
     switch ($_POST['txn_type']) {
         case TxnType::recurring_payment_profile_created:
             $this->createdNewRecurringProfile();
             break;
         case TxnType::recurring_payment:
             $this->paymentCompletedSuccessfully();
             break;
         case TxnType::recurring_payment_failed:
         case TxnType::recurring_payment_profile_cancel:
             $this->paymentFailedOrCanceled();
             break;
     }
     Logger::addLog($this->listener->getTextReport());
 }
Example #3
0
function fireCurl($data, $url)
{
    $domain = Configuration::get('PS_SHOP_DOMAIN');
    $auth_token = Configuration::get('PS_AUTH_TOKEN');
    Tools::getValue('id_order');
    $data_string = Tools::jsonEncode($data);
    $hash_code = hash_hmac('sha256', $data_string, $auth_token);
    Logger::addLog('Riskified URL is ' . $url, 1);
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $headers = array('Content-Type: application/json', 'Content-Length: ' . Tools::strlen($data_string), 'X_RISKIFIED_SHOP_DOMAIN:' . $domain, 'X_RISKIFIED_HMAC_SHA256:' . $hash_code);
    array_push($headers, 'X_RISKIFIED_SUBMIT_NOW:ok');
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_getinfo($ch);
    $result = curl_exec($ch);
    $decoded_response = Tools::jsonDecode($result);
    $order_id = null;
    $status = null;
    if (!is_null($decoded_response) && isset($decoded_response->order)) {
        $order_id = $decoded_response->order->id;
        $status = $decoded_response->order->status;
        if ($status != 'captured' && $order_id) {
            switch ($status) {
                case 'approved':
                    echo 'Reviewed and approved by Riskified';
                    break;
                case 'declined':
                    echo 'Reviewed and declined by Riskified';
                    break;
                case 'submitted':
                    echo 'Order under review by Riskified';
                    break;
            }
        }
    } else {
        if (!is_null($decoded_response) && isset($decoded_response->error)) {
            $error_message = $decoded_response->error->message;
            Logger::addLog('Error occured when submitting an order to Riskified.');
            echo 'Error: ' . $error_message;
        } else {
            $error_message = print_r($decoded_response, true);
            echo 'Error occured: ' . $error_message;
            Logger::addLog('Error occured when submitting an order to Riskified.');
        }
    }
    die;
}
Example #4
0
 public function initContent()
 {
     $order_id = (int) Tools::getValue('merchantReference');
     Logger::addLog('Adyen module: incoming notification for id_order ' . $order_id);
     if ($this->validateNotificationCredential()) {
         $psp_reference = (string) Tools::getValue('pspReference');
         $event_code = (string) Tools::getValue('eventCode');
         $auth_result = (string) Tools::getValue('authResult');
         $payment_method = (string) Tools::getValue('paymentMethod');
         $success = (string) Tools::getValue('success');
         $event_data = !empty($event_code) ? $event_code : $auth_result;
         // check if notification is already executed on server based on psp_reference and event_code
         if ((int) $order_id > 0 && !$this->isDuplicate($psp_reference, $event_code)) {
             // save notification to table so notification is handled only once
             Db::getInstance()->insert('adyen_event_data', array('psp_reference' => pSQL($psp_reference), 'adyen_event_code' => pSQL($event_code), 'adyen_event_result' => pSQL($event_data), 'id_order' => (int) $order_id, 'payment_method' => pSQL($payment_method), 'created_at' => date('Y-m-d H:i:s')));
             // get the order
             $order = new Order($order_id);
             $history = new OrderHistory();
             $history->id_order = (int) $order->id;
             if (strcmp($success, 'false') == 0 || $success == '' || $event_code == 'CANCELLATION') {
                 // failed if post value success is false or not filled in
                 $history->changeIdOrderState((int) Configuration::get('ADYEN_STATUS_CANCELLED'), (int) $order->id);
                 $history->add();
                 Logger::addLog('Adyen module: status for id_order ' . $order->id . ' is changed to cancelled');
             } else {
                 // if success is not false then check if eventCode is AUTHORISATION so that order status is accepted
                 if ($event_code == 'AUTHORISATION') {
                     $history->changeIdOrderState((int) Configuration::get('ADYEN_STATUS_AUTHORIZED'), (int) $order->id);
                     $history->add();
                     Logger::addLog('Adyen module: status for id_order ' . $order->id . ' is changed to authorized');
                 } else {
                     Logger::addLog('Adyen module: status for id_order ' . $order->id . ' is ' . $event_code . ' and is ignored');
                 }
             }
         } else {
             Logger::addLog('Adyen module: incoming notification ignored because it is already handled for id_order ' . $order_id);
         }
     } else {
         Logger::addLog('Adyen module: invalid credential for incoming notification of id_order ' . $order_id, 4);
         // unauthorized
         header('HTTP/1.1 401 Unauthorized', true, 401);
         exit;
     }
     // always return accepted
     die('[accepted]');
 }
 public function makeRequestSoap($params)
 {
     // Test server url: http://packandship-ws-test.kiala.com/psws-web-1.0.0/order?wsdl
     $client = new SoapClient(Configuration::get('KIALASMALL_WS_URL'), array('trace' => true, 'exceptions' => false));
     $result = $client->createOrder($params);
     if (isset($result->trackingNumber)) {
         return $result->trackingNumber;
     } else {
         // Uncomment for debug mode
         /*
         p('KIALASMALL error - [SOAP]: '.$result->getMessage()
           .' [faultCode]: '.(isset($result->detail->orderFault->faultCode) ? $result->detail->orderFault->faultCode : '')
           .' [message]: '.(isset($result->detail->orderFault->message) ? $result->detail->orderFault->message : '')
         );
         echo htmlentities($client->__getLastRequest());
         die();
         */
         Logger::addLog('KIALASMALL error - [SOAP]: ' . $result->getMessage() . ' [faultCode]: ' . $result->detail->orderFault->faultCode . ' [message]: ' . $result->detail->orderFault->message, 4, 1, null, null, true);
     }
     return false;
 }
Example #6
0
 public function process()
 {
     parent::process();
     $params = $this->initParams();
     $call = new Call();
     try {
         $result = $call->createTransaction($params);
     } catch (Exception $e) {
         //d($e);
     }
     if (isset($result->CreateTransactionResult) && isset($result->CreateTransactionResult->TransportKey) && $result->CreateTransactionResult->TransportKey != '') {
         self::$smarty->assign('formLink', $this->_paymentLink[Configuration::get('MERCHANT_WARE_MODE')]);
         self::$smarty->assign('transportKey', Tools::safeOutput($result->CreateTransactionResult->TransportKey));
     } elseif (isset($result->CreateTransactionResult)) {
         Logger::addLog('Module merchantware: ' . $result->CreateTransactionResult->Messages->Message[0]->Information, 2);
         self::$smarty->assign('error', true);
     } else {
         self::$smarty->assign('error', true);
         Logger::addLog('Module merchantware: no message returned', 2);
     }
 }
Example #7
0
 /**
  * Display a warning message indicating that the parameter is deprecated
  */
 public static function displayParameterAsDeprecated($parameter)
 {
     if (_PS_DISPLAY_COMPATIBILITY_WARNING_) {
         $backtrace = debug_backtrace();
         $callee = next($backtrace);
         trigger_error('Parameter <strong>' . $parameter . '</strong> in function <strong>' . $callee['function'] . '()</strong> is deprecated in <strong>' . $callee['file'] . '</strong> on line <strong>' . $callee['Line'] . '</strong><br />', E_USER_WARNING);
         $message = Tools::displayError('The parameter') . ' ' . $parameter . ' ' . Tools::displayError(' in function ') . ' ' . $callee['function'] . ' (' . Tools::displayError('Line') . ' ' . $callee['Line'] . ') ' . Tools::displayError('is deprecated and will be removed in the next major version.');
         Logger::addLog($message, 3, $callee['class']);
     }
 }
Example #8
0
}
/* Do the CURL request ro Authorize.net */
$request = curl_init($url);
curl_setopt($request, CURLOPT_HEADER, 0);
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($request, CURLOPT_POSTFIELDS, $postString);
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE);
$postResponse = curl_exec($request);
curl_close($request);
$response = explode('|', $postResponse);
if (!isset($response[7]) || !isset($response[3]) || !isset($response[9])) {
    $msg = 'Authorize.net returned a malformed response for cart';
    if (isset($response[7])) {
        $msg .= ' ' . (int) $response[7];
    }
    Logger::addLog($msg, 4);
    die('Authorize.net returned a malformed response, aborted.');
}
$message = $response[3];
$payment_method = 'Authorize.net AIM';
switch ($response[0]) {
    case 1:
        // Payment accepted
        $authorizeaim->setTransactionDetail($response);
        $authorizeaim->validateOrder((int) $cart->id, Configuration::get('PS_OS_PAYMENT'), (double) $response[9], $payment_method, $message, NULL, NULL, false, $customer->secure_key);
        break;
    case 4:
        // Hold for review
        $authorizeaim->validateOrder((int) $cart->id, Configuration::get('AUTHORIZE_AIM_HOLD_REVIEW_OS'), (double) $response[9], $authorizeaim->displayName, $response[3], NULL, NULL, false, $customer->secure_key);
        break;
    default:
Example #9
0
 /**
  * @return string
  */
 public function hookDisplayPayment()
 {
     if (!Currency::exists('EUR', 0)) {
         return '<p class="payment_module" style="color:red;">' . $this->l('Mollie Payment Methods are only available when Euros are activated.') . '</p>';
     }
     $issuer_setting = $this->getConfigValue('MOLLIE_ISSUERS');
     try {
         $methods = $this->api->methods->all();
         $issuer_list = in_array($issuer_setting, array(self::ISSUERS_ALWAYS_VISIBLE, self::ISSUERS_ON_CLICK)) ? $this->_getIssuerList() : array();
     } catch (Mollie_API_Exception $e) {
         $methods = array();
         $issuer_list = array();
         if ($this->getConfigValue('MOLLIE_DEBUG_LOG') == self::DEBUG_LOG_ERRORS) {
             Logger::addLog(__METHOD__ . ' said: ' . $e->getMessage(), Mollie::ERROR);
         }
         if ($this->getConfigValue('MOLLIE_DISPLAY_ERRORS')) {
             return '<p class="payment_module" style="color:red;">' . $e->getMessage() . '</p>';
         }
     }
     $this->smarty->assign(array('methods' => $methods, 'issuers' => $issuer_list, 'issuer_setting' => $issuer_setting, 'images' => $this->getConfigValue('MOLLIE_IMAGES'), 'warning' => $this->warning, 'msg_pay_with' => $this->lang['Pay with %s'], 'msg_bankselect' => $this->lang['Select your bank:'], 'module' => $this));
     return $this->display(__FILE__, 'mollie_methods.tpl');
 }
 public function hookPaymentReturn($params)
 {
     if (!$this->active) {
         return;
     }
     $order = $params['objOrder'];
     $state = $order->getCurrentState();
     if ($state == _PS_OS_ERROR_) {
         $status = 'callback';
         $msg = 'SimplePay: Confirmation failed';
         Logger::addLog($msg, 2, 0, 'Order', $order->id);
     } else {
         $status = 'ok';
     }
     $this->smarty->assign('status', $status);
     return $this->display(__FILE__, 'views/templates/hook/confirmation.tpl');
 }
Example #11
0
 /**
  * @param array $data
  * @return Mollie_API_Object_Payment|null
  */
 protected function _createPayment($data)
 {
     $payment = null;
     if ($this->module->getConfigValue('MOLLIE_USE_PROFILE_WEBHOOK')) {
         unset($data['webhookUrl']);
     }
     try {
         /** @var Mollie_API_Object_Payment $payment */
         $payment = $this->module->api->payments->create($data);
     } catch (Mollie_API_Exception $e) {
         try {
             if ($e->getField() == "webhookUrl") {
                 if ($this->module->getConfigValue('MOLLIE_DEBUG_LOG') == Mollie::DEBUG_LOG_ERRORS) {
                     Logger::addLog(__METHOD__ . ' said: Could not reach generated webhook url, falling back to profile webhook url.', Mollie::WARNING);
                 }
                 unset($data['webhookUrl']);
                 $payment = $this->module->api->payments->create($data);
             } else {
                 throw $e;
             }
         } catch (Mollie_API_Exception $e) {
             if ($this->module->getConfigValue('MOLLIE_DEBUG_LOG') == Mollie::DEBUG_LOG_ERRORS) {
                 Logger::addLog(__METHOD__ . ' said: ' . $e->getMessage(), Mollie::CRASH);
             }
             if ($this->module->getConfigValue('MOLLIE_DISPLAY_ERRORS')) {
                 die($this->module->lang['There was an error while processing your request: '] . '<br /><i>' . $e->getMessage() . '</i><br /><br />' . '<a href="' . _PS_BASE_URL_ . __PS_BASE_URI__ . '">' . $this->module->lang['Click here to continue'] . '</a>.');
             } else {
                 Tools::redirect(_PS_BASE_URL_ . __PS_BASE_URI__);
             }
         }
     }
     return $payment;
 }
function updateTracking($static = false, $idShop = 0, $idGroupShop = 0)
{
    $api = new ShipwireTracking();
    $api->retrieveFull();
    $d = $api->sendData();
    if ($d['Status']) {
        if ($static) {
            return false;
        } else {
            die('KO');
        }
    }
    if ($d['TotalOrders'] > 0) {
        foreach ($d['Order'] as $order) {
            $o = array();
            if (isset($order['@attributes'])) {
                $o = $order['@attributes'];
            }
            if (!isset($o['id'])) {
                Logger::addLog('Shipwire: Order ID not defined. >>>>' . print_r($d, true) . '<<<<', 4);
                continue;
            }
            $orderExists = Db::getInstance()->ExecuteS('SELECT `id_order`
				FROM `' . _DB_PREFIX_ . 'shipwire_order`
				WHERE `id_order` = ' . (int) $o['id'] . ' LIMIT 1');
            if (isset($orderExists[0]['id_order']) && !empty($orderExists[0]['id_order'])) {
                Db::getInstance()->Execute('UPDATE `' . _DB_PREFIX_ . 'shipwire_order` SET ' . (isset($order['TrackingNumber']) ? '`tracking_number` = \'' . pSQL($order['TrackingNumber']) . '\',' : '') . (isset($o['shipped']) ? '`shipped` = \'' . pSQL($o['shipped']) . '\'' : '') . (isset($o['shipper']) ? ',`shipper` = \'' . pSQL($o['shipper']) . '\'' : '') . (isset($o['shipDate']) ? ',`shipDate` = \'' . pSQL($o['shipDate']) . '\'' : '') . (isset($o['expectedDeliveryDate']) ? ',`expectedDeliveryDate` = \'' . pSQL($o['expectedDeliveryDate']) . '\'' : '') . (isset($o['href']) ? ',`href` = \'' . pSQL($o['href']) . '\'' : '') . (isset($o['shipperFullName']) ? ',`shipperFullName` = \'' . pSQL($o['shipperFullName']) . '\'' : '') . ' WHERE `id_order` = ' . (int) $o['id']);
            } else {
                Db::getInstance()->Execute('INSERT INTO `' . _DB_PREFIX_ . 'shipwire_order`
				(`id_order`, `id_shop`, `id_group_shop`, `tracking_number`, `shipped`, `shipper`, `shipDate`, `expectedDeliveryDate`, `href`, `shipperFullName`)
				VALUES (
				\'' . pSQL($o['id']) . '\'' . ',' . (int) $idShop . ',' . (int) $idGroupShop . (isset($order['TrackingNumber']) ? ',\'' . pSQL($order['TrackingNumber']) . '\'' : ',\'\'') . (isset($o['shipped']) ? ',\'' . pSQL($o['shipped']) . '\'' : ',\'\'') . (isset($o['shipper']) ? ',\'' . pSQL($o['shipper']) . '\'' : ',\'\'') . (isset($o['shipDate']) ? ',\'' . pSQL($o['shipDate']) . '\'' : ',\'\'') . (isset($o['expectedDeliveryDate']) ? ',\'' . pSQL($o['expectedDeliveryDate']) . '\'' : ',\'\'') . (isset($o['href']) ? ',\'' . pSQL($o['href']) . '\'' : ',\'\'') . (isset($o['shipperFullName']) ? ',\'' . pSQL($o['shipperFullName']) . '\'' : ',\'\'') . ')');
            }
            $result = Db::getInstance()->getValue('SELECT `transaction_ref`
				FROM `' . _DB_PREFIX_ . 'shipwire_order`
				WHERE `id_order` = ' . (int) $o['id']);
            if (empty($result)) {
                $module = new Shipwire();
                $module->updateOrderStatus((int) $o['id'], true);
            }
            if (isset($order['TrackingNumber'])) {
                Db::getInstance()->Execute('UPDATE `' . _DB_PREFIX_ . 'orders`
										SET `shipping_number` = \'' . pSQL($order['TrackingNumber']) . '\'
										WHERE `id_order` = ' . (int) $o['id']);
                if ($o['id']) {
                    $psOrder = new Order($o['id']);
                    if ($psOrder->id) {
                        $history = new OrderHistory();
                        $history->id_order = $o['id'];
                        if (isset($o['shipped']) && $o['shipped'] == 'YES') {
                            $history->changeIdOrderState(Configuration::get('SHIPWIRE_SENT_ID'), $o['id']);
                        }
                        $history->addWithemail();
                    }
                }
            }
        }
    }
    if (Configuration::get('PS_CIPHER_ALGORITHM')) {
        $cipherTool = new Rijndael(_RIJNDAEL_KEY_, _RIJNDAEL_IV_);
    } else {
        $cipherTool = new Blowfish(_COOKIE_KEY_, _COOKIE_IV_);
    }
    $shipWireInventoryUpdate = new ShipwireInventoryUpdate(Configuration::get('SHIPWIRE_API_USER'), $cipherTool->decrypt(Configuration::get('SHIPWIRE_API_PASSWD')));
    $shipWireInventoryUpdate->getInventory();
    if ($static) {
        return true;
    } else {
        die('OK');
    }
}
    /**
     * Process a payment
     *
     * @param string $token Stripe Transaction ID (token)
     */
    public function processPayment($token)
    {
        /* If 1.4 and no backward, then leave */
        if (!$this->backward) {
            return;
        }
        include dirname(__FILE__) . '/lib/Stripe.php';
        Stripe::setApiKey(Configuration::get('STRIPE_MODE') ? Configuration::get('STRIPE_PRIVATE_KEY_LIVE') : Configuration::get('STRIPE_PRIVATE_KEY_TEST'));
        /* Case 1: Charge an existing customer (or create it and charge it) */
        /* Case 2: Just process the transaction, do not save Stripe customer's details */
        if (Configuration::get('STRIPE_SAVE_TOKENS') && !Configuration::get('STRIPE_SAVE_TOKENS_ASK') || Configuration::get('STRIPE_SAVE_TOKENS') && Configuration::get('STRIPE_SAVE_TOKENS_ASK') && Tools::getIsset('stripe_save_token') && Tools::getValue('stripe_save_token')) {
            /* Get or Create a Stripe Customer */
            $stripe_customer = Db::getInstance()->getRow('
			SELECT id_stripe_customer, stripe_customer_id, token
			FROM ' . _DB_PREFIX_ . 'stripe_customer
			WHERE id_customer = ' . (int) $this->context->cookie->id_customer);
            if (!isset($stripe_customer['id_stripe_customer'])) {
                try {
                    $stripe_customer_exists = false;
                    $customer_stripe = Stripe_Customer::create(array('card' => $token, 'description' => $this->l('PrestaShop Customer ID:') . ' ' . (int) $this->context->cookie->id_customer));
                    $stripe_customer['stripe_customer_id'] = $customer_stripe->id;
                } catch (Exception $e) {
                    /* If the Credit card is invalid */
                    $this->_errors['invalid_customer_card'] = true;
                    if (class_exists('Logger')) {
                        Logger::addLog($this->l('Stripe - Invalid Credit Card'), 1, null, 'Cart', (int) $this->context->cart->id, true);
                    }
                }
            } else {
                $stripe_customer_exists = true;
                /* Update the credit card in the database */
                if ($token && $token != $stripe_customer['token']) {
                    try {
                        $cu = Stripe_Customer::retrieve($stripe_customer['stripe_customer_id']);
                        $cu->card = $token;
                        $cu->save();
                        Db::getInstance()->Execute('UPDATE ' . _DB_PREFIX_ . 'stripe_customer SET token = \'' . pSQL($token) . '\' WHERE id_customer_stripe = ' . (int) $stripe_customer['id_stripe_customer']);
                    } catch (Exception $e) {
                        /* If the new Credit card is invalid, do not replace the old one - no warning or error message required */
                        $this->_errors['invalid_customer_card'] = true;
                        if (class_exists('Logger')) {
                            Logger::addLog($this->l('Stripe - Invalid Credit Card (replacing an old card)'), 1, null, 'Cart', (int) $this->context->cart->id, true);
                        }
                    }
                }
            }
        }
        try {
            $charge_details = array('amount' => $this->context->cart->getOrderTotal() * 100, 'currency' => $this->context->currency->iso_code, 'description' => $this->l('PrestaShop Customer ID:') . ' ' . (int) $this->context->cookie->id_customer . ' - ' . $this->l('PrestaShop Cart ID:') . ' ' . (int) $this->context->cart->id);
            /* If we have a Stripe's customer ID for this buyer, charge the customer instead of the card */
            if (isset($stripe_customer['stripe_customer_id']) && !isset($this->_errors['invalid_customer_card'])) {
                $charge_details['customer'] = $stripe_customer['stripe_customer_id'];
            } else {
                $charge_details['card'] = $token;
            }
            $result_json = Tools::jsonDecode(Stripe_Charge::create($charge_details));
            /* Save the Customer ID in PrestaShop to re-use it later */
            if (isset($stripe_customer_exists) && !$stripe_customer_exists) {
                Db::getInstance()->Execute('
				INSERT INTO ' . _DB_PREFIX_ . 'stripe_customer (id_stripe_customer, stripe_customer_id, token, id_customer, cc_last_digits, date_add)
				VALUES (NULL, \'' . pSQL($stripe_customer['stripe_customer_id']) . '\', \'' . pSQL($token) . '\', ' . (int) $this->context->cookie->id_customer . ', ' . (int) Tools::substr(Tools::getValue('StripLastDigits'), 0, 4) . ', NOW())');
            }
            // catch the stripe error the correct way.
        } catch (Stripe_CardError $e) {
            $body = $e->getJsonBody();
            $err = $body['error'];
            //$type = $err['type'];
            $message = $err['message'];
            //$code = $err['code'];
            //$charge = $err['charge'];
            if (class_exists('Logger')) {
                Logger::addLog($this->l('Stripe - Payment transaction failed') . ' ' . $message, 1, null, 'Cart', (int) $this->context->cart->id, true);
            }
            $this->context->cookie->__set("stripe_error", 'There was a problem with your payment');
            $controller = Configuration::get('PS_ORDER_PROCESS_TYPE') ? 'order-opc.php' : 'order.php';
            $location = $this->context->link->getPageLink($controller) . (strpos($controller, '?') !== false ? '&' : '?') . 'step=3#stripe_error';
            header('Location: ' . $location);
            exit;
        } catch (Exception $e) {
            $message = $e->getMessage();
            if (class_exists('Logger')) {
                Logger::addLog($this->l('Stripe - Payment transaction failed') . ' ' . $message, 1, null, 'Cart', (int) $this->context->cart->id, true);
            }
            /* If it's not a critical error, display the payment form again */
            if ($e->getCode() != 'card_declined') {
                $this->context->cookie->__set("stripe_error", $e->getMessage());
                $controller = Configuration::get('PS_ORDER_PROCESS_TYPE') ? 'order-opc.php' : 'order.php';
                header('Location: ' . $this->context->link->getPageLink($controller) . (strpos($controller, '?') !== false ? '&' : '?') . 'step=3#stripe_error');
                exit;
            }
        }
        /* Log Transaction details */
        if (!isset($message)) {
            if (!isset($result_json->fee)) {
                $result_json->fee = 0;
            }
            $order_status = (int) Configuration::get('STRIPE_PAYMENT_ORDER_STATUS');
            $message = $this->l('Stripe Transaction Details:') . "\n\n" . $this->l('Stripe Transaction ID:') . ' ' . $result_json->id . "\n" . $this->l('Amount:') . ' ' . $result_json->amount * 0.01 . "\n" . $this->l('Status:') . ' ' . ($result_json->paid == 'true' ? $this->l('Paid') : $this->l('Unpaid')) . "\n" . $this->l('Processed on:') . ' ' . strftime('%Y-%m-%d %H:%M:%S', $result_json->created) . "\n" . $this->l('Currency:') . ' ' . Tools::strtoupper($result_json->currency) . "\n" . $this->l('Credit card:') . ' ' . $result_json->card->type . ' (' . $this->l('Exp.:') . ' ' . $result_json->card->exp_month . '/' . $result_json->card->exp_year . ')' . "\n" . $this->l('Last 4 digits:') . ' ' . sprintf('%04d', $result_json->card->last4) . ' (' . $this->l('CVC Check:') . ' ' . ($result_json->card->cvc_check == 'pass' ? $this->l('OK') : $this->l('NOT OK')) . ')' . "\n" . $this->l('Processing Fee:') . ' ' . $result_json->fee * 0.01 . "\n" . $this->l('Mode:') . ' ' . ($result_json->livemode == 'true' ? $this->l('Live') : $this->l('Test')) . "\n";
            /* In case of successful payment, the address / zip-code can however fail */
            if (isset($result_json->card->address_line1_check) && $result_json->card->address_line1_check == 'fail') {
                $message .= "\n" . $this->l('Warning: Address line 1 check failed');
                $order_status = (int) Configuration::get('STRIPE_PENDING_ORDER_STATUS');
            }
            if (isset($result_json->card->address_zip_check) && $result_json->card->address_zip_check == 'fail') {
                $message .= "\n" . $this->l('Warning: Address zip-code check failed');
                $order_status = (int) Configuration::get('STRIPE_PENDING_ORDER_STATUS');
            }
            // warn if cvc check fails
            if (isset($result_json->card->cvc_check) && $result_json->card->cvc_check == 'fail') {
                $message .= "\n" . $this->l('Warning: CVC verification check failed');
                $order_status = (int) Configuration::get('STRIPE_PENDING_ORDER_STATUS');
            }
        } else {
            $order_status = (int) Configuration::get('PS_OS_ERROR');
        }
        /* Create the PrestaShop order in database */
        $this->validateOrder((int) $this->context->cart->id, (int) $order_status, $result_json->amount * 0.01, $this->displayName, $message, array(), null, false, $this->context->customer->secure_key);
        /** @since 1.5.0 Attach the Stripe Transaction ID to this Order */
        if (version_compare(_PS_VERSION_, '1.5', '>=')) {
            $new_order = new Order((int) $this->currentOrder);
            if (Validate::isLoadedObject($new_order)) {
                $payment = $new_order->getOrderPaymentCollection();
                if (isset($payment[0])) {
                    $payment[0]->transaction_id = pSQL($result_json->id);
                    $payment[0]->save();
                }
            }
        }
        /* Store the transaction details */
        if (isset($result_json->id)) {
            Db::getInstance()->Execute('
			INSERT INTO ' . _DB_PREFIX_ . 'stripe_transaction (type, id_stripe_customer, id_cart, id_order,
			id_transaction, amount, status, currency, cc_type, cc_exp, cc_last_digits, cvc_check, fee, mode, date_add)
			VALUES (\'payment\', ' . (isset($stripe_customer['id_stripe_customer']) ? (int) $stripe_customer['id_stripe_customer'] : 0) . ', ' . (int) $this->context->cart->id . ', ' . (int) $this->currentOrder . ', \'' . pSQL($result_json->id) . '\',
			\'' . $result_json->amount * 0.01 . '\', \'' . ($result_json->paid == 'true' ? 'paid' : 'unpaid') . '\', \'' . pSQL($result_json->currency) . '\',
			\'' . pSQL($result_json->card->type) . '\', \'' . (int) $result_json->card->exp_month . '/' . (int) $result_json->card->exp_year . '\', ' . (int) $result_json->card->last4 . ',
			' . ($result_json->card->cvc_check == 'pass' ? 1 : 0) . ', \'' . $result_json->fee * 0.01 . '\', \'' . ($result_json->livemode == 'true' ? 'live' : 'test') . '\', NOW())');
        }
        /* Redirect the user to the order confirmation page / history */
        if (_PS_VERSION_ < 1.5) {
            $redirect = __PS_BASE_URI__ . 'order-confirmation.php?id_cart=' . (int) $this->context->cart->id . '&id_module=' . (int) $this->id . '&id_order=' . (int) $this->currentOrder . '&key=' . $this->context->customer->secure_key;
        } else {
            $redirect = __PS_BASE_URI__ . 'index.php?controller=order-confirmation&id_cart=' . (int) $this->context->cart->id . '&id_module=' . (int) $this->id . '&id_order=' . (int) $this->currentOrder . '&key=' . $this->context->customer->secure_key;
        }
        header('Location: ' . $redirect);
        exit;
    }
    Logger::addLog('Missing x_invoice_num', 4);
    die('An unrecoverable error occured: Missing parameter');
}
if (!Validate::isLoadedObject($cart)) {
    Logger::addLog('Cart loading failed for cart ' . (int) $_POST['x_invoice_num'], 4);
    die('An unrecoverable error occured with the cart ' . (int) $_POST['x_invoice_num']);
}
if ($cart->id != $_POST['x_invoice_num']) {
    Logger::addLog('Conflict between cart id order and customer cart id');
    die('An unrecoverable conflict error occured with the cart ' . (int) $_POST['x_invoice_num']);
}
$customer = new Customer((int) $cart->id_customer);
$invoiceAddress = new Address((int) $cart->id_address_invoice);
$currency = new Currency((int) $cart->id_currency);
if (!Validate::isLoadedObject($customer) || !Validate::isLoadedObject($invoiceAddress) && !Validate::isLoadedObject($currency)) {
    Logger::addLog('Issue loading customer, address and/or currency data');
    die('An unrecoverable error occured while retrieving you data');
}
if (Tools::safeOutput(Configuration::get('PAYFORT_START_TEST_MODE'))) {
    $start_payments_secret_api = Tools::safeOutput(Configuration::get('PAYFORT_START_TEST_SECRET_KEY'));
} else {
    $start_payments_secret_api = Tools::safeOutput(Configuration::get('PAYFORT_START_LIVE_SECRET_KEY'));
}
if (Tools::safeOutput(Configuration::get('PAYFORT_START_CAPTURE'))) {
    $capture = 0;
} else {
    $capture = 1;
}
$order_description = "Charge for order";
$order_id = $_POST['x_invoice_num'];
$email = $_POST['payment_email'];
Example #15
0
 /**
  * Display a warning message indicating that the parameter is deprecated
  * (display in firefox console if Firephp is enabled)
  */
 public static function displayParameterAsDeprecated($parameter)
 {
     if (_PS_DISPLAY_COMPATIBILITY_WARNING_) {
         $backtrace = debug_backtrace();
         $callee = next($backtrace);
         trigger_error('Parameter <strong>' . $parameter . '</strong> in function <strong>' . $callee['function'] . '()</strong> is deprecated in <strong>' . $callee['file'] . '</strong> on line <strong>' . $callee['Line'] . '</strong><br />', E_USER_WARNING);
         if (PS_USE_FIREPHP) {
             FB::trace('Parameter <strong>' . $parameter . '</strong> in function <strong>' . $callee['function'] . '()</strong> is deprecated in <strong>' . $callee['file'] . '</strong> on line <strong>' . $callee['Line'] . '</strong><br />', 'deprecated parameter');
         } else {
             $message = sprintf(Tools::displayError('The parameter %1$s in function %2$s (Line %3$s) is deprecated and will be removed in the next major version.'), $parameter, $callee['function'], $callee['Line']);
         }
         Logger::addLog($message, 3, $callee['class']);
     }
 }
Example #16
0
 /**
  * Transforms euro prices from mollie back to the currency of the Cart (order)
  * @param float $amount in euros
  * @param int $cart_id
  * @return float in the currency of the cart
  */
 protected function _convertEuroToCartCurrency($amount, $cart_id)
 {
     $cart = new Cart($cart_id);
     $currency_euro = Currency::getIdByIsoCode('EUR');
     if (!$currency_euro) {
         // No Euro currency available!
         if ($this->module->getConfigValue('MOLLIE_DEBUG_LOG') == Mollie::DEBUG_LOG_ERRORS) {
             Logger::addLog(__METHOD__ . ' said: In order to use this module, you need to enable Euros as currency. Cart ID: ' . $cart_id, Mollie::CRASH);
         }
         die($this->module->lang['This payment method is only available for Euros.']);
     }
     if ($cart->id_currency !== $currency_euro) {
         // Convert euro currency to cart currency
         $amount = Tools::convertPriceFull($amount, Currency::getCurrencyInstance($currency_euro), Currency::getCurrencyInstance($cart->id_currency));
     }
     return round($amount, 2);
 }
    public function postProcess()
    {
        /* PrestaShop demo mode */
        if (_PS_MODE_DEMO_) {
            $this->errors[] = Tools::displayError('This functionality has been disabled.');
            return;
        }
        /* PrestaShop demo mode*/
        if (Tools::isSubmit('submitFileUpload')) {
            if (isset($_FILES['file']) && !empty($_FILES['file']['error'])) {
                switch ($_FILES['file']['error']) {
                    case UPLOAD_ERR_INI_SIZE:
                        $this->errors[] = Tools::displayError('The uploaded file exceeds the upload_max_filesize directive in php.ini. If your server configuration allows it, you may add a directive in your .htaccess.');
                        break;
                    case UPLOAD_ERR_FORM_SIZE:
                        $this->errors[] = Tools::displayError('The uploaded file exceeds the post_max_size directive in php.ini.
							If your server configuration allows it, you may add a directive in your .htaccess, for example:') . '<br/><a href="' . $this->context->link->getAdminLink('AdminMeta') . '" >
						<code>php_value post_max_size 20M</code> ' . Tools::displayError('(click to open "Generators" page)') . '</a>';
                        break;
                        break;
                    case UPLOAD_ERR_PARTIAL:
                        $this->errors[] = Tools::displayError('The uploaded file was only partially uploaded.');
                        break;
                        break;
                    case UPLOAD_ERR_NO_FILE:
                        $this->errors[] = Tools::displayError('No file was uploaded.');
                        break;
                        break;
                }
            } else {
                if (!file_exists($_FILES['file']['tmp_name']) || !@move_uploaded_file($_FILES['file']['tmp_name'], _PS_ADMIN_DIR_ . '/import/' . date('Ymdhis') . '-' . $_FILES['file']['name'])) {
                    $this->errors[] = $this->l('An error occurred while uploading / copying the file.');
                } else {
                    Tools::redirectAdmin(self::$currentIndex . '&token=' . Tools::getValue('token') . '&conf=18');
                }
            }
        } else {
            if (Tools::getValue('import')) {
                // Check if the CSV file exist
                if (Tools::getValue('csv')) {
                    // If i am a superadmin, i can truncate table
                    if ((Shop::isFeatureActive() && $this->context->employee->isSuperAdmin() || !Shop::isFeatureActive()) && Tools::getValue('truncate')) {
                        $this->truncateTables((int) Tools::getValue('entity'));
                    }
                    $import_type = false;
                    switch ((int) Tools::getValue('entity')) {
                        case $this->entities[$import_type = $this->l('Categories')]:
                            $this->categoryImport();
                            $this->clearSmartyCache();
                            break;
                        case $this->entities[$import_type = $this->l('Products')]:
                            $import_type = $this->l('Categories');
                            $this->productImport();
                            $this->clearSmartyCache();
                            break;
                        case $this->entities[$import_type = $this->l('Customers')]:
                            $this->customerImport();
                            break;
                        case $this->entities[$import_type = $this->l('Addresses')]:
                            $this->addressImport();
                            break;
                        case $this->entities[$import_type = $this->l('Combinations')]:
                            $this->attributeImport();
                            $this->clearSmartyCache();
                            break;
                        case $this->entities[$import_type = $this->l('Manufacturers')]:
                            $this->manufacturerImport();
                            $this->clearSmartyCache();
                            break;
                        case $this->entities[$import_type = $this->l('Suppliers')]:
                            $this->supplierImport();
                            $this->clearSmartyCache();
                            break;
                            // @since 1.5.0
                        // @since 1.5.0
                        case $this->entities[$import_type = $this->l('Supply Orders')]:
                            if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
                                $this->supplyOrdersImport();
                            }
                            break;
                            // @since 1.5.0
                        // @since 1.5.0
                        case $this->entities[$import_type = $this->l('Supply Order Details')]:
                            if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
                                $this->supplyOrdersDetailsImport();
                            }
                            break;
                        default:
                            $this->errors[] = $this->l('Please select what you would like to import');
                    }
                    if ($import_type !== false) {
                        $log_message = sprintf($this->l('%s import'), $import_type);
                        if (Tools::getValue('truncate')) {
                            $log_message .= ' ' . $this->l('with truncate');
                        }
                        Logger::addLog($log_message, 1, null, $import_type, null, true, (int) $this->context->employee->id);
                    }
                } else {
                    $this->errors[] = $this->l('You must upload a file in order to proceed to the next step');
                }
            }
        }
        parent::postProcess();
    }
Example #18
0
 /**
  * @see FrontController::initContent()
  */
 public function initContent()
 {
     parent::initContent();
     $data = array();
     /**
      * Set ref is indicative of a payment that is tied to an order instead of a cart, which
      * we still support for transitional reasons.
      */
     if (isset($_GET['ref'])) {
         $order_id = (int) $_GET['id'];
         // Check if user is allowed to be on the return page
         $data['auth'] = Order::getUniqReferenceOf($order_id) === $_GET['ref'];
         if ($data['auth']) {
             $data['mollie_info'] = $this->module->getPaymentBy('order_id', (int) $order_id);
         }
     } elseif (isset($_GET['cart_id'])) {
         $cart_id = (int) $_GET['cart_id'];
         // Check if user that's seeing this is the cart-owner
         $cart = new Cart($cart_id);
         $data['auth'] = (int) $cart->id_customer === $this->context->customer->id;
         if ($data['auth']) {
             $data['mollie_info'] = $this->module->getPaymentBy('cart_id', (int) $cart_id);
         }
     }
     if (isset($data['auth']) && $data['auth']) {
         // any paid payments for this cart?
         if ($data['mollie_info'] === FALSE) {
             $data['mollie_info'] = array();
             $data['msg_details'] = $this->module->lang('The order with this id does not exist.');
         } else {
             switch ($data['mollie_info']['bank_status']) {
                 case Mollie_API_Object_Payment::STATUS_OPEN:
                     $data['msg_details'] = $this->module->lang('We have not received a definite payment status. You will be notified as soon as we receive a confirmation of the bank/merchant.');
                     break;
                 case Mollie_API_Object_Payment::STATUS_CANCELLED:
                     Tools::redirect('order&step=3');
                     break;
                 case Mollie_API_Object_Payment::STATUS_EXPIRED:
                     $data['msg_details'] = $this->module->lang('Unfortunately your order was expired.');
                     break;
                 case Mollie_API_Object_Payment::STATUS_PAID:
                     if (isset($cart_id)) {
                         Tools::redirectLink(__PS_BASE_URI__ . 'index.php?controller=order-confirmation&id_cart=' . $cart_id . '&id_module=' . $this->module->id . '&id_order=' . Order::getOrderByCartId(intval($cart_id)) . '&key=' . $this->context->customer->secure_key);
                     }
                     $data['msg_details'] = $this->module->lang('Thank you. Your order has been received.');
                     break;
                 default:
                     $data['msg_details'] = $this->module->lang('The transaction has an unexpected status.');
                     if (Configuration::get('MOLLIE_DEBUG_LOG') == Mollie::DEBUG_LOG_ERRORS) {
                         Logger::addLog(__METHOD__ . 'said: The transaction has an unexpected status (' . $data['mollie_info']['bank_status'] . ')', Mollie::WARNING);
                     }
             }
         }
     } else {
         $data['mollie_info'] = array();
         $data['msg_details'] = $this->module->lang('You are not authorised to see this page.');
         Tools::redirect(_PS_BASE_URL_ . __PS_BASE_URI__);
     }
     $data['msg_continue'] = '<a href="' . _PS_BASE_URL_ . __PS_BASE_URI__ . '">' . $this->module->lang('Continue shopping') . '</a>';
     $data['msg_welcome'] = $this->module->lang('Welcome back');
     $this->context->smarty->assign($data);
     $this->setTemplate('mollie_return.tpl');
 }
Example #19
0
    public function sendPayment($total, $paramurl)
    {
        $cart = $this->context->cart;
        $payment = array('amount' => $total, 'currency' => 'EUR', 'customerData' => $cart->id, 'paymentSuccessUrl' => $this->context->link->getModuleLink('nimblepayment', 'paymentok', array('paymentcode' => $paramurl)), 'paymentErrorUrl' => $this->context->link->getModuleLink('nimblepayment', 'paymentko', array('paymentcode' => $paramurl)));
        try {
            $p = new Payments();
            $response = $p->SendPaymentClient($this->nimbleapi, $payment);
        } catch (Exception $e) {
            //type error = 3 // problem to send payment
            $this->type_error = $this->module->l('Is not possible to send the payment to Nimble Payments. Sorry for the inconvenience.');
            Logger::addLog('NIMBLE_PAYMENTS. Is not possible to send the payment.', 4);
            $this->setTemplate('payment_failed.tpl');
            return false;
        }
        if (empty($response)) {
            //type error = 6
            $this->type_error = $this->module->l('Unknown error or timeout. Sorry for the inconvenience.');
            Logger::addLog('NIMBLE_PAYMENTS. Unknown error or timeout.', 4);
            $this->setTemplate('payment_failed.tpl');
        } elseif (!isset($response['error'])) {
            if ($response['result']['code'] == 200) {
                //save transaction_id in session. After in validateOrder (paymentok.php) we will use transaction_id
                $this->context->cookie->__set('nimble_transaction_id', $response['data']['id']);
                //Tools::redirect($response['data'][0]['paymentUrl']); //old version
                Tools::redirect($response['data']['paymentUrl']);
            } elseif ($response['result']['code'] == 401) {
                //type error = 7 // 401 unauthorized
                $this->setTemplate('payment_failed.tpl');
                $this->type_error = $this->module->l('Unauthorized access. Please an administrator user should check the credentials 
					and the selected environment to access Nimble Payments. Sorry for the inconvenience.');
                Logger::addLog('NIMBLE_PAYMENTS. Unauthorized access. Please an administrator user should check the credentials 
					and the selected environment to access Nimble Payments. (Code Error: ' . $response['result']['code'] . ')', 4);
            } else {
                //type error = 4 // problem to send payment 2
                $this->setTemplate('payment_failed.tpl');
                $this->type_error = $this->module->l('Is not possible send to the payment to Nimble Payments. Sorry for the inconvenience.
				 Code Error: ') . $response['result']['code'];
                Logger::addLog('NIMBLE_PAYMENTS. Is not possible send to the payment to Nimble Payments (Code Error: ' . $response['result']['code'] . ')', 4);
            }
        } else {
            //type error = 5 // problem to send payment 3
            $this->type_error = $this->module->l('We have received an error from Nimble Payments. Sorry for the inconvenience. Error: ') . $response['error'];
            $this->setTemplate('payment_failed.tpl');
            Logger::addLog('NIMBLE_PAYMENTS. We have received an error from Nimble Payments (Error: ' . $response['error'] . ')', 4);
        }
    }
 public function processUpdate()
 {
     $this->checkProduct();
     if (!empty($this->errors)) {
         $this->display = 'edit';
         return false;
     }
     $id = (int) Tools::getValue('id_' . $this->table);
     /* Update an existing product */
     if (isset($id) && !empty($id)) {
         $object = new $this->className((int) $id);
         $this->object = $object;
         if (Validate::isLoadedObject($object)) {
             $this->_removeTaxFromEcotax();
             $product_type_before = $object->getType();
             $this->copyFromPost($object, $this->table);
             $object->indexed = 0;
             if (Shop::isFeatureActive() && Shop::getContext() != Shop::CONTEXT_SHOP) {
                 $object->setFieldsToUpdate((array) Tools::getValue('multishop_check'));
             }
             // Duplicate combinations if not associated to shop
             if ($this->context->shop->getContext() == Shop::CONTEXT_SHOP && !$object->isAssociatedToShop()) {
                 $is_associated_to_shop = false;
                 $combinations = Product::getProductAttributesIds($object->id);
                 if ($combinations) {
                     foreach ($combinations as $id_combination) {
                         $combination = new Combination((int) $id_combination['id_product_attribute']);
                         $default_combination = new Combination((int) $id_combination['id_product_attribute'], null, (int) $this->object->id_shop_default);
                         $def = ObjectModel::getDefinition($default_combination);
                         foreach ($def['fields'] as $field_name => $row) {
                             $combination->{$field_name} = ObjectModel::formatValue($default_combination->{$field_name}, $def['fields'][$field_name]['type']);
                         }
                         $combination->save();
                     }
                 }
             } else {
                 $is_associated_to_shop = true;
             }
             if ($object->update()) {
                 Logger::addLog(sprintf($this->l('%s edition'), $this->className), 1, null, $this->className, (int) $this->object->id, true, (int) $this->context->employee->id);
                 if (in_array($this->context->shop->getContext(), array(Shop::CONTEXT_SHOP, Shop::CONTEXT_ALL))) {
                     if ($this->isTabSubmitted('Shipping')) {
                         $this->addCarriers();
                     }
                     if ($this->isTabSubmitted('Associations')) {
                         $this->updateAccessories($object);
                     }
                     if ($this->isTabSubmitted('Suppliers')) {
                         $this->processSuppliers();
                     }
                     if ($this->isTabSubmitted('Features')) {
                         $this->processFeatures();
                     }
                     if ($this->isTabSubmitted('Combinations')) {
                         $this->processProductAttribute();
                     }
                     if ($this->isTabSubmitted('Prices')) {
                         $this->processPriceAddition();
                         $this->processSpecificPricePriorities();
                     }
                     if ($this->isTabSubmitted('Customization')) {
                         $this->processCustomizationConfiguration();
                     }
                     if ($this->isTabSubmitted('Attachments')) {
                         $this->processAttachments();
                     }
                     $this->updatePackItems($object);
                     // Disallow avanced stock management if the product become a pack
                     if ($product_type_before == Product::PTYPE_SIMPLE && $object->getType() == Product::PTYPE_PACK) {
                         StockAvailable::setProductDependsOnStock((int) $object->id, false);
                     }
                     $this->updateDownloadProduct($object, 1);
                     $this->updateTags(Language::getLanguages(false), $object);
                     if ($this->isProductFieldUpdated('category_box') && !$object->updateCategories(Tools::getValue('categoryBox'))) {
                         $this->errors[] = Tools::displayError('An error occurred while linking the object.') . ' <b>' . $this->table . '</b> ' . Tools::displayError('To categories');
                     }
                 }
                 if ($this->isTabSubmitted('Warehouses')) {
                     $this->processWarehouses();
                 }
                 if (empty($this->errors)) {
                     Hook::exec('actionProductUpdate', array('product' => $object));
                     if (in_array($object->visibility, array('both', 'search')) && Configuration::get('PS_SEARCH_INDEXATION')) {
                         Search::indexation(false, $object->id);
                     }
                     // Save and preview
                     if (Tools::isSubmit('submitAddProductAndPreview')) {
                         $preview_url = $this->context->link->getProductLink($this->getFieldValue($object, 'id'), $this->getFieldValue($object, 'link_rewrite', $this->context->language->id), Category::getLinkRewrite($this->getFieldValue($object, 'id_category_default'), $this->context->language->id), null, null, Context::getContext()->shop->id, 0, (bool) Configuration::get('PS_REWRITING_SETTINGS'));
                         if (!$object->active) {
                             $admin_dir = dirname($_SERVER['PHP_SELF']);
                             $admin_dir = substr($admin_dir, strrpos($admin_dir, '/') + 1);
                             if (strpos($preview_url, '?') === false) {
                                 $preview_url .= '?';
                             } else {
                                 $preview_url .= '&';
                             }
                             $preview_url .= 'adtoken=' . $this->token . '&ad=' . $admin_dir . '&id_employee=' . (int) $this->context->employee->id;
                         }
                         $this->redirect_after = $preview_url;
                     } else {
                         // Save and stay on same form
                         if ($this->display == 'edit') {
                             $this->confirmations[] = $this->l('Update successful');
                             $this->redirect_after = self::$currentIndex . '&id_product=' . (int) $this->object->id . (Tools::getIsset('id_category') ? '&id_category=' . (int) Tools::getValue('id_category') : '') . '&updateproduct&conf=4&key_tab=' . Tools::safeOutput(Tools::getValue('key_tab')) . '&token=' . $this->token;
                         } else {
                             // Default behavior (save and back)
                             $this->redirect_after = self::$currentIndex . (Tools::getIsset('id_category') ? '&id_category=' . (int) Tools::getValue('id_category') : '') . '&conf=4&token=' . $this->token;
                         }
                     }
                 } else {
                     $this->display = 'edit';
                 }
             } else {
                 if (!$is_associated_to_shop && $combinations) {
                     foreach ($combinations as $id_combination) {
                         $combination = new Combination((int) $id_combination['id_product_attribute']);
                         $combination->delete();
                     }
                 }
                 $this->errors[] = Tools::displayError('An error occurred while updating an object.') . ' <b>' . $this->table . '</b> (' . Db::getInstance()->getMsgError() . ')';
             }
         } else {
             $this->errors[] = Tools::displayError('An error occurred while updating an object.') . ' <b>' . $this->table . '</b> (' . Tools::displayError('The object cannot be loaded. ') . ')';
         }
         return $object;
     }
 }
Example #21
0
 public static function validateAnsver($message)
 {
     Logger::addLog('robokassa: ' . $message);
     die($message);
 }
Example #22
0
 public function postProcess()
 {
     if (Tools::isSubmit('submitSettings')) {
         Configuration::updateValue('PS_SHOP_DOMAIN', Tools::getValue('shop_domain'));
         Configuration::updateValue('PS_AUTH_TOKEN', Tools::getValue('auth_token'));
         Configuration::updateValue('RISKIFIED_MODE', Tools::getValue('riskified_mode'));
         if (Configuration::get('RISKIFIED_MODE') == '1') {
             Logger::addLog('Riskified is in production mode ( ' . Configuration::get('RISKIFIED_MODE') . ' )', 1);
         } else {
             Logger::addLog('Riskified is in sandbox mode ( ' . Configuration::get('RISKIFIED_MODE') . ' )', 0);
         }
         $this->html .= $this->displayConfirmation('API Settings updated');
     }
     if (count($this->_errors)) {
         $err = '';
         foreach ($this->_errors as $error) {
             $err .= $error . '<br />';
         }
         $this->html .= $this->displayError($err);
     }
 }
 public static function log($level, $msg = '')
 {
     if (!$msg) {
         list($level, $msg) = array('debug', $level);
     }
     if ($level == 'debug' && !self::DEBUG_MODE) {
         return;
     } elseif ($level == 'debug' && self::DEBUG_MODE) {
         self::logToFile($level, $msg);
     }
     try {
         if (class_exists('PrestaShopLogger')) {
             PrestaShopLogger::addLog('pilipay:' . $level . ': ' . $msg, 1, 0, 'pilipay', Configuration::get(self::PILIPAY_MERCHANT_NO));
         } elseif (class_exists('Logger')) {
             $msg = strtr($msg, array('{' => '&#123;', '}' => '&#125;', '<' => '&lt;', '>' => '&gt;'));
             Logger::addLog('pilipay:' . $level . ': ' . $msg, 1, 0, 'pilipay', Configuration::get(self::PILIPAY_MERCHANT_NO));
         }
     } catch (Exception $e) {
         if (self::DEBUG_MODE) {
             trigger_error(get_class($e) . ': ' . $e->getMessage() . PHP_EOL . $e->getTraceAsString(), E_USER_WARNING);
         }
     }
 }
Example #24
0
    die;
}
if (!Tools::getValue('invoice_id')) {
    Logger::addLog('Missing invoice_id', 4);
    die('An unrecoverable error occured: Missing parameter');
}
if (!Validate::isLoadedObject($cart)) {
    Logger::addLog('Cart loading failed for cart ' . (int) Tools::getValue('invoice_id'), 4);
    die('An unrecoverable error occured with the cart ' . (int) Tools::getValue('invoice_id'));
}
if ($cart->id != Tools::getValue('invoice_id')) {
    Logger::addLog('Conflict between cart id order and customer cart id');
    die('An unrecoverable conflict error occured with the cart ' . (int) Tools::getValue('invoice_id'));
}
if (!Validate::isLoadedObject($customer) || !Validate::isLoadedObject($address)) {
    Logger::addLog('Issue loading customer and/or address data');
    die('An unrecoverable error occured while retrieving you data');
}
/**
* Check if transaction was processed and approved through the iframe checkout page
*/
if (Tools::getValue('iframe_transaction_approved') == '1') {
    $transaction = array('customer_id' => $customer->id, 'transaction_id' => Tools::getValue('transaction_id'), 'payment_status' => 'Approved', 'invoice_id' => Tools::getValue('invoice_id'), 'payment_type' => Tools::getValue('payment_type'), 'payment_date' => date('Y-m-d H:i:s'), 'total_paid' => Tools::getValue('amount'), 'transaction_type' => Tools::getValue('transaction_type') == 'SALE' ? Configuration::get('PS_OS_PAYMENT') : Configuration::get('BP_OS_AUTHORIZATION'), 'name' => Tools::getValue('name'), 'email' => Tools::getValue('email'), 'payment_account' => Tools::getValue('payment_account'), 'card_type' => Tools::getValue('card_type'), 'expiration_date' => Tools::getValue('card_expiration'));
    /**
     * Check if amount processed through BluePay matches the cart total.
     * If amounts do not match, send the customer back
     * to the payment page.
     */
    if ($bluepay->validate($transaction['transaction_id'], $transaction['invoice_id']) != $transaction['total_paid']) {
        $message = 'Amounts do not match. The order was not created successfully; please try again.';
        $url = 'index.php?controller=order&step=3&error=' . $message;
Example #25
0
 /**
  *
  * @see FrontController::postProcess()
  */
 public function postProcess()
 {
     $cart = $this->context->cart;
     if ($cart->id_customer == 0 || $cart->id_address_delivery == 0 || $cart->id_address_invoice == 0 || !$this->module->active) {
         Tools::redirect('index.php?controller=order&step=1');
     }
     // Check that this payment option is still available in case the customer changed his address just before the end of the checkout process
     $authorized = false;
     foreach (Module::getPaymentModules() as $module) {
         if ($module['name'] == 'adyen') {
             $authorized = true;
             break;
         }
     }
     if (!$authorized) {
         die($this->module->l('This payment method is not available.', 'validation'));
     }
     $customer = new Customer($cart->id_customer);
     if (!Validate::isLoadedObject($customer)) {
         Tools::redirect('index.php?controller=order&step=1');
     }
     // get the selected currency
     $currency = $this->context->currency;
     $total = (double) $cart->getOrderTotal(true, Cart::BOTH);
     // validate order
     // $payment_method name must be the same as module name otherwise successurl won't show
     $this->module->validateOrder($cart->id, Configuration::get('ADYEN_NEW_STATUS'), $total, 'Adyen', null, array(), (int) $currency->id, false, $customer->secure_key);
     Logger::addLog('Adyen module: order is validated for id_order ' . $cart->id);
     // go to form adyen post values (submitted automatically)
     $config = Configuration::getMultiple(array('ADYEN_MERCHANT_ACCOUNT', 'ADYEN_MODE', 'ADYEN_SKIN_CODE', 'ADYEN_HMAC_TEST', 'ADYEN_HMAC_LIVE', 'ADYEN_NOTI_USERNAME', 'ADYEN_NOTI_PASSWORD', 'ADYEN_DAYS_DELIVERY', 'PS_SSL_ENABLED', 'ADYEN_COUNTRY_CODE_ISO', 'ADYEN_LANGUAGE_LOCALE'));
     $customer = new Customer((int) $cart->id_customer);
     $address = new Address((int) $cart->id_address_invoice);
     $country = new Country((int) $address->id_country);
     $language = Language::getIsoById((int) $cart->id_lang);
     if (!Validate::isLoadedObject($address) || !Validate::isLoadedObject($customer) || !Validate::isLoadedObject($currency)) {
         Logger::addLog('Adyen module: invalid address, customer, or currency for id_order ' . $cart->id, 4);
         return $this->module->l('Adyen error: (invalid address, customer, or currency)');
     }
     $merchant_account = (string) $config['ADYEN_MERCHANT_ACCOUNT'];
     $skin_code = (string) $config['ADYEN_SKIN_CODE'];
     $currency_code = (string) $currency->iso_code;
     $shopper_email = (string) $customer->email;
     $merchant_reference = (int) $this->module->currentOrder;
     // set when order is validated
     $payment_amount = number_format($cart->getOrderTotal(true, 3), 2, '', '');
     $shopper_reference = (string) $customer->secure_key;
     if ($config['ADYEN_COUNTRY_CODE_ISO'] != '') {
         $country_code = (string) $config['ADYEN_COUNTRY_CODE_ISO'];
     } else {
         $country_code = (string) $country->iso_code;
     }
     // Locale (language) to present to shopper (e.g. en_US, nl, fr, fr_BE)
     if ($config['ADYEN_LANGUAGE_LOCALE'] != '') {
         $shopper_locale = (string) $config['ADYEN_LANGUAGE_LOCALE'];
     } else {
         $shopper_locale = (string) $language;
     }
     $recurring_contract = 'ONECLICK';
     $ship_before_date = date('Y-m-d', mktime(date('H'), date('i'), date('s'), date('m'), date('j') + (isset($config['ADYEN_DAYS_DELIVERY']) ? $config['ADYEN_DAYS_DELIVERY'] : 5), date('Y')));
     // example: ship in 5 days
     $session_validity = date(DATE_ATOM, mktime(date('H') + 1, date('i'), date('s'), date('m'), date('j'), date('Y')));
     // presentation of the shopping basket.
     $tax_calculation_method = Group::getPriceDisplayMethod((int) Group::getCurrent()->id);
     $use_tax = !($tax_calculation_method == PS_TAX_EXC);
     $shipping_cost = Tools::displayPrice($cart->getOrderTotal($use_tax, Cart::ONLY_SHIPPING), $currency);
     $prod_details = sprintf('Shipment cost: %s <br />', $shipping_cost);
     $prod_details .= 'Order rows: <br />';
     // get order items
     foreach ($cart->getProducts() as $product) {
         $name = $product['name'];
         $qty_ordered = (int) $product['cart_quantity'];
         $row_total = Tools::ps_round($product['total_wt'], 2);
         $prod_details .= sprintf('%s ( Qty: %s ) ( Price: %s %s ) <br />', $name, $qty_ordered, $row_total, $currency_code);
     }
     $order_data = base64_encode(gzencode($prod_details));
     // for elv and cc can be mutliple values seperate by comma(,)
     $blocked_methods = '';
     $hmac_data = $payment_amount . $currency_code . $ship_before_date . $merchant_reference . $skin_code . $merchant_account . $session_validity . $shopper_email . $shopper_reference . $recurring_contract . $blocked_methods;
     $merchant_sig = base64_encode(pack('H*', $this->module->getHmacsha1($this->module->getHmac(), $hmac_data)));
     $brand_code = '';
     $ideal_issuer_id = '';
     $skip_selection = '';
     if (Tools::getValue('payment_type') != '') {
         $brand_code = (string) Tools::getValue('payment_type');
     }
     if (Tools::getValue('ideal_type') != '') {
         $ideal_issuer_id = (int) Tools::getValue('ideal_type');
         $skip_selection = 'true';
     }
     $this->context->smarty->assign(array('merchantAccount' => $merchant_account, 'skinCode' => $skin_code, 'currencyCode' => $currency_code, 'shopperEmail' => $shopper_email, 'merchantReference' => $merchant_reference, 'paymentAmount' => $payment_amount, 'shopperReference' => $shopper_reference, 'shipBeforeDate' => $ship_before_date, 'sessionValidity' => $session_validity, 'shopperLocale' => $shopper_locale, 'countryCode' => $country_code, 'orderData' => $order_data, 'recurringContract' => $recurring_contract, 'merchantSig' => $merchant_sig, 'adyenUrl' => $this->getAdyenUrl($brand_code, $ideal_issuer_id), 'resURL' => ($config['PS_SSL_ENABLED'] ? 'https://' : 'http://') . htmlspecialchars($_SERVER['HTTP_HOST'], ENT_COMPAT, 'UTF-8') . __PS_BASE_URI__ . 'index.php?controller=order-confirmation&key=' . $customer->secure_key . '&id_cart=' . (int) $cart->id . '&id_module=' . (int) $this->module->id . '&id_order=' . (int) $this->module->currentOrder, 'brandCode' => $brand_code, 'skipSelection' => $skip_selection, 'idealIssuerId' => $ideal_issuer_id));
 }
    public function postProcess()
    {
        /* PrestaShop demo mode */
        if (_PS_MODE_DEMO_) {
            $this->errors[] = Tools::displayError('This functionality has been disabled.');
            return;
        }
        /* PrestaShop demo mode*/
        if (Tools::isSubmit('submitFileUpload')) {
            $path = _PS_ADMIN_DIR_ . '/import/' . date('YmdHis') . '-';
            if (isset($_FILES['file']) && !empty($_FILES['file']['error'])) {
                switch ($_FILES['file']['error']) {
                    case UPLOAD_ERR_INI_SIZE:
                        $this->errors[] = Tools::displayError('The uploaded file exceeds the upload_max_filesize directive in php.ini. If your server configuration allows it, you may add a directive in your .htaccess.');
                        break;
                    case UPLOAD_ERR_FORM_SIZE:
                        $this->errors[] = Tools::displayError('The uploaded file exceeds the post_max_size directive in php.ini.
							If your server configuration allows it, you may add a directive in your .htaccess, for example:') . '<br/><a href="' . $this->context->link->getAdminLink('AdminMeta') . '" >
						<code>php_value post_max_size 20M</code> ' . Tools::displayError('(click to open "Generators" page)') . '</a>';
                        break;
                        break;
                    case UPLOAD_ERR_PARTIAL:
                        $this->errors[] = Tools::displayError('The uploaded file was only partially uploaded.');
                        break;
                        break;
                    case UPLOAD_ERR_NO_FILE:
                        $this->errors[] = Tools::displayError('No file was uploaded.');
                        break;
                        break;
                }
            } elseif (!preg_match('/.*\\.csv$/i', $_FILES['file']['name'])) {
                $this->errors[] = Tools::displayError('The extension of your file should be .csv.');
            } elseif (!file_exists($_FILES['file']['tmp_name']) || !@move_uploaded_file($_FILES['file']['tmp_name'], $path . $_FILES['file']['name'])) {
                $this->errors[] = $this->l('An error occurred while uploading / copying the file.');
            } else {
                @chmod($path . $_FILES['file']['name'], 0664);
                Tools::redirectAdmin(self::$currentIndex . '&token=' . Tools::getValue('token') . '&conf=18');
            }
        } elseif (Tools::getValue('import')) {
            // Check if the CSV file exist
            if (Tools::getValue('csv')) {
                // If i am a superadmin, i can truncate table
                if ((Shop::isFeatureActive() && $this->context->employee->isSuperAdmin() || !Shop::isFeatureActive()) && Tools::getValue('truncate')) {
                    $this->truncateTables((int) Tools::getValue('entity'));
                }
                $import_type = false;
                switch ((int) Tools::getValue('entity')) {
                    case $this->entities[$import_type = $this->l('Categories')]:
                        $this->categoryImport();
                        $this->clearSmartyCache();
                        break;
                    case $this->entities[$import_type = $this->l('Products')]:
                        $this->productImport();
                        $this->clearSmartyCache();
                        break;
                    case $this->entities[$import_type = $this->l('Customers')]:
                        $this->customerImport();
                        break;
                    case $this->entities[$import_type = $this->l('Addresses')]:
                        $this->addressImport();
                        break;
                    case $this->entities[$import_type = $this->l('Combinations')]:
                        $this->attributeImport();
                        $this->clearSmartyCache();
                        break;
                    case $this->entities[$import_type = $this->l('Manufacturers')]:
                        $this->manufacturerImport();
                        $this->clearSmartyCache();
                        break;
                    case $this->entities[$import_type = $this->l('Suppliers')]:
                        $this->supplierImport();
                        $this->clearSmartyCache();
                        break;
                    case $this->entities[$import_type = $this->l('Alias')]:
                        $this->aliasImport();
                        break;
                }
                // @since 1.5.0
                if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
                    switch ((int) Tools::getValue('entity')) {
                        case $this->entities[$import_type = $this->l('Supply Orders')]:
                            if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
                                $this->supplyOrdersImport();
                            }
                            break;
                        case $this->entities[$import_type = $this->l('Supply Order Details')]:
                            if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
                                $this->supplyOrdersDetailsImport();
                            }
                            break;
                    }
                }
                if ($import_type !== false) {
                    $log_message = sprintf($this->l('%s import', 'AdminTab', false, false), $import_type);
                    if (Tools::getValue('truncate')) {
                        $log_message .= ' ' . $this->l('with truncate', 'AdminTab', false, false);
                    }
                    Logger::addLog($log_message, 1, null, $import_type, null, true, (int) $this->context->employee->id);
                }
            } else {
                $this->errors[] = $this->l('You must upload a file in order to proceed to the next step');
            }
        } elseif ($filename = Tools::getValue('csvfilename')) {
            $filename = base64_decode($filename);
            $file = _PS_ADMIN_DIR_ . '/import/' . basename($filename);
            if (realpath(dirname($file)) != _PS_ADMIN_DIR_ . DIRECTORY_SEPARATOR . 'import') {
                exit;
            }
            if (!empty($filename)) {
                $bName = basename($filename);
                if ($delete = Tools::getValue('delete') && file_exists($file)) {
                    @unlink($file);
                } elseif (file_exists($file)) {
                    $bName = explode('.', $bName);
                    $bName = strtolower($bName[count($bName) - 1]);
                    $mimeTypes = array('csv' => 'text/csv');
                    if (isset($mimeTypes[$bName])) {
                        $mimeType = $mimeTypes[$bName];
                    } else {
                        $mimeType = 'application/octet-stream';
                    }
                    if (ob_get_level() && ob_get_length() > 0) {
                        ob_end_clean();
                    }
                    header('Content-Transfer-Encoding: binary');
                    header('Content-Type: ' . $mimeType);
                    header('Content-Length: ' . filesize($file));
                    header('Content-Disposition: attachment; filename="' . $filename . '"');
                    $fp = fopen($file, 'rb');
                    while (is_resource($fp) && !feof($fp)) {
                        echo fgets($fp, 16384);
                    }
                    exit;
                }
            }
        }
        parent::postProcess();
    }
Example #27
0
 /**
  * Display error and dies or silently log the error.
  * 
  * @param string $msg
  * @param bool $die
  * @return success of logging
  */
 public static function dieOrLog($msg, $die = true)
 {
     if ($die || defined('_PS_MODE_DEV_') && _PS_MODE_DEV_) {
         die($msg);
     }
     return Logger::addLog($msg);
 }
Example #28
0
    /**
     * Validate an order in database
     * Function called from a payment module
     *
     * @param integer $id_cart Value
     * @param integer $id_order_state Value
     * @param float $amountPaid Amount really paid by customer (in the default currency)
     * @param string $paymentMethod Payment method (eg. 'Credit card')
     * @param string $message Message to attach to order
     */
    public function validateOrder($id_cart, $id_order_state, $amountPaid, $paymentMethod = 'Unknown', $message = NULL, $extraVars = array(), $currency_special = NULL, $dont_touch_amount = false, $secure_key = false)
    {
        global $cart;
        $cart = new Cart((int) $id_cart);
        // Does order already exists ?
        if (!$this->active) {
            die(Tools::displayError());
        }
        if (Validate::isLoadedObject($cart) && $cart->OrderExists() == false) {
            if ($secure_key !== false && $secure_key != $cart->secure_key) {
                die(Tools::displayError());
            }
            // Copying data from cart
            $order = new Order();
            $order->id_carrier = (int) $cart->id_carrier;
            $order->id_customer = (int) $cart->id_customer;
            $order->id_address_invoice = (int) $cart->id_address_invoice;
            $order->id_address_delivery = (int) $cart->id_address_delivery;
            $vat_address = new Address((int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
            $order->id_currency = $currency_special ? (int) $currency_special : (int) $cart->id_currency;
            $order->id_lang = (int) $cart->id_lang;
            $order->id_cart = (int) $cart->id;
            $customer = new Customer((int) $order->id_customer);
            $order->secure_key = $secure_key ? pSQL($secure_key) : pSQL($customer->secure_key);
            $order->payment = $paymentMethod;
            if (isset($this->name)) {
                $order->module = $this->name;
            }
            $order->recyclable = $cart->recyclable;
            $order->gift = (int) $cart->gift;
            $order->gift_message = $cart->gift_message;
            $currency = new Currency($order->id_currency);
            $order->conversion_rate = $currency->conversion_rate;
            $amountPaid = !$dont_touch_amount ? Tools::ps_round((double) $amountPaid, 2) : $amountPaid;
            $order->total_paid_real = $amountPaid;
            $order->total_products = (double) $cart->getOrderTotal(false, Cart::ONLY_PRODUCTS);
            $order->total_products_wt = (double) $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS);
            $order->total_discounts = (double) abs($cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS));
            $order->total_shipping = (double) $cart->getOrderShippingCost();
            $order->carrier_tax_rate = (double) Tax::getCarrierTaxRate($cart->id_carrier, (int) $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
            $order->total_wrapping = (double) abs($cart->getOrderTotal(true, Cart::ONLY_WRAPPING));
            $order->total_paid = (double) Tools::ps_round((double) $cart->getOrderTotal(true, Cart::BOTH), 2);
            $order->invoice_date = '0000-00-00 00:00:00';
            $order->delivery_date = '0000-00-00 00:00:00';
            // Amount paid by customer is not the right one -> Status = payment error
            // We don't use the following condition to avoid the float precision issues : http://www.php.net/manual/en/language.types.float.php
            // if ($order->total_paid != $order->total_paid_real)
            // We use number_format in order to compare two string
            if (number_format($order->total_paid, 2) != number_format($order->total_paid_real, 2)) {
                $id_order_state = Configuration::get('PS_OS_ERROR');
            }
            // Creating order
            if ($cart->OrderExists() == false) {
                $result = $order->add();
            } else {
                $errorMessage = Tools::displayError('An order has already been placed using this cart.');
                Logger::addLog($errorMessage, 4, '0000001', 'Cart', intval($order->id_cart));
                die($errorMessage);
            }
            // Next !
            if ($result and isset($order->id)) {
                if (!$secure_key) {
                    $message .= $this->l('Warning : the secure key is empty, check your payment account before validation');
                }
                // Optional message to attach to this order
                if (isset($message) and !empty($message)) {
                    $msg = new Message();
                    $message = strip_tags($message, '<br>');
                    if (Validate::isCleanHtml($message)) {
                        $msg->message = $message;
                        $msg->id_order = intval($order->id);
                        $msg->private = 1;
                        $msg->add();
                    }
                }
                // Insert products from cart into order_detail table
                $products = $cart->getProducts();
                $productsList = '';
                $db = Db::getInstance();
                $query = 'INSERT INTO `' . _DB_PREFIX_ . 'order_detail`
					(`id_order`, `product_id`, `product_attribute_id`, `product_name`, `product_quantity`, `product_quantity_in_stock`, `product_price`, `reduction_percent`, `reduction_amount`, `group_reduction`, `product_quantity_discount`, `product_ean13`, `product_upc`, `product_reference`, `product_supplier_reference`, `product_weight`, `tax_name`, `tax_rate`, `ecotax`, `ecotax_tax_rate`, `discount_quantity_applied`, `download_deadline`, `download_hash`)
				VALUES ';
                $customizedDatas = Product::getAllCustomizedDatas((int) $order->id_cart);
                Product::addCustomizationPrice($products, $customizedDatas);
                $outOfStock = false;
                $store_all_taxes = array();
                foreach ($products as $key => $product) {
                    $productQuantity = (int) Product::getQuantity((int) $product['id_product'], $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : NULL);
                    $quantityInStock = $productQuantity - (int) $product['cart_quantity'] < 0 ? $productQuantity : (int) $product['cart_quantity'];
                    if ($id_order_state != Configuration::get('PS_OS_CANCELED') and $id_order_state != Configuration::get('PS_OS_ERROR')) {
                        if (Product::updateQuantity($product, (int) $order->id)) {
                            $product['stock_quantity'] -= $product['cart_quantity'];
                        }
                        if ($product['stock_quantity'] < 0 && Configuration::get('PS_STOCK_MANAGEMENT')) {
                            $outOfStock = true;
                        }
                        Product::updateDefaultAttribute($product['id_product']);
                    }
                    $price = Product::getPriceStatic((int) $product['id_product'], false, $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : NULL, 6, NULL, false, true, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    $price_wt = Product::getPriceStatic((int) $product['id_product'], true, $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : NULL, 2, NULL, false, true, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    /* Store tax info */
                    $id_country = (int) Country::getDefaultCountryId();
                    $id_state = 0;
                    $id_county = 0;
                    $rate = 0;
                    $id_address = $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')};
                    $address_infos = Address::getCountryAndState($id_address);
                    if ($address_infos['id_country']) {
                        $id_country = (int) $address_infos['id_country'];
                        $id_state = (int) $address_infos['id_state'];
                        $id_county = (int) County::getIdCountyByZipCode($address_infos['id_state'], $address_infos['postcode']);
                    }
                    $allTaxes = TaxRulesGroup::getTaxes((int) Product::getIdTaxRulesGroupByIdProduct((int) $product['id_product']), $id_country, $id_state, $id_county);
                    // If its a freeOrder, there will be no calculation
                    if ($order->total_products > 0) {
                        // remove order discount quotepart on product price in order to obtain the real tax
                        $ratio = $price / $order->total_products;
                        $order_reduction_amount = (double) abs($cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS)) * $ratio;
                        $tmp_price = $price - $order_reduction_amount;
                        foreach ($allTaxes as $res) {
                            if (!isset($store_all_taxes[$res->id])) {
                                $store_all_taxes[$res->id] = array();
                                $store_all_taxes[$res->id]['amount'] = 0;
                            }
                            $store_all_taxes[$res->id]['name'] = $res->name[(int) $order->id_lang];
                            $store_all_taxes[$res->id]['rate'] = $res->rate;
                            $unit_tax_amount = $tmp_price * ($res->rate * 0.01);
                            $tmp_price = $tmp_price + $unit_tax_amount;
                            $store_all_taxes[$res->id]['amount'] += $unit_tax_amount * $product['cart_quantity'];
                        }
                    }
                    /* End */
                    // Add some informations for virtual products
                    $deadline = '0000-00-00 00:00:00';
                    $download_hash = null;
                    if ($id_product_download = ProductDownload::getIdFromIdProduct((int) $product['id_product'])) {
                        $productDownload = new ProductDownload((int) $id_product_download);
                        $deadline = $productDownload->getDeadLine();
                        $download_hash = $productDownload->getHash();
                    }
                    // Exclude VAT
                    if (!_PS_TAX_) {
                        $product['tax'] = 0;
                        $product['rate'] = 0;
                        $tax_rate = 0;
                    } else {
                        $tax_rate = Tax::getProductTaxRate((int) $product['id_product'], $cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    }
                    $ecotaxTaxRate = 0;
                    if (!empty($product['ecotax'])) {
                        $ecotaxTaxRate = Tax::getProductEcotaxRate($order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    }
                    $product_price = (double) Product::getPriceStatic((int) $product['id_product'], false, $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : NULL, Product::getTaxCalculationMethod((int) $order->id_customer) == PS_TAX_EXC ? 2 : 6, NULL, false, false, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')}, $specificPrice, false, false);
                    $group_reduction = (double) GroupReduction::getValueForProduct((int) $product['id_product'], $customer->id_default_group) * 100;
                    if (!$group_reduction) {
                        $group_reduction = (double) Group::getReduction((int) $order->id_customer);
                    }
                    $quantityDiscount = SpecificPrice::getQuantityDiscount((int) $product['id_product'], Shop::getCurrentShop(), (int) $cart->id_currency, (int) $vat_address->id_country, (int) $customer->id_default_group, (int) $product['cart_quantity']);
                    $unitPrice = Product::getPriceStatic((int) $product['id_product'], true, $product['id_product_attribute'] ? intval($product['id_product_attribute']) : NULL, 2, NULL, false, true, 1, false, (int) $order->id_customer, NULL, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                    $quantityDiscountValue = $quantityDiscount ? (Product::getTaxCalculationMethod((int) $order->id_customer) == PS_TAX_EXC ? Tools::ps_round($unitPrice, 2) : $unitPrice) - $quantityDiscount['price'] * (1 + $tax_rate / 100) : 0.0;
                    $query .= '(' . (int) $order->id . ',
						' . (int) $product['id_product'] . ',
						' . (isset($product['id_product_attribute']) ? (int) $product['id_product_attribute'] : 'NULL') . ',
						\'' . pSQL($product['name'] . ((isset($product['attributes']) and $product['attributes'] != NULL) ? ' - ' . $product['attributes'] : '')) . '\',
						' . (int) $product['cart_quantity'] . ',
						' . $quantityInStock . ',
						' . $product_price . ',
						' . (double) (($specificPrice and $specificPrice['reduction_type'] == 'percentage') ? $specificPrice['reduction'] * 100 : 0.0) . ',
						' . (double) (($specificPrice and $specificPrice['reduction_type'] == 'amount') ? !$specificPrice['id_currency'] ? Tools::convertPrice($specificPrice['reduction'], $order->id_currency) : $specificPrice['reduction'] : 0.0) . ',
						' . $group_reduction . ',
						' . $quantityDiscountValue . ',
						' . (empty($product['ean13']) ? 'NULL' : '\'' . pSQL($product['ean13']) . '\'') . ',
						' . (empty($product['upc']) ? 'NULL' : '\'' . pSQL($product['upc']) . '\'') . ',
						' . (empty($product['reference']) ? 'NULL' : '\'' . pSQL($product['reference']) . '\'') . ',
						' . (empty($product['supplier_reference']) ? 'NULL' : '\'' . pSQL($product['supplier_reference']) . '\'') . ',
						' . (double) ($product['id_product_attribute'] ? $product['weight_attribute'] : $product['weight']) . ',
						\'' . (empty($tax_rate) ? '' : pSQL($product['tax'])) . '\',
						' . (double) $tax_rate . ',
						' . (double) Tools::convertPrice(floatval($product['ecotax']), intval($order->id_currency)) . ',
						' . (double) $ecotaxTaxRate . ',
						' . (($specificPrice and $specificPrice['from_quantity'] > 1) ? 1 : 0) . ',
						\'' . pSQL($deadline) . '\',
						\'' . pSQL($download_hash) . '\'),';
                    $customizationQuantity = 0;
                    if (isset($customizedDatas[$product['id_product']][$product['id_product_attribute']])) {
                        $customizationText = '';
                        foreach ($customizedDatas[$product['id_product']][$product['id_product_attribute']] as $customization) {
                            if (isset($customization['datas'][_CUSTOMIZE_TEXTFIELD_])) {
                                foreach ($customization['datas'][_CUSTOMIZE_TEXTFIELD_] as $text) {
                                    $customizationText .= $text['name'] . ':' . ' ' . $text['value'] . '<br />';
                                }
                            }
                            if (isset($customization['datas'][_CUSTOMIZE_FILE_])) {
                                $customizationText .= count($customization['datas'][_CUSTOMIZE_FILE_]) . ' ' . Tools::displayError('image(s)') . '<br />';
                            }
                            $customizationText .= '---<br />';
                        }
                        $customizationText = rtrim($customizationText, '---<br />');
                        $customizationQuantity = (int) $product['customizationQuantityTotal'];
                        $productsList .= '<tr style="background-color: ' . ($key % 2 ? '#DDE2E6' : '#EBECEE') . ';">
							<td style="padding: 0.6em 0.4em;">' . (isset($product['reference']) && !empty($product['reference']) ? $product['reference'] : '&nbsp;') . '</td>
							<td style="padding: 0.6em 0.4em;"><strong>' . $product['name'] . (isset($product['attributes']) ? ' - ' . $product['attributes'] : '') . ' - ' . $this->l('Customized') . (!empty($customizationText) ? ' - ' . $customizationText : '') . '</strong></td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice(Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt, $currency, false) . '</td>
							<td style="padding: 0.6em 0.4em; text-align: center;">' . $customizationQuantity . '</td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice($customizationQuantity * (Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt), $currency, false) . '</td>
						</tr>';
                    }
                    if (!$customizationQuantity or (int) $product['cart_quantity'] > $customizationQuantity) {
                        $productsList .= '<tr style="background-color: ' . ($key % 2 ? '#DDE2E6' : '#EBECEE') . ';">
							<td style="padding: 0.6em 0.4em;">' . (isset($product['reference']) && !empty($product['reference']) ? $product['reference'] : '&nbsp;') . '</td>
							<td style="padding: 0.6em 0.4em;"><strong>' . $product['name'] . (isset($product['attributes']) ? ' - ' . $product['attributes'] : '') . '</strong></td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice(Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt, $currency, false) . '</td>
							<td style="padding: 0.6em 0.4em; text-align: center;">' . ((int) $product['cart_quantity'] - $customizationQuantity) . '</td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . Tools::displayPrice(((int) $product['cart_quantity'] - $customizationQuantity) * (Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt), $currency, false) . '</td>
						</tr>';
                    }
                }
                // end foreach ($products)
                $query = rtrim($query, ',');
                $result = $db->Execute($query);
                /* Add carrier tax */
                $shippingCostTaxExcl = $cart->getOrderShippingCost((int) $order->id_carrier, false);
                $allTaxes = TaxRulesGroup::getTaxes((int) Carrier::getIdTaxRulesGroupByIdCarrier((int) $order->id_carrier), $id_country, $id_state, $id_county);
                $nTax = 0;
                foreach ($allTaxes as $tax) {
                    if (!isset($tax->id)) {
                        continue;
                    }
                    if (!isset($store_all_taxes[$tax->id])) {
                        $store_all_taxes[$tax->id] = array();
                    }
                    if (!isset($store_all_taxes[$tax->id]['amount'])) {
                        $store_all_taxes[$tax->id]['amount'] = 0;
                    }
                    $store_all_taxes[$tax->id]['name'] = $tax->name[(int) $order->id_lang];
                    $store_all_taxes[$tax->id]['rate'] = $tax->rate;
                    if (!$nTax++) {
                        $store_all_taxes[$tax->id]['amount'] += $shippingCostTaxExcl * (1 + $tax->rate * 0.01) - $shippingCostTaxExcl;
                    } else {
                        $store_all_taxes[$tax->id]['amount'] += $order->total_shipping - $order->total_shipping / (1 + $tax->rate * 0.01);
                    }
                }
                /* Store taxes */
                foreach ($store_all_taxes as $tax) {
                    Db::getInstance()->Execute('
					INSERT INTO `' . _DB_PREFIX_ . 'order_tax` (`id_order`, `tax_name`, `tax_rate`, `amount`)
					VALUES (' . (int) $order->id . ', \'' . pSQL($tax['name']) . '\', ' . (double) $tax['rate'] . ', ' . (double) $tax['amount'] . ')');
                }
                // Insert discounts from cart into order_discount table
                $discounts = $cart->getDiscounts();
                $discountsList = '';
                $total_discount_value = 0;
                $shrunk = false;
                foreach ($discounts as $discount) {
                    $objDiscount = new Discount((int) $discount['id_discount']);
                    $value = $objDiscount->getValue(count($discounts), $cart->getOrderTotal(true, Cart::ONLY_PRODUCTS), $order->total_shipping, $cart->id);
                    if ($objDiscount->id_discount_type == 2 and in_array($objDiscount->behavior_not_exhausted, array(1, 2))) {
                        $shrunk = true;
                    }
                    if ($shrunk and $total_discount_value + $value > $order->total_products_wt + $order->total_shipping + $order->total_wrapping) {
                        $amount_to_add = $order->total_products_wt + $order->total_shipping + $order->total_wrapping - $total_discount_value;
                        if ($objDiscount->id_discount_type == 2 and $objDiscount->behavior_not_exhausted == 2) {
                            $voucher = new Discount();
                            foreach ($objDiscount as $key => $discountValue) {
                                $voucher->{$key} = $discountValue;
                            }
                            $voucher->name = 'VSRK' . (int) $order->id_customer . 'O' . (int) $order->id;
                            $voucher->value = (double) $value - $amount_to_add;
                            $voucher->add();
                            $params['{voucher_amount}'] = Tools::displayPrice($voucher->value, $currency, false);
                            $params['{voucher_num}'] = $voucher->name;
                            $params['{firstname}'] = $customer->firstname;
                            $params['{lastname}'] = $customer->lastname;
                            $params['{id_order}'] = $order->id;
                            $params['{order_name}'] = sprintf("#%06d", (int) $order->id);
                            @Mail::Send((int) $order->id_lang, 'voucher', Mail::l('New voucher regarding your order #', (int) $order->id_lang) . sprintf("%06d", (int) $order->id), $params, $customer->email, $customer->firstname . ' ' . $customer->lastname);
                        }
                    } else {
                        $amount_to_add = $value;
                    }
                    $order->addDiscount($objDiscount->id, $objDiscount->name, $amount_to_add);
                    $total_discount_value += $amount_to_add;
                    if ($id_order_state != Configuration::get('PS_OS_ERROR') and $id_order_state != Configuration::get('PS_OS_CANCELED')) {
                        $objDiscount->quantity = $objDiscount->quantity - 1;
                    }
                    $objDiscount->update();
                    $discountsList .= '<tr style="background-color:#EBECEE;">
							<td colspan="4" style="padding: 0.6em 0.4em; text-align: right;">' . $this->l('Voucher code:') . ' ' . $objDiscount->name . '</td>
							<td style="padding: 0.6em 0.4em; text-align: right;">' . ($value != 0.0 ? '-' : '') . Tools::displayPrice($value, $currency, false) . '</td>
					</tr>';
                }
                // Specify order id for message
                $oldMessage = Message::getMessageByCartId((int) $cart->id);
                if ($oldMessage) {
                    $message = new Message((int) $oldMessage['id_message']);
                    $message->id_order = (int) $order->id;
                    $message->update();
                }
                // Hook new order
                $orderStatus = new OrderState((int) $id_order_state, (int) $order->id_lang);
                if (Validate::isLoadedObject($orderStatus)) {
                    Hook::newOrder($cart, $order, $customer, $currency, $orderStatus);
                    foreach ($cart->getProducts() as $product) {
                        if ($orderStatus->logable) {
                            ProductSale::addProductSale((int) $product['id_product'], (int) $product['cart_quantity']);
                        }
                    }
                }
                if (isset($outOfStock) && $outOfStock && Configuration::get('PS_STOCK_MANAGEMENT')) {
                    $history = new OrderHistory();
                    $history->id_order = (int) $order->id;
                    $history->changeIdOrderState(Configuration::get('PS_OS_OUTOFSTOCK'), (int) $order->id);
                    $history->addWithemail();
                }
                // Set order state in order history ONLY even if the "out of stock" status has not been yet reached
                // So you migth have two order states
                $new_history = new OrderHistory();
                $new_history->id_order = (int) $order->id;
                $new_history->changeIdOrderState((int) $id_order_state, (int) $order->id);
                $new_history->addWithemail(true, $extraVars);
                // Order is reloaded because the status just changed
                $order = new Order($order->id);
                // Send an e-mail to customer
                if ($id_order_state != Configuration::get('PS_OS_ERROR') and $id_order_state != Configuration::get('PS_OS_CANCELED') and $customer->id) {
                    $invoice = new Address((int) $order->id_address_invoice);
                    $delivery = new Address((int) $order->id_address_delivery);
                    $carrier = new Carrier((int) $order->id_carrier, $order->id_lang);
                    $delivery_state = $delivery->id_state ? new State((int) $delivery->id_state) : false;
                    $invoice_state = $invoice->id_state ? new State((int) $invoice->id_state) : false;
                    $data = array('{firstname}' => $customer->firstname, '{lastname}' => $customer->lastname, '{email}' => $customer->email, '{delivery_block_txt}' => $this->_getFormatedAddress($delivery, "\n"), '{invoice_block_txt}' => $this->_getFormatedAddress($invoice, "\n"), '{delivery_block_html}' => $this->_getFormatedAddress($delivery, "<br />", array('firstname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>', 'lastname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>')), '{invoice_block_html}' => $this->_getFormatedAddress($invoice, "<br />", array('firstname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>', 'lastname' => '<span style="color:#DB3484; font-weight:bold;">%s</span>')), '{delivery_company}' => $delivery->company, '{delivery_firstname}' => $delivery->firstname, '{delivery_lastname}' => $delivery->lastname, '{delivery_address1}' => $delivery->address1, '{delivery_address2}' => $delivery->address2, '{delivery_city}' => $delivery->city, '{delivery_postal_code}' => $delivery->postcode, '{delivery_country}' => $delivery->country, '{delivery_state}' => $delivery->id_state ? $delivery_state->name : '', '{delivery_phone}' => $delivery->phone ? $delivery->phone : $delivery->phone_mobile, '{delivery_other}' => $delivery->other, '{invoice_company}' => $invoice->company, '{invoice_vat_number}' => $invoice->vat_number, '{invoice_firstname}' => $invoice->firstname, '{invoice_lastname}' => $invoice->lastname, '{invoice_address2}' => $invoice->address2, '{invoice_address1}' => $invoice->address1, '{invoice_city}' => $invoice->city, '{invoice_postal_code}' => $invoice->postcode, '{invoice_country}' => $invoice->country, '{invoice_state}' => $invoice->id_state ? $invoice_state->name : '', '{invoice_phone}' => $invoice->phone ? $invoice->phone : $invoice->phone_mobile, '{invoice_other}' => $invoice->other, '{order_name}' => sprintf("#%06d", (int) $order->id), '{date}' => Tools::displayDate(date('Y-m-d H:i:s'), (int) $order->id_lang, 1), '{carrier}' => $carrier->name, '{payment}' => Tools::substr($order->payment, 0, 32), '{products}' => $productsList, '{discounts}' => $discountsList, '{total_paid}' => Tools::displayPrice($order->total_paid, $currency, false), '{total_products}' => Tools::displayPrice($order->total_paid - $order->total_shipping - $order->total_wrapping + $order->total_discounts, $currency, false), '{total_discounts}' => Tools::displayPrice($order->total_discounts, $currency, false), '{total_shipping}' => Tools::displayPrice($order->total_shipping, $currency, false), '{total_wrapping}' => Tools::displayPrice($order->total_wrapping, $currency, false));
                    if (is_array($extraVars)) {
                        $data = array_merge($data, $extraVars);
                    }
                    // Join PDF invoice
                    if ((int) Configuration::get('PS_INVOICE') and Validate::isLoadedObject($orderStatus) and $orderStatus->invoice and $order->invoice_number) {
                        $fileAttachment['content'] = PDF::invoice($order, 'S');
                        $fileAttachment['name'] = Configuration::get('PS_INVOICE_PREFIX', (int) $order->id_lang) . sprintf('%06d', $order->invoice_number) . '.pdf';
                        $fileAttachment['mime'] = 'application/pdf';
                    } else {
                        $fileAttachment = null;
                    }
                    if (Validate::isEmail($customer->email)) {
                        Mail::Send((int) $order->id_lang, 'order_conf', Mail::l('Order confirmation', (int) $order->id_lang), $data, $customer->email, $customer->firstname . ' ' . $customer->lastname, NULL, NULL, $fileAttachment);
                    }
                }
                $this->currentOrder = (int) $order->id;
                return true;
            } else {
                $errorMessage = Tools::displayError('Order creation failed');
                Logger::addLog($errorMessage, 4, '0000002', 'Cart', intval($order->id_cart));
                die($errorMessage);
            }
        } else {
            $errorMessage = Tools::displayError('Cart cannot be loaded or an order has already been placed using this cart');
            Logger::addLog($errorMessage, 4, '0000001', 'Cart', intval($cart->id));
            die($errorMessage);
        }
    }
curl_setopt($request, CURLOPT_HEADER, 0);
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($request, CURLOPT_POSTFIELDS, $postString);
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE);
$postResponse = curl_exec($request);
curl_close($request);
$response = explode('|', $postResponse);
if (!isset($response[7]) or !isset($response[3]) or !isset($response[9])) {
    Logger::addLog('Authorize.net returned a malformed response for cart ' . $response[7], 4);
    die('Authorize.net returned a malformed response, aborted.');
}
if ($response[0] == 3) {
    Tools::redirect('order.php?step=3&aimerror=1');
} else {
    /* Does the cart exist and is valid? */
    $cart = new Cart((int) $response[7]);
    if (!Validate::isLoadedObject($cart)) {
        Logger::addLog('Cart loading failed for cart ' . $response[7], 4);
        exit;
    }
    $customer = new Customer((int) $cart->id_customer);
    /* Loading the object */
    $authorizeaim = new authorizeaim();
    $message = $response[3];
    if ($response[0] == 1) {
        $authorizeaim->validateOrder((int) $cart->id, Configuration::get('PS_OS_PAYMENT'), (double) $response[9], $authorizeaim->displayName, $message, NULL, NULL, false, $customer->secure_key);
    } else {
        $authorizeaim->validateOrder((int) $cart->id, Configuration::get('PS_OS_ERROR'), (double) $response[9], $authorizeaim->displayName, $message, NULL, NULL, false, $customer->secure_key);
    }
    Tools::redirect('order-confirmation.php?id_module=' . (int) $authorizeaim->id . '&id_cart=' . (int) $cart->id . '&key=' . $customer->secure_key);
}
Example #30
0
    /**
     * Validate an order in database
     * Function called from a payment module
     *
     * @param integer $id_cart Value
     * @param integer $id_order_state Value
     * @param float $amount_paid Amount really paid by customer (in the default currency)
     * @param string $payment_method Payment method (eg. 'Credit card')
     * @param string $message Message to attach to order
     */
    public function validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method = 'Unknown', $message = null, $extra_vars = array(), $currency_special = null, $dont_touch_amount = false, $secure_key = false, Shop $shop = null)
    {
        $this->context->cart = new Cart($id_cart);
        $this->context->customer = new Customer($this->context->cart->id_customer);
        $this->context->language = new Language($this->context->cart->id_lang);
        $this->context->shop = $shop ? $shop : new Shop($this->context->cart->id_shop);
        $id_currency = $currency_special ? (int) $currency_special : (int) $this->context->cart->id_currency;
        $this->context->currency = new Currency($id_currency, null, $this->context->shop->id);
        if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_delivery') {
            $context_country = $this->context->country;
        }
        $order_status = new OrderState((int) $id_order_state, (int) $this->context->language->id);
        if (!Validate::isLoadedObject($order_status)) {
            throw new PrestaShopException('Can\'t load Order state status');
        }
        if (!$this->active) {
            die(Tools::displayError());
        }
        // Does order already exists ?
        if (Validate::isLoadedObject($this->context->cart) && $this->context->cart->OrderExists() == false) {
            if ($secure_key !== false && $secure_key != $this->context->cart->secure_key) {
                die(Tools::displayError());
            }
            // For each package, generate an order
            $delivery_option_list = $this->context->cart->getDeliveryOptionList();
            $package_list = $this->context->cart->getPackageList();
            $cart_delivery_option = $this->context->cart->getDeliveryOption();
            // If some delivery options are not defined, or not valid, use the first valid option
            foreach ($delivery_option_list as $id_address => $package) {
                if (!isset($cart_delivery_option[$id_address]) || !array_key_exists($cart_delivery_option[$id_address], $package)) {
                    foreach ($package as $key => $val) {
                        $cart_delivery_option[$id_address] = $key;
                        break;
                    }
                }
            }
            $order_list = array();
            $order_detail_list = array();
            $reference = Order::generateReference();
            $this->currentOrderReference = $reference;
            $order_creation_failed = false;
            $cart_total_paid = (double) Tools::ps_round((double) $this->context->cart->getOrderTotal(true, Cart::BOTH), 2);
            foreach ($cart_delivery_option as $id_address => $key_carriers) {
                foreach ($delivery_option_list[$id_address][$key_carriers]['carrier_list'] as $id_carrier => $data) {
                    foreach ($data['package_list'] as $id_package) {
                        // Rewrite the id_warehouse
                        $package_list[$id_address][$id_package]['id_warehouse'] = (int) $this->context->cart->getPackageIdWarehouse($package_list[$id_address][$id_package], (int) $id_carrier);
                        $package_list[$id_address][$id_package]['id_carrier'] = $id_carrier;
                    }
                }
            }
            // Make sure CarRule caches are empty
            CartRule::cleanCache();
            foreach ($package_list as $id_address => $packageByAddress) {
                foreach ($packageByAddress as $id_package => $package) {
                    $order = new Order();
                    $order->product_list = $package['product_list'];
                    if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_delivery') {
                        $address = new Address($id_address);
                        $this->context->country = new Country($address->id_country, $this->context->cart->id_lang);
                    }
                    $carrier = null;
                    if (!$this->context->cart->isVirtualCart() && isset($package['id_carrier'])) {
                        $carrier = new Carrier($package['id_carrier'], $this->context->cart->id_lang);
                        $order->id_carrier = (int) $carrier->id;
                        $id_carrier = (int) $carrier->id;
                    } else {
                        $order->id_carrier = 0;
                        $id_carrier = 0;
                    }
                    $order->id_customer = (int) $this->context->cart->id_customer;
                    $order->id_address_invoice = (int) $this->context->cart->id_address_invoice;
                    $order->id_address_delivery = (int) $id_address;
                    $order->id_currency = $this->context->currency->id;
                    $order->id_lang = (int) $this->context->cart->id_lang;
                    $order->id_cart = (int) $this->context->cart->id;
                    $order->reference = $reference;
                    $order->id_shop = (int) $this->context->shop->id;
                    $order->id_shop_group = (int) $this->context->shop->id_shop_group;
                    $order->secure_key = $secure_key ? pSQL($secure_key) : pSQL($this->context->customer->secure_key);
                    $order->payment = $payment_method;
                    if (isset($this->name)) {
                        $order->module = $this->name;
                    }
                    $order->recyclable = $this->context->cart->recyclable;
                    $order->gift = (int) $this->context->cart->gift;
                    $order->gift_message = $this->context->cart->gift_message;
                    $order->mobile_theme = $this->context->cart->mobile_theme;
                    $order->conversion_rate = $this->context->currency->conversion_rate;
                    $amount_paid = !$dont_touch_amount ? Tools::ps_round((double) $amount_paid, 2) : $amount_paid;
                    $order->total_paid_real = 0;
                    $order->total_products = (double) $this->context->cart->getOrderTotal(false, Cart::ONLY_PRODUCTS, $order->product_list, $id_carrier);
                    $order->total_products_wt = (double) $this->context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS, $order->product_list, $id_carrier);
                    $order->total_discounts_tax_excl = (double) abs($this->context->cart->getOrderTotal(false, Cart::ONLY_DISCOUNTS, $order->product_list, $id_carrier));
                    $order->total_discounts_tax_incl = (double) abs($this->context->cart->getOrderTotal(true, Cart::ONLY_DISCOUNTS, $order->product_list, $id_carrier));
                    $order->total_discounts = $order->total_discounts_tax_incl;
                    $order->total_shipping_tax_excl = (double) $this->context->cart->getPackageShippingCost((int) $id_carrier, false, null, $order->product_list);
                    $order->total_shipping_tax_incl = (double) $this->context->cart->getPackageShippingCost((int) $id_carrier, true, null, $order->product_list);
                    $order->total_shipping = $order->total_shipping_tax_incl;
                    if (!is_null($carrier) && Validate::isLoadedObject($carrier)) {
                        $order->carrier_tax_rate = $carrier->getTaxesRate(new Address($this->context->cart->{Configuration::get('PS_TAX_ADDRESS_TYPE')}));
                    }
                    $order->total_wrapping_tax_excl = (double) abs($this->context->cart->getOrderTotal(false, Cart::ONLY_WRAPPING, $order->product_list, $id_carrier));
                    $order->total_wrapping_tax_incl = (double) abs($this->context->cart->getOrderTotal(true, Cart::ONLY_WRAPPING, $order->product_list, $id_carrier));
                    $order->total_wrapping = $order->total_wrapping_tax_incl;
                    $order->total_paid_tax_excl = (double) Tools::ps_round((double) $this->context->cart->getOrderTotal(false, Cart::BOTH, $order->product_list, $id_carrier), 2);
                    $order->total_paid_tax_incl = (double) Tools::ps_round((double) $this->context->cart->getOrderTotal(true, Cart::BOTH, $order->product_list, $id_carrier), 2);
                    $order->total_paid = $order->total_paid_tax_incl;
                    $order->invoice_date = '0000-00-00 00:00:00';
                    $order->delivery_date = '0000-00-00 00:00:00';
                    // Creating order
                    $result = $order->add();
                    if (!$result) {
                        throw new PrestaShopException('Can\'t save Order');
                    }
                    // Amount paid by customer is not the right one -> Status = payment error
                    // We don't use the following condition to avoid the float precision issues : http://www.php.net/manual/en/language.types.float.php
                    // if ($order->total_paid != $order->total_paid_real)
                    // We use number_format in order to compare two string
                    if ($order_status->logable && number_format($cart_total_paid, 2) != number_format($amount_paid, 2)) {
                        $id_order_state = Configuration::get('PS_OS_ERROR');
                    }
                    $order_list[] = $order;
                    // Insert new Order detail list using cart for the current order
                    $order_detail = new OrderDetail(null, null, $this->context);
                    $order_detail->createList($order, $this->context->cart, $id_order_state, $order->product_list, 0, true, $package_list[$id_address][$id_package]['id_warehouse']);
                    $order_detail_list[] = $order_detail;
                    // Adding an entry in order_carrier table
                    if (!is_null($carrier)) {
                        $order_carrier = new OrderCarrier();
                        $order_carrier->id_order = (int) $order->id;
                        $order_carrier->id_carrier = (int) $id_carrier;
                        $order_carrier->weight = (double) $order->getTotalWeight();
                        $order_carrier->shipping_cost_tax_excl = (double) $order->total_shipping_tax_excl;
                        $order_carrier->shipping_cost_tax_incl = (double) $order->total_shipping_tax_incl;
                        $order_carrier->add();
                    }
                }
            }
            // The country can only change if the address used for the calculation is the delivery address, and if multi-shipping is activated
            if (Configuration::get('PS_TAX_ADDRESS_TYPE') == 'id_address_delivery') {
                $this->context->country = $context_country;
            }
            // Register Payment only if the order status validate the order
            if ($order_status->logable) {
                // $order is the last order loop in the foreach
                // The method addOrderPayment of the class Order make a create a paymentOrder
                //     linked to the order reference and not to the order id
                if (isset($extra_vars['transaction_id'])) {
                    $transaction_id = $extra_vars['transaction_id'];
                } else {
                    $transaction_id = null;
                }
                if (!$order->addOrderPayment($amount_paid, null, $transaction_id)) {
                    throw new PrestaShopException('Can\'t save Order Payment');
                }
            }
            // Next !
            $only_one_gift = false;
            $cart_rule_used = array();
            $products = $this->context->cart->getProducts();
            $cart_rules = $this->context->cart->getCartRules();
            // Make sure CarRule caches are empty
            CartRule::cleanCache();
            foreach ($order_detail_list as $key => $order_detail) {
                $order = $order_list[$key];
                if (!$order_creation_failed && isset($order->id)) {
                    if (!$secure_key) {
                        $message .= '<br />' . Tools::displayError('Warning: the secure key is empty, check your payment account before validation');
                    }
                    // Optional message to attach to this order
                    if (isset($message) & !empty($message)) {
                        $msg = new Message();
                        $message = strip_tags($message, '<br>');
                        if (Validate::isCleanHtml($message)) {
                            $msg->message = $message;
                            $msg->id_order = intval($order->id);
                            $msg->private = 1;
                            $msg->add();
                        }
                    }
                    // Insert new Order detail list using cart for the current order
                    //$orderDetail = new OrderDetail(null, null, $this->context);
                    //$orderDetail->createList($order, $this->context->cart, $id_order_state);
                    // Construct order detail table for the email
                    $products_list = '';
                    $virtual_product = true;
                    foreach ($products as $key => $product) {
                        $price = Product::getPriceStatic((int) $product['id_product'], false, $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : null, 6, null, false, true, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                        $price_wt = Product::getPriceStatic((int) $product['id_product'], true, $product['id_product_attribute'] ? (int) $product['id_product_attribute'] : null, 2, null, false, true, $product['cart_quantity'], false, (int) $order->id_customer, (int) $order->id_cart, (int) $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')});
                        $customization_quantity = 0;
                        $customized_datas = Product::getAllCustomizedDatas((int) $order->id_cart);
                        if (isset($customized_datas[$product['id_product']][$product['id_product_attribute']])) {
                            $customization_text = '';
                            foreach ($customized_datas[$product['id_product']][$product['id_product_attribute']][$order->id_address_delivery] as $customization) {
                                if (isset($customization['datas'][Product::CUSTOMIZE_TEXTFIELD])) {
                                    foreach ($customization['datas'][Product::CUSTOMIZE_TEXTFIELD] as $text) {
                                        $customization_text .= $text['name'] . ': ' . $text['value'] . '<br />';
                                    }
                                }
                                if (isset($customization['datas'][Product::CUSTOMIZE_FILE])) {
                                    $customization_text .= sprintf(Tools::displayError('%d image(s)'), count($customization['datas'][Product::CUSTOMIZE_FILE])) . '<br />';
                                }
                                $customization_text .= '---<br />';
                            }
                            $customization_text = rtrim($customization_text, '---<br />');
                            $customization_quantity = (int) $product['customization_quantity'];
                            $products_list .= '<tr style="background-color: ' . ($key % 2 ? '#DDE2E6' : '#EBECEE') . ';">
								<td style="padding: 0.6em 0.4em;width: 15%;">' . $product['reference'] . '</td>
								<td style="padding: 0.6em 0.4em;width: 30%;"><strong>' . $product['name'] . (isset($product['attributes']) ? ' - ' . $product['attributes'] : '') . ' - ' . Tools::displayError('Customized') . (!empty($customization_text) ? ' - ' . $customization_text : '') . '</strong></td>
								<td style="padding: 0.6em 0.4em; width: 20%;">' . Tools::displayPrice(Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt, $this->context->currency, false) . '</td>
								<td style="padding: 0.6em 0.4em; width: 15%;">' . $customization_quantity . '</td>
								<td style="padding: 0.6em 0.4em; width: 20%;">' . Tools::displayPrice($customization_quantity * (Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt), $this->context->currency, false) . '</td>
							</tr>';
                        }
                        if (!$customization_quantity || (int) $product['cart_quantity'] > $customization_quantity) {
                            $products_list .= '<tr style="background-color: ' . ($key % 2 ? '#DDE2E6' : '#EBECEE') . ';">
								<td style="padding: 0.6em 0.4em;width: 15%;">' . $product['reference'] . '</td>
								<td style="padding: 0.6em 0.4em;width: 30%;"><strong>' . $product['name'] . (isset($product['attributes']) ? ' - ' . $product['attributes'] : '') . '</strong></td>
								<td style="padding: 0.6em 0.4em; width: 20%;">' . Tools::displayPrice(Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt, $this->context->currency, false) . '</td>
								<td style="padding: 0.6em 0.4em; width: 15%;">' . ((int) $product['cart_quantity'] - $customization_quantity) . '</td>
								<td style="padding: 0.6em 0.4em; width: 20%;">' . Tools::displayPrice(((int) $product['cart_quantity'] - $customization_quantity) * (Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt), $this->context->currency, false) . '</td>
							</tr>';
                        }
                        // Check if is not a virutal product for the displaying of shipping
                        if (!$product['is_virtual']) {
                            $virtual_product &= false;
                        }
                    }
                    // end foreach ($products)
                    $cart_rules_list = '';
                    foreach ($cart_rules as $cart_rule) {
                        $package = array('id_carrier' => $order->id_carrier, 'id_address' => $order->id_address_delivery, 'products' => $order->product_list);
                        $values = array('tax_incl' => $cart_rule['obj']->getContextualValue(true, $this->context, CartRule::FILTER_ACTION_ALL_NOCAP, $package), 'tax_excl' => $cart_rule['obj']->getContextualValue(false, $this->context, CartRule::FILTER_ACTION_ALL_NOCAP, $package));
                        // If the reduction is not applicable to this order, then continue with the next one
                        if (!$values['tax_excl']) {
                            continue;
                        }
                        /* IF
                         ** - This is not multi-shipping
                         ** - The value of the voucher is greater than the total of the order
                         ** - Partial use is allowed
                         ** - This is an "amount" reduction, not a reduction in % or a gift
                         ** THEN
                         ** The voucher is cloned with a new value corresponding to the remainder
                         */
                        if (count($order_list) == 1 && $values['tax_incl'] > $order->total_products_wt && $cart_rule['obj']->partial_use == 1 && $cart_rule['obj']->reduction_amount > 0) {
                            // Create a new voucher from the original
                            $voucher = new CartRule($cart_rule['obj']->id);
                            // We need to instantiate the CartRule without lang parameter to allow saving it
                            unset($voucher->id);
                            // Set a new voucher code
                            $voucher->code = empty($voucher->code) ? substr(md5($order->id . '-' . $order->id_customer . '-' . $cart_rule['obj']->id), 0, 16) : $voucher->code . '-2';
                            if (preg_match('/\\-([0-9]{1,2})\\-([0-9]{1,2})$/', $voucher->code, $matches) && $matches[1] == $matches[2]) {
                                $voucher->code = preg_replace('/' . $matches[0] . '$/', '-' . (intval($matches[1]) + 1), $voucher->code);
                            }
                            // Set the new voucher value
                            if ($voucher->reduction_tax) {
                                $voucher->reduction_amount = $values['tax_incl'] - $order->total_products_wt;
                            } else {
                                $voucher->reduction_amount = $values['tax_excl'] - $order->total_products;
                            }
                            $voucher->id_customer = $order->id_customer;
                            $voucher->quantity = 1;
                            if ($voucher->add()) {
                                // If the voucher has conditions, they are now copied to the new voucher
                                CartRule::copyConditions($cart_rule['obj']->id, $voucher->id);
                                $params = array('{voucher_amount}' => Tools::displayPrice($voucher->reduction_amount, $this->context->currency, false), '{voucher_num}' => $voucher->code, '{firstname}' => $this->context->customer->firstname, '{lastname}' => $this->context->customer->lastname, '{id_order}' => $order->reference, '{order_name}' => $order->getUniqReference());
                                Mail::Send((int) $order->id_lang, 'voucher', sprintf(Mail::l('New voucher regarding your order %s', (int) $order->id_lang), $order->reference), $params, $this->context->customer->email, $this->context->customer->firstname . ' ' . $this->context->customer->lastname, null, null, null, null, _PS_MAIL_DIR_, false, (int) $order->id_shop);
                            }
                            $values['tax_incl'] -= $values['tax_incl'] - $order->total_products_wt;
                            $values['tax_excl'] -= $values['tax_excl'] - $order->total_products;
                        }
                        $order->addCartRule($cart_rule['obj']->id, $cart_rule['obj']->name, $values, 0, $cart_rule['obj']->free_shipping);
                        if ($id_order_state != Configuration::get('PS_OS_ERROR') && $id_order_state != Configuration::get('PS_OS_CANCELED') && !in_array($cart_rule['obj']->id, $cart_rule_used)) {
                            $cart_rule_used[] = $cart_rule['obj']->id;
                            // Create a new instance of Cart Rule without id_lang, in order to update its quantity
                            $cart_rule_to_update = new CartRule($cart_rule['obj']->id);
                            $cart_rule_to_update->quantity = max(0, $cart_rule_to_update->quantity - 1);
                            $cart_rule_to_update->update();
                        }
                        $cart_rules_list .= '
						<tr>
							<td colspan="4" style="padding:0.6em 0.4em;text-align:right">' . Tools::displayError('Voucher name:') . ' ' . $cart_rule['obj']->name . '</td>
							<td style="padding:0.6em 0.4em;text-align:right">' . ($values['tax_incl'] != 0.0 ? '-' : '') . Tools::displayPrice($values['tax_incl'], $this->context->currency, false) . '</td>
						</tr>';
                    }
                    // Specify order id for message
                    $old_message = Message::getMessageByCartId((int) $this->context->cart->id);
                    if ($old_message) {
                        $update_message = new Message((int) $old_message['id_message']);
                        $update_message->id_order = (int) $order->id;
                        $update_message->update();
                        // Add this message in the customer thread
                        $customer_thread = new CustomerThread();
                        $customer_thread->id_contact = 0;
                        $customer_thread->id_customer = (int) $order->id_customer;
                        $customer_thread->id_shop = (int) $this->context->shop->id;
                        $customer_thread->id_order = (int) $order->id;
                        $customer_thread->id_lang = (int) $this->context->language->id;
                        $customer_thread->email = $this->context->customer->email;
                        $customer_thread->status = 'open';
                        $customer_thread->token = Tools::passwdGen(12);
                        $customer_thread->add();
                        $customer_message = new CustomerMessage();
                        $customer_message->id_customer_thread = $customer_thread->id;
                        $customer_message->id_employee = 0;
                        $customer_message->message = $update_message->message;
                        $customer_message->private = 0;
                        if (!$customer_message->add()) {
                            $this->errors[] = Tools::displayError('An error occurred while saving message');
                        }
                    }
                    // Hook validate order
                    Hook::exec('actionValidateOrder', array('cart' => $this->context->cart, 'order' => $order, 'customer' => $this->context->customer, 'currency' => $this->context->currency, 'orderStatus' => $order_status));
                    foreach ($this->context->cart->getProducts() as $product) {
                        if ($order_status->logable) {
                            ProductSale::addProductSale((int) $product['id_product'], (int) $product['cart_quantity']);
                        }
                    }
                    if (Configuration::get('PS_STOCK_MANAGEMENT') && $order_detail->getStockState()) {
                        $history = new OrderHistory();
                        $history->id_order = (int) $order->id;
                        $history->changeIdOrderState(Configuration::get('PS_OS_OUTOFSTOCK'), $order, true);
                        $history->addWithemail();
                    }
                    // Set order state in order history ONLY even if the "out of stock" status has not been yet reached
                    // So you migth have two order states
                    $new_history = new OrderHistory();
                    $new_history->id_order = (int) $order->id;
                    $new_history->changeIdOrderState((int) $id_order_state, $order, true);
                    $new_history->addWithemail(true, $extra_vars);
                    unset($order_detail);
                    // Order is reloaded because the status just changed
                    $order = new Order($order->id);
                    // Send an e-mail to customer (one order = one email)
                    if ($id_order_state != Configuration::get('PS_OS_ERROR') && $id_order_state != Configuration::get('PS_OS_CANCELED') && $this->context->customer->id) {
                        $invoice = new Address($order->id_address_invoice);
                        $delivery = new Address($order->id_address_delivery);
                        $delivery_state = $delivery->id_state ? new State($delivery->id_state) : false;
                        $invoice_state = $invoice->id_state ? new State($invoice->id_state) : false;
                        $data = array('{firstname}' => $this->context->customer->firstname, '{lastname}' => $this->context->customer->lastname, '{email}' => $this->context->customer->email, '{delivery_block_txt}' => $this->_getFormatedAddress($delivery, "\n"), '{invoice_block_txt}' => $this->_getFormatedAddress($invoice, "\n"), '{delivery_block_html}' => $this->_getFormatedAddress($delivery, '<br />', array('firstname' => '<span style="font-weight:bold;">%s</span>', 'lastname' => '<span style="font-weight:bold;">%s</span>')), '{invoice_block_html}' => $this->_getFormatedAddress($invoice, '<br />', array('firstname' => '<span style="font-weight:bold;">%s</span>', 'lastname' => '<span style="font-weight:bold;">%s</span>')), '{delivery_company}' => $delivery->company, '{delivery_firstname}' => $delivery->firstname, '{delivery_lastname}' => $delivery->lastname, '{delivery_address1}' => $delivery->address1, '{delivery_address2}' => $delivery->address2, '{delivery_city}' => $delivery->city, '{delivery_postal_code}' => $delivery->postcode, '{delivery_country}' => $delivery->country, '{delivery_state}' => $delivery->id_state ? $delivery_state->name : '', '{delivery_phone}' => $delivery->phone ? $delivery->phone : $delivery->phone_mobile, '{delivery_other}' => $delivery->other, '{invoice_company}' => $invoice->company, '{invoice_vat_number}' => $invoice->vat_number, '{invoice_firstname}' => $invoice->firstname, '{invoice_lastname}' => $invoice->lastname, '{invoice_address2}' => $invoice->address2, '{invoice_address1}' => $invoice->address1, '{invoice_city}' => $invoice->city, '{invoice_postal_code}' => $invoice->postcode, '{invoice_country}' => $invoice->country, '{invoice_state}' => $invoice->id_state ? $invoice_state->name : '', '{invoice_phone}' => $invoice->phone ? $invoice->phone : $invoice->phone_mobile, '{invoice_other}' => $invoice->other, '{order_name}' => $order->getUniqReference(), '{date}' => Tools::displayDate(date('Y-m-d H:i:s'), (int) $order->id_lang, 1), '{carrier}' => $virtual_product ? Tools::displayError('No carrier') : $carrier->name, '{payment}' => Tools::substr($order->payment, 0, 32), '{products}' => $this->formatProductAndVoucherForEmail($products_list), '{discounts}' => $this->formatProductAndVoucherForEmail($cart_rules_list), '{total_paid}' => Tools::displayPrice($order->total_paid, $this->context->currency, false), '{total_products}' => Tools::displayPrice($order->total_paid - $order->total_shipping - $order->total_wrapping + $order->total_discounts, $this->context->currency, false), '{total_discounts}' => Tools::displayPrice($order->total_discounts, $this->context->currency, false), '{total_shipping}' => Tools::displayPrice($order->total_shipping, $this->context->currency, false), '{total_wrapping}' => Tools::displayPrice($order->total_wrapping, $this->context->currency, false));
                        if (is_array($extra_vars)) {
                            $data = array_merge($data, $extra_vars);
                        }
                        // Join PDF invoice
                        if ((int) Configuration::get('PS_INVOICE') && $order_status->invoice && $order->invoice_number) {
                            $pdf = new PDF($order->getInvoicesCollection(), PDF::TEMPLATE_INVOICE, $this->context->smarty);
                            $file_attachement['content'] = $pdf->render(false);
                            $file_attachement['name'] = Configuration::get('PS_INVOICE_PREFIX', (int) $order->id_lang, null, $order->id_shop) . sprintf('%06d', $order->invoice_number) . '.pdf';
                            $file_attachement['mime'] = 'application/pdf';
                        } else {
                            $file_attachement = null;
                        }
                        if (Validate::isEmail($this->context->customer->email)) {
                            Mail::Send((int) $order->id_lang, 'order_conf', Mail::l('Order confirmation', (int) $order->id_lang), $data, $this->context->customer->email, $this->context->customer->firstname . ' ' . $this->context->customer->lastname, null, null, $file_attachement, null, _PS_MAIL_DIR_, false, (int) $order->id_shop);
                        }
                    }
                    // updates stock in shops
                    if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
                        $product_list = $order->getProducts();
                        foreach ($product_list as $product) {
                            // if the available quantities depends on the physical stock
                            if (StockAvailable::dependsOnStock($product['product_id'])) {
                                // synchronizes
                                StockAvailable::synchronize($product['product_id'], $order->id_shop);
                            }
                        }
                    }
                } else {
                    $error = Tools::displayError('Order creation failed');
                    Logger::addLog($error, 4, '0000002', 'Cart', intval($order->id_cart));
                    die($error);
                }
            }
            // End foreach $order_detail_list
            // Use the last order as currentOrder
            $this->currentOrder = (int) $order->id;
            return true;
        } else {
            $error = Tools::displayError('Cart cannot be loaded or an order has already been placed using this cart');
            Logger::addLog($error, 4, '0000001', 'Cart', intval($this->context->cart->id));
            die($error);
        }
    }