klarna_checkout.php (84456B)
1 <?php 2 class ControllerExtensionPaymentKlarnaCheckout extends Controller { 3 public function index() { 4 $this->load->language('extension/payment/klarna_checkout'); 5 6 $this->load->model('extension/payment/klarna_checkout'); 7 $this->load->model('localisation/country'); 8 9 $this->document->setTitle($this->language->get('heading_title')); 10 11 $data['column_left'] = $this->load->controller('common/column_left'); 12 $data['column_right'] = $this->load->controller('common/column_right'); 13 $data['content_top'] = $this->load->controller('common/content_top'); 14 $data['content_bottom'] = $this->load->controller('common/content_bottom'); 15 $data['footer'] = $this->load->controller('common/footer'); 16 $data['header'] = $this->load->controller('common/header'); 17 18 $this->response->setOutput($this->load->view('extension/payment/klarna_checkout', $data)); 19 } 20 21 public function main() { 22 $this->load->language('extension/payment/klarna_checkout'); 23 24 $this->load->model('extension/payment/klarna_checkout'); 25 $this->load->model('localisation/country'); 26 27 $redirect = false; 28 $html_snippet = ''; 29 30 // Validate cart has products and has stock. 31 if ((!$this->cart->hasProducts() && empty($this->session->data['vouchers'])) || (!$this->cart->hasStock() && !$this->config->get('config_stock_checkout'))) { 32 $redirect = $this->url->link('checkout/cart'); 33 } 34 35 // Validate minimum quantity requirements. 36 $products = $this->cart->getProducts(); 37 38 foreach ($products as $product) { 39 $product_total = 0; 40 41 foreach ($products as $product_2) { 42 if ($product_2['product_id'] == $product['product_id']) { 43 $product_total += $product_2['quantity']; 44 } 45 } 46 47 if ($product['minimum'] > $product_total) { 48 $redirect = $this->url->link('checkout/cart'); 49 } 50 } 51 52 // Validate cart has recurring products 53 if ($this->cart->hasRecurringProducts()) { 54 $redirect = $this->url->link('checkout/cart'); 55 } 56 57 list($totals, $taxes, $total) = $this->model_extension_payment_klarna_checkout->getTotals(); 58 59 if ($this->config->get('klarna_checkout_total') > 0 && $this->config->get('klarna_checkout_total') > $total) { 60 $redirect = $this->url->link('checkout/cart'); 61 } 62 63 if (!$this->config->get('klarna_checkout_status')) { 64 $redirect = $this->url->link('checkout/cart'); 65 } 66 67 if ($this->model_extension_payment_klarna_checkout->checkForPaymentTaxes($products)) { 68 $redirect = $this->url->link('checkout/cart'); 69 } 70 71 $text_title = $this->language->get('text_title'); 72 73 unset($this->session->data['success']); 74 75 $this->setPayment(); 76 $this->setShipping(); 77 78 $this->session->data['payment_method'] = array( 79 'code' => 'klarna_checkout', 80 'title' => $text_title, 81 'terms' => $this->url->link('information/information', 'information_id=' . $this->config->get('klarna_checkout_terms'), true), 82 'sort_order' => '1' 83 ); 84 85 // Shipping 86 $unset_shipping_method = true; 87 if (isset($this->session->data['shipping_method']) && isset($this->session->data['shipping_methods'])) { 88 foreach ($this->session->data['shipping_methods'] as $shipping_method) { 89 if ($shipping_method['quote']) { 90 foreach ($shipping_method['quote'] as $quote) { 91 if ($quote['code'] == $this->session->data['shipping_method']['code']) { 92 $unset_shipping_method = false; 93 break 2; 94 } 95 } 96 } 97 } 98 } 99 100 if ($unset_shipping_method) { 101 unset($this->session->data['shipping_method']); 102 } 103 104 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']))) { 105 $this->session->data['shipping_method'] = $this->model_extension_payment_klarna_checkout->getDefaultShippingMethod($this->session->data['shipping_methods']); 106 } 107 108 //Klarna Connector 109 list($klarna_account, $connector) = $this->model_extension_payment_klarna_checkout->getConnector($this->config->get('klarna_checkout_account'), $this->session->data['currency']); 110 111 if (!$klarna_account || !$connector) { 112 $redirect = $this->url->link('checkout/cart'); 113 } 114 115 if (!$redirect) { 116 // Get currency code and currency value to use to calculate taxes 117 118 // Build order_lines 119 $create_order = true; 120 $klarna_checkout = false; 121 122 $this->createOrder(); 123 124 list($klarna_order_data, $encrypted_order_data) = $this->klarnaOrderData($klarna_account); 125 126 if (isset($this->session->data['klarna_checkout_currency']) && $this->session->data['klarna_checkout_currency'] != $this->session->data['currency']) { 127 $this->model_extension_payment_klarna_checkout->log('Currency changed, unsetting kc order id'); 128 unset($this->session->data['klarna_checkout_order_id']); 129 unset($this->session->data['klarna_checkout_data']); 130 } 131 132 $this->session->data['klarna_checkout_currency'] = $this->session->data['currency']; 133 134 // Fetch or create order 135 if (isset($this->session->data['klarna_checkout_order_id'])) { 136 $retrieve = $this->model_extension_payment_klarna_checkout->orderRetrieve($connector, $this->session->data['klarna_checkout_order_id']); 137 138 if ($retrieve) { 139 //If address has changed, unset klarna_checkout_order_id and create new order 140 $address_change = false; 141 142 if (isset($this->session->data['klarna_checkout_data']) && $this->session->data['klarna_checkout_data']) { 143 if (isset($this->session->data['klarna_checkout_data']['zone_code'])) { 144 $kc_region = $this->session->data['klarna_checkout_data']['zone_code']; 145 } else { 146 $kc_region = ''; 147 } 148 149 if (isset($this->session->data['klarna_checkout_data']['iso_code_2'])) { 150 $kc_country = $this->session->data['klarna_checkout_data']['iso_code_2']; 151 } else { 152 $kc_country = ''; 153 } 154 155 if (isset($this->session->data['shipping_address']['zone_code'])) { 156 $oc_region = $this->session->data['shipping_address']['zone_code']; 157 } else { 158 $oc_region = ''; 159 } 160 161 if (isset($this->session->data['shipping_address']['iso_code_2'])) { 162 $oc_country = $this->session->data['shipping_address']['iso_code_2']; 163 } else { 164 $oc_country = ''; 165 } 166 167 $kc_address = array( 168 'region' => $kc_region, 169 'country' => $kc_country, 170 ); 171 172 $oc_address = array( 173 'region' => $oc_region, 174 'country' => $oc_country, 175 ); 176 177 //If address has changed, dont use retrieved order, create new one instead 178 if (array_diff(array_map('strtolower', $kc_address), array_map('strtolower', $oc_address))) { 179 $address_change = true; 180 } 181 } 182 183 if (!$address_change) { 184 $this->model_extension_payment_klarna_checkout->log('Order Updated'); 185 $this->model_extension_payment_klarna_checkout->log($klarna_order_data); 186 187 $create_order = false; 188 189 $update = $this->model_extension_payment_klarna_checkout->orderUpdate($connector, $this->session->data['klarna_checkout_order_id'], $klarna_order_data); 190 191 if ($update) { 192 $klarna_checkout = $update->fetch(); 193 194 $this->model_extension_payment_klarna_checkout->updateOrder($this->session->data['order_id'], $klarna_checkout['order_id'], $encrypted_order_data); 195 } 196 } 197 } 198 } 199 200 if ($create_order) { 201 $this->model_extension_payment_klarna_checkout->log('Order Created'); 202 $this->model_extension_payment_klarna_checkout->log($klarna_order_data); 203 204 unset($this->session->data['klarna_checkout_data']); 205 206 $create = $this->model_extension_payment_klarna_checkout->orderCreate($connector, $klarna_order_data); 207 208 if ($create) { 209 $klarna_checkout = $create->fetch(); 210 211 $this->model_extension_payment_klarna_checkout->addOrder($this->session->data['order_id'], $klarna_checkout['order_id'], $encrypted_order_data); 212 } 213 } 214 215 if ($klarna_checkout) { 216 $this->session->data['klarna_checkout_order_id'] = $klarna_checkout['order_id']; 217 218 $html_snippet = $klarna_checkout['html_snippet']; 219 } 220 } 221 222 if (isset($this->request->post['response']) && $this->request->post['response'] == 'template') { 223 $data['redirect'] = $redirect; 224 225 $data['klarna_checkout'] = $html_snippet; 226 227 $this->response->setOutput($this->load->view('extension/payment/klarna_checkout_main', $data)); 228 } elseif (isset($this->request->post['response']) && $this->request->post['response'] == 'json') { 229 $json['redirect'] = $redirect; 230 231 $this->response->addHeader('Content-Type: application/json'); 232 $this->response->setOutput(json_encode($json)); 233 } 234 } 235 236 public function sidebar() { 237 $this->load->language('checkout/checkout'); 238 $this->load->language('extension/payment/klarna_checkout'); 239 240 $this->load->model('extension/payment/klarna_checkout'); 241 242 if (!$this->config->get('klarna_checkout_status')) { 243 return false; 244 } 245 246 $this->setPayment(); 247 $this->setShipping(); 248 249 // Shipping 250 $unset_shipping_method = true; 251 if (isset($this->session->data['shipping_method']) && isset($this->session->data['shipping_methods'])) { 252 foreach ($this->session->data['shipping_methods'] as $shipping_method) { 253 if ($shipping_method['quote']) { 254 foreach ($shipping_method['quote'] as $quote) { 255 if ($quote['code'] == $this->session->data['shipping_method']['code']) { 256 $unset_shipping_method = false; 257 break 2; 258 } 259 } 260 } 261 } 262 } 263 264 if ($unset_shipping_method) { 265 unset($this->session->data['shipping_method']); 266 } 267 268 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']))) { 269 $this->session->data['shipping_method'] = $this->model_extension_payment_klarna_checkout->getDefaultShippingMethod($this->session->data['shipping_methods']); 270 } 271 272 $data['shipping_required'] = $this->cart->hasShipping(); 273 274 if (isset($this->session->data['shipping_methods'])) { 275 $data['shipping_methods'] = $this->session->data['shipping_methods']; 276 } else { 277 unset($data['shipping_method']); 278 279 $data['shipping_methods'] = array(); 280 } 281 282 if (isset($this->session->data['shipping_method']['code'])) { 283 $data['code'] = $this->session->data['shipping_method']['code']; 284 } else { 285 $data['code'] = ''; 286 } 287 288 $this->load->model('tool/image'); 289 $this->load->model('tool/upload'); 290 291 $data['products'] = array(); 292 293 foreach ($this->cart->getProducts() as $product) { 294 if ($product['image']) { 295 $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')); 296 } else { 297 $image = ''; 298 } 299 300 $option_data = array(); 301 302 foreach ($product['option'] as $option) { 303 if ($option['type'] != 'file') { 304 $value = $option['value']; 305 } else { 306 $upload_info = $this->model_tool_upload->getUploadByCode($option['value']); 307 308 if ($upload_info) { 309 $value = $upload_info['name']; 310 } else { 311 $value = ''; 312 } 313 } 314 315 $option_data[] = array( 316 'name' => $option['name'], 317 'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value), 318 'type' => $option['type'] 319 ); 320 } 321 322 // Display prices 323 if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) { 324 $price = $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']); 325 } else { 326 $price = false; 327 } 328 329 // Display prices 330 if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) { 331 $total = $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax')) * $product['quantity'], $this->session->data['currency']); 332 } else { 333 $total = false; 334 } 335 336 $data['products'][] = array( 337 'cart_id' => $product['cart_id'], 338 'thumb' => $image, 339 'name' => $product['name'], 340 'model' => $product['model'], 341 'option' => $option_data, 342 'recurring' => ($product['recurring'] ? $product['recurring']['name'] : ''), 343 'quantity' => $product['quantity'], 344 'price' => $price, 345 'total' => $total, 346 'href' => $this->url->link('product/product', 'product_id=' . $product['product_id']) 347 ); 348 } 349 350 // Gift Voucher 351 $data['vouchers'] = array(); 352 353 if (!empty($this->session->data['vouchers'])) { 354 foreach ($this->session->data['vouchers'] as $key => $voucher) { 355 $data['vouchers'][] = array( 356 'key' => $key, 357 'description' => $voucher['description'], 358 'amount' => $this->currency->format($voucher['amount'], $this->session->data['currency']) 359 ); 360 } 361 } 362 363 $totals = array(); 364 $taxes = $this->cart->getTaxes(); 365 $total = 0; 366 367 // Because __call can not keep var references so we put them into an array. 368 $total_data = array( 369 'totals' => &$totals, 370 'taxes' => &$taxes, 371 'total' => &$total 372 ); 373 374 $this->load->model('setting/extension'); 375 376 $sort_order = array(); 377 378 $results = $this->model_setting_extension->getExtensions('total'); 379 380 foreach ($results as $key => $value) { 381 $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); 382 } 383 384 array_multisort($sort_order, SORT_ASC, $results); 385 386 foreach ($results as $result) { 387 if ($this->config->get($result['code'] . '_status')) { 388 $this->load->model('extension/total/' . $result['code']); 389 390 // We have to put the totals in an array so that they pass by reference. 391 $this->{'model_extension_total_' . $result['code']}->getTotal($total_data); 392 } 393 } 394 395 $sort_order = array(); 396 397 foreach ($totals as $key => $value) { 398 $sort_order[$key] = $value['sort_order']; 399 } 400 401 array_multisort($sort_order, SORT_ASC, $totals); 402 403 $data['totals'] = array(); 404 405 foreach ($totals as $total) { 406 $data['totals'][] = array( 407 'title' => $total['title'], 408 'text' => $this->currency->format($total['value'], $this->session->data['currency']) 409 ); 410 } 411 412 $this->response->setOutput($this->load->view('extension/payment/klarna_checkout_sidebar', $data)); 413 } 414 415 public function shippingAddress() { 416 $this->load->model('extension/payment/klarna_checkout'); 417 $this->load->model('localisation/zone'); 418 419 if (!$this->config->get('klarna_checkout_status')) { 420 return false; 421 } 422 423 $json = array(); 424 425 unset($this->session->data['shipping_address']); 426 unset($this->session->data['shipping_methods']); 427 428 if (($this->request->server['REQUEST_METHOD'] == 'POST') && isset($this->request->post['country'])) { 429 $country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode3($this->request->post['country']); 430 431 if ($country_info) { 432 // Set default zone for shipping calculations. Get overwritten by correct data when order is confirmed 433 $zones = $this->model_localisation_zone->getZonesByCountryId($country_info['country_id']); 434 435 $zone = array(); 436 if (isset($this->request->post['region']) && !empty($this->request->post['region'])) { 437 $zone = $this->model_extension_payment_klarna_checkout->getZoneByCode($this->request->post['region'], $country_info['country_id']); 438 } 439 440 if ($zone || $zones) { 441 $this->session->data['shipping_address'] = array( 442 'address_id' => null, 443 'firstname' => utf8_substr($this->request->post['given_name'], 0, 32), 444 'lastname' => utf8_substr($this->request->post['family_name'], 0, 32), 445 'company' => null, 446 'address_1' => utf8_substr($this->request->post['street_address'], 0, 128), 447 'address_2' => utf8_substr($this->request->post['street_address'], 129, 256), 448 'postcode' => utf8_substr($this->request->post['postal_code'], 0, 10), 449 'city' => utf8_substr($this->request->post['city'], 0, 128), 450 'zone_id' => ($zone ? $zone['zone_id'] : $zones[0]['zone_id']), 451 'zone' => ($zone ? $zone['name'] : $zones[0]['name']), 452 'zone_code' => ($zone ? $zone['code'] : $zones[0]['code']), 453 'country_id' => $country_info['country_id'], 454 'country' => $country_info['name'], 455 'iso_code_2' => $country_info['iso_code_2'], 456 'iso_code_3' => $country_info['iso_code_3'], 457 'address_format' => $country_info['address_format'], 458 'custom_field' => array(), 459 ); 460 461 $this->tax->unsetRates(); 462 $this->tax->setShippingAddress($this->session->data['shipping_address']['country_id'], $this->session->data['shipping_address']['zone_id']); 463 $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); 464 } 465 } else { 466 $this->model_extension_payment_klarna_checkout->log('Couldnt find country: ' . $this->request->post['country']); 467 } 468 } 469 470 $this->response->addHeader('Content-Type: application/json'); 471 $this->response->setOutput(json_encode($json)); 472 } 473 474 public function cartTotal() { 475 $this->load->language('checkout/cart'); 476 477 if (!$this->config->get('klarna_checkout_status')) { 478 return false; 479 } 480 481 // Totals 482 $this->load->model('setting/extension'); 483 484 $totals = array(); 485 $taxes = $this->cart->getTaxes(); 486 $total = 0; 487 488 // Because __call can not keep var references so we put them into an array. 489 $total_data = array( 490 'totals' => &$totals, 491 'taxes' => &$taxes, 492 'total' => &$total 493 ); 494 495 // Display prices 496 if (($this->config->get('config_customer_price') && $this->customer->isLogged()) || !$this->config->get('config_customer_price')) { 497 $sort_order = array(); 498 499 $results = $this->model_setting_extension->getExtensions('total'); 500 501 foreach ($results as $key => $value) { 502 $sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order'); 503 } 504 505 array_multisort($sort_order, SORT_ASC, $results); 506 507 foreach ($results as $result) { 508 if ($this->config->get($result['code'] . '_status')) { 509 $this->load->model('extension/total/' . $result['code']); 510 511 // We have to put the totals in an array so that they pass by reference. 512 $this->{'model_extension_total_' . $result['code']}->getTotal($total_data); 513 } 514 } 515 516 $sort_order = array(); 517 518 foreach ($totals as $key => $value) { 519 $sort_order[$key] = $value['sort_order']; 520 } 521 522 array_multisort($sort_order, SORT_ASC, $totals); 523 524 $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'])); 525 } 526 527 $this->response->addHeader('Content-Type: application/json'); 528 $this->response->setOutput(json_encode($total)); 529 } 530 531 public function addressUpdate() { 532 $this->load->language('extension/payment/klarna_checkout'); 533 534 $this->load->model('account/customer'); 535 $this->load->model('checkout/order'); 536 $this->load->model('extension/payment/klarna_checkout'); 537 $this->load->model('localisation/zone'); 538 539 if (!$this->config->get('klarna_checkout_status')) { 540 return false; 541 } 542 543 $process = true; 544 545 $request = json_decode(file_get_contents('php://input')); 546 547 $json = array(); 548 549 $http_response_code = 400; 550 551 // Check to see if request data is complete 552 if (!$request || !isset($request->order_lines) || empty($request->order_lines) || !isset($request->shipping_address) || empty($request->shipping_address)) { 553 $this->model_extension_payment_klarna_checkout->log('Request data incomplete. Full request below:'); 554 $this->model_extension_payment_klarna_checkout->log($request); 555 $process = false; 556 } 557 558 // Get Klarna order info from db 559 if ($process) { 560 $order_id = null; 561 562 foreach ($request->order_lines as $order_line) { 563 if ($order_line->type == 'physical' || $order_line->type == 'digital' || $order_line->type == 'gift_card') { 564 $order_id = $this->encryption->decrypt($this->config->get('config_encryption'), $order_line->merchant_data); 565 break; 566 } 567 } 568 569 if ($order_id) { 570 // Get klarna order data from db 571 $klarna_checkout_order = $this->model_extension_payment_klarna_checkout->getOrderByOrderId($order_id); 572 573 if (!$klarna_checkout_order || !$klarna_checkout_order['data']) { 574 $this->model_extension_payment_klarna_checkout->log('No klarna order found using order_id: ' . $order_id); 575 $process = false; 576 } 577 } else { 578 $process = false; 579 } 580 } 581 582 if ($process) { 583 $klarna_checkout_order_data = json_decode($this->encryption->decrypt($this->config->get('config_encryption'), $klarna_checkout_order['data']), true); 584 585 // Check credentials in request with ones stored in db 586 $valid_request = false; 587 foreach ($this->config->get('klarna_checkout_account') as $account) { 588 if (($account['merchant_id'] == $klarna_checkout_order_data['merchant_id']) && ($account['secret'] == $klarna_checkout_order_data['secret'])) { 589 $valid_request = true; 590 break; 591 } 592 } 593 594 if (!$valid_request) { 595 $this->model_extension_payment_klarna_checkout->log('Cannot validate request. Terminating.'); 596 $process = false; 597 } 598 } 599 600 // Request is valid, we can spoof/simulate the customer to calculate shipping 601 if ($process) { 602 session_destroy(); 603 session_id($klarna_checkout_order_data['session_id']); 604 session_start(); 605 $this->session->start('default', $klarna_checkout_order_data['session_key']); 606 607 if ($klarna_checkout_order_data['customer_id']) { 608 $customer_info = $this->model_account_customer->getCustomer($klarna_checkout_order_data['customer_id']); 609 610 if ($customer_info) { 611 $this->customer->login($customer_info['email'], '', true); 612 } 613 } 614 615 $order_info = $this->model_checkout_order->getOrder($order_id); 616 617 if (!$order_info) { 618 $this->model_extension_payment_klarna_checkout->log('No order found using order_id: ' . $order_id . '. Full request below:'); 619 $this->model_extension_payment_klarna_checkout->log($request); 620 $process = false; 621 } 622 623 // Set more session data from the order 624 $this->session->data['currency'] = $order_info['currency_code']; 625 $this->session->data['language'] = $order_info['language_code']; 626 627 $country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode2($request->shipping_address->country); 628 629 if (!$country_info) { 630 $this->model_extension_payment_klarna_checkout->log('No country found using: ' . $request->shipping_address->country . '. Full request below:'); 631 $this->model_extension_payment_klarna_checkout->log($request); 632 } 633 634 if ($order_info && $country_info) { 635 $zones = $this->model_localisation_zone->getZonesByCountryId($country_info['country_id']); 636 637 $zone = array(); 638 if (isset($request->shipping_address->region) && !empty($request->shipping_address->region)) { 639 $zone = $this->model_extension_payment_klarna_checkout->getZoneByCode($request->shipping_address->region, $country_info['country_id']); 640 } 641 642 if ($zone || $zones) { 643 $this->session->data['shipping_address'] = array( 644 'address_id' => null, 645 'firstname' => null, 646 'lastname' => null, 647 'company' => null, 648 'address_1' => null, 649 'address_2' => null, 650 'postcode' => null, 651 'city' => null, 652 'zone_id' => ($zone ? $zone['zone_id'] : $zones[0]['zone_id']), 653 'zone' => ($zone ? $zone['name'] : $zones[0]['name']), 654 'zone_code' => ($zone ? $zone['code'] : $zones[0]['code']), 655 'country_id' => $country_info['country_id'], 656 'country' => $country_info['name'], 657 'iso_code_2' => $country_info['iso_code_2'], 658 'iso_code_3' => $country_info['iso_code_3'], 659 'address_format' => '', 660 'custom_field' => array() 661 ); 662 663 $this->session->data['klarna_checkout_data'] = array( 664 'email' => $request->billing_address->email, 665 'firstname' => $request->billing_address->given_name, 666 'lastname' => $request->billing_address->family_name, 667 'telephone' => $request->billing_address->phone, 668 'iso_code_2' => $this->session->data['shipping_address']['iso_code_2'], 669 'zone_code' => $this->session->data['shipping_address']['zone_code'] 670 ); 671 672 // Unset $tax_rates 673 $this->tax->unsetRates(); 674 $this->tax->setShippingAddress($country_info['country_id'], ($zone ? $zone['zone_id'] : $zones[0]['zone_id'])); 675 $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); 676 677 //Check if customer is US. If so, send taxes differently 678 if ($this->session->data['shipping_address']['iso_code_2'] === 'US') { 679 $include_taxes = false; 680 } else { 681 $include_taxes = true; 682 } 683 684 $method_data = array(); 685 686 $this->load->model('setting/extension'); 687 688 $results = $this->model_setting_extension->getExtensions('shipping'); 689 690 foreach ($results as $result) { 691 if ($this->config->get('shipping_' . $result['code'] . '_status')) { 692 $this->load->model('extension/shipping/' . $result['code']); 693 694 $quote = $this->{'model_extension_shipping_' . $result['code']}->getQuote($this->session->data['shipping_address']); 695 696 if ($quote) { 697 $method_data[$result['code']] = array( 698 'title' => $quote['title'], 699 'quote' => $quote['quote'], 700 'sort_order' => $quote['sort_order'], 701 'error' => $quote['error'] 702 ); 703 } 704 } 705 } 706 707 $sort_order = array(); 708 709 foreach ($method_data as $key => $value) { 710 $sort_order[$key] = $value['sort_order']; 711 } 712 713 array_multisort($sort_order, SORT_ASC, $method_data); 714 715 $shipping_methods = $method_data; 716 717 if ($shipping_methods) { 718 list($klarna_account, $connector) = $this->model_extension_payment_klarna_checkout->getConnector($this->config->get('klarna_checkout_account'), $this->session->data['currency']); 719 720 if ($klarna_account && $connector) { 721 list($klarna_order_data, $encrypted_order_data) = $this->klarnaOrderData($klarna_account); 722 723 if ($this->cart->hasShipping()) { 724 $shipping_method = array(); 725 726 if (isset($this->session->data['shipping_method']) && !empty($this->session->data['shipping_method'])) { 727 foreach ($shipping_methods as $individual_shipping_method) { 728 if ($individual_shipping_method['quote']) { 729 foreach ($individual_shipping_method['quote'] as $quote) { 730 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'])) { 731 $shipping_method = $quote; 732 break 2; 733 } 734 } 735 } 736 } 737 } 738 739 // If the current shipping method isn't in the available shipping methods, assign default 740 if (!$shipping_method) { 741 $this->session->data['shipping_method'] = $this->model_extension_payment_klarna_checkout->getDefaultShippingMethod($shipping_methods); 742 } 743 744 $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; 745 746 if ($include_taxes) { 747 $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; 748 } else { 749 $total_tax_amount = 0; 750 } 751 752 $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; 753 754 $tax_rate = 0; 755 756 if ($include_taxes && $total_tax_amount && $total_sub_amount) { 757 $tax_rate = ($total_tax_amount / $total_sub_amount) * 100; 758 } 759 760 foreach ($klarna_order_data['order_lines'] as $key => $order_line) { 761 if ($order_line['type'] == 'shipping_fee') { 762 unset($klarna_order_data['order_lines'][$key]); 763 break; 764 } 765 } 766 767 $klarna_order_data['order_lines'][] = array( 768 'type' => 'shipping_fee', 769 'name' => $this->session->data['shipping_method']['title'], 770 'quantity' => '1', 771 '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), 772 'tax_rate' => round($tax_rate * 100), 773 'total_amount' => round($total_amount), 774 'total_tax_amount' => round($total_tax_amount), 775 'total_discount_amount' => 0 776 ); 777 } 778 779 list($totals, $taxes, $total) = $this->model_extension_payment_klarna_checkout->getTotals(); 780 781 //If $include_taxes is false, means customer is US so we add a new sales_tax order line with all the tax 782 if (!$include_taxes) { 783 foreach ($klarna_order_data['order_lines'] as $key => $order_line) { 784 if ($order_line['type'] == 'sales_tax') { 785 unset($klarna_order_data['order_lines'][$key]); 786 break; 787 } 788 } 789 790 $klarna_order_data['order_lines'][] = array( 791 'type' => 'sales_tax', 792 'name' => $this->language->get('text_sales_tax'), 793 'quantity' => '1', 794 'unit_price' => round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100), 795 'tax_rate' => 0, 796 'total_amount' => round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100), 797 'total_tax_amount' => 0, 798 'total_discount_amount' => 0 799 ); 800 } 801 802 $http_response_code = 200; 803 804 $json = array( 805 'order_amount' => round($this->currency->format($total, $order_info['currency_code'], $order_info['currency_value'], false) * 100), 806 'order_tax_amount' => round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100), 807 'order_lines' => array_values($klarna_order_data['order_lines']) 808 ); 809 } 810 } 811 } 812 } 813 } 814 815 $this->model_extension_payment_klarna_checkout->log($http_response_code); 816 $this->model_extension_payment_klarna_checkout->log($json); 817 818 http_response_code($http_response_code); 819 $this->response->addHeader('Content-Type: application/json'); 820 $this->response->setOutput(json_encode($json)); 821 } 822 823 public function notification() { 824 $this->load->model('extension/payment/klarna_checkout'); 825 $this->load->model('checkout/order'); 826 827 if (!$this->config->get('klarna_checkout_status')) { 828 return false; 829 } 830 831 $request = json_decode(file_get_contents('php://input')); 832 833 if (isset($request->order_id)) { 834 $klarna_checkout_order = $this->model_extension_payment_klarna_checkout->getOrder($request->order_id); 835 836 if ($klarna_checkout_order) { 837 $order_info = $this->model_checkout_order->getOrder($klarna_checkout_order['order_id']); 838 839 if ($order_info) { 840 list($klarna_account, $connector) = $this->model_extension_payment_klarna_checkout->getConnector($this->config->get('klarna_checkout_account'), $order_info['currency_code']); 841 842 if (!$klarna_account || !$connector) { 843 $this->model_extension_payment_klarna_checkout->log('Could not getConnector'); 844 } 845 846 $retrieve = $this->model_extension_payment_klarna_checkout->omOrderRetrieve($connector, $request->order_id); 847 848 $order_status_id = false; 849 if ($retrieve) { 850 switch ($request->event_type) { 851 case 'FRAUD_RISK_ACCEPTED': 852 $order_status_id = $this->config->get('klarna_checkout_order_status_fraud_accepted_id'); 853 break; 854 case 'FRAUD_RISK_REJECTED': 855 $order_status_id = $this->config->get('klarna_checkout_order_status_fraud_rejected_id'); 856 break; 857 } 858 } 859 860 if ($order_status_id) { 861 $this->model_checkout_order->addOrderHistory($klarna_checkout_order['order_id'], $order_status_id); 862 } 863 } 864 } else { 865 $this->model_extension_payment_klarna_checkout->log('Could not find order id using ' . $request->order_id); 866 } 867 } else { 868 $this->model_extension_payment_klarna_checkout->log('$request->order_id is not set'); 869 } 870 } 871 872 public function validation() { 873 $this->load->model('account/customer'); 874 $this->load->model('checkout/order'); 875 $this->load->model('extension/payment/klarna_checkout'); 876 877 if (!$this->config->get('klarna_checkout_status')) { 878 return false; 879 } 880 881 $validate = true; 882 883 $request = json_decode(file_get_contents('php://input')); 884 885 $json = array(); 886 887 // Check to see if request data is complete 888 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)) { 889 $this->model_extension_payment_klarna_checkout->log('Request data incomplete. Full request below:'); 890 $this->model_extension_payment_klarna_checkout->log($request); 891 $validate = false; 892 } 893 894 // Get Klarna order info from db 895 if ($validate) { 896 $order_id = null; 897 898 foreach ($request->order_lines as $order_line) { 899 if ($order_line->type == 'physical' || $order_line->type == 'digital' || $order_line->type == 'gift_card') { 900 $order_id = $this->encryption->decrypt($this->config->get('config_encryption'), $order_line->merchant_data); 901 break; 902 } 903 } 904 905 if ($order_id) { 906 // Get klarna order data from db 907 $klarna_checkout_order = $this->model_extension_payment_klarna_checkout->getOrderByOrderId($order_id); 908 909 if (!$klarna_checkout_order || !$klarna_checkout_order['data']) { 910 $this->model_extension_payment_klarna_checkout->log('No klarna order found using order_id: ' . $order_id); 911 $validate = false; 912 } 913 } else { 914 $this->model_extension_payment_klarna_checkout->log('Cannot get decrypted order_id'); 915 $validate = false; 916 } 917 } 918 919 if ($validate) { 920 $klarna_checkout_order_data = json_decode($this->encryption->decrypt($klarna_checkout_order['data']), true); 921 922 // Check credentials in request with ones stored in db 923 $valid_request = false; 924 foreach ($this->config->get('klarna_checkout_account') as $account) { 925 if (($account['merchant_id'] == $klarna_checkout_order_data['merchant_id']) && ($account['secret'] == $klarna_checkout_order_data['secret'])) { 926 $valid_request = true; 927 break; 928 } 929 } 930 931 if (!$valid_request) { 932 $this->model_extension_payment_klarna_checkout->log('Cannot validate request. Terminating.'); 933 $validate = false; 934 } 935 } 936 937 // Spoof/simulate the customer to calculate shipping 938 if ($validate) { 939 session_destroy(); 940 session_id($klarna_checkout_order_data['session_id']); 941 session_start(); 942 $this->session->start('default', $klarna_checkout_order_data['session_key']); 943 944 if ($klarna_checkout_order_data['customer_id']) { 945 $customer_info = $this->model_account_customer->getCustomer($klarna_checkout_order_data['customer_id']); 946 947 if ($customer_info) { 948 $this->customer->login($customer_info['email'], '', true); 949 } 950 } 951 952 // Validate cart has products and has stock. 953 if ((!$this->cart->hasProducts() && empty($this->session->data['vouchers'])) || (!$this->cart->hasStock() && !$this->config->get('config_stock_checkout'))) { 954 $this->model_extension_payment_klarna_checkout->log('Cart has no products or cart has no stock'); 955 $validate = false; 956 } 957 958 // Validate minimum quantity requirements. 959 $products = $this->cart->getProducts(); 960 961 foreach ($products as $product) { 962 $product_total = 0; 963 964 foreach ($products as $product_2) { 965 if ($product_2['product_id'] == $product['product_id']) { 966 $product_total += $product_2['quantity']; 967 } 968 } 969 970 if ($product['minimum'] > $product_total) { 971 $this->model_extension_payment_klarna_checkout->log('Cart doesnt meet minimum quantities'); 972 $validate = false; 973 } 974 } 975 976 // Validate cart has recurring products 977 if ($this->cart->hasRecurringProducts()) { 978 $this->model_extension_payment_klarna_checkout->log('Cart has recurring products'); 979 $validate = false; 980 } 981 } 982 983 // Check order total to see if session matches post data 984 if ($validate) { 985 $order_info = $this->model_checkout_order->getOrder($order_id); 986 987 if ($order_info) { 988 // Unset $tax_rates and set them again using correct shipping data 989 $this->tax->unsetRates(); 990 $this->tax->setShippingAddress($this->session->data['shipping_address']['country_id'], $this->session->data['shipping_address']['zone_id']); 991 $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); 992 993 list($totals, $taxes, $total) = $this->model_extension_payment_klarna_checkout->getTotals(); 994 995 // Check order_amount 996 if (round($this->currency->format($total, $order_info['currency_code'], $order_info['currency_value'], false) * 100) != $request->order_amount) { 997 $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)); 998 $this->model_extension_payment_klarna_checkout->log($order_info); 999 $this->model_extension_payment_klarna_checkout->log($this->cart->getTaxes()); 1000 $validate = false; 1001 } 1002 1003 // Check order_tax_amount 1004 if (round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100) != $request->order_tax_amount) { 1005 $this->model_extension_payment_klarna_checkout->log('Klarna Checkout order_tax_amount does not match session tax total. Totals below:'); 1006 $this->model_extension_payment_klarna_checkout->log('Session taxes:'); 1007 $this->model_extension_payment_klarna_checkout->log(round($this->currency->format(array_sum($taxes), $order_info['currency_code'], $order_info['currency_value'], false) * 100)); 1008 $this->model_extension_payment_klarna_checkout->log('Request taxes:'); 1009 $this->model_extension_payment_klarna_checkout->log($request->order_tax_amount); 1010 $validate = false; 1011 } 1012 } else { 1013 $this->model_extension_payment_klarna_checkout->log('Cannot find order using: ' . $order_id); 1014 $validate = false; 1015 } 1016 } 1017 1018 // If validates, add customer's email (if guest checkout) and then send 200 response 1019 if ($validate) { 1020 if (!$this->customer->isLogged()) { 1021 $this->model_extension_payment_klarna_checkout->updateOcOrderEmail($order_id, utf8_substr($request->shipping_address->email, 0, 96)); 1022 } 1023 1024 // Update OpenCart order with payment and shipping details 1025 $payment_country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode2($request->billing_address->country); 1026 $shipping_country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode2($request->shipping_address->country); 1027 1028 //If region is passed, try to update OpenCart order with correct region/zone 1029 $payment_zone_info = array(); 1030 if ($payment_country_info && isset($request->billing_address->region)) { 1031 $payment_zone_info = $this->model_extension_payment_klarna_checkout->getZoneByCode($request->billing_address->region, $payment_country_info['country_id']); 1032 } 1033 1034 $shipping_zone_info = array(); 1035 if ($shipping_country_info && isset($request->shipping_address->region)) { 1036 $shipping_zone_info = $this->model_extension_payment_klarna_checkout->getZoneByCode($request->shipping_address->region, $shipping_country_info['country_id']); 1037 } 1038 1039 $order_data = array( 1040 'firstname' => utf8_substr($request->billing_address->given_name, 0, 32), 1041 'lastname' => utf8_substr($request->billing_address->family_name, 0, 32), 1042 'telephone' => utf8_substr($request->billing_address->phone, 0, 32), 1043 'payment_firstname' => utf8_substr($request->billing_address->given_name, 0, 32), 1044 'payment_lastname' => utf8_substr($request->billing_address->family_name, 0, 32), 1045 'payment_address_1' => utf8_substr($request->billing_address->street_address, 0, 128), 1046 'payment_address_2' => (isset($request->billing_address->street_address2) ? utf8_substr($request->billing_address->street_address2, 0, 128) : ''), 1047 'payment_city' => utf8_substr($request->billing_address->city, 0, 128), 1048 'payment_postcode' => utf8_substr($request->billing_address->postal_code, 0, 10), 1049 'payment_zone' => ($payment_zone_info ? $payment_zone_info['name'] : ''), 1050 'payment_zone_id' => ($payment_zone_info ? $payment_zone_info['zone_id'] : ''), 1051 'payment_country' => ($payment_country_info ? $payment_country_info['name'] : ''), 1052 'payment_country_id' => ($payment_country_info ? $payment_country_info['country_id'] : ''), 1053 'payment_address_format' => ($payment_country_info ? $payment_country_info['address_format'] : ''), 1054 'shipping_firstname' => utf8_substr($request->shipping_address->given_name, 0, 32), 1055 'shipping_lastname' => utf8_substr($request->shipping_address->family_name, 0, 32), 1056 'shipping_address_1' => utf8_substr($request->shipping_address->street_address, 0, 128), 1057 'shipping_address_2' => (isset($request->shipping_address->street_address2) ? utf8_substr($request->shipping_address->street_address2, 0, 128) : ''), 1058 'shipping_city' => utf8_substr($request->shipping_address->city, 0, 128), 1059 'shipping_postcode' => utf8_substr($request->shipping_address->postal_code, 0, 10), 1060 'shipping_zone' => ($shipping_zone_info ? $shipping_zone_info['name'] : ''), 1061 'shipping_zone_id' => ($shipping_zone_info ? $shipping_zone_info['zone_id'] : ''), 1062 'shipping_country' => ($shipping_country_info ? $shipping_country_info['name'] : ''), 1063 'shipping_country_id' => ($shipping_country_info ? $shipping_country_info['country_id'] : ''), 1064 'shipping_address_format' => ($shipping_country_info ? $shipping_country_info['address_format'] : '') 1065 ); 1066 1067 $this->model_extension_payment_klarna_checkout->updateOcOrder($order_id, $order_data); 1068 1069 $this->model_checkout_order->addOrderHistory($order_id, $this->config->get('config_order_status_id')); 1070 1071 http_response_code(200); 1072 } else { 1073 http_response_code(303); 1074 $this->response->addHeader('Location: ' . $this->url->link('checkout/failure', '', true)); 1075 } 1076 1077 $this->response->addHeader('Content-Type: application/json'); 1078 $this->response->setOutput(json_encode($json)); 1079 } 1080 1081 public function confirmation() { 1082 $this->load->language('extension/payment/klarna_checkout'); 1083 1084 if (!$this->config->get('klarna_checkout_status')) { 1085 return false; 1086 } 1087 1088 if (isset($this->session->data['order_id'])) { 1089 $this->cart->clear(); 1090 1091 unset($this->session->data['shipping_method']); 1092 unset($this->session->data['shipping_methods']); 1093 unset($this->session->data['payment_method']); 1094 unset($this->session->data['payment_methods']); 1095 unset($this->session->data['guest']); 1096 unset($this->session->data['comment']); 1097 unset($this->session->data['order_id']); 1098 unset($this->session->data['coupon']); 1099 unset($this->session->data['reward']); 1100 unset($this->session->data['voucher']); 1101 unset($this->session->data['vouchers']); 1102 unset($this->session->data['totals']); 1103 1104 unset($this->session->data['klarna_checkout_order_id']); 1105 unset($this->session->data['klarna_checkout_data']); 1106 } 1107 1108 $this->document->setTitle($this->language->get('heading_title_success')); 1109 1110 $data['breadcrumbs'] = array(); 1111 1112 $data['breadcrumbs'][] = array( 1113 'text' => $this->language->get('text_home'), 1114 'href' => $this->url->link('common/home') 1115 ); 1116 1117 $data['breadcrumbs'][] = array( 1118 'text' => $this->language->get('text_basket'), 1119 'href' => $this->url->link('checkout/cart') 1120 ); 1121 1122 $data['breadcrumbs'][] = array( 1123 'text' => $this->language->get('text_checkout'), 1124 'href' => $this->url->link('checkout/checkout', '', true) 1125 ); 1126 1127 $data['breadcrumbs'][] = array( 1128 'text' => $this->language->get('text_success'), 1129 'href' => $this->url->link('checkout/success') 1130 ); 1131 1132 $data['continue'] = $this->url->link('common/home'); 1133 1134 $data['column_left'] = $this->load->controller('common/column_left'); 1135 $data['column_right'] = $this->load->controller('common/column_right'); 1136 $data['content_top'] = $this->load->controller('common/content_top'); 1137 $data['content_bottom'] = $this->load->controller('common/content_bottom'); 1138 $data['footer'] = $this->load->controller('common/footer'); 1139 $data['header'] = $this->load->controller('common/header'); 1140 1141 $this->load->model('extension/payment/klarna_checkout'); 1142 $this->load->model('checkout/order'); 1143 1144 $klarna_checkout = false; 1145 $html_snippet = ''; 1146 1147 if (isset($this->request->get['klarna_order_id'])) { 1148 $klarna_checkout_order = $this->model_extension_payment_klarna_checkout->getOrder($this->request->get['klarna_order_id']); 1149 1150 if ($klarna_checkout_order) { 1151 $order_info = $this->model_checkout_order->getOrder($klarna_checkout_order['order_id']); 1152 1153 if ($order_info) { 1154 list($klarna_account, $connector) = $this->model_extension_payment_klarna_checkout->getConnector($this->config->get('klarna_checkout_account'), $order_info['currency_code']); 1155 1156 if (!$klarna_account || !$connector) { 1157 $this->model_extension_payment_klarna_checkout->log('Could not getConnector'); 1158 $this->response->redirect($this->url->link('checkout/failure', '', true)); 1159 } 1160 1161 $retrieve = $this->model_extension_payment_klarna_checkout->orderRetrieve($connector, $this->request->get['klarna_order_id']); 1162 1163 if ($retrieve) { 1164 $klarna_checkout = $retrieve->fetch(); 1165 1166 if ($klarna_checkout && $klarna_checkout['html_snippet']) { 1167 $html_snippet = $klarna_checkout['html_snippet']; 1168 } 1169 } else { 1170 $this->response->redirect($this->url->link('checkout/cart', '', true)); 1171 } 1172 } 1173 } else { 1174 $this->model_extension_payment_klarna_checkout->log('Could not find order id using ' . $this->request->get['klarna_order_id']); 1175 $this->response->redirect($this->url->link('checkout/failure', '', true)); 1176 } 1177 } else { 1178 $this->model_extension_payment_klarna_checkout->log('$this->request->get[\'klarna_order_id\'] is not set'); 1179 $this->response->redirect($this->url->link('checkout/failure', '', true)); 1180 } 1181 1182 $data['klarna_checkout'] = $html_snippet; 1183 1184 $this->response->setOutput($this->load->view('extension/payment/klarna_checkout_success', $data)); 1185 } 1186 1187 public function push() { 1188 $this->load->model('extension/payment/klarna_checkout'); 1189 $this->load->model('checkout/order'); 1190 1191 if (!$this->config->get('klarna_checkout_status')) { 1192 return false; 1193 } 1194 1195 if (isset($this->request->get['klarna_order_id'])) { 1196 $klarna_checkout_order = $this->model_extension_payment_klarna_checkout->getOrder($this->request->get['klarna_order_id']); 1197 1198 if ($klarna_checkout_order) { 1199 $order_info = $this->model_checkout_order->getOrder($klarna_checkout_order['order_id']); 1200 1201 if ($order_info) { 1202 list($klarna_account, $connector) = $this->model_extension_payment_klarna_checkout->getConnector($this->config->get('klarna_checkout_account'), $order_info['currency_code']); 1203 1204 if ($klarna_account && $connector) { 1205 $order = $this->model_extension_payment_klarna_checkout->omOrderRetrieve($connector, $this->request->get['klarna_order_id']); 1206 1207 $this->model_extension_payment_klarna_checkout->log('Order details from push:'); 1208 $this->model_extension_payment_klarna_checkout->log($order); 1209 1210 if ($order) { 1211 if ($order->acknowledge()) { 1212 // Update OpenCart order with payment and shipping details 1213 $payment_country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode2($order['billing_address']['country']); 1214 $shipping_country_info = $this->model_extension_payment_klarna_checkout->getCountryByIsoCode2($order['shipping_address']['country']); 1215 1216 //If region is passed, try to update OpenCart order with correct region/zone 1217 $payment_zone_info = array(); 1218 if ($payment_country_info && isset($order['billing_address']['region'])) { 1219 $payment_zone_info = $this->model_extension_payment_klarna_checkout->getZoneByCode($order['billing_address']['region'], $payment_country_info['country_id']); 1220 } 1221 1222 $shipping_zone_info = array(); 1223 if ($shipping_country_info && isset($order['shipping_address']['region'])) { 1224 $shipping_zone_info = $this->model_extension_payment_klarna_checkout->getZoneByCode($order['shipping_address']['region'], $shipping_country_info['country_id']); 1225 } 1226 1227 $order_data = array( 1228 'firstname' => utf8_substr($order['billing_address']['given_name'], 0, 32), 1229 'lastname' => utf8_substr($order['billing_address']['family_name'], 0, 32), 1230 'telephone' => utf8_substr($order['billing_address']['phone'], 0, 32), 1231 'payment_firstname' => utf8_substr($order['billing_address']['given_name'], 0, 32), 1232 'payment_lastname' => utf8_substr($order['billing_address']['family_name'], 0, 32), 1233 'payment_address_1' => utf8_substr($order['billing_address']['street_address'], 0, 128), 1234 'payment_address_2' => (isset($order['billing_address']['street_address2']) ? utf8_substr($order['billing_address']['street_address2'], 0, 128) : ''), 1235 'payment_city' => utf8_substr($order['billing_address']['city'], 0, 128), 1236 'payment_postcode' => utf8_substr($order['billing_address']['postal_code'], 0, 10), 1237 'payment_zone' => ($payment_zone_info ? $payment_zone_info['name'] : ''), 1238 'payment_zone_id' => ($payment_zone_info ? $payment_zone_info['zone_id'] : ''), 1239 'payment_country' => ($payment_country_info ? $payment_country_info['name'] : ''), 1240 'payment_country_id' => ($payment_country_info ? $payment_country_info['country_id'] : ''), 1241 'payment_address_format' => ($payment_country_info ? $payment_country_info['address_format'] : ''), 1242 'shipping_firstname' => utf8_substr($order['shipping_address']['given_name'], 0, 32), 1243 'shipping_lastname' => utf8_substr($order['shipping_address']['family_name'], 0, 32), 1244 'shipping_address_1' => utf8_substr($order['shipping_address']['street_address'], 0, 128), 1245 'shipping_address_2' => (isset($order['shipping_address']['street_address2']) ? utf8_substr($order['shipping_address']['street_address2'], 0, 128) : ''), 1246 'shipping_city' => utf8_substr($order['shipping_address']['city'], 0, 128), 1247 'shipping_postcode' => utf8_substr($order['shipping_address']['postal_code'], 0, 10), 1248 'shipping_zone' => ($shipping_zone_info ? $shipping_zone_info['name'] : ''), 1249 'shipping_zone_id' => ($shipping_zone_info ? $shipping_zone_info['zone_id'] : ''), 1250 'shipping_country' => ($shipping_country_info ? $shipping_country_info['name'] : ''), 1251 'shipping_country_id' => ($shipping_country_info ? $shipping_country_info['country_id'] : ''), 1252 'shipping_address_format' => ($shipping_country_info ? $shipping_country_info['address_format'] : '') 1253 ); 1254 1255 $this->model_extension_payment_klarna_checkout->updateOcOrder($klarna_checkout_order['order_id'], $order_data); 1256 1257 $order_status_id = false; 1258 switch ($order['status']) { 1259 case 'AUTHORIZED': 1260 $order_status_id = $this->config->get('klarna_checkout_order_status_authorised_id'); 1261 1262 if ($order['fraud_status'] == 'PENDING') { 1263 $order_status_id = $this->config->get('klarna_checkout_order_status_fraud_pending_id'); 1264 } elseif ($order['fraud_status'] == 'REJECTED') { 1265 $order_status_id = $this->config->get('klarna_checkout_order_status_fraud_rejected_id'); 1266 } 1267 break; 1268 case 'PART_CAPTURED': 1269 $order_status_id = $this->config->get('klarna_checkout_order_status_part_captured_id'); 1270 break; 1271 case 'CAPTURED': 1272 $order_status_id = $this->config->get('klarna_checkout_order_status_captured_id'); 1273 break; 1274 case 'CANCELLED': 1275 $order_status_id = $this->config->get('klarna_checkout_order_status_cancelled_id'); 1276 break; 1277 } 1278 1279 if ($order_status_id) { 1280 $this->model_checkout_order->addOrderHistory($klarna_checkout_order['order_id'], $order_status_id); 1281 } 1282 } 1283 } else { 1284 $this->model_extension_payment_klarna_checkout->log('Cannot retrieve KC order using order_id: ' . $this->request->get['klarna_order_id']); 1285 } 1286 } 1287 } 1288 } else { 1289 $this->model_extension_payment_klarna_checkout->log('Cannot find KC order using order_id: ' . $this->request->get['klarna_order_id']); 1290 } 1291 } 1292 } 1293 1294 private function setPayment() { 1295 $this->load->model('account/address'); 1296 $this->load->model('localisation/country'); 1297 $this->load->model('localisation/zone'); 1298 1299 if (isset($this->session->data['payment_address']) && !empty($this->session->data['payment_address'])) { 1300 $this->session->data['payment_address'] = $this->session->data['payment_address']; 1301 } elseif ($this->customer->isLogged() && $this->customer->getAddressId()) { 1302 $this->session->data['payment_address'] = $this->model_account_address->getAddress($this->customer->getAddressId()); 1303 } else { 1304 $country_info = $this->model_localisation_country->getCountry($this->config->get('config_country_id')); 1305 1306 $zone_info = $this->model_localisation_zone->getZone($this->config->get('config_zone_id')); 1307 1308 $this->session->data['payment_address'] = array( 1309 'address_id' => null, 1310 'firstname' => null, 1311 'lastname' => null, 1312 'company' => null, 1313 'address_1' => null, 1314 'address_2' => null, 1315 'postcode' => null, 1316 'city' => null, 1317 'zone_id' => $zone_info['zone_id'], 1318 'zone' => $zone_info['name'], 1319 'zone_code' => $zone_info['code'], 1320 'country_id' => $country_info['country_id'], 1321 'country' => $country_info['name'], 1322 'iso_code_2' => $country_info['iso_code_2'], 1323 'iso_code_3' => $country_info['iso_code_3'], 1324 'address_format' => '', 1325 'custom_field' => array() 1326 ); 1327 } 1328 1329 $this->tax->setPaymentAddress($this->session->data['payment_address']['country_id'], $this->session->data['payment_address']['zone_id']); 1330 $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); 1331 } 1332 1333 private function setShipping() { 1334 $this->load->model('account/address'); 1335 $this->load->model('localisation/country'); 1336 $this->load->model('localisation/zone'); 1337 1338 if (isset($this->session->data['shipping_address']) && !empty($this->session->data['shipping_address'])) { 1339 $this->session->data['shipping_address'] = $this->session->data['shipping_address']; 1340 } elseif ($this->customer->isLogged() && $this->customer->getAddressId()) { 1341 $this->session->data['shipping_address'] = $this->model_account_address->getAddress($this->customer->getAddressId()); 1342 } else { 1343 $country_info = $this->model_localisation_country->getCountry($this->config->get('config_country_id')); 1344 1345 $zone_info = $this->model_localisation_zone->getZone($this->config->get('config_zone_id')); 1346 1347 $this->session->data['shipping_address'] = array( 1348 'address_id' => null, 1349 'firstname' => null, 1350 'lastname' => null, 1351 'company' => null, 1352 'address_1' => null, 1353 'address_2' => null, 1354 'postcode' => null, 1355 'city' => null, 1356 'zone_id' => $zone_info['zone_id'], 1357 'zone' => $zone_info['name'], 1358 'zone_code' => $zone_info['code'], 1359 'country_id' => $country_info['country_id'], 1360 'country' => $country_info['name'], 1361 'iso_code_2' => $country_info['iso_code_2'], 1362 'iso_code_3' => $country_info['iso_code_3'], 1363 'address_format' => '', 1364 'custom_field' => array() 1365 ); 1366 } 1367 1368 $this->tax->unsetRates(); 1369 $this->tax->setShippingAddress($this->session->data['shipping_address']['country_id'], $this->session->data['shipping_address']['zone_id']); 1370 $this->tax->setStoreAddress($this->config->get('config_country_id'), $this->config->get('config_zone_id')); 1371 1372 if (isset($this->session->data['shipping_address'])) { 1373 // Shipping Methods 1374 $method_data = array(); 1375 1376 $this->load->model('setting/extension'); 1377 1378 $results = $this->model_setting_extension->getExtensions('shipping'); 1379 1380 foreach ($results as $result) { 1381 if ($this->config->get('shipping_' . $result['code'] . '_status')) { 1382 $this->load->model('extension/shipping/' . $result['code']); 1383 1384 $quote = $this->{'model_extension_shipping_' . $result['code']}->getQuote($this->session->data['shipping_address']); 1385 1386 if ($quote) { 1387 $method_data[$result['code']] = array( 1388 'title' => $quote['title'], 1389 'quote' => $quote['quote'], 1390 'sort_order' => $quote['sort_order'], 1391 'error' => $quote['error'] 1392 ); 1393 } 1394 } 1395 } 1396 1397 $sort_order = array(); 1398 1399 foreach ($method_data as $key => $value) { 1400 $sort_order[$key] = $value['sort_order']; 1401 } 1402 1403 array_multisort($sort_order, SORT_ASC, $method_data); 1404 1405 $this->session->data['shipping_methods'] = $method_data; 1406 } 1407 } 1408 1409 private function createOrder() { 1410 //Klarna defaults: 1411 $this->session->data['comment'] = ''; 1412 1413 if (!$this->customer->isLogged()) { 1414 $this->session->data['guest'] = array( 1415 'customer_group_id' => $this->config->get('config_customer_group_id'), 1416 'firstname' => '', 1417 'lastname' => '', 1418 'email' => '', 1419 'telephone' => '', 1420 'fax' => '', 1421 'custom_field' => array(), 1422 ); 1423 } 1424 1425 //OpenCart: 1426 $order_data = array(); 1427 1428 list($totals, $taxes, $total) = $this->model_extension_payment_klarna_checkout->getTotals(); 1429 1430 $order_data['totals'] = $totals; 1431 1432 $this->load->language('checkout/checkout'); 1433 1434 $order_data['invoice_prefix'] = $this->config->get('config_invoice_prefix'); 1435 $order_data['store_id'] = $this->config->get('config_store_id'); 1436 $order_data['store_name'] = $this->config->get('config_name'); 1437 1438 if ($order_data['store_id']) { 1439 $order_data['store_url'] = $this->config->get('config_url'); 1440 } else { 1441 $order_data['store_url'] = HTTP_SERVER; 1442 } 1443 1444 if ($this->customer->isLogged()) { 1445 $this->load->model('account/customer'); 1446 1447 $customer_info = $this->model_account_customer->getCustomer($this->customer->getId()); 1448 1449 $order_data['customer_id'] = $this->customer->getId(); 1450 $order_data['customer_group_id'] = $customer_info['customer_group_id']; 1451 $order_data['firstname'] = $customer_info['firstname']; 1452 $order_data['lastname'] = $customer_info['lastname']; 1453 $order_data['email'] = $customer_info['email']; 1454 $order_data['telephone'] = $customer_info['telephone']; 1455 $order_data['custom_field'] = json_decode($customer_info['custom_field'], true); 1456 } elseif (isset($this->session->data['guest'])) { 1457 $order_data['customer_id'] = 0; 1458 $order_data['customer_group_id'] = $this->session->data['guest']['customer_group_id']; 1459 $order_data['firstname'] = $this->session->data['guest']['firstname']; 1460 $order_data['lastname'] = $this->session->data['guest']['lastname']; 1461 $order_data['email'] = $this->session->data['guest']['email']; 1462 $order_data['telephone'] = $this->session->data['guest']['telephone']; 1463 $order_data['custom_field'] = $this->session->data['guest']['custom_field']; 1464 } 1465 1466 $order_data['payment_firstname'] = $this->session->data['payment_address']['firstname']; 1467 $order_data['payment_lastname'] = $this->session->data['payment_address']['lastname']; 1468 $order_data['payment_company'] = $this->session->data['payment_address']['company']; 1469 $order_data['payment_address_1'] = $this->session->data['payment_address']['address_1']; 1470 $order_data['payment_address_2'] = $this->session->data['payment_address']['address_2']; 1471 $order_data['payment_city'] = $this->session->data['payment_address']['city']; 1472 $order_data['payment_postcode'] = $this->session->data['payment_address']['postcode']; 1473 $order_data['payment_zone'] = $this->session->data['payment_address']['zone']; 1474 $order_data['payment_zone_id'] = $this->session->data['payment_address']['zone_id']; 1475 $order_data['payment_country'] = $this->session->data['payment_address']['country']; 1476 $order_data['payment_country_id'] = $this->session->data['payment_address']['country_id']; 1477 $order_data['payment_address_format'] = $this->session->data['payment_address']['address_format']; 1478 $order_data['payment_custom_field'] = (isset($this->session->data['payment_address']['custom_field']) ? $this->session->data['payment_address']['custom_field'] : array()); 1479 1480 if (isset($this->session->data['payment_method']['title'])) { 1481 $order_data['payment_method'] = $this->session->data['payment_method']['title']; 1482 } else { 1483 $order_data['payment_method'] = ''; 1484 } 1485 1486 if (isset($this->session->data['payment_method']['code'])) { 1487 $order_data['payment_code'] = $this->session->data['payment_method']['code']; 1488 } else { 1489 $order_data['payment_code'] = ''; 1490 } 1491 1492 if ($this->cart->hasShipping()) { 1493 $order_data['shipping_firstname'] = $this->session->data['shipping_address']['firstname']; 1494 $order_data['shipping_lastname'] = $this->session->data['shipping_address']['lastname']; 1495 $order_data['shipping_company'] = $this->session->data['shipping_address']['company']; 1496 $order_data['shipping_address_1'] = $this->session->data['shipping_address']['address_1']; 1497 $order_data['shipping_address_2'] = $this->session->data['shipping_address']['address_2']; 1498 $order_data['shipping_city'] = $this->session->data['shipping_address']['city']; 1499 $order_data['shipping_postcode'] = $this->session->data['shipping_address']['postcode']; 1500 $order_data['shipping_zone'] = $this->session->data['shipping_address']['zone']; 1501 $order_data['shipping_zone_id'] = $this->session->data['shipping_address']['zone_id']; 1502 $order_data['shipping_country'] = $this->session->data['shipping_address']['country']; 1503 $order_data['shipping_country_id'] = $this->session->data['shipping_address']['country_id']; 1504 $order_data['shipping_address_format'] = $this->session->data['shipping_address']['address_format']; 1505 $order_data['shipping_custom_field'] = (isset($this->session->data['shipping_address']['custom_field']) ? $this->session->data['shipping_address']['custom_field'] : array()); 1506 1507 if (isset($this->session->data['shipping_method']['title'])) { 1508 $order_data['shipping_method'] = $this->session->data['shipping_method']['title']; 1509 } else { 1510 $order_data['shipping_method'] = ''; 1511 } 1512 1513 if (isset($this->session->data['shipping_method']['code'])) { 1514 $order_data['shipping_code'] = $this->session->data['shipping_method']['code']; 1515 } else { 1516 $order_data['shipping_code'] = ''; 1517 } 1518 } else { 1519 $order_data['shipping_firstname'] = ''; 1520 $order_data['shipping_lastname'] = ''; 1521 $order_data['shipping_company'] = ''; 1522 $order_data['shipping_address_1'] = ''; 1523 $order_data['shipping_address_2'] = ''; 1524 $order_data['shipping_city'] = ''; 1525 $order_data['shipping_postcode'] = ''; 1526 $order_data['shipping_zone'] = ''; 1527 $order_data['shipping_zone_id'] = ''; 1528 $order_data['shipping_country'] = ''; 1529 $order_data['shipping_country_id'] = ''; 1530 $order_data['shipping_address_format'] = ''; 1531 $order_data['shipping_custom_field'] = array(); 1532 $order_data['shipping_method'] = ''; 1533 $order_data['shipping_code'] = ''; 1534 } 1535 1536 $order_data['products'] = array(); 1537 1538 foreach ($this->cart->getProducts() as $product) { 1539 $option_data = array(); 1540 1541 foreach ($product['option'] as $option) { 1542 $option_data[] = array( 1543 'product_option_id' => $option['product_option_id'], 1544 'product_option_value_id' => $option['product_option_value_id'], 1545 'option_id' => $option['option_id'], 1546 'option_value_id' => $option['option_value_id'], 1547 'name' => $option['name'], 1548 'value' => $option['value'], 1549 'type' => $option['type'] 1550 ); 1551 } 1552 1553 $order_data['products'][] = array( 1554 'product_id' => $product['product_id'], 1555 'name' => $product['name'], 1556 'model' => $product['model'], 1557 'option' => $option_data, 1558 'download' => $product['download'], 1559 'quantity' => $product['quantity'], 1560 'subtract' => $product['subtract'], 1561 'price' => $product['price'], 1562 'total' => $product['total'], 1563 'tax' => $this->tax->getTax($product['price'], $product['tax_class_id']), 1564 'reward' => $product['reward'] 1565 ); 1566 } 1567 1568 // Gift Voucher 1569 $order_data['vouchers'] = array(); 1570 1571 if (!empty($this->session->data['vouchers'])) { 1572 foreach ($this->session->data['vouchers'] as $voucher) { 1573 $order_data['vouchers'][] = array( 1574 'description' => $voucher['description'], 1575 'code' => token(10), 1576 'to_name' => $voucher['to_name'], 1577 'to_email' => $voucher['to_email'], 1578 'from_name' => $voucher['from_name'], 1579 'from_email' => $voucher['from_email'], 1580 'voucher_theme_id' => $voucher['voucher_theme_id'], 1581 'message' => $voucher['message'], 1582 'amount' => $voucher['amount'] 1583 ); 1584 } 1585 } 1586 1587 $order_data['comment'] = $this->session->data['comment']; 1588 $order_data['total'] = $total; 1589 1590 if (isset($this->request->cookie['tracking'])) { 1591 $order_data['tracking'] = $this->request->cookie['tracking']; 1592 1593 $subtotal = $this->cart->getSubTotal(); 1594 1595 // Affiliate 1596 $this->load->model('affiliate/affiliate'); 1597 1598 $affiliate_info = $this->model_affiliate_affiliate->getAffiliateByCode($this->request->cookie['tracking']); 1599 1600 if ($affiliate_info) { 1601 $order_data['affiliate_id'] = $affiliate_info['affiliate_id']; 1602 $order_data['commission'] = ($subtotal / 100) * $affiliate_info['commission']; 1603 } else { 1604 $order_data['affiliate_id'] = 0; 1605 $order_data['commission'] = 0; 1606 } 1607 1608 // Marketing 1609 $this->load->model('checkout/marketing'); 1610 1611 $marketing_info = $this->model_checkout_marketing->getMarketingByCode($this->request->cookie['tracking']); 1612 1613 if ($marketing_info) { 1614 $order_data['marketing_id'] = $marketing_info['marketing_id']; 1615 } else { 1616 $order_data['marketing_id'] = 0; 1617 } 1618 } else { 1619 $order_data['affiliate_id'] = 0; 1620 $order_data['commission'] = 0; 1621 $order_data['marketing_id'] = 0; 1622 $order_data['tracking'] = ''; 1623 } 1624 1625 $order_data['language_id'] = $this->config->get('config_language_id'); 1626 $order_data['currency_id'] = $this->currency->getId($this->session->data['currency']); 1627 $order_data['currency_code'] = $this->session->data['currency']; 1628 $order_data['currency_value'] = $this->currency->getValue($this->session->data['currency']); 1629 $order_data['ip'] = $this->request->server['REMOTE_ADDR']; 1630 1631 if (!empty($this->request->server['HTTP_X_FORWARDED_FOR'])) { 1632 $order_data['forwarded_ip'] = $this->request->server['HTTP_X_FORWARDED_FOR']; 1633 } elseif (!empty($this->request->server['HTTP_CLIENT_IP'])) { 1634 $order_data['forwarded_ip'] = $this->request->server['HTTP_CLIENT_IP']; 1635 } else { 1636 $order_data['forwarded_ip'] = ''; 1637 } 1638 1639 if (isset($this->request->server['HTTP_USER_AGENT'])) { 1640 $order_data['user_agent'] = $this->request->server['HTTP_USER_AGENT']; 1641 } else { 1642 $order_data['user_agent'] = ''; 1643 } 1644 1645 if (isset($this->request->server['HTTP_ACCEPT_LANGUAGE'])) { 1646 $order_data['accept_language'] = $this->request->server['HTTP_ACCEPT_LANGUAGE']; 1647 } else { 1648 $order_data['accept_language'] = ''; 1649 } 1650 1651 $this->load->model('checkout/order'); 1652 1653 $this->session->data['order_id'] = $this->model_checkout_order->addOrder($order_data); 1654 } 1655 1656 private function klarnaOrderData($klarna_account) { 1657 $this->load->language('extension/payment/klarna_checkout'); 1658 1659 $this->load->model('extension/payment/klarna_checkout'); 1660 $this->load->model('localisation/country'); 1661 1662 $currency_code = $this->session->data['currency']; 1663 $currency_value = $this->currency->getValue($this->session->data['currency']); 1664 1665 // Shipping 1666 $unset_shipping_method = true; 1667 if (isset($this->session->data['shipping_method']) && isset($this->session->data['shipping_methods'])) { 1668 foreach ($this->session->data['shipping_methods'] as $shipping_method) { 1669 if ($shipping_method['quote']) { 1670 foreach ($shipping_method['quote'] as $quote) { 1671 if ($quote == $this->session->data['shipping_method']) { 1672 $unset_shipping_method = false; 1673 break 2; 1674 } 1675 } 1676 } 1677 } 1678 } 1679 1680 if ($unset_shipping_method) { 1681 unset($this->session->data['shipping_method']); 1682 } 1683 1684 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']))) { 1685 $this->session->data['shipping_method'] = $this->model_extension_payment_klarna_checkout->getDefaultShippingMethod($this->session->data['shipping_methods']); 1686 } 1687 1688 //Check if customer is US. If so, send taxes differently 1689 if ($this->session->data['shipping_address']['iso_code_2'] === 'US') { 1690 $include_taxes = false; 1691 } else { 1692 $include_taxes = true; 1693 } 1694 1695 if ($this->cart->hasShipping() && isset($this->session->data['shipping_method']) && !empty($this->session->data['shipping_method'])) { 1696 $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; 1697 1698 if ($include_taxes) { 1699 $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; 1700 } else { 1701 $total_tax_amount = 0; 1702 } 1703 1704 $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; 1705 1706 $tax_rate = 0; 1707 1708 if ($include_taxes && $total_tax_amount && $total_sub_amount) { 1709 $tax_rate = ($total_tax_amount / $total_sub_amount) * 100; 1710 } 1711 1712 $klarna_order_data['order_lines'][] = array( 1713 'type' => 'shipping_fee', 1714 'name' => $this->session->data['shipping_method']['title'], 1715 'quantity' => '1', 1716 '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), 1717 'tax_rate' => round($tax_rate * 100), 1718 'total_amount' => round($total_amount), 1719 'total_tax_amount' => round($total_tax_amount), 1720 'total_discount_amount' => 0 1721 ); 1722 } 1723 1724 // Billing Address 1725 if (isset($this->session->data['klarna_checkout_data'])) { 1726 $klarna_order_data['billing_address'] = array( 1727 'given_name' => $this->session->data['klarna_checkout_data']['firstname'], 1728 'family_name' => $this->session->data['klarna_checkout_data']['lastname'], 1729 'email' => $this->session->data['klarna_checkout_data']['email'], 1730 'phone' => $this->session->data['klarna_checkout_data']['telephone'], 1731 'postal_code' => $this->session->data['shipping_address']['postcode'], 1732 'region' => $this->session->data['shipping_address']['zone_code'], 1733 'country' => $this->session->data['shipping_address']['iso_code_2'], 1734 ); 1735 } else { 1736 $klarna_order_data['billing_address'] = array( 1737 'given_name' => $this->session->data['shipping_address']['firstname'], 1738 'family_name' => $this->session->data['shipping_address']['lastname'], 1739 'email' => ($this->customer->isLogged() ? $this->customer->getEmail() : null), 1740 'phone' => ($this->customer->isLogged() ? $this->customer->getTelephone() : null) 1741 ); 1742 } 1743 1744 // Order Total 1745 list($totals, $taxes, $total) = $this->model_extension_payment_klarna_checkout->getTotals(); 1746 1747 $merchant_urls = array( 1748 'checkout' => html_entity_decode($this->url->link('extension/payment/klarna_checkout', 'klarna_order_id={checkout.order.id}', true)), 1749 'confirmation' => html_entity_decode($this->url->link('extension/payment/klarna_checkout/confirmation', 'klarna_order_id={checkout.order.id}', true)), 1750 'push' => html_entity_decode($this->url->link('extension/payment/klarna_checkout/push', 'klarna_order_id={checkout.order.id}', true)), 1751 'validation' => html_entity_decode($this->url->link('extension/payment/klarna_checkout/validation', 'klarna_order_id={checkout.order.id}', true)), 1752 'address_update' => html_entity_decode($this->url->link('extension/payment/klarna_checkout/addressUpdate', 'klarna_order_id={checkout.order.id}', true)), 1753 'notification' => html_entity_decode($this->url->link('extension/payment/klarna_checkout/notification', 'klarna_order_id={checkout.order.id}', true)), 1754 ); 1755 1756 if ($this->config->get('klarna_checkout_terms')) { 1757 $merchant_urls['terms'] = html_entity_decode($this->url->link('information/information', 'information_id=' . $this->config->get('klarna_checkout_terms'), true)); 1758 } 1759 1760 $country_info = $this->model_localisation_country->getCountry($klarna_account['country']); 1761 1762 if ($country_info) { 1763 $klarna_order_data['purchase_country'] = $country_info['iso_code_2']; 1764 } 1765 1766 $klarna_order_data['purchase_currency'] = $currency_code; 1767 $klarna_order_data['locale'] = $klarna_account['locale']; 1768 1769 $klarna_order_data['order_amount'] = round($this->currency->format($total, $currency_code, $currency_value, false) * 100); 1770 $klarna_order_data['order_tax_amount'] = round($this->currency->format(array_sum($taxes), $currency_code, $currency_value, false) * 100); 1771 1772 $klarna_order_data['merchant_urls'] = $merchant_urls; 1773 1774 // Callback data to be used to spoof/simulate customer to accurately calculate shipping 1775 $encrypted_order_data = $this->encryption->encrypt($this->config->get('config_encryption'), json_encode(array( 1776 'session_id' => session_id(), 1777 'session_key' => $this->session->getId(), 1778 'customer_id' => $this->customer->getId(), 1779 'order_id' => $this->session->data['order_id'], 1780 'merchant_id' => $klarna_account['merchant_id'], 1781 'secret' => $klarna_account['secret'] 1782 ))); 1783 1784 $encrypted_order_id = $this->encryption->encrypt($this->config->get('config_encryption'), $this->session->data['order_id']); 1785 1786 $klarna_order_data['merchant_reference1'] = $this->session->data['order_id']; 1787 1788 $klarna_order_data['options'] = array(); 1789 1790 if ($this->config->get('klarna_checkout_colour_button')) { 1791 $klarna_order_data['options']['color_button'] = $this->config->get('klarna_checkout_colour_button'); 1792 } 1793 1794 if ($this->config->get('klarna_checkout_colour_button_text')) { 1795 $klarna_order_data['options']['color_button_text'] = $this->config->get('klarna_checkout_colour_button_text'); 1796 } 1797 1798 if ($this->config->get('klarna_checkout_colour_checkbox')) { 1799 $klarna_order_data['options']['color_checkbox'] = $this->config->get('klarna_checkout_colour_checkbox'); 1800 } 1801 1802 if ($this->config->get('klarna_checkout_colour_checkbox_checkmark')) { 1803 $klarna_order_data['options']['color_checkbox_checkmark'] = $this->config->get('klarna_checkout_colour_checkbox_checkmark'); 1804 } 1805 1806 if ($this->config->get('klarna_checkout_colour_header')) { 1807 $klarna_order_data['options']['color_header'] = $this->config->get('klarna_checkout_colour_header'); 1808 } 1809 1810 if ($this->config->get('klarna_checkout_colour_link')) { 1811 $klarna_order_data['options']['color_link'] = $this->config->get('klarna_checkout_colour_link'); 1812 } 1813 1814 if ($this->config->get('klarna_checkout_separate_shipping_address')) { 1815 $klarna_order_data['options']['allow_separate_shipping_address'] = true; 1816 } 1817 1818 // Only pass DOB/title mandatory for UK stores 1819 if ($country_info['iso_code_2'] == 'GB') { 1820 if ($this->config->get('klarna_checkout_dob_mandatory')) { 1821 $klarna_order_data['options']['date_of_birth_mandatory'] = true; 1822 } 1823 1824 if ($this->config->get('klarna_checkout_title_mandatory')) { 1825 $klarna_order_data['options']['title_mandatory'] = true; 1826 } 1827 } 1828 1829 if ($this->config->get('klarna_checkout_additional_text_box') && $this->customer->isLogged() && !$this->customer->getNewsletter()) { 1830 $klarna_order_data['options']['additional_checkbox'] = array( 1831 'text' => $this->language->get('text_newsletter'), 1832 'checked' => false, 1833 'required' => false 1834 ); 1835 } 1836 1837 $shipping_countries = $this->model_extension_payment_klarna_checkout->getCountriesByGeoZone($klarna_account['shipping']); 1838 1839 $klarna_shipping_countries = array(); 1840 foreach ($shipping_countries as $shipping_country) { 1841 $country_info = $this->model_localisation_country->getCountry($shipping_country['country_id']); 1842 1843 if ($country_info && $country_info['iso_code_2']) { 1844 $klarna_shipping_countries[] = $country_info['iso_code_2']; 1845 } 1846 } 1847 1848 $klarna_order_data['shipping_countries'] = $klarna_shipping_countries; 1849 1850 $average_product_tax_rate = array(); 1851 1852 // Products (Add these last because we send encrypted session order_id) 1853 foreach ($this->cart->getProducts() as $product) { 1854 $total_amount = $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $include_taxes) * $product['quantity'], $currency_code, $currency_value, false) * 100; 1855 1856 if ($include_taxes) { 1857 $total_tax_amount = $this->currency->format($this->tax->getTax($product['price'], $product['tax_class_id']) * $product['quantity'], $currency_code, $currency_value, false) * 100; 1858 } else { 1859 $total_tax_amount = 0; 1860 } 1861 1862 $total_sub_amount = $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], false) * $product['quantity'], $currency_code, $currency_value, false) * 100; 1863 1864 $tax_rate = 0; 1865 1866 if ($include_taxes && $total_tax_amount && $total_sub_amount) { 1867 $tax_rate = ($total_tax_amount / $total_sub_amount) * 100; 1868 } 1869 1870 $average_product_tax_rate[] = round($tax_rate * 100); 1871 1872 $klarna_order_data['order_lines'][] = array( 1873 'type' => ($product['shipping'] ? 'physical' : 'digital'), 1874 'reference' => $product['model'], 1875 'name' => $product['name'], 1876 'quantity' => $product['quantity'], 1877 'quantity_unit' => 'pcs', 1878 'unit_price' => round($this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $include_taxes), $currency_code, $currency_value, false) * 100), 1879 'tax_rate' => round($tax_rate * 100), 1880 'total_amount' => round($total_amount), 1881 'total_tax_amount' => round($total_tax_amount), 1882 'merchant_data' => $encrypted_order_id, 1883 'total_discount_amount' => 0 1884 ); 1885 } 1886 1887 // Gift Voucher 1888 if (!empty($this->session->data['vouchers'])) { 1889 foreach ($this->session->data['vouchers'] as $key => $voucher) { 1890 $klarna_order_data['order_lines'][] = array( 1891 'type' => 'gift_card', 1892 'reference' => '', 1893 'name' => $voucher['description'], 1894 'quantity' => 1, 1895 'quantity_unit' => 'pcs', 1896 'unit_price' => round($this->currency->format($voucher['amount'], $currency_code, $currency_value, false) * 100), 1897 'tax_rate' => 0, 1898 'total_amount' => round($this->currency->format($voucher['amount'], $currency_code, $currency_value, false) * 100), 1899 'total_tax_amount' => 0, 1900 'merchant_data' => $encrypted_order_id, 1901 'total_discount_amount' => 0 1902 ); 1903 } 1904 } 1905 1906 foreach ($totals as $result) { 1907 if ($result['code'] == 'coupon') { 1908 $discount_total_price = 0; 1909 $discount_sub_total_price = 0; 1910 foreach ($this->cart->getProducts() as $product) { 1911 $discount_total_price += $this->tax->calculate($result['value'], $product['tax_class_id'], $include_taxes); 1912 $discount_sub_total_price += $result['value']; 1913 } 1914 1915 $average_discount_total_price = $discount_total_price / count($average_product_tax_rate); 1916 1917 $average_discount_sub_total_price = $discount_sub_total_price / count($average_product_tax_rate); 1918 1919 $total_tax_amount = ($average_discount_sub_total_price / 100) * (array_sum($average_product_tax_rate) / count($average_product_tax_rate)); 1920 1921 $klarna_order_data['order_lines'][] = array( 1922 'type' => 'discount', 1923 'name' => $result['title'], 1924 'quantity' => '1', 1925 'unit_price' => round($this->currency->format($average_discount_total_price, $currency_code, $currency_value, false) * 100), 1926 'tax_rate' => array_sum($average_product_tax_rate) / count($average_product_tax_rate), 1927 'total_amount' => round($this->currency->format($average_discount_total_price, $currency_code, $currency_value, false) * 100), 1928 'total_tax_amount' => round($total_tax_amount), 1929 'total_discount_amount' => 0 1930 ); 1931 } 1932 1933 if ($result['code'] == 'voucher') { 1934 $klarna_order_data['order_lines'][] = array( 1935 'type' => 'discount', 1936 'name' => $result['title'], 1937 'quantity' => '1', 1938 'unit_price' => round($this->currency->format($result['value'], $currency_code, $currency_value, false) * 100), 1939 'tax_rate' => 0, 1940 'total_amount' => round($this->currency->format($result['value'], $currency_code, $currency_value, false) * 100), 1941 'total_tax_amount' => 0, 1942 'total_discount_amount' => 0 1943 ); 1944 } 1945 } 1946 1947 //If $include_taxes is false, means customer is US so we add a new sales_tax order line with all the tax 1948 if (!$include_taxes) { 1949 $klarna_order_data['order_lines'][] = array( 1950 'type' => 'sales_tax', 1951 'name' => $this->language->get('text_sales_tax'), 1952 'quantity' => '1', 1953 'unit_price' => round($this->currency->format(array_sum($taxes), $currency_code, $currency_value, false) * 100), 1954 'tax_rate' => 0, 1955 'total_amount' => round($this->currency->format(array_sum($taxes), $currency_code, $currency_value, false) * 100), 1956 'total_tax_amount' => 0, 1957 'total_discount_amount' => 0 1958 ); 1959 } 1960 1961 return array($klarna_order_data, $encrypted_order_data); 1962 } 1963 }