Linux altar53.supremepanel53.com 4.18.0-553.8.1.lve.el8.x86_64 #1 SMP Thu Jul 4 16:24:39 UTC 2024 x86_64
/ home/ bdapparelinfo/ dhakazone.com/ catalog/ controller/ extension/ payment/ |
|
<?php class ControllerExtensionPaymentKlarnaCheckout extends Controller { public function index() { $this->load->language('extension/payment/klarna_checkout'); $this->load->model('extension/payment/klarna_checkout'); $this->load->model('localisation/country'); $this->document->setTitle($this->language->get('heading_title')); $data['column_left'] = $this->load->controller('common/column_left'); $data['column_right'] = $this->load->controller('common/column_right'); $data['content_top'] = $this->load->controller('common/content_top'); $data['content_bottom'] = $this->load->controller('common/content_bottom'); $data['footer'] = $this->load->controller('common/footer'); $data['header'] = $this->load->controller('common/header'); $this->response->setOutput($this->load->view('extension/payment/klarna_checkout', $data)); } public function main() { $this->load->language('extension/payment/klarna_checkout'); $this->load->model('extension/payment/klarna_checkout'); $this->load->model('localisation/country'); $redirect = false; $html_snippet = ''; // Validate cart has products and has stock. if ((!$this->cart->hasProducts() && empty($this->session->data['vouchers'])) || (!$this->cart->hasStock() && !$this->config->get('config_stock_checkout'))) { $redirect = $this->url->link('checkout/cart'); } // Validate minimum quantity requirements. $products = $this->cart->getProducts(); foreach ($products as $product) { $product_total = 0; foreach ($products as $product_2) { if ($product_2['product_id'] == $product['product_id']) { $product_total += $product_2['quantity']; } } if ($product['minimum'] > $product_total) { $redirect = $this->url->link('checkout/cart'); } } // Validate cart has recurring products if ($this->cart->hasRecurringProducts()) { $redirect = $this->url->link('checkout/cart'); } list($totals, $taxes, $total) = $this->model_extension_payment_klarna_checkout->getTotals(); if ($this->config->get('klarna_checkout_total') > 0 && $this->config->get('klarna_checkout_total') > $total) { $redirect = $this->url->link('checkout/cart'); } if (!$this->config->get('klarna_checkout_status')) { $redirect = $this->url->link('checkout/cart'); } if ($this->model_extension_payment_klarna_checkout->checkForPaymentTaxes($products)) { $redirect = $this->url->link('checkout/cart'); } $text_title = $this->language->get('text_title'); unset($this->session->data['success']); $this->setPayment(); $this->setShipping(); $this->session->data['payment_method'] = array( 'code' => 'klarna_checkout', 'title' => $text_title, 'terms' => $this->url->link('information/information', 'information_id=' . $this->config->get('klarna_checkout_terms'), true), 'sort_order' => '1' ); // Shipping $unset_shipping_method = true; if (isset($this->session->data['shipping_method']) && isset($this->session->data['shipping_methods'])) { foreach ($this->session->data['shipping_methods'] as $shipping_method) { if ($shipping_method['quote']) { foreach ($shipping_method['quote'] as $quote) { if ($quote['code'] == $this->session->data['shipping_method']['code']) { $unset_shipping_method = false; break 2; } } } } } if ($unset_shipping_method) { unset($this->session->data['shipping_method']); } if ((!isset($this->session->data['shipping_method']) || empty($this->session->data['shipping_method'])) && (isset($this->session->data['shipping_methods']) && !empty($this->session->data['shipping_methods']))) { $this->session->data['shipping_method'] = $this->model_extension_payment_klarna_checkout->getDefaultShippingMethod($this->session->data['shipping_methods']); } //Klarna Connector list($klarna_account, $connector) = $this->model_extension_payment_klarna_checkout->getConnector($this->config->get('klarna_checkout_account'), $this->session->data['currency']); if (!$klarna_account || !$connector) { $redirect = $this->url->link('checkout/cart'); } if (!$redirect) { // Get currency code and currency value to use to calculate taxes // Build order_lines $create_order = true; $klarna_checkout = false; $this->createOrder(); list($klarna_order_data, $encrypted_order_data) = $this->klarnaOrderData($klarna_account); if (isset($this->session->data['klarna_checkout_currency']) && $this->session->data['klarna_checkout_currency'] != $this->session->data['currency']) { $this->model_extension_payment_klarna_checkout->log('Currency changed, unsetting kc order id'); unset($this->session->data['klarna_checkout_order_id']); unset($this->session->data['klarna_checkout_data']); } $this->session->data['klarna_checkout_currency'] = $this->session->data['currency']; // Fetch or create order if (isset($this->session->data['klarna_checkout_order_id'])) { $retrieve = $this->model_extension_payment_klarna_checkout->orderRetrieve($connector, $this->session->data['klarna_checkout_order_id']); if ($retrieve) { //If address has changed, unset klarna_checkout_order_id and create new order $address_change = false; if (isset($this->session->data['klarna_checkout_data']) && $this->session->data['klarna_checkout_data']) { if (isset($this->session->data['klarna_checkout_data']['zone_code'])) { $kc_region = $this->session->data['klarna_checkout_data']['zone_code']; } else { $kc_region = ''; } if (isset($this->session->data['klarna_checkout_data']['iso_code_2'])) { $kc_country = $this->session->data['klarna_checkout_data']['iso_code_2']; } else { $kc_country = ''; } if (isset($this->session->data['shipping_address']['zone_code'])) { $oc_region = $this->session->data['shipping_address']['zone_code']; } else { $oc_region = ''; } if (isset($this->session->data['shipping_address']['iso_code_2'])) { $oc_country = $this->session->data['shipping_address']['iso_code_2']; } else { $oc_country = ''; } $kc_address = array( 'region' => $kc_region, 'country' => $kc_country, ); $oc_address = array( 'region' => $oc_region, 'country' => $oc_country, ); //If address has changed, dont use retrieved order, create new one instead if (array_diff(array_map('strtolower', $kc_address), array_map('strtolower', $oc_address))) { $address_change = true; } } if (!$address_change) { $this->model_extension_payment_klarna_checkout->log('Order Updated'); $this->model_extension_payment_klarna_checkout->log($klarna_order_data); $create_order = false; $update = $this->model_extension_payment_klarna_checkout->orderUpdate($connector, $this->session->data['klarna_checkout_order_id'], $klarna_order_data); if ($update) { $klarna_checkout = $update->fetch(); $this->model_extension_payment_klarna_checkout->updateOrder($this->session->data['order_id'], $klarna_checkout['order_id'], $encrypted_order_data); } } } } if ($create_order) { $this->model_extension_payment_klarna_checkout->log('Order Created'); $this->model_extension_payment_klarna_checkout->log($klarna_order_data); unset($this->session->data['klarna_checkout_data']); $create = $this->model_extension_payment_klarna_checkout->orderCreate($connector, $klarna_order_data); if ($create) { $klarna_checkout = $create->fetch(); $this->model_extension_payment_klarna_checkout->addOrder($this->session->data['order_id'], $klarna_checkout['order_id'], $encrypted_order_data); } } if ($klarna_checkout) { $this->session->data['klarna_checkout_order_id'] = $klarna_checkout['order_id']; $html_snippet = $klarna_checkout['html_snippet']; } } if (isset($this->request->post['response']) && $this->request->post['response'] == 'template') { $data['redirect'] = $redirect; $data['klarna_checkout'] = $html_snippet; $this->response->setOutput($this->load->view('extension/payment/klarna_checkout_main', $data)); } elseif (isset($this->request->post['response']) && $this->request->post['response'] == 'json') { $json['redirect'] = $redirect; $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($json)); } } public function sidebar() { $this->load->language('checkout/checkout'); $this->load->language('extension/payment/klarna_checkout'); $this->load->model('extension/payment/klarna_checkout'); if (!$this->config->get('klarna_checkout_status')) { return false; } $this->setPayment(); $this->setShipping(); // Shipping $unset_shipping_method = true; if (isset($this->session->data['shipping_method']) && isset($this->session->data['shipping_methods'])) { foreach ($this->session->data['shipping_methods'] as $shipping_method) { if ($shipping_method['quote']) { foreach ($shipping_method['quote'] as $quote) { if ($quote['code'] == $this->session->data['shipping_method']['code']) { $unset_shipping_method = false; break 2; } } } } } if ($unset_shipping_method) { unset($this->session->data['shipping_method']); } if ((!isset($this->session->data['shipping_method']) || empty($this->session->data['shipping_method'])) && (isset($this->session->data['shipping_methods']) && !empty($this->session->data['shipping_methods']))) { $this->session->data['shipping_method'] = $this->model_extension_payment_klarna_checkout->getDefaultShippingMethod($this->session->data['shipping_methods']); } $data['shipping_required'] = $this->cart->hasShipping(); if (isset($this->session->data['shipping_methods'])) { $data['shipping_methods'] = $this->session->data['shipping_methods']; } else { unset($data['shipping_method']); $data['shipping_methods'] = array(); } if (isset($this->session->data['shipping_method']['code'])) { $data['code'] = $this->session->data['shipping_method']['code']; } else { $data['code'] = ''; } $this->load->model('tool/image'); $this->load->model('tool/upload'); $data['products'] = array(); foreach ($this->cart->getProducts() as $product) { if ($product['image']) { $image = $this->model_tool_image->resize($product['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_cart_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_cart_height')); } else { $image = ''; } $option_data = array(); foreach ($product['option'] as $option) { if ($option['type'] != 'file') { $value = $option['value']; } else { $upload_info = $this->model_tool_upload->getUploadByCode($option['value']); if ($upload_info) { $value = $upload_info['name']; } else { $value = ''; } } $option_data[] = array( 'name' => $option['name'], 'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value), 'type' => $option['type'] ); } // Display prices if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) { $price = $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']); } else { $price = false; } // Display prices if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) { $total = $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax')) * $product['quantity'], $this->session->data['currency']); } else { $total = false; } $data['products'][] = array( 'cart_id' => $product['cart_id'], 'thumb' => $image, 'name' => $product['name'], 'model' => $product['model'], 'option' => $option_data, 'recurring' => ($product['recurring'] ? $product['recurring']['name'] : ''), 'quantity' => $product['quantity'], 'price' => $price, 'total' => $total, 'href' => $this->url->link('product/product', 'product_id=' . $product['product_id']) ); } // Gift Voucher $data['vouchers'] = array(); if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $key => $voucher) { $data['vouchers'][] = array( 'key' => $key, 'description' => $voucher['description'], 'amount' => $this->currency->format($voucher['amount'], $this->session->data['currency']) ); } } $totals = array(); $taxes = $this->cart->getTaxes(); $total = 0; // Because __call can not keep var references so we put them into an array. $total_data = array( 'totals' => &$totals, 'taxes' => &$taxes, 'total' => &$total ); $this->load->model('setting/extension'); $sort_order = array(); $results = $this->model_setting_extension->getExtensions('total'); foreach ($results as $key => $value) { $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); } array_multisort($sort_order, SORT_ASC, $results); foreach ($results as $result) { if ($this->config->get($result['code'] . '_status')) { $this->load->model('extension/total/' . $result['code']); // We have to put the totals in an array so that they pass by reference. $this->{'model_extension_total_' . $result['code']}->getTotal($total_data); } } $sort_order = array(); foreach ($totals as $key => $value) { $sort_order[$key] = $value['sort_order']; } array_multisort($sort_order, SORT_ASC, $totals); $data['totals'] = array(); foreach ($totals as $total) { $data['totals'][] = array( 'title' => $total['title'], 'text' => $this->currency->format($total['value'], $this->session->data['currency']) ); } $this->response->setOutput($this->load->view('extension/payment/klarna_checkout_sidebar', $data)); } public function shippingAddress() { $this->load->model('extension/payment/klarna_checkout'); $this->load->model('localisation/zone'); if (!$this->config->get('klarna_checkout_status')) { return false; } $json = array(); unset($this->session->data['shipping_address']); unset($this->session->data['shipping_methods']); if (($this->request->server['REQUEST_METHOD'] == 'POST') && isset($this->request->post['country'])) { $country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode3($this->request->post['country']); if ($country_info) { // Set default zone for shipping calculations. Get overwritten by correct data when order is confirmed $zones = $this->model_localisation_zone->getZonesByCountryId($country_info['country_id']); $zone = array(); if (isset($this->request->post['region']) && !empty($this->request->post['region'])) { $zone = $this->model_extension_payment_klarna_checkout->getZoneByCode($this->request->post['region'], $country_info['country_id']); } if ($zone || $zones) { $this->session->data['shipping_address'] = array( 'address_id' => null, 'firstname' => utf8_substr($this->request->post['given_name'], 0, 32), 'lastname' => utf8_substr($this->request->post['family_name'], 0, 32), 'company' => null, 'address_1' => utf8_substr($this->request->post['street_address'], 0, 128), 'address_2' => utf8_substr($this->request->post['street_address'], 129, 256), 'postcode' => utf8_substr($this->request->post['postal_code'], 0, 10), 'city' => utf8_substr($this->request->post['city'], 0, 128), 'zone_id' => ($zone ? $zone['zone_id'] : $zones[0]['zone_id']), 'zone' => ($zone ? $zone['name'] : $zones[0]['name']), 'zone_code' => ($zone ? $zone['code'] : $zones[0]['code']), 'country_id' => $country_info['country_id'], 'country' => $country_info['name'], 'iso_code_2' => $country_info['iso_code_2'], 'iso_code_3' => $country_info['iso_code_3'], 'address_format' => $country_info['address_format'], 'custom_field' => array(), ); $this->tax->unsetRates(); $this->tax->setShippingAddress($this->session->data['shipping_address']['country_id'], $this->session->data['shipping_address']['zone_id']); $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); } } else { $this->model_extension_payment_klarna_checkout->log('Couldnt find country: ' . $this->request->post['country']); } } $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($json)); } public function cartTotal() { $this->load->language('checkout/cart'); if (!$this->config->get('klarna_checkout_status')) { return false; } // Totals $this->load->model('setting/extension'); $totals = array(); $taxes = $this->cart->getTaxes(); $total = 0; // Because __call can not keep var references so we put them into an array. $total_data = array( 'totals' => &$totals, 'taxes' => &$taxes, 'total' => &$total ); // Display prices if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) { $sort_order = array(); $results = $this->model_setting_extension->getExtensions('total'); foreach ($results as $key => $value) { $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); } array_multisort($sort_order, SORT_ASC, $results); foreach ($results as $result) { if ($this->config->get($result['code'] . '_status')) { $this->load->model('extension/total/' . $result['code']); // We have to put the totals in an array so that they pass by reference. $this->{'model_extension_total_' . $result['code']}->getTotal($total_data); } } $sort_order = array(); foreach ($totals as $key => $value) { $sort_order[$key] = $value['sort_order']; } array_multisort($sort_order, SORT_ASC, $totals); $total = sprintf($this->language->get('text_items'), $this->cart->countProducts() + (isset($this->session->data['vouchers']) ? count($this->session->data['vouchers']) : 0), $this->currency->format($total, $this->session->data['currency'])); } $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($total)); } public function addressUpdate() { $this->load->language('extension/payment/klarna_checkout'); $this->load->model('account/customer'); $this->load->model('checkout/order'); $this->load->model('extension/payment/klarna_checkout'); $this->load->model('localisation/zone'); if (!$this->config->get('klarna_checkout_status')) { return false; } $process = true; $request = json_decode(file_get_contents('php://input')); $json = array(); $http_response_code = 400; // Check to see if request data is complete if (!$request || !isset($request->order_lines) || empty($request->order_lines) || !isset($request->shipping_address) || empty($request->shipping_address)) { $this->model_extension_payment_klarna_checkout->log('Request data incomplete. Full request below:'); $this->model_extension_payment_klarna_checkout->log($request); $process = false; } // Get Klarna order info from db if ($process) { $order_id = null; foreach ($request->order_lines as $order_line) { if ($order_line->type == 'physical' || $order_line->type == 'digital' || $order_line->type == 'gift_card') { $order_id = $this->encryption->decrypt($this->config->get('config_encryption'), $order_line->merchant_data); break; } } if ($order_id) { // Get klarna order data from db $klarna_checkout_order = $this->model_extension_payment_klarna_checkout->getOrderByOrderId($order_id); if (!$klarna_checkout_order || !$klarna_checkout_order['data']) { $this->model_extension_payment_klarna_checkout->log('No klarna order found using order_id: ' . $order_id); $process = false; } } else { $process = false; } } if ($process) { $klarna_checkout_order_data = json_decode($this->encryption->decrypt($this->config->get('config_encryption'), $klarna_checkout_order['data']), true); // Check credentials in request with ones stored in db $valid_request = false; foreach ($this->config->get('klarna_checkout_account') as $account) { if (($account['merchant_id'] == $klarna_checkout_order_data['merchant_id']) && ($account['secret'] == $klarna_checkout_order_data['secret'])) { $valid_request = true; break; } } if (!$valid_request) { $this->model_extension_payment_klarna_checkout->log('Cannot validate request. Terminating.'); $process = false; } } // Request is valid, we can spoof/simulate the customer to calculate shipping if ($process) { session_destroy(); session_id($klarna_checkout_order_data['session_id']); session_start(); $this->session->start('default', $klarna_checkout_order_data['session_key']); if ($klarna_checkout_order_data['customer_id']) { $customer_info = $this->model_account_customer->getCustomer($klarna_checkout_order_data['customer_id']); if ($customer_info) { $this->customer->login($customer_info['email'], '', true); } } $order_info = $this->model_checkout_order->getOrder($order_id); if (!$order_info) { $this->model_extension_payment_klarna_checkout->log('No order found using order_id: ' . $order_id . '. Full request below:'); $this->model_extension_payment_klarna_checkout->log($request); $process = false; } // Set more session data from the order $this->session->data['currency'] = $order_info['currency_code']; $this->session->data['language'] = $order_info['language_code']; $country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode2($request->shipping_address->country); if (!$country_info) { $this->model_extension_payment_klarna_checkout->log('No country found using: ' . $request->shipping_address->country . '. Full request below:'); $this->model_extension_payment_klarna_checkout->log($request); } if ($order_info && $country_info) { $zones = $this->model_localisation_zone->getZonesByCountryId($country_info['country_id']); $zone = array(); if (isset($request->shipping_address->region) && !empty($request->shipping_address->region)) { $zone = $this->model_extension_payment_klarna_checkout->getZoneByCode($request->shipping_address->region, $country_info['country_id']); } if ($zone || $zones) { $this->session->data['shipping_address'] = array( 'address_id' => null, 'firstname' => null, 'lastname' => null, 'company' => null, 'address_1' => null, 'address_2' => null, 'postcode' => null, 'city' => null, 'zone_id' => ($zone ? $zone['zone_id'] : $zones[0]['zone_id']), 'zone' => ($zone ? $zone['name'] : $zones[0]['name']), 'zone_code' => ($zone ? $zone['code'] : $zones[0]['code']), 'country_id' => $country_info['country_id'], 'country' => $country_info['name'], 'iso_code_2' => $country_info['iso_code_2'], 'iso_code_3' => $country_info['iso_code_3'], 'address_format' => '', 'custom_field' => array() ); $this->session->data['klarna_checkout_data'] = array( 'email' => $request->billing_address->email, 'firstname' => $request->billing_address->given_name, 'lastname' => $request->billing_address->family_name, 'telephone' => $request->billing_address->phone, 'iso_code_2' => $this->session->data['shipping_address']['iso_code_2'], 'zone_code' => $this->session->data['shipping_address']['zone_code'] ); // Unset $tax_rates $this->tax->unsetRates(); $this->tax->setShippingAddress($country_info['country_id'], ($zone ? $zone['zone_id'] : $zones[0]['zone_id'])); $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); //Check if customer is US. If so, send taxes differently if ($this->session->data['shipping_address']['iso_code_2'] === 'US') { $include_taxes = false; } else { $include_taxes = true; } $method_data = array(); $this->load->model('setting/extension'); $results = $this->model_setting_extension->getExtensions('shipping'); foreach ($results as $result) { if ($this->config->get('shipping_' . $result['code'] . '_status')) { $this->load->model('extension/shipping/' . $result['code']); $quote = $this->{'model_extension_shipping_' . $result['code']}->getQuote($this->session->data['shipping_address']); if ($quote) { $method_data[$result['code']] = array( 'title' => $quote['title'], 'quote' => $quote['quote'], 'sort_order' => $quote['sort_order'], 'error' => $quote['error'] ); } } } $sort_order = array(); foreach ($method_data as $key => $value) { $sort_order[$key] = $value['sort_order']; } array_multisort($sort_order, SORT_ASC, $method_data); $shipping_methods = $method_data; if ($shipping_methods) { list($klarna_account, $connector) = $this->model_extension_payment_klarna_checkout->getConnector($this->config->get('klarna_checkout_account'), $this->session->data['currency']); if ($klarna_account && $connector) { list($klarna_order_data, $encrypted_order_data) = $this->klarnaOrderData($klarna_account); if ($this->cart->hasShipping()) { $shipping_method = array(); if (isset($this->session->data['shipping_method']) && !empty($this->session->data['shipping_method'])) { foreach ($shipping_methods as $individual_shipping_method) { if ($individual_shipping_method['quote']) { foreach ($individual_shipping_method['quote'] as $quote) { if (($this->session->data['shipping_method']['code'] == $quote['code']) && ($this->session->data['shipping_method']['title'] == $quote['title']) && ($this->session->data['shipping_method']['cost'] == $quote['cost']) && ($this->session->data['shipping_method']['tax_class_id'] == $quote['tax_class_id'])) { $shipping_method = $quote; break 2; } } } } } // If the current shipping method isn't in the available shipping methods, assign default if (!$shipping_method) { $this->session->data['shipping_method'] = $this->model_extension_payment_klarna_checkout->getDefaultShippingMethod($shipping_methods); } $total_amount = $this->currency->format($this->tax->calculate($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id'], $include_taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100; if ($include_taxes) { $total_tax_amount = $this->currency->format($this->tax->getTax($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id']), $order_info['currency_code'], $order_info['currency_value'], false) * 100; } else { $total_tax_amount = 0; } $total_sub_amount = $this->currency->format($this->tax->calculate($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id'], false), $order_info['currency_code'], $order_info['currency_value'], false) * 100; $tax_rate = 0; if ($include_taxes && $total_tax_amount && $total_sub_amount) { $tax_rate = ($total_tax_amount / $total_sub_amount) * 100; } foreach ($klarna_order_data['order_lines'] as $key => $order_line) { if ($order_line['type'] == 'shipping_fee') { unset($klarna_order_data['order_lines'][$key]); break; } } $klarna_order_data['order_lines'][] = array( 'type' => 'shipping_fee', 'name' => $this->session->data['shipping_method']['title'], 'quantity' => '1', 'unit_price' => round($this->currency->format($this->tax->calculate($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id'], $include_taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100), 'tax_rate' => round($tax_rate * 100), 'total_amount' => round($total_amount), 'total_tax_amount' => round($total_tax_amount), 'total_discount_amount' => 0 ); } list($totals, $taxes, $total) = $this->model_extension_payment_klarna_checkout->getTotals(); //If $include_taxes is false, means customer is US so we add a new sales_tax order line with all the tax if (!$include_taxes) { foreach ($klarna_order_data['order_lines'] as $key => $order_line) { if ($order_line['type'] == 'sales_tax') { unset($klarna_order_data['order_lines'][$key]); break; } } $klarna_order_data['order_lines'][] = array( 'type' => 'sales_tax', 'name' => $this->language->get('text_sales_tax'), 'quantity' => '1', 'unit_price' => round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100), 'tax_rate' => 0, 'total_amount' => round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100), 'total_tax_amount' => 0, 'total_discount_amount' => 0 ); } $http_response_code = 200; $json = array( 'order_amount' => round($this->currency->format($total, $order_info['currency_code'], $order_info['currency_value'], false) * 100), 'order_tax_amount' => round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100), 'order_lines' => array_values($klarna_order_data['order_lines']) ); } } } } } $this->model_extension_payment_klarna_checkout->log($http_response_code); $this->model_extension_payment_klarna_checkout->log($json); http_response_code($http_response_code); $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($json)); } public function notification() { $this->load->model('extension/payment/klarna_checkout'); $this->load->model('checkout/order'); if (!$this->config->get('klarna_checkout_status')) { return false; } $request = json_decode(file_get_contents('php://input')); if (isset($request->order_id)) { $klarna_checkout_order = $this->model_extension_payment_klarna_checkout->getOrder($request->order_id); if ($klarna_checkout_order) { $order_info = $this->model_checkout_order->getOrder($klarna_checkout_order['order_id']); if ($order_info) { list($klarna_account, $connector) = $this->model_extension_payment_klarna_checkout->getConnector($this->config->get('klarna_checkout_account'), $order_info['currency_code']); if (!$klarna_account || !$connector) { $this->model_extension_payment_klarna_checkout->log('Could not getConnector'); } $retrieve = $this->model_extension_payment_klarna_checkout->omOrderRetrieve($connector, $request->order_id); $order_status_id = false; if ($retrieve) { switch ($request->event_type) { case 'FRAUD_RISK_ACCEPTED': $order_status_id = $this->config->get('klarna_checkout_order_status_fraud_accepted_id'); break; case 'FRAUD_RISK_REJECTED': $order_status_id = $this->config->get('klarna_checkout_order_status_fraud_rejected_id'); break; } } if ($order_status_id) { $this->model_checkout_order->addOrderHistory($klarna_checkout_order['order_id'], $order_status_id); } } } else { $this->model_extension_payment_klarna_checkout->log('Could not find order id using ' . $request->order_id); } } else { $this->model_extension_payment_klarna_checkout->log('$request->order_id is not set'); } } public function validation() { $this->load->model('account/customer'); $this->load->model('checkout/order'); $this->load->model('extension/payment/klarna_checkout'); if (!$this->config->get('klarna_checkout_status')) { return false; } $validate = true; $request = json_decode(file_get_contents('php://input')); $json = array(); // Check to see if request data is complete if (!$request || !isset($request->order_lines) || empty($request->order_lines) || !isset($request->shipping_address) || empty($request->shipping_address) || !isset($request->billing_address) || empty($request->billing_address)) { $this->model_extension_payment_klarna_checkout->log('Request data incomplete. Full request below:'); $this->model_extension_payment_klarna_checkout->log($request); $validate = false; } // Get Klarna order info from db if ($validate) { $order_id = null; foreach ($request->order_lines as $order_line) { if ($order_line->type == 'physical' || $order_line->type == 'digital' || $order_line->type == 'gift_card') { $order_id = $this->encryption->decrypt($this->config->get('config_encryption'), $order_line->merchant_data); break; } } if ($order_id) { // Get klarna order data from db $klarna_checkout_order = $this->model_extension_payment_klarna_checkout->getOrderByOrderId($order_id); if (!$klarna_checkout_order || !$klarna_checkout_order['data']) { $this->model_extension_payment_klarna_checkout->log('No klarna order found using order_id: ' . $order_id); $validate = false; } } else { $this->model_extension_payment_klarna_checkout->log('Cannot get decrypted order_id'); $validate = false; } } if ($validate) { $klarna_checkout_order_data = json_decode($this->encryption->decrypt($klarna_checkout_order['data']), true); // Check credentials in request with ones stored in db $valid_request = false; foreach ($this->config->get('klarna_checkout_account') as $account) { if (($account['merchant_id'] == $klarna_checkout_order_data['merchant_id']) && ($account['secret'] == $klarna_checkout_order_data['secret'])) { $valid_request = true; break; } } if (!$valid_request) { $this->model_extension_payment_klarna_checkout->log('Cannot validate request. Terminating.'); $validate = false; } } // Spoof/simulate the customer to calculate shipping if ($validate) { session_destroy(); session_id($klarna_checkout_order_data['session_id']); session_start(); $this->session->start('default', $klarna_checkout_order_data['session_key']); if ($klarna_checkout_order_data['customer_id']) { $customer_info = $this->model_account_customer->getCustomer($klarna_checkout_order_data['customer_id']); if ($customer_info) { $this->customer->login($customer_info['email'], '', true); } } // Validate cart has products and has stock. if ((!$this->cart->hasProducts() && empty($this->session->data['vouchers'])) || (!$this->cart->hasStock() && !$this->config->get('config_stock_checkout'))) { $this->model_extension_payment_klarna_checkout->log('Cart has no products or cart has no stock'); $validate = false; } // Validate minimum quantity requirements. $products = $this->cart->getProducts(); foreach ($products as $product) { $product_total = 0; foreach ($products as $product_2) { if ($product_2['product_id'] == $product['product_id']) { $product_total += $product_2['quantity']; } } if ($product['minimum'] > $product_total) { $this->model_extension_payment_klarna_checkout->log('Cart doesnt meet minimum quantities'); $validate = false; } } // Validate cart has recurring products if ($this->cart->hasRecurringProducts()) { $this->model_extension_payment_klarna_checkout->log('Cart has recurring products'); $validate = false; } } // Check order total to see if session matches post data if ($validate) { $order_info = $this->model_checkout_order->getOrder($order_id); if ($order_info) { // Unset $tax_rates and set them again using correct shipping data $this->tax->unsetRates(); $this->tax->setShippingAddress($this->session->data['shipping_address']['country_id'], $this->session->data['shipping_address']['zone_id']); $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); list($totals, $taxes, $total) = $this->model_extension_payment_klarna_checkout->getTotals(); // Check order_amount if (round($this->currency->format($total, $order_info['currency_code'], $order_info['currency_value'], false) * 100) != $request->order_amount) { $this->model_extension_payment_klarna_checkout->log('Klarna Checkout order_amount does not match session order total. Klarna Request: ' . $request->order_amount . '. OpenCart: ' . round($this->currency->format($total, $order_info['currency_code'], $order_info['currency_value'], false) * 100)); $this->model_extension_payment_klarna_checkout->log($order_info); $this->model_extension_payment_klarna_checkout->log($this->cart->getTaxes()); $validate = false; } // Check order_tax_amount if (round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100) != $request->order_tax_amount) { $this->model_extension_payment_klarna_checkout->log('Klarna Checkout order_tax_amount does not match session tax total. Totals below:'); $this->model_extension_payment_klarna_checkout->log('Session taxes:'); $this->model_extension_payment_klarna_checkout->log(round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100)); $this->model_extension_payment_klarna_checkout->log('Request taxes:'); $this->model_extension_payment_klarna_checkout->log($request->order_tax_amount); $validate = false; } } else { $this->model_extension_payment_klarna_checkout->log('Cannot find order using: ' . $order_id); $validate = false; } } // If validates, add customer's email (if guest checkout) and then send 200 response if ($validate) { if (!$this->customer->isLogged()) { $this->model_extension_payment_klarna_checkout->updateOcOrderEmail($order_id, utf8_substr($request->shipping_address->email, 0, 96)); } // Update OpenCart order with payment and shipping details $payment_country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode2($request->billing_address->country); $shipping_country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode2($request->shipping_address->country); //If region is passed, try to update OpenCart order with correct region/zone $payment_zone_info = array(); if ($payment_country_info && isset($request->billing_address->region)) { $payment_zone_info = $this->model_extension_payment_klarna_checkout->getZoneByCode($request->billing_address->region, $payment_country_info['country_id']); } $shipping_zone_info = array(); if ($shipping_country_info && isset($request->shipping_address->region)) { $shipping_zone_info = $this->model_extension_payment_klarna_checkout->getZoneByCode($request->shipping_address->region, $shipping_country_info['country_id']); } $order_data = array( 'firstname' => utf8_substr($request->billing_address->given_name, 0, 32), 'lastname' => utf8_substr($request->billing_address->family_name, 0, 32), 'telephone' => utf8_substr($request->billing_address->phone, 0, 32), 'payment_firstname' => utf8_substr($request->billing_address->given_name, 0, 32), 'payment_lastname' => utf8_substr($request->billing_address->family_name, 0, 32), 'payment_address_1' => utf8_substr($request->billing_address->street_address, 0, 128), 'payment_address_2' => (isset($request->billing_address->street_address2) ? utf8_substr($request->billing_address->street_address2, 0, 128) : ''), 'payment_city' => utf8_substr($request->billing_address->city, 0, 128), 'payment_postcode' => utf8_substr($request->billing_address->postal_code, 0, 10), 'payment_zone' => ($payment_zone_info ? $payment_zone_info['name'] : ''), 'payment_zone_id' => ($payment_zone_info ? $payment_zone_info['zone_id'] : ''), 'payment_country' => ($payment_country_info ? $payment_country_info['name'] : ''), 'payment_country_id' => ($payment_country_info ? $payment_country_info['country_id'] : ''), 'payment_address_format' => ($payment_country_info ? $payment_country_info['address_format'] : ''), 'shipping_firstname' => utf8_substr($request->shipping_address->given_name, 0, 32), 'shipping_lastname' => utf8_substr($request->shipping_address->family_name, 0, 32), 'shipping_address_1' => utf8_substr($request->shipping_address->street_address, 0, 128), 'shipping_address_2' => (isset($request->shipping_address->street_address2) ? utf8_substr($request->shipping_address->street_address2, 0, 128) : ''), 'shipping_city' => utf8_substr($request->shipping_address->city, 0, 128), 'shipping_postcode' => utf8_substr($request->shipping_address->postal_code, 0, 10), 'shipping_zone' => ($shipping_zone_info ? $shipping_zone_info['name'] : ''), 'shipping_zone_id' => ($shipping_zone_info ? $shipping_zone_info['zone_id'] : ''), 'shipping_country' => ($shipping_country_info ? $shipping_country_info['name'] : ''), 'shipping_country_id' => ($shipping_country_info ? $shipping_country_info['country_id'] : ''), 'shipping_address_format' => ($shipping_country_info ? $shipping_country_info['address_format'] : '') ); $this->model_extension_payment_klarna_checkout->updateOcOrder($order_id, $order_data); $this->model_checkout_order->addOrderHistory($order_id, $this->config->get('config_order_status_id')); http_response_code(200); } else { http_response_code(303); $this->response->addHeader('Location: ' . $this->url->link('checkout/failure', '', true)); } $this->response->addHeader('Content-Type: application/json'); $this->response->setOutput(json_encode($json)); } public function confirmation() { $this->load->language('extension/payment/klarna_checkout'); if (!$this->config->get('klarna_checkout_status')) { return false; } if (isset($this->session->data['order_id'])) { $this->cart->clear(); unset($this->session->data['shipping_method']); unset($this->session->data['shipping_methods']); unset($this->session->data['payment_method']); unset($this->session->data['payment_methods']); unset($this->session->data['guest']); unset($this->session->data['comment']); unset($this->session->data['order_id']); unset($this->session->data['coupon']); unset($this->session->data['reward']); unset($this->session->data['voucher']); unset($this->session->data['vouchers']); unset($this->session->data['totals']); unset($this->session->data['klarna_checkout_order_id']); unset($this->session->data['klarna_checkout_data']); } $this->document->setTitle($this->language->get('heading_title_success')); $data['breadcrumbs'] = array(); $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/home') ); $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_basket'), 'href' => $this->url->link('checkout/cart') ); $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_checkout'), 'href' => $this->url->link('checkout/checkout', '', true) ); $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_success'), 'href' => $this->url->link('checkout/success') ); $data['continue'] = $this->url->link('common/home'); $data['column_left'] = $this->load->controller('common/column_left'); $data['column_right'] = $this->load->controller('common/column_right'); $data['content_top'] = $this->load->controller('common/content_top'); $data['content_bottom'] = $this->load->controller('common/content_bottom'); $data['footer'] = $this->load->controller('common/footer'); $data['header'] = $this->load->controller('common/header'); $this->load->model('extension/payment/klarna_checkout'); $this->load->model('checkout/order'); $klarna_checkout = false; $html_snippet = ''; if (isset($this->request->get['klarna_order_id'])) { $klarna_checkout_order = $this->model_extension_payment_klarna_checkout->getOrder($this->request->get['klarna_order_id']); if ($klarna_checkout_order) { $order_info = $this->model_checkout_order->getOrder($klarna_checkout_order['order_id']); if ($order_info) { list($klarna_account, $connector) = $this->model_extension_payment_klarna_checkout->getConnector($this->config->get('klarna_checkout_account'), $order_info['currency_code']); if (!$klarna_account || !$connector) { $this->model_extension_payment_klarna_checkout->log('Could not getConnector'); $this->response->redirect($this->url->link('checkout/failure', '', true)); } $retrieve = $this->model_extension_payment_klarna_checkout->orderRetrieve($connector, $this->request->get['klarna_order_id']); if ($retrieve) { $klarna_checkout = $retrieve->fetch(); if ($klarna_checkout && $klarna_checkout['html_snippet']) { $html_snippet = $klarna_checkout['html_snippet']; } } else { $this->response->redirect($this->url->link('checkout/cart', '', true)); } } } else { $this->model_extension_payment_klarna_checkout->log('Could not find order id using ' . $this->request->get['klarna_order_id']); $this->response->redirect($this->url->link('checkout/failure', '', true)); } } else { $this->model_extension_payment_klarna_checkout->log('$this->request->get[\'klarna_order_id\'] is not set'); $this->response->redirect($this->url->link('checkout/failure', '', true)); } $data['klarna_checkout'] = $html_snippet; $this->response->setOutput($this->load->view('extension/payment/klarna_checkout_success', $data)); } public function push() { $this->load->model('extension/payment/klarna_checkout'); $this->load->model('checkout/order'); if (!$this->config->get('klarna_checkout_status')) { return false; } if (isset($this->request->get['klarna_order_id'])) { $klarna_checkout_order = $this->model_extension_payment_klarna_checkout->getOrder($this->request->get['klarna_order_id']); if ($klarna_checkout_order) { $order_info = $this->model_checkout_order->getOrder($klarna_checkout_order['order_id']); if ($order_info) { list($klarna_account, $connector) = $this->model_extension_payment_klarna_checkout->getConnector($this->config->get('klarna_checkout_account'), $order_info['currency_code']); if ($klarna_account && $connector) { $order = $this->model_extension_payment_klarna_checkout->omOrderRetrieve($connector, $this->request->get['klarna_order_id']); $this->model_extension_payment_klarna_checkout->log('Order details from push:'); $this->model_extension_payment_klarna_checkout->log($order); if ($order) { if ($order->acknowledge()) { // Update OpenCart order with payment and shipping details $payment_country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode2($order['billing_address']['country']); $shipping_country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode2($order['shipping_address']['country']); //If region is passed, try to update OpenCart order with correct region/zone $payment_zone_info = array(); if ($payment_country_info && isset($order['billing_address']['region'])) { $payment_zone_info = $this->model_extension_payment_klarna_checkout->getZoneByCode($order['billing_address']['region'], $payment_country_info['country_id']); } $shipping_zone_info = array(); if ($shipping_country_info && isset($order['shipping_address']['region'])) { $shipping_zone_info = $this->model_extension_payment_klarna_checkout->getZoneByCode($order['shipping_address']['region'], $shipping_country_info['country_id']); } $order_data = array( 'firstname' => utf8_substr($order['billing_address']['given_name'], 0, 32), 'lastname' => utf8_substr($order['billing_address']['family_name'], 0, 32), 'telephone' => utf8_substr($order['billing_address']['phone'], 0, 32), 'payment_firstname' => utf8_substr($order['billing_address']['given_name'], 0, 32), 'payment_lastname' => utf8_substr($order['billing_address']['family_name'], 0, 32), 'payment_address_1' => utf8_substr($order['billing_address']['street_address'], 0, 128), 'payment_address_2' => (isset($order['billing_address']['street_address2']) ? utf8_substr($order['billing_address']['street_address2'], 0, 128) : ''), 'payment_city' => utf8_substr($order['billing_address']['city'], 0, 128), 'payment_postcode' => utf8_substr($order['billing_address']['postal_code'], 0, 10), 'payment_zone' => ($payment_zone_info ? $payment_zone_info['name'] : ''), 'payment_zone_id' => ($payment_zone_info ? $payment_zone_info['zone_id'] : ''), 'payment_country' => ($payment_country_info ? $payment_country_info['name'] : ''), 'payment_country_id' => ($payment_country_info ? $payment_country_info['country_id'] : ''), 'payment_address_format' => ($payment_country_info ? $payment_country_info['address_format'] : ''), 'shipping_firstname' => utf8_substr($order['shipping_address']['given_name'], 0, 32), 'shipping_lastname' => utf8_substr($order['shipping_address']['family_name'], 0, 32), 'shipping_address_1' => utf8_substr($order['shipping_address']['street_address'], 0, 128), 'shipping_address_2' => (isset($order['shipping_address']['street_address2']) ? utf8_substr($order['shipping_address']['street_address2'], 0, 128) : ''), 'shipping_city' => utf8_substr($order['shipping_address']['city'], 0, 128), 'shipping_postcode' => utf8_substr($order['shipping_address']['postal_code'], 0, 10), 'shipping_zone' => ($shipping_zone_info ? $shipping_zone_info['name'] : ''), 'shipping_zone_id' => ($shipping_zone_info ? $shipping_zone_info['zone_id'] : ''), 'shipping_country' => ($shipping_country_info ? $shipping_country_info['name'] : ''), 'shipping_country_id' => ($shipping_country_info ? $shipping_country_info['country_id'] : ''), 'shipping_address_format' => ($shipping_country_info ? $shipping_country_info['address_format'] : '') ); $this->model_extension_payment_klarna_checkout->updateOcOrder($klarna_checkout_order['order_id'], $order_data); $order_status_id = false; switch ($order['status']) { case 'AUTHORIZED': $order_status_id = $this->config->get('klarna_checkout_order_status_authorised_id'); if ($order['fraud_status'] == 'PENDING') { $order_status_id = $this->config->get('klarna_checkout_order_status_fraud_pending_id'); } elseif ($order['fraud_status'] == 'REJECTED') { $order_status_id = $this->config->get('klarna_checkout_order_status_fraud_rejected_id'); } break; case 'PART_CAPTURED': $order_status_id = $this->config->get('klarna_checkout_order_status_part_captured_id'); break; case 'CAPTURED': $order_status_id = $this->config->get('klarna_checkout_order_status_captured_id'); break; case 'CANCELLED': $order_status_id = $this->config->get('klarna_checkout_order_status_cancelled_id'); break; } if ($order_status_id) { $this->model_checkout_order->addOrderHistory($klarna_checkout_order['order_id'], $order_status_id); } } } else { $this->model_extension_payment_klarna_checkout->log('Cannot retrieve KC order using order_id: ' . $this->request->get['klarna_order_id']); } } } } else { $this->model_extension_payment_klarna_checkout->log('Cannot find KC order using order_id: ' . $this->request->get['klarna_order_id']); } } } private function setPayment() { $this->load->model('account/address'); $this->load->model('localisation/country'); $this->load->model('localisation/zone'); if (isset($this->session->data['payment_address']) && !empty($this->session->data['payment_address'])) { $this->session->data['payment_address'] = $this->session->data['payment_address']; } elseif ($this->customer->isLogged() && $this->customer->getAddressId()) { $this->session->data['payment_address'] = $this->model_account_address->getAddress($this->customer->getAddressId()); } else { $country_info = $this->model_localisation_country->getCountry($this->config->get('config_country_id')); $zone_info = $this->model_localisation_zone->getZone($this->config->get('config_zone_id')); $this->session->data['payment_address'] = array( 'address_id' => null, 'firstname' => null, 'lastname' => null, 'company' => null, 'address_1' => null, 'address_2' => null, 'postcode' => null, 'city' => null, 'zone_id' => $zone_info['zone_id'], 'zone' => $zone_info['name'], 'zone_code' => $zone_info['code'], 'country_id' => $country_info['country_id'], 'country' => $country_info['name'], 'iso_code_2' => $country_info['iso_code_2'], 'iso_code_3' => $country_info['iso_code_3'], 'address_format' => '', 'custom_field' => array() ); } $this->tax->setPaymentAddress($this->session->data['payment_address']['country_id'], $this->session->data['payment_address']['zone_id']); $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); } private function setShipping() { $this->load->model('account/address'); $this->load->model('localisation/country'); $this->load->model('localisation/zone'); if (isset($this->session->data['shipping_address']) && !empty($this->session->data['shipping_address'])) { $this->session->data['shipping_address'] = $this->session->data['shipping_address']; } elseif ($this->customer->isLogged() && $this->customer->getAddressId()) { $this->session->data['shipping_address'] = $this->model_account_address->getAddress($this->customer->getAddressId()); } else { $country_info = $this->model_localisation_country->getCountry($this->config->get('config_country_id')); $zone_info = $this->model_localisation_zone->getZone($this->config->get('config_zone_id')); $this->session->data['shipping_address'] = array( 'address_id' => null, 'firstname' => null, 'lastname' => null, 'company' => null, 'address_1' => null, 'address_2' => null, 'postcode' => null, 'city' => null, 'zone_id' => $zone_info['zone_id'], 'zone' => $zone_info['name'], 'zone_code' => $zone_info['code'], 'country_id' => $country_info['country_id'], 'country' => $country_info['name'], 'iso_code_2' => $country_info['iso_code_2'], 'iso_code_3' => $country_info['iso_code_3'], 'address_format' => '', 'custom_field' => array() ); } $this->tax->unsetRates(); $this->tax->setShippingAddress($this->session->data['shipping_address']['country_id'], $this->session->data['shipping_address']['zone_id']); $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); if (isset($this->session->data['shipping_address'])) { // Shipping Methods $method_data = array(); $this->load->model('setting/extension'); $results = $this->model_setting_extension->getExtensions('shipping'); foreach ($results as $result) { if ($this->config->get('shipping_' . $result['code'] . '_status')) { $this->load->model('extension/shipping/' . $result['code']); $quote = $this->{'model_extension_shipping_' . $result['code']}->getQuote($this->session->data['shipping_address']); if ($quote) { $method_data[$result['code']] = array( 'title' => $quote['title'], 'quote' => $quote['quote'], 'sort_order' => $quote['sort_order'], 'error' => $quote['error'] ); } } } $sort_order = array(); foreach ($method_data as $key => $value) { $sort_order[$key] = $value['sort_order']; } array_multisort($sort_order, SORT_ASC, $method_data); $this->session->data['shipping_methods'] = $method_data; } } private function createOrder() { //Klarna defaults: $this->session->data['comment'] = ''; if (!$this->customer->isLogged()) { $this->session->data['guest'] = array( 'customer_group_id' => $this->config->get('config_customer_group_id'), 'firstname' => '', 'lastname' => '', 'email' => '', 'telephone' => '', 'fax' => '', 'custom_field' => array(), ); } //OpenCart: $order_data = array(); list($totals, $taxes, $total) = $this->model_extension_payment_klarna_checkout->getTotals(); $order_data['totals'] = $totals; $this->load->language('checkout/checkout'); $order_data['invoice_prefix'] = $this->config->get('config_invoice_prefix'); $order_data['store_id'] = $this->config->get('config_store_id'); $order_data['store_name'] = $this->config->get('config_name'); if ($order_data['store_id']) { $order_data['store_url'] = $this->config->get('config_url'); } else { $order_data['store_url'] = HTTP_SERVER; } if ($this->customer->isLogged()) { $this->load->model('account/customer'); $customer_info = $this->model_account_customer->getCustomer($this->customer->getId()); $order_data['customer_id'] = $this->customer->getId(); $order_data['customer_group_id'] = $customer_info['customer_group_id']; $order_data['firstname'] = $customer_info['firstname']; $order_data['lastname'] = $customer_info['lastname']; $order_data['email'] = $customer_info['email']; $order_data['telephone'] = $customer_info['telephone']; $order_data['custom_field'] = json_decode($customer_info['custom_field'], true); } elseif (isset($this->session->data['guest'])) { $order_data['customer_id'] = 0; $order_data['customer_group_id'] = $this->session->data['guest']['customer_group_id']; $order_data['firstname'] = $this->session->data['guest']['firstname']; $order_data['lastname'] = $this->session->data['guest']['lastname']; $order_data['email'] = $this->session->data['guest']['email']; $order_data['telephone'] = $this->session->data['guest']['telephone']; $order_data['custom_field'] = $this->session->data['guest']['custom_field']; } $order_data['payment_firstname'] = $this->session->data['payment_address']['firstname']; $order_data['payment_lastname'] = $this->session->data['payment_address']['lastname']; $order_data['payment_company'] = $this->session->data['payment_address']['company']; $order_data['payment_address_1'] = $this->session->data['payment_address']['address_1']; $order_data['payment_address_2'] = $this->session->data['payment_address']['address_2']; $order_data['payment_city'] = $this->session->data['payment_address']['city']; $order_data['payment_postcode'] = $this->session->data['payment_address']['postcode']; $order_data['payment_zone'] = $this->session->data['payment_address']['zone']; $order_data['payment_zone_id'] = $this->session->data['payment_address']['zone_id']; $order_data['payment_country'] = $this->session->data['payment_address']['country']; $order_data['payment_country_id'] = $this->session->data['payment_address']['country_id']; $order_data['payment_address_format'] = $this->session->data['payment_address']['address_format']; $order_data['payment_custom_field'] = (isset($this->session->data['payment_address']['custom_field']) ? $this->session->data['payment_address']['custom_field'] : array()); if (isset($this->session->data['payment_method']['title'])) { $order_data['payment_method'] = $this->session->data['payment_method']['title']; } else { $order_data['payment_method'] = ''; } if (isset($this->session->data['payment_method']['code'])) { $order_data['payment_code'] = $this->session->data['payment_method']['code']; } else { $order_data['payment_code'] = ''; } if ($this->cart->hasShipping()) { $order_data['shipping_firstname'] = $this->session->data['shipping_address']['firstname']; $order_data['shipping_lastname'] = $this->session->data['shipping_address']['lastname']; $order_data['shipping_company'] = $this->session->data['shipping_address']['company']; $order_data['shipping_address_1'] = $this->session->data['shipping_address']['address_1']; $order_data['shipping_address_2'] = $this->session->data['shipping_address']['address_2']; $order_data['shipping_city'] = $this->session->data['shipping_address']['city']; $order_data['shipping_postcode'] = $this->session->data['shipping_address']['postcode']; $order_data['shipping_zone'] = $this->session->data['shipping_address']['zone']; $order_data['shipping_zone_id'] = $this->session->data['shipping_address']['zone_id']; $order_data['shipping_country'] = $this->session->data['shipping_address']['country']; $order_data['shipping_country_id'] = $this->session->data['shipping_address']['country_id']; $order_data['shipping_address_format'] = $this->session->data['shipping_address']['address_format']; $order_data['shipping_custom_field'] = (isset($this->session->data['shipping_address']['custom_field']) ? $this->session->data['shipping_address']['custom_field'] : array()); if (isset($this->session->data['shipping_method']['title'])) { $order_data['shipping_method'] = $this->session->data['shipping_method']['title']; } else { $order_data['shipping_method'] = ''; } if (isset($this->session->data['shipping_method']['code'])) { $order_data['shipping_code'] = $this->session->data['shipping_method']['code']; } else { $order_data['shipping_code'] = ''; } } else { $order_data['shipping_firstname'] = ''; $order_data['shipping_lastname'] = ''; $order_data['shipping_company'] = ''; $order_data['shipping_address_1'] = ''; $order_data['shipping_address_2'] = ''; $order_data['shipping_city'] = ''; $order_data['shipping_postcode'] = ''; $order_data['shipping_zone'] = ''; $order_data['shipping_zone_id'] = ''; $order_data['shipping_country'] = ''; $order_data['shipping_country_id'] = ''; $order_data['shipping_address_format'] = ''; $order_data['shipping_custom_field'] = array(); $order_data['shipping_method'] = ''; $order_data['shipping_code'] = ''; } $order_data['products'] = array(); foreach ($this->cart->getProducts() as $product) { $option_data = array(); foreach ($product['option'] as $option) { $option_data[] = array( 'product_option_id' => $option['product_option_id'], 'product_option_value_id' => $option['product_option_value_id'], 'option_id' => $option['option_id'], 'option_value_id' => $option['option_value_id'], 'name' => $option['name'], 'value' => $option['value'], 'type' => $option['type'] ); } $order_data['products'][] = array( 'product_id' => $product['product_id'], 'name' => $product['name'], 'model' => $product['model'], 'option' => $option_data, 'download' => $product['download'], 'quantity' => $product['quantity'], 'subtract' => $product['subtract'], 'price' => $product['price'], 'total' => $product['total'], 'tax' => $this->tax->getTax($product['price'], $product['tax_class_id']), 'reward' => $product['reward'] ); } // Gift Voucher $order_data['vouchers'] = array(); if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $voucher) { $order_data['vouchers'][] = array( 'description' => $voucher['description'], 'code' => token(10), 'to_name' => $voucher['to_name'], 'to_email' => $voucher['to_email'], 'from_name' => $voucher['from_name'], 'from_email' => $voucher['from_email'], 'voucher_theme_id' => $voucher['voucher_theme_id'], 'message' => $voucher['message'], 'amount' => $voucher['amount'] ); } } $order_data['comment'] = $this->session->data['comment']; $order_data['total'] = $total; if (isset($this->request->cookie['tracking'])) { $order_data['tracking'] = $this->request->cookie['tracking']; $subtotal = $this->cart->getSubTotal(); // Affiliate $this->load->model('affiliate/affiliate'); $affiliate_info = $this->model_affiliate_affiliate->getAffiliateByCode($this->request->cookie['tracking']); if ($affiliate_info) { $order_data['affiliate_id'] = $affiliate_info['affiliate_id']; $order_data['commission'] = ($subtotal / 100) * $affiliate_info['commission']; } else { $order_data['affiliate_id'] = 0; $order_data['commission'] = 0; } // Marketing $this->load->model('checkout/marketing'); $marketing_info = $this->model_checkout_marketing->getMarketingByCode($this->request->cookie['tracking']); if ($marketing_info) { $order_data['marketing_id'] = $marketing_info['marketing_id']; } else { $order_data['marketing_id'] = 0; } } else { $order_data['affiliate_id'] = 0; $order_data['commission'] = 0; $order_data['marketing_id'] = 0; $order_data['tracking'] = ''; } $order_data['language_id'] = $this->config->get('config_language_id'); $order_data['currency_id'] = $this->currency->getId($this->session->data['currency']); $order_data['currency_code'] = $this->session->data['currency']; $order_data['currency_value'] = $this->currency->getValue($this->session->data['currency']); $order_data['ip'] = $this->request->server['REMOTE_ADDR']; if (!empty($this->request->server['HTTP_X_FORWARDED_FOR'])) { $order_data['forwarded_ip'] = $this->request->server['HTTP_X_FORWARDED_FOR']; } elseif (!empty($this->request->server['HTTP_CLIENT_IP'])) { $order_data['forwarded_ip'] = $this->request->server['HTTP_CLIENT_IP']; } else { $order_data['forwarded_ip'] = ''; } if (isset($this->request->server['HTTP_USER_AGENT'])) { $order_data['user_agent'] = $this->request->server['HTTP_USER_AGENT']; } else { $order_data['user_agent'] = ''; } if (isset($this->request->server['HTTP_ACCEPT_LANGUAGE'])) { $order_data['accept_language'] = $this->request->server['HTTP_ACCEPT_LANGUAGE']; } else { $order_data['accept_language'] = ''; } $this->load->model('checkout/order'); $this->session->data['order_id'] = $this->model_checkout_order->addOrder($order_data); } private function klarnaOrderData($klarna_account) { $this->load->language('extension/payment/klarna_checkout'); $this->load->model('extension/payment/klarna_checkout'); $this->load->model('localisation/country'); $currency_code = $this->session->data['currency']; $currency_value = $this->currency->getValue($this->session->data['currency']); // Shipping $unset_shipping_method = true; if (isset($this->session->data['shipping_method']) && isset($this->session->data['shipping_methods'])) { foreach ($this->session->data['shipping_methods'] as $shipping_method) { if ($shipping_method['quote']) { foreach ($shipping_method['quote'] as $quote) { if ($quote == $this->session->data['shipping_method']) { $unset_shipping_method = false; break 2; } } } } } if ($unset_shipping_method) { unset($this->session->data['shipping_method']); } if ((!isset($this->session->data['shipping_method']) || empty($this->session->data['shipping_method'])) && (isset($this->session->data['shipping_methods']) && !empty($this->session->data['shipping_methods']))) { $this->session->data['shipping_method'] = $this->model_extension_payment_klarna_checkout->getDefaultShippingMethod($this->session->data['shipping_methods']); } //Check if customer is US. If so, send taxes differently if ($this->session->data['shipping_address']['iso_code_2'] === 'US') { $include_taxes = false; } else { $include_taxes = true; } if ($this->cart->hasShipping() && isset($this->session->data['shipping_method']) && !empty($this->session->data['shipping_method'])) { $total_amount = $this->currency->format($this->tax->calculate($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id'], $include_taxes), $currency_code, $currency_value, false) * 100; if ($include_taxes) { $total_tax_amount = $this->currency->format($this->tax->getTax($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id']), $currency_code, $currency_value, false) * 100; } else { $total_tax_amount = 0; } $total_sub_amount = $this->currency->format($this->tax->calculate($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id'], false), $currency_code, $currency_value, false) * 100; $tax_rate = 0; if ($include_taxes && $total_tax_amount && $total_sub_amount) { $tax_rate = ($total_tax_amount / $total_sub_amount) * 100; } $klarna_order_data['order_lines'][] = array( 'type' => 'shipping_fee', 'name' => $this->session->data['shipping_method']['title'], 'quantity' => '1', 'unit_price' => round($this->currency->format($this->tax->calculate($this->session->data['shipping_method']['cost'], $this->session->data['shipping_method']['tax_class_id'], $include_taxes), $currency_code, $currency_value, false) * 100), 'tax_rate' => round($tax_rate * 100), 'total_amount' => round($total_amount), 'total_tax_amount' => round($total_tax_amount), 'total_discount_amount' => 0 ); } // Billing Address if (isset($this->session->data['klarna_checkout_data'])) { $klarna_order_data['billing_address'] = array( 'given_name' => $this->session->data['klarna_checkout_data']['firstname'], 'family_name' => $this->session->data['klarna_checkout_data']['lastname'], 'email' => $this->session->data['klarna_checkout_data']['email'], 'phone' => $this->session->data['klarna_checkout_data']['telephone'], 'postal_code' => $this->session->data['shipping_address']['postcode'], 'region' => $this->session->data['shipping_address']['zone_code'], 'country' => $this->session->data['shipping_address']['iso_code_2'], ); } else { $klarna_order_data['billing_address'] = array( 'given_name' => $this->session->data['shipping_address']['firstname'], 'family_name' => $this->session->data['shipping_address']['lastname'], 'email' => ($this->customer->isLogged() ? $this->customer->getEmail() : null), 'phone' => ($this->customer->isLogged() ? $this->customer->getTelephone() : null) ); } // Order Total list($totals, $taxes, $total) = $this->model_extension_payment_klarna_checkout->getTotals(); $merchant_urls = array( 'checkout' => html_entity_decode($this->url->link('extension/payment/klarna_checkout', 'klarna_order_id={checkout.order.id}', true)), 'confirmation' => html_entity_decode($this->url->link('extension/payment/klarna_checkout/confirmation', 'klarna_order_id={checkout.order.id}', true)), 'push' => html_entity_decode($this->url->link('extension/payment/klarna_checkout/push', 'klarna_order_id={checkout.order.id}', true)), 'validation' => html_entity_decode($this->url->link('extension/payment/klarna_checkout/validation', 'klarna_order_id={checkout.order.id}', true)), 'address_update' => html_entity_decode($this->url->link('extension/payment/klarna_checkout/addressUpdate', 'klarna_order_id={checkout.order.id}', true)), 'notification' => html_entity_decode($this->url->link('extension/payment/klarna_checkout/notification', 'klarna_order_id={checkout.order.id}', true)), ); if ($this->config->get('klarna_checkout_terms')) { $merchant_urls['terms'] = html_entity_decode($this->url->link('information/information', 'information_id=' . $this->config->get('klarna_checkout_terms'), true)); } $country_info = $this->model_localisation_country->getCountry($klarna_account['country']); if ($country_info) { $klarna_order_data['purchase_country'] = $country_info['iso_code_2']; } $klarna_order_data['purchase_currency'] = $currency_code; $klarna_order_data['locale'] = $klarna_account['locale']; $klarna_order_data['order_amount'] = round($this->currency->format($total, $currency_code, $currency_value, false) * 100); $klarna_order_data['order_tax_amount'] = round($this->currency->format(array_sum($taxes), $currency_code, $currency_value, false) * 100); $klarna_order_data['merchant_urls'] = $merchant_urls; // Callback data to be used to spoof/simulate customer to accurately calculate shipping $encrypted_order_data = $this->encryption->encrypt($this->config->get('config_encryption'), json_encode(array( 'session_id' => session_id(), 'session_key' => $this->session->getId(), 'customer_id' => $this->customer->getId(), 'order_id' => $this->session->data['order_id'], 'merchant_id' => $klarna_account['merchant_id'], 'secret' => $klarna_account['secret'] ))); $encrypted_order_id = $this->encryption->encrypt($this->config->get('config_encryption'), $this->session->data['order_id']); $klarna_order_data['merchant_reference1'] = $this->session->data['order_id']; $klarna_order_data['options'] = array(); if ($this->config->get('klarna_checkout_colour_button')) { $klarna_order_data['options']['color_button'] = $this->config->get('klarna_checkout_colour_button'); } if ($this->config->get('klarna_checkout_colour_button_text')) { $klarna_order_data['options']['color_button_text'] = $this->config->get('klarna_checkout_colour_button_text'); } if ($this->config->get('klarna_checkout_colour_checkbox')) { $klarna_order_data['options']['color_checkbox'] = $this->config->get('klarna_checkout_colour_checkbox'); } if ($this->config->get('klarna_checkout_colour_checkbox_checkmark')) { $klarna_order_data['options']['color_checkbox_checkmark'] = $this->config->get('klarna_checkout_colour_checkbox_checkmark'); } if ($this->config->get('klarna_checkout_colour_header')) { $klarna_order_data['options']['color_header'] = $this->config->get('klarna_checkout_colour_header'); } if ($this->config->get('klarna_checkout_colour_link')) { $klarna_order_data['options']['color_link'] = $this->config->get('klarna_checkout_colour_link'); } if ($this->config->get('klarna_checkout_separate_shipping_address')) { $klarna_order_data['options']['allow_separate_shipping_address'] = true; } // Only pass DOB/title mandatory for UK stores if ($country_info['iso_code_2'] == 'GB') { if ($this->config->get('klarna_checkout_dob_mandatory')) { $klarna_order_data['options']['date_of_birth_mandatory'] = true; } if ($this->config->get('klarna_checkout_title_mandatory')) { $klarna_order_data['options']['title_mandatory'] = true; } } if ($this->config->get('klarna_checkout_additional_text_box') && $this->customer->isLogged() && !$this->customer->getNewsletter()) { $klarna_order_data['options']['additional_checkbox'] = array( 'text' => $this->language->get('text_newsletter'), 'checked' => false, 'required' => false ); } $shipping_countries = $this->model_extension_payment_klarna_checkout->getCountriesByGeoZone($klarna_account['shipping']); $klarna_shipping_countries = array(); foreach ($shipping_countries as $shipping_country) { $country_info = $this->model_localisation_country->getCountry($shipping_country['country_id']); if ($country_info && $country_info['iso_code_2']) { $klarna_shipping_countries[] = $country_info['iso_code_2']; } } $klarna_order_data['shipping_countries'] = $klarna_shipping_countries; $average_product_tax_rate = array(); // Products (Add these last because we send encrypted session order_id) foreach ($this->cart->getProducts() as $product) { $total_amount = $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $include_taxes) * $product['quantity'], $currency_code, $currency_value, false) * 100; if ($include_taxes) { $total_tax_amount = $this->currency->format($this->tax->getTax($product['price'], $product['tax_class_id']) * $product['quantity'], $currency_code, $currency_value, false) * 100; } else { $total_tax_amount = 0; } $total_sub_amount = $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], false) * $product['quantity'], $currency_code, $currency_value, false) * 100; $tax_rate = 0; if ($include_taxes && $total_tax_amount && $total_sub_amount) { $tax_rate = ($total_tax_amount / $total_sub_amount) * 100; } $average_product_tax_rate[] = round($tax_rate * 100); $klarna_order_data['order_lines'][] = array( 'type' => ($product['shipping'] ? 'physical' : 'digital'), 'reference' => $product['model'], 'name' => $product['name'], 'quantity' => $product['quantity'], 'quantity_unit' => 'pcs', 'unit_price' => round($this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $include_taxes), $currency_code, $currency_value, false) * 100), 'tax_rate' => round($tax_rate * 100), 'total_amount' => round($total_amount), 'total_tax_amount' => round($total_tax_amount), 'merchant_data' => $encrypted_order_id, 'total_discount_amount' => 0 ); } // Gift Voucher if (!empty($this->session->data['vouchers'])) { foreach ($this->session->data['vouchers'] as $key => $voucher) { $klarna_order_data['order_lines'][] = array( 'type' => 'gift_card', 'reference' => '', 'name' => $voucher['description'], 'quantity' => 1, 'quantity_unit' => 'pcs', 'unit_price' => round($this->currency->format($voucher['amount'], $currency_code, $currency_value, false) * 100), 'tax_rate' => 0, 'total_amount' => round($this->currency->format($voucher['amount'], $currency_code, $currency_value, false) * 100), 'total_tax_amount' => 0, 'merchant_data' => $encrypted_order_id, 'total_discount_amount' => 0 ); } } foreach ($totals as $result) { if ($result['code'] == 'coupon') { $discount_total_price = 0; $discount_sub_total_price = 0; foreach ($this->cart->getProducts() as $product) { $discount_total_price += $this->tax->calculate($result['value'], $product['tax_class_id'], $include_taxes); $discount_sub_total_price += $result['value']; } $average_discount_total_price = $discount_total_price / count($average_product_tax_rate); $average_discount_sub_total_price = $discount_sub_total_price / count($average_product_tax_rate); $total_tax_amount = ($average_discount_sub_total_price / 100) * (array_sum($average_product_tax_rate) / count($average_product_tax_rate)); $klarna_order_data['order_lines'][] = array( 'type' => 'discount', 'name' => $result['title'], 'quantity' => '1', 'unit_price' => round($this->currency->format($average_discount_total_price, $currency_code, $currency_value, false) * 100), 'tax_rate' => array_sum($average_product_tax_rate) / count($average_product_tax_rate), 'total_amount' => round($this->currency->format($average_discount_total_price, $currency_code, $currency_value, false) * 100), 'total_tax_amount' => round($total_tax_amount), 'total_discount_amount' => 0 ); } if ($result['code'] == 'voucher') { $klarna_order_data['order_lines'][] = array( 'type' => 'discount', 'name' => $result['title'], 'quantity' => '1', 'unit_price' => round($this->currency->format($result['value'], $currency_code, $currency_value, false) * 100), 'tax_rate' => 0, 'total_amount' => round($this->currency->format($result['value'], $currency_code, $currency_value, false) * 100), 'total_tax_amount' => 0, 'total_discount_amount' => 0 ); } } //If $include_taxes is false, means customer is US so we add a new sales_tax order line with all the tax if (!$include_taxes) { $klarna_order_data['order_lines'][] = array( 'type' => 'sales_tax', 'name' => $this->language->get('text_sales_tax'), 'quantity' => '1', 'unit_price' => round($this->currency->format(array_sum($taxes), $currency_code, $currency_value, false) * 100), 'tax_rate' => 0, 'total_amount' => round($this->currency->format(array_sum($taxes), $currency_code, $currency_value, false) * 100), 'total_tax_amount' => 0, 'total_discount_amount' => 0 ); } return array($klarna_order_data, $encrypted_order_data); } }