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()); }
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; }
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; }
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); } }
/** * 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']); } }
} /* 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:
/** * @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'); }
/** * @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'];
/** * 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']); } }
/** * 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(); }
/** * @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'); }
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; } }
public static function validateAnsver($message) { Logger::addLog('robokassa: ' . $message); die($message); }
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('{' => '{', '}' => '}', '<' => '<', '>' => '>')); 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); } } }
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;
/** * * @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(); }
/** * 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); }
/** * 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'] : ' ') . '</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'] : ' ') . '</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); }
/** * 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); } }