shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

pp_express.php (85094B)


      1 <?php
      2 class ControllerExtensionPaymentPPExpress extends Controller {
      3 	public function index() {
      4 		$this->load->language('extension/payment/pp_express');
      5 		
      6 		$data['payment_pp_express_incontext_disable'] = $this->config->get('payment_pp_express_incontext_disable');
      7 
      8 		if ($this->config->get('payment_pp_express_test') == 1) {
      9 			$data['username'] = $this->config->get('payment_pp_express_sandbox_username');
     10 		} else {
     11 			$data['username'] = $this->config->get('payment_pp_express_username');
     12 		}
     13 
     14 		$data['continue'] = $this->url->link('extension/payment/pp_express/checkout', '', true);
     15 
     16 		unset($this->session->data['paypal']);
     17 
     18 		return $this->load->view('extension/payment/pp_express', $data);
     19 	}
     20 
     21 	public function express() {
     22 		$this->load->model('extension/payment/pp_express');
     23 
     24 		if ((!$this->cart->hasProducts() && empty($this->session->data['vouchers'])) || (!$this->cart->hasStock() && !$this->config->get('config_stock_checkout'))) {
     25 			$this->response->redirect($this->url->link('checkout/cart'));
     26 		}
     27 
     28 		if ($this->customer->isLogged()) {
     29 			/**
     30 			 * If the customer is already logged in
     31 			 */
     32 			$this->session->data['paypal']['guest'] = false;
     33 
     34 			unset($this->session->data['guest']);
     35 		} else {
     36 			if ($this->config->get('config_checkout_guest') && !$this->config->get('config_customer_price') && !$this->cart->hasDownload() && !$this->cart->hasRecurringProducts()) {
     37 				/**
     38 				 * If the guest checkout is allowed (config ok, no login for price and doesn't have downloads)
     39 				 */
     40 				$this->session->data['paypal']['guest'] = true;
     41 			} else {
     42 				/**
     43 				 * If guest checkout disabled or login is required before price or order has downloads
     44 				 *
     45 				 * Send them to the normal checkout flow.
     46 				 */
     47 				unset($this->session->data['guest']);
     48 
     49 				$this->response->redirect($this->url->link('checkout/checkout', '', true));
     50 			}
     51 		}
     52 
     53 		unset($this->session->data['shipping_method']);
     54 		unset($this->session->data['shipping_methods']);
     55 		unset($this->session->data['payment_method']);
     56 		unset($this->session->data['payment_methods']);
     57 
     58 		$this->load->model('tool/image');
     59 
     60 		if ($this->cart->hasShipping()) {
     61 			$shipping = 2;
     62 		} else {
     63 			$shipping = 1;
     64 		}
     65 
     66 		$max_amount = $this->cart->getTotal() * 1.5;
     67 		$max_amount = $this->currency->format($max_amount, $this->session->data['currency'], '', false);
     68 
     69 		$data = array(
     70 			'METHOD'             => 'SetExpressCheckout',
     71 			'MAXAMT'             => $max_amount,
     72 			'RETURNURL'          => $this->url->link('extension/payment/pp_express/expressReturn', '', true),
     73 			'CANCELURL'          => $this->url->link('checkout/cart', '', true),
     74 			'REQCONFIRMSHIPPING' => 0,
     75 			'NOSHIPPING'         => $shipping,
     76 			'ALLOWNOTE'          => $this->config->get('payment_pp_express_allow_note'),
     77 			'LOCALECODE'         => 'EN',
     78 			'LANDINGPAGE'        => 'Login',
     79 			'HDRIMG'             => $this->model_tool_image->resize($this->config->get('payment_pp_express_logo'), 750, 90),
     80 			'PAYFLOWCOLOR'       => $this->config->get('payment_pp_express_colour'),
     81 			'CHANNELTYPE'        => 'Merchant'
     82 		);
     83 
     84 		if (isset($this->session->data['pp_login']['seamless']['access_token']) && (isset($this->session->data['pp_login']['seamless']['customer_id']) && $this->session->data['pp_login']['seamless']['customer_id'] == $this->customer->getId()) && $this->config->get('module_pp_login_seamless')) {
     85 			$data['IDENTITYACCESSTOKEN'] = $this->session->data['pp_login']['seamless']['access_token'];
     86 		}
     87 
     88 		$data = array_merge($data, $this->model_extension_payment_pp_express->paymentRequestInfo());
     89 
     90 		$result = $this->model_extension_payment_pp_express->call($data);
     91 
     92 		/**
     93 		 * If a failed PayPal setup happens, handle it.
     94 		 */
     95 		if (!isset($result['TOKEN'])) {
     96 			$this->session->data['error'] = $result['L_LONGMESSAGE0'];
     97 			/**
     98 			 * Unable to add error message to user as the session errors/success are not
     99 			 * used on the cart or checkout pages - need to be added?
    100 			 * If PayPal debug log is off then still log error to normal error log.
    101 			 */
    102 
    103 			$this->log->write('Unable to create PayPal call: ' . json_encode($result));
    104 
    105 			$this->response->redirect($this->url->link('checkout/checkout', '', true));
    106 		}
    107 
    108 		$this->session->data['paypal']['token'] = $result['TOKEN'];
    109 
    110 		if ($this->config->get('payment_pp_express_test') == 1) {
    111 			header('Location: https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $result['TOKEN']);
    112 		} else {
    113 			header('Location: https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $result['TOKEN']);
    114 		}
    115 	}
    116 
    117 	public function expressReturn() {
    118 		/**
    119 		 * This is the url when PayPal has completed the auth.
    120 		 *
    121 		 * It has no output, instead it sets the data and locates to checkout
    122 		 */
    123 		$this->load->model('extension/payment/pp_express');
    124 		$data = array(
    125 			'METHOD' => 'GetExpressCheckoutDetails',
    126 			'TOKEN'  => $this->session->data['paypal']['token']
    127 		);
    128 
    129 		$result = $this->model_extension_payment_pp_express->call($data);
    130 		$this->session->data['paypal']['payerid']   = $result['PAYERID'];
    131 		$this->session->data['paypal']['result']    = $result;
    132 
    133 		$this->session->data['comment'] = '';
    134 		if (isset($result['PAYMENTREQUEST_0_NOTETEXT'])) {
    135 			$this->session->data['comment'] = $result['PAYMENTREQUEST_0_NOTETEXT'];
    136 		}
    137 
    138 		if ($this->session->data['paypal']['guest'] == true) {
    139 
    140 			$this->session->data['guest']['customer_group_id'] = $this->config->get('config_customer_group_id');
    141 			$this->session->data['guest']['firstname'] = trim($result['FIRSTNAME']);
    142 			$this->session->data['guest']['lastname'] = trim($result['LASTNAME']);
    143 			$this->session->data['guest']['email'] = trim($result['EMAIL']);
    144 
    145 			if (isset($result['PHONENUM'])) {
    146 				$this->session->data['guest']['telephone'] = $result['PHONENUM'];
    147 			} else {
    148 				$this->session->data['guest']['telephone'] = '';
    149 			}
    150 
    151 			$this->session->data['guest']['payment']['firstname'] = trim($result['FIRSTNAME']);
    152 			$this->session->data['guest']['payment']['lastname'] = trim($result['LASTNAME']);
    153 
    154 			if (isset($result['BUSINESS'])) {
    155 				$this->session->data['guest']['payment']['company'] = $result['BUSINESS'];
    156 			} else {
    157 				$this->session->data['guest']['payment']['company'] = '';
    158 			}
    159 
    160 			$this->session->data['guest']['payment']['company_id'] = '';
    161 			$this->session->data['guest']['payment']['tax_id'] = '';
    162 
    163 			if ($this->cart->hasShipping()) {
    164 				$shipping_name = explode(' ', trim($result['PAYMENTREQUEST_0_SHIPTONAME']));
    165 				$shipping_first_name = $shipping_name[0];
    166 				unset($shipping_name[0]);
    167 				$shipping_last_name = implode(' ', $shipping_name);
    168 
    169 				$this->session->data['guest']['payment']['address_1'] = $result['PAYMENTREQUEST_0_SHIPTOSTREET'];
    170 				if (isset($result['PAYMENTREQUEST_0_SHIPTOSTREET2'])) {
    171 					$this->session->data['guest']['payment']['address_2'] = $result['PAYMENTREQUEST_0_SHIPTOSTREET2'];
    172 				} else {
    173 					$this->session->data['guest']['payment']['address_2'] = '';
    174 				}
    175 
    176 				$this->session->data['guest']['payment']['postcode'] = $result['PAYMENTREQUEST_0_SHIPTOZIP'];
    177 				$this->session->data['guest']['payment']['city'] = $result['PAYMENTREQUEST_0_SHIPTOCITY'];
    178 
    179 				$this->session->data['guest']['shipping']['firstname'] = $shipping_first_name;
    180 				$this->session->data['guest']['shipping']['lastname'] = $shipping_last_name;
    181 				$this->session->data['guest']['shipping']['company'] = '';
    182 				$this->session->data['guest']['shipping']['address_1'] = $result['PAYMENTREQUEST_0_SHIPTOSTREET'];
    183 
    184 				if (isset($result['PAYMENTREQUEST_0_SHIPTOSTREET2'])) {
    185 					$this->session->data['guest']['shipping']['address_2'] = $result['PAYMENTREQUEST_0_SHIPTOSTREET2'];
    186 				} else {
    187 					$this->session->data['guest']['shipping']['address_2'] = '';
    188 				}
    189 
    190 				$this->session->data['guest']['shipping']['postcode'] = $result['PAYMENTREQUEST_0_SHIPTOZIP'];
    191 				$this->session->data['guest']['shipping']['city'] = $result['PAYMENTREQUEST_0_SHIPTOCITY'];
    192 
    193 				$this->session->data['shipping_postcode'] = $result['PAYMENTREQUEST_0_SHIPTOZIP'];
    194 
    195 				$country_info = $this->db->query("SELECT * FROM `" . DB_PREFIX . "country` WHERE `iso_code_2` = '" . $this->db->escape($result['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE']) . "' AND `status` = '1' LIMIT 1")->row;
    196 
    197 				if ($country_info) {
    198 					$this->session->data['guest']['shipping']['country_id'] = $country_info['country_id'];
    199 					$this->session->data['guest']['shipping']['country'] = $country_info['name'];
    200 					$this->session->data['guest']['shipping']['iso_code_2'] = $country_info['iso_code_2'];
    201 					$this->session->data['guest']['shipping']['iso_code_3'] = $country_info['iso_code_3'];
    202 					$this->session->data['guest']['shipping']['address_format'] = $country_info['address_format'];
    203 					$this->session->data['guest']['payment']['country_id'] = $country_info['country_id'];
    204 					$this->session->data['guest']['payment']['country'] = $country_info['name'];
    205 					$this->session->data['guest']['payment']['iso_code_2'] = $country_info['iso_code_2'];
    206 					$this->session->data['guest']['payment']['iso_code_3'] = $country_info['iso_code_3'];
    207 					$this->session->data['guest']['payment']['address_format'] = $country_info['address_format'];
    208 					$this->session->data['shipping_country_id'] = $country_info['country_id'];
    209 				} else {
    210 					$this->session->data['guest']['shipping']['country_id'] = '';
    211 					$this->session->data['guest']['shipping']['country'] = '';
    212 					$this->session->data['guest']['shipping']['iso_code_2'] = '';
    213 					$this->session->data['guest']['shipping']['iso_code_3'] = '';
    214 					$this->session->data['guest']['shipping']['address_format'] = '';
    215 					$this->session->data['guest']['payment']['country_id'] = '';
    216 					$this->session->data['guest']['payment']['country'] = '';
    217 					$this->session->data['guest']['payment']['iso_code_2'] = '';
    218 					$this->session->data['guest']['payment']['iso_code_3'] = '';
    219 					$this->session->data['guest']['payment']['address_format'] = '';
    220 					$this->session->data['shipping_country_id'] = '';
    221 				}
    222 
    223 				if (isset($result['PAYMENTREQUEST_0_SHIPTOSTATE'])) {
    224 					$returned_shipping_zone = $result['PAYMENTREQUEST_0_SHIPTOSTATE'];
    225 				} else {
    226 					$returned_shipping_zone = '';
    227 				}
    228 
    229 				$zone_info = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone` WHERE (`name` = '" . $this->db->escape($returned_shipping_zone) . "' OR `code` = '" . $this->db->escape($returned_shipping_zone) . "') AND `status` = '1' AND `country_id` = '" . (int)$country_info['country_id'] . "' LIMIT 1")->row;
    230 
    231 				if ($zone_info) {
    232 					$this->session->data['guest']['shipping']['zone'] = $zone_info['name'];
    233 					$this->session->data['guest']['shipping']['zone_code'] = $zone_info['code'];
    234 					$this->session->data['guest']['shipping']['zone_id'] = $zone_info['zone_id'];
    235 					$this->session->data['guest']['payment']['zone'] = $zone_info['name'];
    236 					$this->session->data['guest']['payment']['zone_code'] = $zone_info['code'];
    237 					$this->session->data['guest']['payment']['zone_id'] = $zone_info['zone_id'];
    238 					$this->session->data['shipping_zone_id'] = $zone_info['zone_id'];
    239 				} else {
    240 					$this->session->data['guest']['shipping']['zone'] = '';
    241 					$this->session->data['guest']['shipping']['zone_code'] = '';
    242 					$this->session->data['guest']['shipping']['zone_id'] = '';
    243 					$this->session->data['guest']['payment']['zone'] = '';
    244 					$this->session->data['guest']['payment']['zone_code'] = '';
    245 					$this->session->data['guest']['payment']['zone_id'] = '';
    246 					$this->session->data['shipping_zone_id'] = '';
    247 				}
    248 
    249 				$this->session->data['guest']['shipping_address'] = true;
    250 			} else {
    251 				$this->session->data['guest']['payment']['address_1'] = '';
    252 				$this->session->data['guest']['payment']['address_2'] = '';
    253 				$this->session->data['guest']['payment']['postcode'] = '';
    254 				$this->session->data['guest']['payment']['city'] = '';
    255 				$this->session->data['guest']['payment']['country_id'] = '';
    256 				$this->session->data['guest']['payment']['country'] = '';
    257 				$this->session->data['guest']['payment']['iso_code_2'] = '';
    258 				$this->session->data['guest']['payment']['iso_code_3'] = '';
    259 				$this->session->data['guest']['payment']['address_format'] = '';
    260 				$this->session->data['guest']['payment']['zone'] = '';
    261 				$this->session->data['guest']['payment']['zone_code'] = '';
    262 				$this->session->data['guest']['payment']['zone_id'] = '';
    263 				$this->session->data['guest']['shipping_address'] = false;
    264 			}
    265 
    266 			$this->session->data['account'] = 'guest';
    267 
    268 			unset($this->session->data['shipping_method']);
    269 			unset($this->session->data['shipping_methods']);
    270 			unset($this->session->data['payment_method']);
    271 			unset($this->session->data['payment_methods']);
    272 		} else {
    273 			unset($this->session->data['guest']);
    274 			/**
    275 			 * if the user is logged in, add the address to the account and set the ID.
    276 			 */
    277 
    278 			if ($this->cart->hasShipping()) {
    279 				$this->load->model('account/address');
    280 
    281 				$addresses = $this->model_account_address->getAddresses();
    282 
    283 				/**
    284 				 * Compare all of the user addresses and see if there is a match
    285 				 */
    286 				$match = false;
    287 				foreach($addresses as $address) {
    288 					if (trim(strtolower($address['address_1'])) == trim(strtolower($result['PAYMENTREQUEST_0_SHIPTOSTREET'])) && trim(strtolower($address['postcode'])) == trim(strtolower($result['PAYMENTREQUEST_0_SHIPTOZIP']))) {
    289 						$match = true;
    290 
    291 						$this->session->data['payment_address_id'] = $address['address_id'];
    292 						$this->session->data['payment_country_id'] = $address['country_id'];
    293 						$this->session->data['payment_zone_id'] = $address['zone_id'];
    294 
    295 						$this->session->data['shipping_address_id'] = $address['address_id'];
    296 						$this->session->data['shipping_country_id'] = $address['country_id'];
    297 						$this->session->data['shipping_zone_id'] = $address['zone_id'];
    298 						$this->session->data['shipping_postcode'] = $address['postcode'];
    299 
    300 						break;
    301 					}
    302 				}
    303 
    304 				/**
    305 				 * If there is no address match add the address and set the info.
    306 				 */
    307 				if ($match == false) {
    308 
    309 					$shipping_name = explode(' ', trim($result['PAYMENTREQUEST_0_SHIPTONAME']));
    310 					$shipping_first_name = $shipping_name[0];
    311 					unset($shipping_name[0]);
    312 					$shipping_last_name = implode(' ', $shipping_name);
    313 
    314 					$country_info = $this->db->query("SELECT * FROM `" . DB_PREFIX . "country` WHERE `iso_code_2` = '" . $this->db->escape($result['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE']) . "' AND `status` = '1' LIMIT 1")->row;
    315 					$zone_info = $this->db->query("SELECT * FROM `" . DB_PREFIX . "zone` WHERE (`name` = '" . $this->db->escape($result['PAYMENTREQUEST_0_SHIPTOSTATE']) . "' OR `code` = '" . $this->db->escape($result['PAYMENTREQUEST_0_SHIPTOSTATE']) . "') AND `status` = '1' AND `country_id` = '" . (int)$country_info['country_id'] . "'")->row;
    316 
    317 					$address_data = array(
    318 						'firstname'  => $shipping_first_name,
    319 						'lastname'   => $shipping_last_name,
    320 						'company'    => '',
    321 						'company_id' => '',
    322 						'tax_id'     => '',
    323 						'address_1'  => $result['PAYMENTREQUEST_0_SHIPTOSTREET'],
    324 						'address_2'  => (isset($result['PAYMENTREQUEST_0_SHIPTOSTREET2']) ? $result['PAYMENTREQUEST_0_SHIPTOSTREET2'] : ''),
    325 						'postcode'   => $result['PAYMENTREQUEST_0_SHIPTOZIP'],
    326 						'city'       => $result['PAYMENTREQUEST_0_SHIPTOCITY'],
    327 						'zone_id'    => (isset($zone_info['zone_id']) ? $zone_info['zone_id'] : 0),
    328 						'country_id' => (isset($country_info['country_id']) ? $country_info['country_id'] : 0)
    329 					);
    330 
    331 					$address_id = $this->model_account_address->addAddress($this->customer->getId(), $address_data);
    332 
    333 					$this->session->data['payment_address_id'] = $address_id;
    334 					$this->session->data['payment_country_id'] = $address_data['country_id'];
    335 					$this->session->data['payment_zone_id'] = $address_data['zone_id'];
    336 
    337 					$this->session->data['shipping_address_id'] = $address_id;
    338 					$this->session->data['shipping_country_id'] = $address_data['country_id'];
    339 					$this->session->data['shipping_zone_id'] = $address_data['zone_id'];
    340 					$this->session->data['shipping_postcode'] = $address_data['postcode'];
    341 				}
    342 			} else {
    343 				$this->session->data['payment_address_id'] = '';
    344 				$this->session->data['payment_country_id'] = '';
    345 				$this->session->data['payment_zone_id'] = '';
    346 			}
    347 		}
    348 
    349 		$this->response->redirect($this->url->link('extension/payment/pp_express/expressConfirm', '', true));
    350 	}
    351 
    352 	public function expressConfirm() {
    353 		$this->load->language('extension/payment/pp_express');
    354 		$this->load->language('checkout/cart');
    355 
    356 		$this->load->model('tool/image');
    357 
    358 		// Coupon
    359 		if (isset($this->request->post['coupon']) && $this->validateCoupon()) {
    360 			$this->session->data['coupon'] = $this->request->post['coupon'];
    361 
    362 			$this->session->data['success'] = $this->language->get('text_coupon');
    363 
    364 			$this->response->redirect($this->url->link('extension/payment/pp_express/expressConfirm', '', true));
    365 		}
    366 
    367 		// Voucher
    368 		if (isset($this->request->post['voucher']) && $this->validateVoucher()) {
    369 			$this->session->data['voucher'] = $this->request->post['voucher'];
    370 
    371 			$this->session->data['success'] = $this->language->get('text_voucher');
    372 
    373 			$this->response->redirect($this->url->link('extension/payment/pp_express/expressConfirm', '', true));
    374 		}
    375 
    376 		// Reward
    377 		if (isset($this->request->post['reward']) && $this->validateReward()) {
    378 			$this->session->data['reward'] = abs($this->request->post['reward']);
    379 
    380 			$this->session->data['success'] = $this->language->get('text_reward');
    381 
    382 			$this->response->redirect($this->url->link('extension/payment/pp_express/expressConfirm', '', true));
    383 		}
    384 
    385 		$this->document->setTitle($this->language->get('express_text_title'));
    386 
    387 		$data['breadcrumbs'] = array();
    388 
    389 		$data['breadcrumbs'][] = array(
    390 			'href' => $this->url->link('common/home'),
    391 			'text' => $this->language->get('text_home')
    392 		);
    393 
    394 		$data['breadcrumbs'][] = array(
    395 			'href' => $this->url->link('extension/payment/pp_express/express'),
    396 			'text' => $this->language->get('text_title')
    397 		);
    398 
    399 		$data['breadcrumbs'][] = array(
    400 			'href' => $this->url->link('extension/payment/pp_express/expressConfirm'),
    401 			'text' => $this->language->get('express_text_title')
    402 		);
    403 
    404 		$points = $this->customer->getRewardPoints();
    405 
    406 		$points_total = 0;
    407 
    408 		foreach ($this->cart->getProducts() as $product) {
    409 			if ($product['points']) {
    410 				$points_total += $product['points'];
    411 			}
    412 		}
    413 
    414 		$data['button_shipping'] = $this->language->get('button_express_shipping');
    415 		$data['button_confirm'] = $this->language->get('button_express_confirm');
    416 
    417 		if (isset($this->request->post['next'])) {
    418 			$data['next'] = $this->request->post['next'];
    419 		} else {
    420 			$data['next'] = '';
    421 		}
    422 
    423 		$data['action'] = $this->url->link('extension/payment/pp_express/expressConfirm', '', true);
    424 
    425 		$this->load->model('tool/upload');
    426 
    427 		$products = $this->cart->getProducts();
    428 
    429 		foreach ($products as $product) {
    430 			$product_total = 0;
    431 
    432 			foreach ($products as $product_2) {
    433 				if ($product_2['product_id'] == $product['product_id']) {
    434 					$product_total += $product_2['quantity'];
    435 				}
    436 			}
    437 
    438 			if ($product['minimum'] > $product_total) {
    439 				$data['error_warning'] = sprintf($this->language->get('error_minimum'), $product['name'], $product['minimum']);
    440 			}
    441 
    442 			if ($product['image']) {
    443 				$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'));
    444 			} else {
    445 				$image = '';
    446 			}
    447 
    448 			$option_data = array();
    449 
    450 			foreach ($product['option'] as $option) {
    451 				if ($option['type'] != 'file') {
    452 					$value = $option['value'];
    453 				} else {
    454 					$upload_info = $this->model_tool_upload->getUploadByCode($option['value']);
    455 
    456 					if ($upload_info) {
    457 						$value = $upload_info['name'];
    458 					} else {
    459 						$value = '';
    460 					}
    461 				}
    462 
    463 				$option_data[] = array(
    464 					'name'  => $option['name'],
    465 					'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value)
    466 				);
    467 			}
    468 
    469 			// Display prices
    470 			if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
    471 				$unit_price = $this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax'));
    472 
    473 				$price = $this->currency->format($unit_price, $this->session->data['currency']);
    474 				$total = $this->currency->format($unit_price * $product['quantity'], $this->session->data['currency']);
    475 			} else {
    476 				$price = false;
    477 				$total = false;
    478 			}
    479 
    480 			$recurring_description = '';
    481 
    482 			if ($product['recurring']) {
    483 				$frequencies = array(
    484 					'day'        => $this->language->get('text_day'),
    485 					'week'       => $this->language->get('text_week'),
    486 					'semi_month' => $this->language->get('text_semi_month'),
    487 					'month'      => $this->language->get('text_month'),
    488 					'year'       => $this->language->get('text_year'),
    489 				);
    490 
    491 				if ($product['recurring']['trial']) {
    492 					$recurring_price = $this->currency->format($this->tax->calculate($product['recurring']['trial_price'] * $product['quantity'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
    493 					$recurring_description = sprintf($this->language->get('text_trial_description'), $recurring_price, $product['recurring']['trial_cycle'], $frequencies[$product['recurring']['trial_frequency']], $product['recurring']['trial_duration']) . ' ';
    494 				}
    495 
    496 				$recurring_price = $this->currency->format($this->tax->calculate($product['recurring']['price'] * $product['quantity'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']);
    497 
    498 				if ($product['recurring']['duration']) {
    499 					$recurring_description .= sprintf($this->language->get('text_payment_description'), $recurring_price, $product['recurring']['cycle'], $frequencies[$product['recurring']['frequency']], $product['recurring']['duration']);
    500 				} else {
    501 					$recurring_description .= sprintf($this->language->get('text_payment_cancel'), $recurring_price, $product['recurring']['cycle'], $frequencies[$product['recurring']['frequency']], $product['recurring']['duration']);
    502 				}
    503 			}
    504 
    505 			$data['products'][] = array(
    506 				'cart_id'               => $product['cart_id'],
    507 				'thumb'                 => $image,
    508 				'name'                  => $product['name'],
    509 				'model'                 => $product['model'],
    510 				'option'                => $option_data,
    511 				'quantity'              => $product['quantity'],
    512 				'stock'                 => $product['stock'] ? true : !(!$this->config->get('config_stock_checkout') || $this->config->get('config_stock_warning')),
    513 				'reward'                => ($product['reward'] ? sprintf($this->language->get('text_points'), $product['reward']) : ''),
    514 				'price'                 => $price,
    515 				'total'                 => $total,
    516 				'href'                  => $this->url->link('product/product', 'product_id=' . $product['product_id']),
    517 				'remove'                => $this->url->link('checkout/cart', 'remove=' . $product['cart_id']),
    518 				'recurring'             => $product['recurring'],
    519 				'recurring_name'        => (isset($product['recurring']['recurring_name']) ? $product['recurring']['recurring_name'] : ''),
    520 				'recurring_description' => $recurring_description
    521 			);
    522 		}
    523 
    524 		$data['vouchers'] = array();
    525 
    526 		if ($this->cart->hasShipping()) {
    527 
    528 			$data['has_shipping'] = true;
    529 			/**
    530 			 * Shipping services
    531 			 */
    532 			if ($this->customer->isLogged()) {
    533 				$this->load->model('account/address');
    534 				$shipping_address = $this->model_account_address->getAddress($this->session->data['shipping_address_id']);
    535 			} elseif (isset($this->session->data['guest'])) {
    536 				$shipping_address = $this->session->data['guest']['shipping'];
    537 			}
    538 
    539 			if (!empty($shipping_address)) {
    540 				// Shipping Methods
    541 				$quote_data = array();
    542 
    543 				$this->load->model('setting/extension');
    544 
    545 				$results = $this->model_setting_extension->getExtensions('shipping');
    546 
    547 				if (!empty($results)) {
    548 					foreach ($results as $result) {
    549 						if ($this->config->get('shipping_' . $result['code'] . '_status')) {
    550 							$this->load->model('extension/shipping/' . $result['code']);
    551 
    552 							$quote = $this->{'model_extension_shipping_' . $result['code']}->getQuote($shipping_address);
    553 
    554 							if ($quote) {
    555 								$quote_data[$result['code']] = array(
    556 									'title'      => $quote['title'],
    557 									'quote'      => $quote['quote'],
    558 									'sort_order' => $quote['sort_order'],
    559 									'error'      => $quote['error']
    560 								);
    561 							}
    562 						}
    563 					}
    564 
    565 					if (!empty($quote_data)) {
    566 						$sort_order = array();
    567 
    568 						foreach ($quote_data as $key => $value) {
    569 							$sort_order[$key] = $value['sort_order'];
    570 						}
    571 
    572 						array_multisort($sort_order, SORT_ASC, $quote_data);
    573 
    574 						$this->session->data['shipping_methods'] = $quote_data;
    575 						$data['shipping_methods'] = $quote_data;
    576 
    577 						if (!isset($this->session->data['shipping_method'])) {
    578 							//default the shipping to the very first option.
    579 							$key1 = key($quote_data);
    580 							$key2 = key($quote_data[$key1]['quote']);
    581 							$this->session->data['shipping_method'] = $quote_data[$key1]['quote'][$key2];
    582 						}
    583 
    584 						$data['code'] = $this->session->data['shipping_method']['code'];
    585 						$data['action_shipping'] = $this->url->link('extension/payment/pp_express/shipping', '', true);
    586 					} else {
    587 						unset($this->session->data['shipping_methods']);
    588 						unset($this->session->data['shipping_method']);
    589 						$data['error_no_shipping'] = $this->language->get('error_no_shipping');
    590 					}
    591 				} else {
    592 					unset($this->session->data['shipping_methods']);
    593 					unset($this->session->data['shipping_method']);
    594 					$data['error_no_shipping'] = $this->language->get('error_no_shipping');
    595 				}
    596 			}
    597 		} else {
    598 			$data['has_shipping'] = false;
    599 		}
    600 
    601 		// Totals
    602 		$this->load->model('setting/extension');
    603 
    604 		$totals = array();
    605 		$taxes = $this->cart->getTaxes();
    606 		$total = 0;
    607 
    608 		// Because __call can not keep var references so we put them into an array.
    609 		$total_data = array(
    610 			'totals' => &$totals,
    611 			'taxes'  => &$taxes,
    612 			'total'  => &$total
    613 		);
    614 
    615 		// Display prices
    616 		if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
    617 			$sort_order = array();
    618 
    619 			$results = $this->model_setting_extension->getExtensions('total');
    620 
    621 			foreach ($results as $key => $value) {
    622 				$sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order');
    623 			}
    624 
    625 			array_multisort($sort_order, SORT_ASC, $results);
    626 
    627 			foreach ($results as $result) {
    628 				if ($this->config->get('total_' . $result['code'] . '_status')) {
    629 					$this->load->model('extension/total/' . $result['code']);
    630 
    631 					// We have to put the totals in an array so that they pass by reference.
    632 					$this->{'model_extension_total_' . $result['code']}->getTotal($total_data);
    633 				}
    634 			}
    635 
    636 			$sort_order = array();
    637 
    638 			foreach ($totals as $key => $value) {
    639 				$sort_order[$key] = $value['sort_order'];
    640 			}
    641 
    642 			array_multisort($sort_order, SORT_ASC, $totals);
    643 		}
    644 
    645 		$data['totals'] = array();
    646 
    647 		foreach ($totals as $total) {
    648 			$data['totals'][] = array(
    649 				'title' => $total['title'],
    650 				'text'  => $this->currency->format($total['value'], $this->session->data['currency']),
    651 			);
    652 		}
    653 
    654 		/**
    655 		 * Payment methods
    656 		 */
    657 		if ($this->customer->isLogged() && isset($this->session->data['payment_address_id'])) {
    658 			$this->load->model('account/address');
    659 			$payment_address = $this->model_account_address->getAddress($this->session->data['payment_address_id']);
    660 		} elseif (isset($this->session->data['guest'])) {
    661 			$payment_address = $this->session->data['guest']['payment'];
    662 		}
    663 
    664 		$method_data = array();
    665 
    666 		$this->load->model('setting/extension');
    667 
    668 		$results = $this->model_setting_extension->getExtensions('payment');
    669 
    670 		foreach ($results as $result) {
    671 			if ($this->config->get('payment_' . $result['code'] . '_status')) {
    672 				$this->load->model('extension/payment/' . $result['code']);
    673 
    674 				$method = $this->{'model_extension_payment_' . $result['code']}->getMethod($payment_address, $total);
    675 
    676 				if ($method) {
    677 					$method_data[$result['code']] = $method;
    678 				}
    679 			}
    680 		}
    681 
    682 		$sort_order = array();
    683 
    684 		foreach ($method_data as $key => $value) {
    685 			$sort_order[$key] = $value['sort_order'];
    686 		}
    687 
    688 		array_multisort($sort_order, SORT_ASC, $method_data);
    689 
    690 		if (!isset($method_data['pp_express'])) {
    691 			$this->session->data['error_warning'] = $this->language->get('error_unavailable');
    692 			$this->response->redirect($this->url->link('checkout/checkout', '', true));
    693 		}
    694 
    695 		$this->session->data['payment_methods'] = $method_data;
    696 		$this->session->data['payment_method'] = $method_data['pp_express'];
    697 
    698 		$data['action_confirm'] = $this->url->link('extension/payment/pp_express/expressComplete', '', true);
    699 
    700 		if (isset($this->session->data['error_warning'])) {
    701 			$data['error_warning'] = $this->session->data['error_warning'];
    702 			unset($this->session->data['error_warning']);
    703 		} else {
    704 			$data['error_warning'] = '';
    705 		}
    706 
    707 		if (isset($this->session->data['success'])) {
    708 			$data['success'] = $this->session->data['success'];
    709 			unset($this->session->data['success']);
    710 		} else {
    711 			$data['success'] = '';
    712 		}
    713 
    714 		if (isset($this->session->data['attention'])) {
    715 			$data['attention'] = $this->session->data['attention'];
    716 			unset($this->session->data['attention']);
    717 		} else {
    718 			$data['attention'] = '';
    719 		}
    720 
    721 		$data['coupon'] = $this->load->controller('extension/total/coupon');
    722 		$data['voucher'] = $this->load->controller('extension/total/voucher');
    723 		$data['reward'] = $this->load->controller('extension/total/reward');
    724 		$data['column_left'] = $this->load->controller('common/column_left');
    725 		$data['column_right'] = $this->load->controller('common/column_right');
    726 		$data['content_top'] = $this->load->controller('common/content_top');
    727 		$data['content_bottom'] = $this->load->controller('common/content_bottom');
    728 		$data['footer'] = $this->load->controller('common/footer');
    729 		$data['header'] = $this->load->controller('common/header');
    730 
    731 		$this->response->setOutput($this->load->view('extension/payment/pp_express_confirm', $data));
    732 	}
    733 
    734 	public function expressComplete() {
    735 		$this->load->language('extension/payment/pp_express');
    736 		$redirect = '';
    737 
    738 		if ($this->cart->hasShipping()) {
    739 			// Validate if shipping address has been set.
    740 			$this->load->model('account/address');
    741 
    742 			if ($this->customer->isLogged() && isset($this->session->data['shipping_address_id'])) {
    743 				$shipping_address = $this->model_account_address->getAddress($this->session->data['shipping_address_id']);
    744 			} elseif (isset($this->session->data['guest'])) {
    745 				$shipping_address = $this->session->data['guest']['shipping'];
    746 			}
    747 
    748 			if (empty($shipping_address)) {
    749 				$redirect = $this->url->link('checkout/checkout', '', true);
    750 			}
    751 
    752 			// Validate if shipping method has been set.
    753 			if (!isset($this->session->data['shipping_method'])) {
    754 				$redirect = $this->url->link('checkout/checkout', '', true);
    755 			}
    756 		} else {
    757 			unset($this->session->data['shipping_method']);
    758 			unset($this->session->data['shipping_methods']);
    759 		}
    760 
    761 		// Validate if payment address has been set.
    762 		$this->load->model('account/address');
    763 
    764 		if ($this->customer->isLogged() && isset($this->session->data['payment_address_id'])) {
    765 			$payment_address = $this->model_account_address->getAddress($this->session->data['payment_address_id']);
    766 		} elseif (isset($this->session->data['guest'])) {
    767 			$payment_address = $this->session->data['guest']['payment'];
    768 		}
    769 
    770 		// Validate if payment method has been set.
    771 		if (!isset($this->session->data['payment_method'])) {
    772 			$redirect = $this->url->link('checkout/checkout', '', true);
    773 		}
    774 
    775 		// Validate cart has products and has stock.
    776 		if ((!$this->cart->hasProducts() && empty($this->session->data['vouchers'])) || (!$this->cart->hasStock() && !$this->config->get('config_stock_checkout'))) {
    777 			$redirect = $this->url->link('checkout/cart');
    778 		}
    779 
    780 		// Validate minimum quantity requirements.
    781 		$products = $this->cart->getProducts();
    782 
    783 		foreach ($products as $product) {
    784 			$product_total = 0;
    785 
    786 			foreach ($products as $product_2) {
    787 				if ($product_2['product_id'] == $product['product_id']) {
    788 					$product_total += $product_2['quantity'];
    789 				}
    790 			}
    791 
    792 			if ($product['minimum'] > $product_total) {
    793 				$redirect = $this->url->link('checkout/cart');
    794 
    795 				break;
    796 			}
    797 		}
    798 
    799 		if ($redirect == '') {
    800 			$totals = array();
    801 			$taxes = $this->cart->getTaxes();
    802 			$total = 0;
    803 
    804 			// Because __call can not keep var references so we put them into an array.
    805 			$total_data = array(
    806 				'totals' => &$totals,
    807 				'taxes'  => &$taxes,
    808 				'total'  => &$total
    809 			);
    810 
    811 			$this->load->model('setting/extension');
    812 
    813 			$sort_order = array();
    814 
    815 			$results = $this->model_setting_extension->getExtensions('total');
    816 
    817 			foreach ($results as $key => $value) {
    818 				$sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order');
    819 			}
    820 
    821 			array_multisort($sort_order, SORT_ASC, $results);
    822 
    823 			foreach ($results as $result) {
    824 				if ($this->config->get('total_' . $result['code'] . '_status')) {
    825 					$this->load->model('extension/total/' . $result['code']);
    826 
    827 					// We have to put the totals in an array so that they pass by reference.
    828 					$this->{'model_extension_total_' . $result['code']}->getTotal($total_data);
    829 				}
    830 			}
    831 
    832 			$sort_order = array();
    833 
    834 			foreach ($totals as $key => $value) {
    835 				$sort_order[$key] = $value['sort_order'];
    836 			}
    837 
    838 			array_multisort($sort_order, SORT_ASC, $totals);
    839 
    840 			$this->load->language('checkout/checkout');
    841 
    842 			$data = array();
    843 
    844 			$data['invoice_prefix'] = $this->config->get('config_invoice_prefix');
    845 			$data['store_id'] = $this->config->get('config_store_id');
    846 			$data['store_name'] = $this->config->get('config_name');
    847 
    848 			if ($data['store_id']) {
    849 				$data['store_url'] = $this->config->get('config_url');
    850 			} else {
    851 				$data['store_url'] = HTTP_SERVER;
    852 			}
    853 
    854 			if ($this->customer->isLogged() && isset($this->session->data['payment_address_id'])) {
    855 				$data['customer_id'] = $this->customer->getId();
    856 				$data['customer_group_id'] = $this->config->get('config_customer_group_id');
    857 				$data['firstname'] = $this->customer->getFirstName();
    858 				$data['lastname'] = $this->customer->getLastName();
    859 				$data['email'] = $this->customer->getEmail();
    860 				$data['telephone'] = $this->customer->getTelephone();
    861 
    862 				$this->load->model('account/address');
    863 
    864 				$payment_address = $this->model_account_address->getAddress($this->session->data['payment_address_id']);
    865 			} elseif (isset($this->session->data['guest'])) {
    866 				$data['customer_id'] = 0;
    867 				$data['customer_group_id'] = $this->session->data['guest']['customer_group_id'];
    868 				$data['firstname'] = $this->session->data['guest']['firstname'];
    869 				$data['lastname'] = $this->session->data['guest']['lastname'];
    870 				$data['email'] = $this->session->data['guest']['email'];
    871 				$data['telephone'] = $this->session->data['guest']['telephone'];
    872 
    873 				$payment_address = $this->session->data['guest']['payment'];
    874 			}
    875 
    876 			$data['payment_firstname'] = isset($payment_address['firstname']) ? $payment_address['firstname'] : '';
    877 			$data['payment_lastname'] = isset($payment_address['lastname']) ? $payment_address['lastname'] : '';
    878 			$data['payment_company'] = isset($payment_address['company']) ? $payment_address['company'] : '';
    879 			$data['payment_company_id'] = isset($payment_address['company_id']) ? $payment_address['company_id'] : '';
    880 			$data['payment_tax_id'] = isset($payment_address['tax_id']) ? $payment_address['tax_id'] : '';
    881 			$data['payment_address_1'] = isset($payment_address['address_1']) ? $payment_address['address_1'] : '';
    882 			$data['payment_address_2'] = isset($payment_address['address_2']) ? $payment_address['address_2'] : '';
    883 			$data['payment_city'] = isset($payment_address['city']) ? $payment_address['city'] : '';
    884 			$data['payment_postcode'] = isset($payment_address['postcode']) ? $payment_address['postcode'] : '';
    885 			$data['payment_zone'] = isset($payment_address['zone']) ? $payment_address['zone'] : '';
    886 			$data['payment_zone_id'] = isset($payment_address['zone_id']) ? $payment_address['zone_id'] : '';
    887 			$data['payment_country'] = isset($payment_address['country']) ? $payment_address['country'] : '';
    888 			$data['payment_country_id'] = isset($payment_address['country_id']) ? $payment_address['country_id'] : '';
    889 			$data['payment_address_format'] = isset($payment_address['address_format']) ? $payment_address['address_format'] : '';
    890 
    891 			$data['payment_method'] = '';
    892 			if (isset($this->session->data['payment_method']['title'])) {
    893 				$data['payment_method'] = $this->session->data['payment_method']['title'];
    894 			}
    895 
    896 			$data['payment_code'] = '';
    897 			if (isset($this->session->data['payment_method']['code'])) {
    898 				$data['payment_code'] = $this->session->data['payment_method']['code'];
    899 			}
    900 
    901 			if ($this->cart->hasShipping()) {
    902 				if ($this->customer->isLogged()) {
    903 					$this->load->model('account/address');
    904 
    905 					$shipping_address = $this->model_account_address->getAddress($this->session->data['shipping_address_id']);
    906 				} elseif (isset($this->session->data['guest'])) {
    907 					$shipping_address = $this->session->data['guest']['shipping'];
    908 				}
    909 
    910 				$data['shipping_firstname'] = $shipping_address['firstname'];
    911 				$data['shipping_lastname'] = $shipping_address['lastname'];
    912 				$data['shipping_company'] = $shipping_address['company'];
    913 				$data['shipping_address_1'] = $shipping_address['address_1'];
    914 				$data['shipping_address_2'] = $shipping_address['address_2'];
    915 				$data['shipping_city'] = $shipping_address['city'];
    916 				$data['shipping_postcode'] = $shipping_address['postcode'];
    917 				$data['shipping_zone'] = $shipping_address['zone'];
    918 				$data['shipping_zone_id'] = $shipping_address['zone_id'];
    919 				$data['shipping_country'] = $shipping_address['country'];
    920 				$data['shipping_country_id'] = $shipping_address['country_id'];
    921 				$data['shipping_address_format'] = $shipping_address['address_format'];
    922 
    923 				$data['shipping_method'] = '';
    924 				if (isset($this->session->data['shipping_method']['title'])) {
    925 					$data['shipping_method'] = $this->session->data['shipping_method']['title'];
    926 				}
    927 
    928 				$data['shipping_code'] = '';
    929 				if (isset($this->session->data['shipping_method']['code'])) {
    930 					$data['shipping_code'] = $this->session->data['shipping_method']['code'];
    931 				}
    932 			} else {
    933 				$data['shipping_firstname'] = '';
    934 				$data['shipping_lastname'] = '';
    935 				$data['shipping_company'] = '';
    936 				$data['shipping_address_1'] = '';
    937 				$data['shipping_address_2'] = '';
    938 				$data['shipping_city'] = '';
    939 				$data['shipping_postcode'] = '';
    940 				$data['shipping_zone'] = '';
    941 				$data['shipping_zone_id'] = '';
    942 				$data['shipping_country'] = '';
    943 				$data['shipping_country_id'] = '';
    944 				$data['shipping_address_format'] = '';
    945 				$data['shipping_method'] = '';
    946 				$data['shipping_code'] = '';
    947 			}
    948 
    949 			$product_data = array();
    950 
    951 			foreach ($this->cart->getProducts() as $product) {
    952 				$option_data = array();
    953 
    954 				foreach ($product['option'] as $option) {
    955 					$option_data[] = array(
    956 						'product_option_id'       => $option['product_option_id'],
    957 						'product_option_value_id' => $option['product_option_value_id'],
    958 						'option_id'               => $option['option_id'],
    959 						'option_value_id'         => $option['option_value_id'],
    960 						'name'                    => $option['name'],
    961 						'value'                   => $option['value'],
    962 						'type'                    => $option['type']
    963 					);
    964 				}
    965 
    966 				$product_data[] = array(
    967 					'product_id' => $product['product_id'],
    968 					'name'       => $product['name'],
    969 					'model'      => $product['model'],
    970 					'option'     => $option_data,
    971 					'download'   => $product['download'],
    972 					'quantity'   => $product['quantity'],
    973 					'subtract'   => $product['subtract'],
    974 					'price'      => $product['price'],
    975 					'total'      => $product['total'],
    976 					'tax'        => $this->tax->getTax($product['price'], $product['tax_class_id']),
    977 					'reward'     => $product['reward']
    978 				);
    979 			}
    980 
    981 			// Gift Voucher
    982 			$voucher_data = array();
    983 
    984 			if (!empty($this->session->data['vouchers'])) {
    985 				foreach ($this->session->data['vouchers'] as $voucher) {
    986 					$voucher_data[] = array(
    987 						'description'      => $voucher['description'],
    988 						'code'             => token(10),
    989 						'to_name'          => $voucher['to_name'],
    990 						'to_email'         => $voucher['to_email'],
    991 						'from_name'        => $voucher['from_name'],
    992 						'from_email'       => $voucher['from_email'],
    993 						'voucher_theme_id' => $voucher['voucher_theme_id'],
    994 						'message'          => $voucher['message'],
    995 						'amount'           => $voucher['amount']
    996 					);
    997 				}
    998 			}
    999 
   1000 			$data['products'] = $product_data;
   1001 			$data['vouchers'] = $voucher_data;
   1002 			$data['totals'] = $totals;
   1003 			$data['comment'] = $this->session->data['comment'];
   1004 			$data['total'] = $total;
   1005 
   1006 			if (isset($this->request->cookie['tracking'])) {
   1007 				$data['tracking'] = $this->request->cookie['tracking'];
   1008 
   1009 				$subtotal = $this->cart->getSubTotal();
   1010 
   1011 				// Affiliate
   1012 				$this->load->model('affiliate/affiliate');
   1013 
   1014 				$affiliate_info = $this->model_affiliate_affiliate->getAffiliateByCode($this->request->cookie['tracking']);
   1015 
   1016 				if ($affiliate_info) {
   1017 					$data['affiliate_id'] = $affiliate_info['affiliate_id'];
   1018 					$data['commission'] = ($subtotal / 100) * $affiliate_info['commission'];
   1019 				} else {
   1020 					$data['affiliate_id'] = 0;
   1021 					$data['commission'] = 0;
   1022 				}
   1023 
   1024 				// Marketing
   1025 				$this->load->model('checkout/marketing');
   1026 
   1027 				$marketing_info = $this->model_checkout_marketing->getMarketingByCode($this->request->cookie['tracking']);
   1028 
   1029 				if ($marketing_info) {
   1030 					$data['marketing_id'] = $marketing_info['marketing_id'];
   1031 				} else {
   1032 					$data['marketing_id'] = 0;
   1033 				}
   1034 			} else {
   1035 				$data['affiliate_id'] = 0;
   1036 				$data['commission'] = 0;
   1037 				$data['marketing_id'] = 0;
   1038 				$data['tracking'] = '';
   1039 			}
   1040 
   1041 			$data['language_id'] = $this->config->get('config_language_id');
   1042 			$data['currency_id'] = $this->currency->getId($this->session->data['currency']);
   1043 			$data['currency_code'] = $this->session->data['currency'];
   1044 			$data['currency_value'] = $this->currency->getValue($this->session->data['currency']);
   1045 			$data['ip'] = $this->request->server['REMOTE_ADDR'];
   1046 
   1047 			if (!empty($this->request->server['HTTP_X_FORWARDED_FOR'])) {
   1048 				$data['forwarded_ip'] = $this->request->server['HTTP_X_FORWARDED_FOR'];
   1049 			} elseif (!empty($this->request->server['HTTP_CLIENT_IP'])) {
   1050 				$data['forwarded_ip'] = $this->request->server['HTTP_CLIENT_IP'];
   1051 			} else {
   1052 				$data['forwarded_ip'] = '';
   1053 			}
   1054 
   1055 			if (isset($this->request->server['HTTP_USER_AGENT'])) {
   1056 				$data['user_agent'] = $this->request->server['HTTP_USER_AGENT'];
   1057 			} else {
   1058 				$data['user_agent'] = '';
   1059 			}
   1060 
   1061 			if (isset($this->request->server['HTTP_ACCEPT_LANGUAGE'])) {
   1062 				$data['accept_language'] = $this->request->server['HTTP_ACCEPT_LANGUAGE'];
   1063 			} else {
   1064 				$data['accept_language'] = '';
   1065 			}
   1066 
   1067 			$this->load->model('account/custom_field');
   1068 			$this->load->model('checkout/order');
   1069 
   1070 			$order_id = $this->model_checkout_order->addOrder($data);
   1071 			$this->session->data['order_id'] = $order_id;
   1072 
   1073 			$this->load->model('extension/payment/pp_express');
   1074 
   1075 			$paypal_data = array(
   1076 				'TOKEN'                      => $this->session->data['paypal']['token'],
   1077 				'PAYERID'                    => $this->session->data['paypal']['payerid'],
   1078 				'METHOD'                     => 'DoExpressCheckoutPayment',
   1079 				'PAYMENTREQUEST_0_NOTIFYURL' => $this->url->link('extension/payment/pp_express/ipn', '', true),
   1080 				'RETURNFMFDETAILS'           => 1
   1081 			);
   1082 
   1083 			$paypal_data = array_merge($paypal_data, $this->model_extension_payment_pp_express->paymentRequestInfo());
   1084 
   1085 			$result = $this->model_extension_payment_pp_express->call($paypal_data);
   1086 
   1087 			if ($result['ACK'] == 'Success') {
   1088 				//handle order status
   1089 				switch($result['PAYMENTINFO_0_PAYMENTSTATUS']) {
   1090 					case 'Canceled_Reversal':
   1091 						$order_status_id = $this->config->get('payment_pp_express_canceled_reversal_status_id');
   1092 						break;
   1093 					case 'Completed':
   1094 						$order_status_id = $this->config->get('payment_pp_express_completed_status_id');
   1095 						break;
   1096 					case 'Denied':
   1097 						$order_status_id = $this->config->get('payment_pp_express_denied_status_id');
   1098 						break;
   1099 					case 'Expired':
   1100 						$order_status_id = $this->config->get('payment_pp_express_expired_status_id');
   1101 						break;
   1102 					case 'Failed':
   1103 						$order_status_id = $this->config->get('payment_pp_express_failed_status_id');
   1104 						break;
   1105 					case 'Pending':
   1106 						$order_status_id = $this->config->get('payment_pp_express_pending_status_id');
   1107 						break;
   1108 					case 'Processed':
   1109 						$order_status_id = $this->config->get('payment_pp_express_processed_status_id');
   1110 						break;
   1111 					case 'Refunded':
   1112 						$order_status_id = $this->config->get('payment_pp_express_refunded_status_id');
   1113 						break;
   1114 					case 'Reversed':
   1115 						$order_status_id = $this->config->get('payment_pp_express_reversed_status_id');
   1116 						break;
   1117 					case 'Voided':
   1118 						$order_status_id = $this->config->get('payment_pp_express_voided_status_id');
   1119 						break;
   1120 				}
   1121 
   1122 				$this->model_checkout_order->addOrderHistory($order_id, $order_status_id);
   1123 
   1124 				//add order to paypal table
   1125 				$paypal_order_data = array(
   1126 					'order_id'         => $order_id,
   1127 					'capture_status'   => ($this->config->get('payment_pp_express_transaction') == 'Sale' ? 'Complete' : 'NotComplete'),
   1128 					'currency_code'    => $result['PAYMENTINFO_0_CURRENCYCODE'],
   1129 					'authorization_id' => $result['PAYMENTINFO_0_TRANSACTIONID'],
   1130 					'total'            => $result['PAYMENTINFO_0_AMT']
   1131 				);
   1132 
   1133 				$paypal_order_id = $this->model_extension_payment_pp_express->addOrder($paypal_order_data);
   1134 
   1135 				//add transaction to paypal transaction table
   1136 				$paypal_transaction_data = array(
   1137 					'paypal_order_id'       => $paypal_order_id,
   1138 					'transaction_id'        => $result['PAYMENTINFO_0_TRANSACTIONID'],
   1139 					'parent_id' => '',
   1140 					'note'                  => '',
   1141 					'msgsubid'              => '',
   1142 					'receipt_id'            => (isset($result['PAYMENTINFO_0_RECEIPTID']) ? $result['PAYMENTINFO_0_RECEIPTID'] : ''),
   1143 					'payment_type'          => $result['PAYMENTINFO_0_PAYMENTTYPE'],
   1144 					'payment_status'        => $result['PAYMENTINFO_0_PAYMENTSTATUS'],
   1145 					'pending_reason'        => $result['PAYMENTINFO_0_PENDINGREASON'],
   1146 					'transaction_entity'    => ($this->config->get('payment_pp_express_transaction') == 'Sale' ? 'payment' : 'auth'),
   1147 					'amount'                => $result['PAYMENTINFO_0_AMT'],
   1148 					'debug_data'            => json_encode($result)
   1149 				);
   1150 
   1151 				$this->model_extension_payment_pp_express->addTransaction($paypal_transaction_data);
   1152 
   1153 				$recurring_products = $this->cart->getRecurringProducts();
   1154 
   1155 				//loop through any products that are recurring items
   1156 				if ($recurring_products) {
   1157 					$this->load->language('extension/payment/pp_express');
   1158 
   1159 					$this->load->model('checkout/recurring');
   1160 
   1161 					$billing_period = array(
   1162 						'day'        => 'Day',
   1163 						'week'       => 'Week',
   1164 						'semi_month' => 'SemiMonth',
   1165 						'month'      => 'Month',
   1166 						'year'       => 'Year'
   1167 					);
   1168 
   1169 					foreach($recurring_products as $item) {
   1170 						$data = array(
   1171 							'METHOD'             => 'CreateRecurringPaymentsProfile',
   1172 							'TOKEN'              => $this->session->data['paypal']['token'],
   1173 							'PROFILESTARTDATE'   => gmdate("Y-m-d\TH:i:s\Z", gmmktime(gmdate("H"), gmdate("i")+5, gmdate("s"), gmdate("m"), gmdate("d"), gmdate("y"))),
   1174 							'BILLINGPERIOD'      => $billing_period[$item['recurring']['frequency']],
   1175 							'BILLINGFREQUENCY'   => $item['recurring']['cycle'],
   1176 							'TOTALBILLINGCYCLES' => $item['recurring']['duration'],
   1177 							'AMT'                => $this->currency->format($this->tax->calculate($item['recurring']['price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $item['quantity'],
   1178 							'CURRENCYCODE'       => $this->session->data['currency']
   1179 						);
   1180 
   1181 						//trial information
   1182 						if ($item['recurring']['trial']) {
   1183 							$data_trial = array(
   1184 								'TRIALBILLINGPERIOD'      => $billing_period[$item['recurring']['trial_frequency']],
   1185 								'TRIALBILLINGFREQUENCY'   => $item['recurring']['trial_cycle'],
   1186 								'TRIALTOTALBILLINGCYCLES' => $item['recurring']['trial_duration'],
   1187 								'TRIALAMT'                => $this->currency->format($this->tax->calculate($item['recurring']['trial_price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $item['quantity']
   1188 							);
   1189 
   1190 							$trial_amt = $this->currency->format($this->tax->calculate($item['recurring']['trial_price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $item['quantity'] . ' ' . $this->session->data['currency'];
   1191 							$trial_text =  sprintf($this->language->get('text_trial'), $trial_amt, $item['recurring']['trial_cycle'], $item['recurring']['trial_frequency'], $item['recurring']['trial_duration']);
   1192 
   1193 							$data = array_merge($data, $data_trial);
   1194 						} else {
   1195 							$trial_text = '';
   1196 						}
   1197 
   1198 						$recurring_amt = $this->currency->format($this->tax->calculate($item['recurring']['price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false)  * $item['quantity'] . ' ' . $this->session->data['currency'];
   1199 						$recurring_description = $trial_text . sprintf($this->language->get('text_recurring'), $recurring_amt, $item['recurring']['cycle'], $item['recurring']['frequency']);
   1200 
   1201 						if ($item['recurring']['duration'] > 0) {
   1202 							$recurring_description .= sprintf($this->language->get('text_length'), $item['recurring']['duration']);
   1203 						}
   1204 
   1205 						//create new recurring and set to pending status as no payment has been made yet.
   1206 						$recurring_id = $this->model_checkout_recurring->addRecurring($order_id, $recurring_description, $item['recurring']);
   1207 
   1208 						$data['PROFILEREFERENCE'] = $recurring_id;
   1209 						$data['DESC'] = $recurring_description;
   1210 
   1211 						$result = $this->model_extension_payment_pp_express->call($data);
   1212 
   1213 						if (isset($result['PROFILEID'])) {
   1214 							$this->model_checkout_recurring->addReference($recurring_id, $result['PROFILEID']);
   1215 						} else {
   1216 							// there was an error creating the recurring, need to log and also alert admin / user
   1217 
   1218 						}
   1219 					}
   1220 				}
   1221 
   1222 				$this->response->redirect($this->url->link('checkout/success'));
   1223 
   1224 				if (isset($result['REDIRECTREQUIRED']) && $result['REDIRECTREQUIRED'] == true) {
   1225 					//- handle german redirect here
   1226 					$this->response->redirect('https://www.paypal.com/cgi-bin/webscr?cmd=_complete-express-checkout&token=' . $this->session->data['paypal']['token']);
   1227 				}
   1228 			} else {
   1229 				if ($result['L_ERRORCODE0'] == '10486') {
   1230 					if (isset($this->session->data['paypal_redirect_count'])) {
   1231 
   1232 						if ($this->session->data['paypal_redirect_count'] == 2) {
   1233 							$this->session->data['paypal_redirect_count'] = 0;
   1234 							$this->session->data['error'] = $this->language->get('error_too_many_failures');
   1235 							$this->response->redirect($this->url->link('checkout/checkout', '', true));
   1236 						} else {
   1237 							$this->session->data['paypal_redirect_count']++;
   1238 						}
   1239 					} else {
   1240 						$this->session->data['paypal_redirect_count'] = 1;
   1241 					}
   1242 
   1243 					if ($this->config->get('payment_pp_express_test') == 1) {
   1244 						$this->response->redirect('https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $this->session->data['paypal']['token']);
   1245 					} else {
   1246 						$this->response->redirect('https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $this->session->data['paypal']['token']);
   1247 					}
   1248 				}
   1249 
   1250 				$this->session->data['error_warning'] = $result['L_LONGMESSAGE0'];
   1251 				$this->response->redirect($this->url->link('extension/payment/pp_express/expressConfirm', '', true));
   1252 			}
   1253 		} else {
   1254 			$this->response->redirect($redirect);
   1255 		}
   1256 	}
   1257 
   1258 	public function checkout() {
   1259 		if ((!$this->cart->hasProducts() && empty($this->session->data['vouchers'])) || (!$this->cart->hasStock() && !$this->config->get('config_stock_checkout'))) {
   1260 			$this->response->redirect($this->url->link('checkout/cart'));
   1261 		}
   1262 
   1263 		$this->load->model('extension/payment/pp_express');
   1264 		$this->load->model('tool/image');
   1265 		$this->load->model('checkout/order');
   1266 
   1267 		$order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
   1268 
   1269 		$max_amount = $this->cart->getTotal() * 1.5;
   1270 		$max_amount = $this->currency->format($max_amount, $this->session->data['currency'], '', false);
   1271 
   1272 		if ($this->cart->hasShipping()) {
   1273 			$shipping = 0;
   1274 
   1275 			// PayPal requires some countries to use zone code (not name) to be sent in SHIPTOSTATE
   1276 			$ship_to_state_codes = array(
   1277 				'30', // Brazil
   1278 				'38', // Canada
   1279 				'105', // Italy
   1280 				'138', // Mexico
   1281 				'223', // USA
   1282 			);
   1283 
   1284 			if (in_array($order_info['shipping_country_id'], $ship_to_state_codes)) {
   1285 				$ship_to_state = $order_info['shipping_zone_code'];
   1286 			} else {
   1287 				$ship_to_state = $order_info['shipping_zone'];
   1288 			}
   1289 
   1290 			$data_shipping = array(
   1291 				'PAYMENTREQUEST_0_SHIPTONAME'        => html_entity_decode($order_info['shipping_firstname'] . ' ' . $order_info['shipping_lastname'], ENT_QUOTES, 'UTF-8'),
   1292 				'PAYMENTREQUEST_0_SHIPTOSTREET'      => html_entity_decode($order_info['shipping_address_1'], ENT_QUOTES, 'UTF-8'),
   1293 				'PAYMENTREQUEST_0_SHIPTOSTREET2'     => html_entity_decode($order_info['shipping_address_2'], ENT_QUOTES, 'UTF-8'),
   1294 				'PAYMENTREQUEST_0_SHIPTOCITY'        => html_entity_decode($order_info['shipping_city'], ENT_QUOTES, 'UTF-8'),
   1295 				'PAYMENTREQUEST_0_SHIPTOSTATE'       => html_entity_decode($ship_to_state, ENT_QUOTES, 'UTF-8'),
   1296 				'PAYMENTREQUEST_0_SHIPTOZIP'         => html_entity_decode($order_info['shipping_postcode'], ENT_QUOTES, 'UTF-8'),
   1297 				'PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE' => $order_info['shipping_iso_code_2'],
   1298 				'ADDROVERRIDE' 						 => 1,
   1299 			);
   1300 		} else {
   1301 			$shipping = 1;
   1302 			$data_shipping = array();
   1303 		}
   1304 
   1305 		$data = array(
   1306 			'METHOD'             => 'SetExpressCheckout',
   1307 			'MAXAMT'             => $max_amount,
   1308 			'RETURNURL'          => $this->url->link('extension/payment/pp_express/checkoutReturn', '', true),
   1309 			'CANCELURL'          => $this->url->link('checkout/checkout', '', true),
   1310 			'REQCONFIRMSHIPPING' => 0,
   1311 			'NOSHIPPING'         => $shipping,
   1312 			'LOCALECODE'         => 'EN',
   1313 			'LANDINGPAGE'        => 'Login',
   1314 			'HDRIMG'             => $this->model_tool_image->resize($this->config->get('payment_pp_express_logo'), 750, 90),
   1315 			'PAYFLOWCOLOR'       => $this->config->get('payment_pp_express_colour'),
   1316 			'CHANNELTYPE'        => 'Merchant',
   1317 			'ALLOWNOTE'          => $this->config->get('payment_pp_express_allow_note')
   1318 		);
   1319 
   1320 		$data = array_merge($data, $data_shipping);
   1321 
   1322 		if (isset($this->session->data['pp_login']['seamless']['access_token']) && (isset($this->session->data['pp_login']['seamless']['customer_id']) && $this->session->data['pp_login']['seamless']['customer_id'] == $this->customer->getId()) && $this->config->get('module_pp_login_seamless')) {
   1323 			$data['IDENTITYACCESSTOKEN'] = $this->session->data['pp_login']['seamless']['access_token'];
   1324 		}
   1325 
   1326 		$data = array_merge($data, $this->model_extension_payment_pp_express->paymentRequestInfo());
   1327 
   1328 		$result = $this->model_extension_payment_pp_express->call($data);
   1329 
   1330 		/**
   1331 		 * If a failed PayPal setup happens, handle it.
   1332 		 */
   1333 		if (!isset($result['TOKEN'])) {
   1334 			$this->session->data['error'] = $result['L_LONGMESSAGE0'];
   1335 			/**
   1336 			 * Unable to add error message to user as the session errors/success are not
   1337 			 * used on the cart or checkout pages - need to be added?
   1338 			 * If PayPal debug log is off then still log error to normal error log.
   1339 			 */
   1340 			$this->log->write('Unable to create Paypal session' . json_encode($result));
   1341 
   1342 			$this->response->redirect($this->url->link('checkout/checkout', '', true));
   1343 		}
   1344 
   1345 		$this->session->data['paypal']['token'] = $result['TOKEN'];
   1346 
   1347 		if ($this->config->get('payment_pp_express_test') == 1) {
   1348 			header('Location: https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $result['TOKEN'] . '&useraction=commit');
   1349 		} else {
   1350 			header('Location: https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $result['TOKEN'] . '&useraction=commit');
   1351 		}
   1352 	}
   1353 
   1354 	public function checkoutReturn() {
   1355 		$this->load->language('extension/payment/pp_express');
   1356 
   1357 		$this->load->model('extension/payment/pp_express');
   1358 		$this->load->model('checkout/order');
   1359 
   1360 		$data = array(
   1361 			'METHOD' => 'GetExpressCheckoutDetails',
   1362 			'TOKEN'  => $this->session->data['paypal']['token']
   1363 		);
   1364 
   1365 		$result = $this->model_extension_payment_pp_express->call($data);
   1366 
   1367 		$this->session->data['paypal']['payerid'] = $result['PAYERID'];
   1368 		$this->session->data['paypal']['result'] = $result;
   1369 
   1370 		$order_id = $this->session->data['order_id'];
   1371 
   1372 		$paypal_data = array(
   1373 			'TOKEN'                      => $this->session->data['paypal']['token'],
   1374 			'PAYERID'                    => $this->session->data['paypal']['payerid'],
   1375 			'METHOD'                     => 'DoExpressCheckoutPayment',
   1376 			'PAYMENTREQUEST_0_NOTIFYURL' => $this->url->link('extension/payment/pp_express/ipn', '', true),
   1377 			'RETURNFMFDETAILS'           => 1
   1378 		);
   1379 
   1380 		$paypal_data = array_merge($paypal_data, $this->model_extension_payment_pp_express->paymentRequestInfo());
   1381 
   1382 		$result = $this->model_extension_payment_pp_express->call($paypal_data);
   1383 
   1384 		if ($result['ACK'] == 'Success') {
   1385 			//handle order status
   1386 			switch($result['PAYMENTINFO_0_PAYMENTSTATUS']) {
   1387 				case 'Canceled_Reversal':
   1388 					$order_status_id = $this->config->get('payment_pp_express_canceled_reversal_status_id');
   1389 					break;
   1390 				case 'Completed':
   1391 					$order_status_id = $this->config->get('payment_pp_express_completed_status_id');
   1392 					break;
   1393 				case 'Denied':
   1394 					$order_status_id = $this->config->get('payment_pp_express_denied_status_id');
   1395 					break;
   1396 				case 'Expired':
   1397 					$order_status_id = $this->config->get('payment_pp_express_expired_status_id');
   1398 					break;
   1399 				case 'Failed':
   1400 					$order_status_id = $this->config->get('payment_pp_express_failed_status_id');
   1401 					break;
   1402 				case 'Pending':
   1403 					$order_status_id = $this->config->get('payment_pp_express_pending_status_id');
   1404 					break;
   1405 				case 'Processed':
   1406 					$order_status_id = $this->config->get('payment_pp_express_processed_status_id');
   1407 					break;
   1408 				case 'Refunded':
   1409 					$order_status_id = $this->config->get('payment_pp_express_refunded_status_id');
   1410 					break;
   1411 				case 'Reversed':
   1412 					$order_status_id = $this->config->get('payment_pp_express_reversed_status_id');
   1413 					break;
   1414 				case 'Voided':
   1415 					$order_status_id = $this->config->get('payment_pp_express_voided_status_id');
   1416 					break;
   1417 			}
   1418 
   1419 			$this->model_checkout_order->addOrderHistory($order_id, $order_status_id);
   1420 
   1421 			//add order to paypal table
   1422 			$paypal_order_data = array(
   1423 				'order_id'         => $order_id,
   1424 				'capture_status'   => ($this->config->get('payment_pp_express_transaction') == 'Sale' ? 'Complete' : 'NotComplete'),
   1425 				'currency_code'    => $result['PAYMENTINFO_0_CURRENCYCODE'],
   1426 				'authorization_id' => $result['PAYMENTINFO_0_TRANSACTIONID'],
   1427 				'total'            => $result['PAYMENTINFO_0_AMT']
   1428 			);
   1429 
   1430 			$paypal_order_id = $this->model_extension_payment_pp_express->addOrder($paypal_order_data);
   1431 
   1432 			//add transaction to paypal transaction table
   1433 			$paypal_transaction_data = array(
   1434 				'paypal_order_id'       => $paypal_order_id,
   1435 				'transaction_id'        => $result['PAYMENTINFO_0_TRANSACTIONID'],
   1436 				'parent_id' => '',
   1437 				'note'                  => '',
   1438 				'msgsubid'              => '',
   1439 				'receipt_id'            => (isset($result['PAYMENTINFO_0_RECEIPTID']) ? $result['PAYMENTINFO_0_RECEIPTID'] : ''),
   1440 				'payment_type'          => $result['PAYMENTINFO_0_PAYMENTTYPE'],
   1441 				'payment_status'        => $result['PAYMENTINFO_0_PAYMENTSTATUS'],
   1442 				'pending_reason'        => $result['PAYMENTINFO_0_PENDINGREASON'],
   1443 				'transaction_entity'    => ($this->config->get('payment_pp_express_transaction') == 'Sale' ? 'payment' : 'auth'),
   1444 				'amount'                => $result['PAYMENTINFO_0_AMT'],
   1445 				'debug_data'            => json_encode($result)
   1446 			);
   1447 			$this->model_extension_payment_pp_express->addTransaction($paypal_transaction_data);
   1448 
   1449 			$recurring_products = $this->cart->getRecurringProducts();
   1450 
   1451 			//loop through any products that are recurring items
   1452 			if ($recurring_products) {
   1453 				$this->load->model('checkout/recurring');
   1454 
   1455 				$billing_period = array(
   1456 					'day'        => 'Day',
   1457 					'week'       => 'Week',
   1458 					'semi_month' => 'SemiMonth',
   1459 					'month'      => 'Month',
   1460 					'year'       => 'Year'
   1461 				);
   1462 
   1463 				foreach ($recurring_products as $item) {
   1464 					$data = array(
   1465 						'METHOD'             => 'CreateRecurringPaymentsProfile',
   1466 						'TOKEN'              => $this->session->data['paypal']['token'],
   1467 						'PROFILESTARTDATE'   => gmdate("Y-m-d\TH:i:s\Z", gmmktime(gmdate('H'), gmdate('i') + 5, gmdate('s'), gmdate('m'), gmdate('d'), gmdate('y'))),
   1468 						'BILLINGPERIOD'      => $billing_period[$item['recurring']['frequency']],
   1469 						'BILLINGFREQUENCY'   => $item['recurring']['cycle'],
   1470 						'TOTALBILLINGCYCLES' => $item['recurring']['duration'],
   1471 						'AMT'                => $this->currency->format($this->tax->calculate($item['recurring']['price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $item['quantity'],
   1472 						'CURRENCYCODE'       => $this->session->data['currency']
   1473 					);
   1474 
   1475 					//trial information
   1476 					if ($item['recurring']['trial'] == 1) {
   1477 						$data_trial = array(
   1478 							'TRIALBILLINGPERIOD'      => $billing_period[$item['recurring']['trial_frequency']],
   1479 							'TRIALBILLINGFREQUENCY'   => $item['recurring']['trial_cycle'],
   1480 							'TRIALTOTALBILLINGCYCLES' => $item['recurring']['trial_duration'],
   1481 							'TRIALAMT'                => $this->currency->format($this->tax->calculate($item['recurring']['trial_price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $item['quantity']
   1482 						);
   1483 
   1484 						$trial_amt = $this->currency->format($this->tax->calculate($item['recurring']['trial_price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false) * $item['quantity'] . ' ' . $this->session->data['currency'];
   1485 						$trial_text =  sprintf($this->language->get('text_trial'), $trial_amt, $item['recurring']['trial_cycle'], $item['recurring']['trial_frequency'], $item['recurring']['trial_duration']);
   1486 
   1487 						$data = array_merge($data, $data_trial);
   1488 					} else {
   1489 						$trial_text = '';
   1490 					}
   1491 
   1492 					$recurring_amt = $this->currency->format($this->tax->calculate($item['recurring']['price'], $item['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency'], false, false)  * $item['quantity'] . ' ' . $this->session->data['currency'];
   1493 					$recurring_description = $trial_text . sprintf($this->language->get('text_recurring'), $recurring_amt, $item['recurring']['cycle'], $item['recurring']['frequency']);
   1494 
   1495 					if ($item['recurring']['duration'] > 0) {
   1496 						$recurring_description .= sprintf($this->language->get('text_length'), $item['recurring']['duration']);
   1497 					}
   1498 
   1499 					//create new recurring and set to pending status as no payment has been made yet.
   1500 					$recurring_id = $this->model_checkout_recurring->addRecurring($order_id, $recurring_description, $item['recurring']);
   1501 
   1502 					$data['PROFILEREFERENCE'] = $recurring_id;
   1503 					$data['DESC'] = $recurring_description;
   1504 
   1505 					$result = $this->model_extension_payment_pp_express->call($data);
   1506 
   1507 					if (isset($result['PROFILEID'])) {
   1508 						$this->model_checkout_recurring->editReference($recurring_id, $result['PROFILEID']);
   1509 					} else {
   1510 						// there was an error creating the recurring, need to log and also alert admin / user
   1511 
   1512 					}
   1513 				}
   1514 			}
   1515 
   1516 			if (isset($result['REDIRECTREQUIRED']) && $result['REDIRECTREQUIRED'] == true) {
   1517 				//- handle german redirect here
   1518 				$this->response->redirect('https://www.paypal.com/cgi-bin/webscr?cmd=_complete-express-checkout&token=' . $this->session->data['paypal']['token']);
   1519 			} else {
   1520 				$this->response->redirect($this->url->link('checkout/success'));
   1521 			}
   1522 		} else {
   1523 			if ($result['L_ERRORCODE0'] == '10486') {
   1524 				if (isset($this->session->data['paypal_redirect_count'])) {
   1525 
   1526 					if ($this->session->data['paypal_redirect_count'] == 2) {
   1527 						$this->session->data['paypal_redirect_count'] = 0;
   1528 						$this->session->data['error'] = $this->language->get('error_too_many_failures');
   1529 
   1530 						$this->response->redirect($this->url->link('checkout/checkout', '', true));
   1531 					} else {
   1532 						$this->session->data['paypal_redirect_count']++;
   1533 					}
   1534 				} else {
   1535 					$this->session->data['paypal_redirect_count'] = 1;
   1536 				}
   1537 
   1538 				if ($this->config->get('payment_pp_express_test') == 1) {
   1539 					$this->response->redirect('https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $this->session->data['paypal']['token']);
   1540 				} else {
   1541 					$this->response->redirect('https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $this->session->data['paypal']['token']);
   1542 				}
   1543 			}
   1544 
   1545 			$this->load->language('extension/payment/pp_express');
   1546 
   1547 			$data['breadcrumbs'] = array();
   1548 
   1549 			$data['breadcrumbs'][] = array(
   1550 				'href' => $this->url->link('common/home'),
   1551 				'text' => $this->language->get('text_home')
   1552 			);
   1553 
   1554 			$data['breadcrumbs'][] = array(
   1555 				'href' => $this->url->link('checkout/cart'),
   1556 				'text' => $this->language->get('text_cart')
   1557 			);
   1558 
   1559 			$data['heading_title'] = $this->language->get('error_heading_title');
   1560 
   1561 			$data['text_error'] = '<div class="warning">' . $result['L_ERRORCODE0'] . ' : ' . $result['L_LONGMESSAGE0'] . '</div>';
   1562 
   1563 			$data['button_continue'] = $this->language->get('button_continue');
   1564 
   1565 			$data['continue'] = $this->url->link('checkout/cart');
   1566 
   1567 			unset($this->session->data['success']);
   1568 
   1569 			$this->response->addHeader($this->request->server['SERVER_PROTOCOL'] . ' 404 Not Found');
   1570 
   1571 			$data['column_left'] = $this->load->controller('common/column_left');
   1572 			$data['column_right'] = $this->load->controller('common/column_right');
   1573 			$data['content_top'] = $this->load->controller('common/content_top');
   1574 			$data['content_bottom'] = $this->load->controller('common/content_bottom');
   1575 			$data['footer'] = $this->load->controller('common/footer');
   1576 			$data['header'] = $this->load->controller('common/header');
   1577 
   1578 			$this->response->setOutput($this->load->view('error/not_found', $data));
   1579 		}
   1580 	}
   1581 
   1582 	public function ipn() {
   1583 		$this->load->model('extension/payment/pp_express');
   1584 		$this->load->model('account/recurring');
   1585 
   1586 		$request = 'cmd=_notify-validate';
   1587 
   1588 		foreach ($_POST as $key => $value) {
   1589 			$request .= '&' . $key . '=' . urlencode(html_entity_decode($value, ENT_QUOTES, 'UTF-8'));
   1590 		}
   1591 
   1592 		if ($this->config->get('payment_pp_express_test') == 1) {
   1593 			$curl = curl_init('https://www.sandbox.paypal.com/cgi-bin/webscr');
   1594 		} else {
   1595 			$curl = curl_init('https://www.paypal.com/cgi-bin/webscr');
   1596 		}
   1597 
   1598 		curl_setopt($curl, CURLOPT_POST, true);
   1599 		curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
   1600 		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
   1601 		curl_setopt($curl, CURLOPT_HEADER, false);
   1602 		curl_setopt($curl, CURLOPT_TIMEOUT, 30);
   1603 		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
   1604 
   1605 		$response = trim(curl_exec($curl));
   1606 
   1607 		if (!$response) {
   1608 			$this->model_extension_payment_pp_express->log(array('error' => curl_error($curl),'error_no' => curl_errno($curl)), 'Curl failed');
   1609 		}
   1610 
   1611 		$this->model_extension_payment_pp_express->log(array('request' => $request,'response' => $response), 'IPN data');
   1612 
   1613 		if ((string)$response == "VERIFIED")  {
   1614 			if (isset($this->request->post['transaction_entity'])) {
   1615 				$this->log->write($this->request->post['transaction_entity']);
   1616 			}
   1617 
   1618 			if (isset($this->request->post['txn_id'])) {
   1619 				$transaction = $this->model_extension_payment_pp_express->getTransactionRow($this->request->post['txn_id']);
   1620 			} else {
   1621 				$transaction = false;
   1622 			}
   1623 
   1624 			if (isset($this->request->post['parent_txn_id'])) {
   1625 				$parent_transaction = $this->model_extension_payment_pp_express->getTransactionRow($this->request->post['parent_txn_id']);
   1626 			} else {
   1627 				$parent_transaction = false;
   1628 			}
   1629 
   1630 			if ($transaction) {
   1631 				//transaction exists, check for cleared payment or updates etc
   1632 				$this->model_extension_payment_pp_express->log('Transaction exists', 'IPN data');
   1633 
   1634 				//if the transaction is pending but the new status is completed
   1635 				if ($transaction['payment_status'] != $this->request->post['payment_status']) {
   1636 					$this->db->query("UPDATE `" . DB_PREFIX . "paypal_order_transaction` SET `payment_status` = '" . $this->db->escape($this->request->post['payment_status']) . "' WHERE `transaction_id` = '" . $this->db->escape($transaction['transaction_id']) . "' LIMIT 1");
   1637 				} elseif ($transaction['payment_status'] == 'Pending' && ($transaction['pending_reason'] != $this->request->post['pending_reason'])) {
   1638 					//payment is still pending but the pending reason has changed, update it.
   1639 					$this->db->query("UPDATE `" . DB_PREFIX . "paypal_order_transaction` SET `pending_reason` = '" . $this->db->escape($this->request->post['pending_reason']) . "' WHERE `transaction_id` = '" . $this->db->escape($transaction['transaction_id']) . "' LIMIT 1");
   1640 				}
   1641 			} else {
   1642 				$this->model_extension_payment_pp_express->log('Transaction does not exist', 'IPN data');
   1643 
   1644 				if ($parent_transaction) {
   1645 					//parent transaction exists
   1646 					$this->model_extension_payment_pp_express->log('Parent transaction exists', 'IPN data');
   1647 
   1648 					//add new related transaction
   1649 					$transaction = array(
   1650 						'paypal_order_id'       => $parent_transaction['paypal_order_id'],
   1651 						'transaction_id'        => $this->request->post['txn_id'],
   1652 						'parent_id' => $this->request->post['parent_txn_id'],
   1653 						'note'                  => '',
   1654 						'msgsubid'              => '',
   1655 						'receipt_id'            => (isset($this->request->post['receipt_id']) ? $this->request->post['receipt_id'] : ''),
   1656 						'payment_type'          => (isset($this->request->post['payment_type']) ? $this->request->post['payment_type'] : ''),
   1657 						'payment_status'        => (isset($this->request->post['payment_status']) ? $this->request->post['payment_status'] : ''),
   1658 						'pending_reason'        => (isset($this->request->post['pending_reason']) ? $this->request->post['pending_reason'] : ''),
   1659 						'amount'                => $this->request->post['mc_gross'],
   1660 						'debug_data'            => json_encode($this->request->post),
   1661 						'transaction_entity'    => (isset($this->request->post['transaction_entity']) ? $this->request->post['transaction_entity'] : '')
   1662 					);
   1663 
   1664 					$this->model_extension_payment_pp_express->addTransaction($transaction);
   1665 
   1666 					/**
   1667 					 * If there has been a refund, log this against the parent transaction.
   1668 					 */
   1669 					if (isset($this->request->post['payment_status']) && $this->request->post['payment_status'] == 'Refunded') {
   1670 						if (($this->request->post['mc_gross'] * -1) == $parent_transaction['amount']) {
   1671 							$this->db->query("UPDATE `" . DB_PREFIX . "paypal_order_transaction` SET `payment_status` = 'Refunded' WHERE `transaction_id` = '" . $this->db->escape($parent_transaction['transaction_id']) . "' LIMIT 1");
   1672 						} else {
   1673 							$this->db->query("UPDATE `" . DB_PREFIX . "paypal_order_transaction` SET `payment_status` = 'Partially-Refunded' WHERE `transaction_id` = '" . $this->db->escape($parent_transaction['transaction_id']) . "' LIMIT 1");
   1674 						}
   1675 					}
   1676 
   1677 					/**
   1678 					 * If the capture payment is now complete
   1679 					 */
   1680 					if (isset($this->request->post['auth_status']) && $this->request->post['auth_status'] == 'Completed' && $parent_transaction['payment_status'] == 'Pending') {
   1681 						$captured = $this->currency->format($this->model_extension_payment_pp_express->getTotalCaptured($parent_transaction['paypal_order_id']), $this->session->data['currency'], false, false);
   1682 						$refunded = $this->currency->format($this->model_extension_payment_pp_express->getRefundedTotal($parent_transaction['paypal_order_id']), $this->session->data['currency'], false, false);
   1683 						$remaining = $this->currency->format($parent_transaction['amount'] - $captured + $refunded, $this->session->data['currency'], false, false);
   1684 
   1685 						$this->model_extension_payment_pp_express->log('Captured: ' . $captured, 'IPN data');
   1686 						$this->model_extension_payment_pp_express->log('Refunded: ' . $refunded, 'IPN data');
   1687 						$this->model_extension_payment_pp_express->log('Remaining: ' . $remaining, 'IPN data');
   1688 
   1689 						if ($remaining > 0.00) {
   1690 							$transaction = array(
   1691 								'paypal_order_id'       => $parent_transaction['paypal_order_id'],
   1692 								'transaction_id'        => '',
   1693 								'parent_id' 			=> $this->request->post['parent_txn_id'],
   1694 								'note'                  => '',
   1695 								'msgsubid'              => '',
   1696 								'receipt_id'            => '',
   1697 								'payment_type'          => '',
   1698 								'payment_status'        => 'Void',
   1699 								'pending_reason'        => '',
   1700 								'amount'                => '',
   1701 								'debug_data'            => 'Voided after capture',
   1702 								'transaction_entity'    => 'auth'
   1703 							);
   1704 
   1705 							$this->model_extension_payment_pp_express->addTransaction($transaction);
   1706 						}
   1707 
   1708 						$this->model_extension_payment_pp_express->updateOrder('Complete', $parent_transaction['order_id']);
   1709 					}
   1710 
   1711 				} else {
   1712 					//parent transaction doesn't exists, need to investigate?
   1713 					$this->model_extension_payment_pp_express->log('Parent transaction not found', 'IPN data');
   1714 				}
   1715 			}
   1716 
   1717 			/*
   1718 			 * Subscription payments
   1719 			 *
   1720 			 * recurring ID should always exist if its a recurring payment transaction.
   1721 			 *
   1722 			 * also the reference will match a recurring payment ID
   1723 			 */
   1724 			if (isset($this->request->post['txn_type'])) {
   1725 				$this->model_extension_payment_pp_express->log($this->request->post['txn_type'], 'IPN data');
   1726 
   1727 				//payment
   1728 				if ($this->request->post['txn_type'] == 'recurring_payment') {
   1729 					$recurring = $this->model_account_recurring->getOrderRecurringByReference($this->request->post['recurring_payment_id']);
   1730 
   1731 					$this->model_extension_payment_pp_express->log($recurring, 'IPN data');
   1732 
   1733 					if ($recurring != false) {
   1734 						$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "', `date_added` = NOW(), `amount` = '" . (float)$this->request->post['amount'] . "', `type` = '1'");
   1735 
   1736 						//as there was a payment the recurring is active, ensure it is set to active (may be been suspended before)
   1737 						if ($recurring['status'] != 1) {
   1738 							$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 2 WHERE `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "'");
   1739 						}
   1740 					}
   1741 				}
   1742 
   1743 				//suspend
   1744 				if ($this->request->post['txn_type'] == 'recurring_payment_suspended') {
   1745 					$recurring = $this->model_account_recurring->getOrderRecurringByReference($this->request->post['recurring_payment_id']);
   1746 
   1747 					if ($recurring != false) {
   1748 						$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "', `date_added` = NOW(), `type` = '6'");
   1749 						$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 3 WHERE `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "' LIMIT 1");
   1750 					}
   1751 				}
   1752 
   1753 				//suspend due to max failed
   1754 				if ($this->request->post['txn_type'] == 'recurring_payment_suspended_due_to_max_failed_payment') {
   1755 					$recurring = $this->model_account_recurring->getOrderRecurringByReference($this->request->post['recurring_payment_id']);
   1756 
   1757 					if ($recurring != false) {
   1758 						$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "', `date_added` = NOW(), `type` = '7'");
   1759 						$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 3 WHERE `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "' LIMIT 1");
   1760 					}
   1761 				}
   1762 
   1763 				//payment failed
   1764 				if ($this->request->post['txn_type'] == 'recurring_payment_failed') {
   1765 					$recurring = $this->model_account_recurring->getOrderRecurringByReference($this->request->post['recurring_payment_id']);
   1766 
   1767 					if ($recurring != false) {
   1768 						$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "', `date_added` = NOW(), `type` = '4'");
   1769 					}
   1770 				}
   1771 
   1772 				//outstanding payment failed
   1773 				if ($this->request->post['txn_type'] == 'recurring_payment_outstanding_payment_failed') {
   1774 					$recurring = $this->model_account_recurring->getOrderRecurringByReference($this->request->post['recurring_payment_id']);
   1775 
   1776 					if ($recurring != false) {
   1777 						$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "', `date_added` = NOW(), `type` = '8'");
   1778 					}
   1779 				}
   1780 
   1781 				//outstanding payment
   1782 				if ($this->request->post['txn_type'] == 'recurring_payment_outstanding_payment') {
   1783 					$recurring = $this->model_account_recurring->getOrderRecurringByReference($this->request->post['recurring_payment_id']);
   1784 
   1785 					if ($recurring != false) {
   1786 						$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "', `date_added` = NOW(), `amount` = '" . (float)$this->request->post['amount'] . "', `type` = '2'");
   1787 
   1788 						//as there was a payment the recurring is active, ensure it is set to active (may be been suspended before)
   1789 						if ($recurring['status'] != 1) {
   1790 							$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 2 WHERE `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "'");
   1791 						}
   1792 					}
   1793 				}
   1794 
   1795 				//date_added
   1796 				if ($this->request->post['txn_type'] == 'recurring_payment_profile_date_added') {
   1797 					$recurring = $this->model_account_recurring->getOrderRecurringByReference($this->request->post['recurring_payment_id']);
   1798 
   1799 					if ($recurring != false) {
   1800 						$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "', `date_added` = NOW(), `type` = '0'");
   1801 
   1802 						if ($recurring['status'] != 1) {
   1803 							$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 2 WHERE `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "'");
   1804 						}
   1805 					}
   1806 				}
   1807 
   1808 				//cancelled
   1809 				if ($this->request->post['txn_type'] == 'recurring_payment_profile_cancel') {
   1810 					$recurring = $this->model_account_recurring->getOrderRecurringByReference($this->request->post['recurring_payment_id']);
   1811 
   1812 					if ($recurring != false && $recurring['status'] != 3) {
   1813 						$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "', `date_added` = NOW(), `type` = '5'");
   1814 						$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 4 WHERE `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "' LIMIT 1");
   1815 					}
   1816 				}
   1817 
   1818 				//skipped
   1819 				if ($this->request->post['txn_type'] == 'recurring_payment_skipped') {
   1820 					$recurring = $this->model_account_recurring->getOrderRecurringByReference($this->request->post['recurring_payment_id']);
   1821 
   1822 					if ($recurring != false) {
   1823 						$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "', `date_added` = NOW(), `type` = '3'");
   1824 					}
   1825 				}
   1826 
   1827 				//expired
   1828 				if ($this->request->post['txn_type'] == 'recurring_payment_expired') {
   1829 					$recurring = $this->model_account_recurring->getOrderRecurringByReference($this->request->post['recurring_payment_id']);
   1830 
   1831 					if ($recurring != false) {
   1832 						$this->db->query("INSERT INTO `" . DB_PREFIX . "order_recurring_transaction` SET `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "', `date_added` = NOW(), `type` = '9'");
   1833 						$this->db->query("UPDATE `" . DB_PREFIX . "order_recurring` SET `status` = 5 WHERE `order_recurring_id` = '" . (int)$recurring['order_recurring_id'] . "' LIMIT 1");
   1834 					}
   1835 				}
   1836 			}
   1837 		} elseif ((string)$response == "INVALID") {
   1838 			$this->model_extension_payment_pp_express->log(array('IPN was invalid'), 'IPN fail');
   1839 		} else {
   1840 			$this->model_extension_payment_pp_express->log('Response string unknown: ' . (string)$response, 'IPN data');
   1841 		}
   1842 
   1843 		header("HTTP/1.1 200 Ok");
   1844 	}
   1845 
   1846 	public function shipping() {
   1847 		$this->shippingValidate($this->request->post['shipping_method']);
   1848 
   1849 		$this->response->redirect($this->url->link('extension/payment/pp_express/expressConfirm'));
   1850 	}
   1851 
   1852 	protected function shippingValidate($code) {
   1853 		$this->load->language('checkout/cart');
   1854 		$this->load->language('extension/payment/pp_express');
   1855 
   1856 		if (empty($code)) {
   1857 			$this->session->data['error_warning'] = $this->language->get('error_shipping');
   1858 			return false;
   1859 		} else {
   1860 			$shipping = explode('.', $code);
   1861 
   1862 			if (!isset($shipping[0]) || !isset($shipping[1]) || !isset($this->session->data['shipping_methods'][$shipping[0]]['quote'][$shipping[1]])) {
   1863 				$this->session->data['error_warning'] = $this->language->get('error_shipping');
   1864 				return false;
   1865 			} else {
   1866 				$this->session->data['shipping_method'] = $this->session->data['shipping_methods'][$shipping[0]]['quote'][$shipping[1]];
   1867 				$this->session->data['success'] = $this->language->get('text_shipping_updated');
   1868 				return true;
   1869 			}
   1870 		}
   1871 	}
   1872 
   1873 	protected function validateCoupon() {
   1874 		$this->load->model('extension/total/coupon');
   1875 
   1876 		$coupon_info = $this->model_extension_total_coupon->getCoupon($this->request->post['coupon']);
   1877 
   1878 		if ($coupon_info) {
   1879 			return true;
   1880 		} else {
   1881 			$this->session->data['error_warning'] = $this->language->get('error_coupon');
   1882 			return false;
   1883 		}
   1884 	}
   1885 
   1886 	protected function validateVoucher() {
   1887 		$this->load->model('extension/total/coupon');
   1888 
   1889 		$voucher_info = $this->model_extension_total_voucher->getVoucher($this->request->post['voucher']);
   1890 
   1891 		if ($voucher_info) {
   1892 			return true;
   1893 		} else {
   1894 			$this->session->data['error_warning'] = $this->language->get('error_voucher');
   1895 			return false;
   1896 		}
   1897 	}
   1898 
   1899 	protected function validateReward() {
   1900 		$points = $this->customer->getRewardPoints();
   1901 
   1902 		$points_total = 0;
   1903 
   1904 		foreach ($this->cart->getProducts() as $product) {
   1905 			if ($product['points']) {
   1906 				$points_total += $product['points'];
   1907 			}
   1908 		}
   1909 
   1910 		$error = '';
   1911 
   1912 		if (empty($this->request->post['reward'])) {
   1913 			$error = $this->language->get('error_reward');
   1914 		}
   1915 
   1916 		if ($this->request->post['reward'] > $points) {
   1917 			$error = sprintf($this->language->get('error_points'), $this->request->post['reward']);
   1918 		}
   1919 
   1920 		if ($this->request->post['reward'] > $points_total) {
   1921 			$error = sprintf($this->language->get('error_maximum'), $points_total);
   1922 		}
   1923 
   1924 		if (!$error) {
   1925 			return true;
   1926 		} else {
   1927 			$this->session->data['error_warning'] = $error;
   1928 			return false;
   1929 		}
   1930 	}
   1931 }