<?php
//-----------------------------------------
// Author: Qphoria@gmail.com
// Web: http://www.OpenCartGuru.com/
//-----------------------------------------
class ControllerPaymentPPHosted extends Controller {

	private $error;
	private $order_info;
	private $name = '';

	protected function index() {

		$this->name = basename(__FILE__, '.php');

		$this->data = array_merge($this->data, $this->load->language('payment/' . $this->name));

		if (!$this->config->get($this->name . '_test')) {
    		$this->data['action'] = 'https://securepayments.paypal.com/acquiringweb?cmd=_hosted-payment';
    		//$this->data['action'] = 'https://securepayments.paypal.com/acquiringweb';
  		} else {
			$this->data['action'] = 'https://securepayments.sandbox.paypal.com/acquiringweb';
		}

		$this->load->model('checkout/order');

		$this->data['testmode'] = $this->config->get($this->name . '_test');

		$this->data['continue'] = HTTPS_SERVER . 'index.php?route=checkout/success';

		$this->order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);


		// v14x Backwards Compatibility
		if (isset($this->order_info['currency_code'])) { $this->order_info['currency'] = $this->order_info['currency_code']; }
		if (isset($this->order_info['currency_value'])) { $this->order_info['value'] = $this->order_info['currency_value']; }

		# Check for supported currency, otherwise convert to default.
		$currencies = array('AUD','CAD','EUR','GBP','JPY','USD','NZD','CHF','HKD','SGD','SEK','DKK','PLN','NOK','HUF','CZK','ILS','MXN','MYR','BRL','PHP','PLN','TWD','THB');
		if (in_array($this->order_info['currency'], $currencies)) {
			$currency = $this->order_info['currency'];
		} else {
			$currency = 'GBP';
		}


		# Get all totals and discount total
		$total = 0;
        $total_data = array();
		$taxes = $this->cart->getTaxes();

		if (method_exists($this->document, 'addBreadcrumb')) { //1.4.x
			$this->load->model('checkout/extension');
			$results = $this->model_checkout_extension->getExtensions('total');
		} else {
			$this->load->model('setting/extension');
			$results = $this->model_setting_extension->getExtensions('total');
		}

		$sort_order = array();

		foreach ($results as $key => $value) {
			// v15x compatibility
			if (!isset($value['key']) && isset($value['code'])) {
				$value['key'] = $value['code'];
			}
			$sort_order[$key] = $this->config->get($value['key'] . '_sort_order');
		}

		array_multisort($sort_order, SORT_ASC, $results);

		$discount_total = 0;
		foreach ($results as $result) {

			// v15x compatibility
			if (!isset($result['key']) && isset($result['code'])) {
				$result['key'] = $result['code'];
			}

			$this->load->model('total/' . $result['key']);
			$old_total = $total;
			$this->{'model_total_' . $result['key']}->getTotal($total_data, $total, $taxes);

			if ($total < $old_total) {
				$discount_total += $old_total - $total;
			}
		}

		$this->data['total'] = $total;


		# Get Shipping Total
		$shipping_total = 0;
		if ($this->cart->hasShipping()) {
			$shipping_total = $this->session->data['shipping_method']['cost'];
		}


		# Get Tax Total
		$tax_total = 0;
		foreach ($taxes as $key => $value) {
			$tax_total += $value;
		}


		# Create form fields
		$this->data['fields'] = array();
		$this->data['fields']['cmd'] = '_hosted-payment';
		$this->data['fields']['upload'] = '1';

		$product_total = 0;
		$i = 1;
		//$product_total = $this->currency->format($this->cart->getSubtotal(), $currency, FALSE, FALSE);
		$product_total = $this->cart->getSubtotal();

		if ($discount_total) {
			//$product_total -= $this->currency->format($discount_total, $currency, FALSE, FALSE);
			$product_total -= $discount_total;
		}

		$this->data['fields']['shipping'] = $this->currency->format($shipping_total, $currency, FALSE, FALSE);
		$this->data['fields']['tax'] = $this->currency->format($tax_total, $currency, FALSE, FALSE);

		# Get any remaining balance as a handling fee
		//$remaining_total = $total - $product_total - $tax_total - $shipping_total + $discount_total;
		$remaining_total = $total - $product_total - $tax_total - $shipping_total;
		if ($remaining_total > 0) {
			//$product_total += number_format(abs($this->currency->format($remaining_total, $currency, FALSE, FALSE)), 2, '.', '');
			$product_total += number_format(abs($remaining_total), 2, '.', '');
		}
		//$this->data['fields']['subtotal'] = $product_total;
		$this->data['fields']['subtotal'] = $this->currency->format($product_total, $currency, FALSE, FALSE);

		# Finish the rest of the form
		$this->data['fields']['business'] = $this->config->get($this->name . '_email');
		$this->data['fields']['currency_code'] = $currency;
		$this->data['fields']['showShippingAddress'] = 'true';

		# If no shipping address, just use the billing address
		if (!isset($this->session->data['shipping_address_id']) && !isset($this->session->data['guest']['shipping'])) {

			// Shipping Address uses payment address
			$this->data['fields']['first_name'] = html_entity_decode($this->order_info['payment_firstname'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['last_name'] = html_entity_decode($this->order_info['payment_lastname'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['address1'] = html_entity_decode($this->order_info['payment_address_1'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['address2'] = html_entity_decode($this->order_info['payment_address_2'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['city'] = html_entity_decode($this->order_info['payment_city'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['zip'] = html_entity_decode($this->order_info['payment_postcode'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['country'] = $this->order_info['payment_iso_code_2'];
			if ($this->order_info['payment_iso_code_2'] == 'US') {
				$this->load->model('localisation/zone');
				$zone = $this->model_localisation_zone->getZone($this->order_info['payment_zone_id']);
				if (isset($zone['code'])) {
					$this->data['fields']['state'] = html_entity_decode($zone['code'], ENT_QUOTES, 'UTF-8');
				}
				$phone = preg_replace("/[^0-9.]/", "", html_entity_decode($this->order_info['telephone'], ENT_QUOTES, 'UTF-8'));
				$this->data['fields']['night_phone_a'] = html_entity_decode(substr($phone,0,3), ENT_QUOTES, 'UTF-8');
				$this->data['fields']['night_phone_b'] = html_entity_decode(substr($phone,3,3), ENT_QUOTES, 'UTF-8');
				$this->data['fields']['night_phone_c'] = html_entity_decode(substr($phone,6), ENT_QUOTES, 'UTF-8');
			}

			// Billing Address
			$this->data['fields']['billing_first_name'] = html_entity_decode($this->order_info['payment_firstname'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_last_name'] = html_entity_decode($this->order_info['payment_lastname'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_address1'] = html_entity_decode($this->order_info['payment_address_1'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_address2'] = html_entity_decode($this->order_info['payment_address_2'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_city'] = html_entity_decode($this->order_info['payment_city'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_zip'] = html_entity_decode($this->order_info['payment_postcode'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_country'] = $this->order_info['payment_iso_code_2'];
			if ($this->order_info['payment_iso_code_2'] == 'US') {
				$this->load->model('localisation/zone');
				$zone = $this->model_localisation_zone->getZone($this->order_info['payment_zone_id']);
				if (isset($zone['code'])) {
					$this->data['fields']['billing_state'] = html_entity_decode($zone['code'], ENT_QUOTES, 'UTF-8');
				}
			}
		} else { // if there is a shipping address, separate the two

			// Shipping Address uses shipping address
			$this->data['fields']['first_name'] = html_entity_decode($this->order_info['shipping_firstname'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['last_name'] = html_entity_decode($this->order_info['shipping_lastname'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['address1'] = html_entity_decode($this->order_info['shipping_address_1'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['address2'] = html_entity_decode($this->order_info['shipping_address_2'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['city'] = html_entity_decode($this->order_info['shipping_city'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['zip'] = html_entity_decode($this->order_info['payment_postcode'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['country'] = $this->order_info['payment_iso_code_2'];
			if ($this->order_info['shipping_iso_code_2'] == 'US') {
				$this->load->model('localisation/zone');
				$zone = $this->model_localisation_zone->getZone($this->order_info['shipping_zone_id']);
				if (isset($zone['code'])) {
					$this->data['fields']['state'] = html_entity_decode($zone['code'], ENT_QUOTES, 'UTF-8');
				}
				$phone = preg_replace("/[^0-9.]/", "", html_entity_decode($this->order_info['telephone'], ENT_QUOTES, 'UTF-8'));
				$this->data['fields']['night_phone_a'] = html_entity_decode(substr($phone,0,3), ENT_QUOTES, 'UTF-8');
				$this->data['fields']['night_phone_b'] = html_entity_decode(substr($phone,3,3), ENT_QUOTES, 'UTF-8');
				$this->data['fields']['night_phone_c'] = html_entity_decode(substr($phone,6), ENT_QUOTES, 'UTF-8');
			}

			// Billing Address
			$this->data['fields']['billing_first_name'] = html_entity_decode($this->order_info['payment_firstname'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_last_name'] = html_entity_decode($this->order_info['payment_lastname'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_address1'] = html_entity_decode($this->order_info['payment_address_1'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_address2'] = html_entity_decode($this->order_info['payment_address_2'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_city'] = html_entity_decode($this->order_info['payment_city'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_zip'] = html_entity_decode($this->order_info['payment_postcode'], ENT_QUOTES, 'UTF-8');
			$this->data['fields']['billing_country'] = $this->order_info['payment_iso_code_2'];
			if ($this->order_info['payment_iso_code_2'] == 'US') {
				$this->load->model('localisation/zone');
				$zone = $this->model_localisation_zone->getZone($this->order_info['payment_zone_id']);
				if (isset($zone['code'])) {
					$this->data['fields']['billing_state'] = html_entity_decode($zone['code'], ENT_QUOTES, 'UTF-8');
				}
			}
		}

		$this->data['fields']['email'] = $this->order_info['email'];
		//$this->data['fields']['12306942']['invoice'] = $this->session->data['order_id'] . ' - ' . html_entity_decode($this->order_info['payment_firstname'], ENT_QUOTES, 'UTF-8') . ' ' . html_entity_decode($this->order_info['payment_lastname'], ENT_QUOTES, 'UTF-8');
		$this->data['fields']['12306942']['invoice'] = $this->session->data['order_id'];
		$this->data['fields']['lc'] = $this->session->data['language'];
		//$this->data['fields']['rm'] = '2';
		$this->data['fields']['charset'] = 'utf-8';

		if (!$this->config->get($this->name . '_transaction')) {
			$this->data['fields']['paymentaction'] = 'authorization';
		} else {
			$this->data['fields']['paymentaction'] = 'sale';
		}

		//$this->data['fields']['return'] = HTTPS_SERVER . 'index.php?route=payment/' . $this->name . '/pdt';
		$this->data['fields']['return'] = HTTPS_SERVER . 'index.php?route=checkout/success';
		$this->data['fields']['notify_url'] = HTTP_SERVER . 'index.php?route=payment/' . $this->name . '/callback';

		if (method_exists($this->document, 'addBreadcrumb')) { //1.4.x
			if ($this->request->get['route'] != 'checkout/guest_step_3') {
				$this->data['fields']['cancel_return'] = HTTPS_SERVER . 'index.php?route=checkout/payment';
			} else {
				$this->data['fields']['cancel_return'] = HTTPS_SERVER . 'index.php?route=checkout/guest_step_2';
			}
		} else {
			$this->data['fields']['cancel_return'] = HTTPS_SERVER . 'index.php?route=checkout/checkout';
		}

		$this->load->library('encryption');

		$encryption = new Encryption($this->config->get('config_encryption'));

		$this->data['fields']['custom'] = $encryption->encrypt($this->session->data['order_id']);

		if ($this->request->get['route'] != 'checkout/guest_step_3') {
			$this->data['back'] = HTTPS_SERVER . 'index.php?route=checkout/payment';
		} else {
			$this->data['back'] = HTTPS_SERVER . 'index.php?route=checkout/guest_step_2';
		}

		$this->id = 'payment';

		if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/' . $this->name . '.tpl')) {
			$this->template = $this->config->get('config_template') . '/template/payment/' . $this->name . '.tpl';
		} else {
			$this->template = 'default/template/payment/' . $this->name . '.tpl';
		}

		$this->render();
	}

	public function confirm() {
		$this->name = basename(__FILE__, '.php');
		# If total is 0.00, bypass paypal and force completed checkout
		$this->load->model('checkout/order');
		$order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
		// v14x Backwards Compatibility
		if (isset($order_info['currency_code'])) { $order_info['currency'] = $order_info['currency_code']; }
		if (isset($order_info['currency_value'])) { $order_info['value'] = $order_info['currency_value']; }
		if (!(float)$order_info['total']) {
			$this->load->model('checkout/order');
			$this->model_checkout_order->confirm($this->session->data['order_id'], $this->config->get($this->name . '_order_status_id'));
			$this->redirect(HTTPS_SERVER . 'index.php?route=checkout/success');
		}

		# If using ajax pre-confirm, set the order to "pending" before payment is made.
		# Only use when IPN and PDT are both failing.
		# Not meant to be a solution, but a temporary workaround
		if ($this->config->get($this->name . '_ajax')) {
			$this->load->model('checkout/order');
			$this->model_checkout_order->confirm($this->session->data['order_id'], $this->config->get('config_order_status_id'));
		}
	}

	public function fail($msg) {
		echo '<html><head><script type="text/javascript">';
		echo 'alert("'.$msg.'");';
		echo 'window.location="' . (HTTPS_SERVER  . 'index.php?route=checkout/checkout') . '";';
		echo '</script></head></html>';
	}

	public function callback() {
		$this->name = basename(__FILE__, '.php');
		if (isset($this->request->post)) {
        	$p_msg = "DEBUG POST VARS::"; foreach($this->request->post as $k=>$v) { $p_msg .= $k."=".$v."&"; }
		}
		if (isset($this->request->get)) {
        	$g_msg = "DEBUG GET VARS::"; foreach($this->request->get as $k=>$v) { $g_msg .= $k."=".$v."&"; }
		}

		if ($this->config->get($this->name . '_debug')) {
			$this->log->write("PP_HOSTED :: IPN INIT <-- $p_msg");
		}

		if (isset($this->request->post['memo'])) {
			$memo = $this->request->post['memo'];
		} else {
			$memo = '';
		}

		$this->data = array_merge($this->data, $this->load->language('payment/' . $this->name));

		$this->load->library('encryption');

		$encryption = new Encryption($this->config->get('config_encryption'));

		if (isset($this->request->post['custom'])) {
			$order_id = $encryption->decrypt($this->request->post['custom']);
		} else {
			$order_id = 0;
		}

		$this->load->model('checkout/order');

		$this->order_info = $this->model_checkout_order->getOrder($order_id);

		if ($this->order_info) {

			/*
			$request = 'cmd=_notify-validate';

			$get_magic_quotes_exists = false;
	        if (function_exists('get_magic_quotes_gpc')) {
	            $get_magic_quotes_exists = true;
	        }

			foreach ($this->request->post as $key => $value) {
				if ($get_magic_quotes_exists && get_magic_quotes_gpc() == 1) {
					//$request .= '&' . $key . '=' . urlencode(stripslashes($value));
					$request .= '&' . $key . '=' . urlencode($value);
				} else {
					//$request .= '&' . $key . '=' . urlencode(stripslashes($value));
					$request .= '&' . $key . '=' . urlencode($value);
					//$request .= '&' . $key . '=' . html_entity_decode(urlencode($value));
				}
			}

			if (!$this->config->get($this->name . '_test')) {
				$ch = curl_init('https://securepayments.paypal.com/acquiringweb?cmd=_hosted-payment');
			} else {
				$ch = curl_init('https://securepayments.sandbox.paypal.com/acquiringweb');
			}

			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded", "Content-Length: " . strlen($request)));
			curl_setopt($ch, CURLOPT_HEADER, false);
			curl_setopt($ch, CURLOPT_VERBOSE, 1);
			curl_setopt($ch, CURLOPT_TIMEOUT, 30);
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

			$response = curl_exec($ch);

			curl_close($ch);

			if ($this->config->get($this->name . '_debug')) {
				$this->log->write("PP_HOSTED :: IPN REQ  --> $request");
				$this->log->write("PP_HOSTED :: IPN RESP <-- $response");
			}

			if (!$this->validate($this->request->post)) {
				if ($this->order_info['order_status_id'] == '0') {
					$this->model_checkout_order->confirm($order_id, $this->config->get($this->name . '_order_status_id_pending'), $memo . "\r\n\r\n" . $this->error);
				} elseif ($this->order_info['order_status_id'] != $this->config->get($this->name . '_order_status_id')) {
					$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id_pending'),  $this->error, FALSE);
				}
				mail($this->config->get('config_email'), sprintf($this->language->get('text_attn_email'), $order_id), $this->error . "\r\n\r\n" . str_replace("&", "\n", $p_msg));
			}

			$verified = false;
			if (strcmp($response, 'VERIFIED') == 0) {
				$verified = true;
			}
			*/
			$verified = true;
			$this->checkPaymentStatus($this->request->post, $verified);
		}
	}

	private function checkPaymentStatus($data, $verified) {

		if (isset($this->request->post)) {
        	$p_msg = "DEBUG POST VARS::"; foreach($this->request->post as $k=>$v) { $p_msg .= $k."=".$v."&"; }
		}
		if (isset($this->request->get)) {
        	$g_msg = "DEBUG GET VARS::"; foreach($this->request->get as $k=>$v) { $g_msg .= $k."=".$v."&"; }
		}

		if (isset($this->order_info['order_id'])) {
			$order_id = $this->order_info['order_id'];
		} else {
			$order_id = 0;
		}

		//$updateComment = $data['reason_code'];
		$updateComment = '';

		switch($data['payment_status']){
			case 'Completed':
				if ($verified) {
					if ($this->order_info['order_status_id'] == '0') {
						$this->model_checkout_order->confirm($order_id, $this->config->get($this->name . '_order_status_id'), $data['payment_status']);
					} elseif (isset($data['payment_type']) && $data['payment_type'] == 'echeck') {
						$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id'), $data['payment_status'], TRUE);
					} elseif ($this->order_info['order_status_id'] != $this->config->get($this->name . '_order_status_id')) {
						$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id'), $data['payment_status'], FALSE);
					}
				} else {
					if ($this->order_info['order_status_id'] == '0') {
						$this->model_checkout_order->confirm($order_id, $this->config->get($this->name . '_order_status_id_pending'), $data['payment_status']);
					} elseif ($this->order_info['order_status_id'] != $this->config->get($this->name . '_order_status_id')) {
						$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id_pending'), $data['payment_status'], FALSE);
					}
					if (!isset($data['payment_type']) || (isset($data['payment_type']) && $data['payment_type'] != 'echeck')) {
						mail($this->config->get('config_email'), sprintf($this->language->get('text_attn_email'), $order_id), ($this->language->get('error_verify') . "\r\n\r\n" . $p_msg . "\r\n\r\n" . $g_msg));
					}
				}
				break;
			case 'Canceled_Reversal':
				if ($this->order_info['order_status_id'] == '0') {
					$this->model_checkout_order->confirm($order_id, $this->config->get($this->name . '_order_status_id_canceled_reversal'), $updateComment);
				} else {
					$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id_canceled_reversal'), $updateComment, FALSE);
				}
				break;
			case 'Denied':
				if ($this->order_info['order_status_id'] == '0') {
					$this->model_checkout_order->confirm($order_id, $this->config->get($this->name . '_order_status_id_denied'), $updateComment);
				} else {
					$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id_denied'), $updateComment, FALSE);
				}
				break;
			case 'Failed':
				if ($this->order_info['order_status_id'] == '0') {
					$this->model_checkout_order->confirm($order_id, $this->config->get($this->name . '_order_status_id_failed'), $updateComment);
				} else {
					$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id_failed'), $updateComment, FALSE);
				}
				break;
			case 'Pending':
				if ($this->order_info['order_status_id'] == '0') {
					$this->model_checkout_order->confirm($order_id, $this->config->get($this->name . '_order_status_id_pending'), $data['pending_reason']);
				} else {
					$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id_pending'), $data['pending_reason'], TRUE);
				}
				break;
			case 'Refunded':
				if ($this->order_info['order_status_id'] == '0') {
					$this->model_checkout_order->confirm($order_id, $this->config->get($this->name . '_order_status_id_refunded'), $updateComment);
				} else {
					$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id_refunded'), $updateComment, FALSE);
				}
				break;
			case 'Reversed':
				if ($this->order_info['order_status_id'] == '0') {
					$this->model_checkout_order->confirm($order_id, $this->config->get($this->name . '_order_status_id_reversed'), $updateComment);
				} else {
					$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id_reversed'), $updateComment, FALSE);
				}
				break;
			default:
				if ($this->order_info['order_status_id'] == '0') {
					$this->model_checkout_order->confirm($order_id, $this->config->get($this->name . '_order_status_id_unspecified'), $updateComment);
				} else {
					$this->model_checkout_order->update($order_id, $this->config->get($this->name . '_order_status_id_unspecified'), $updateComment, FALSE);
				}
				break;
		}

		if ($data['payment_status'] != 'Completed') {
			if (!isset($data['payment_type']) || (isset($data['payment_type']) && $data['payment_type'] == 'echeck')) {
				mail($this->config->get('config_email'), sprintf($this->language->get('text_attn_email'), $order_id), ($this->language->get('error_non_complete') . "\r\n\r\n" . $p_msg . "\r\n\r\n" . $g_msg));
			}
		}

		$this->redirect(HTTPS_SERVER . 'index.php?route=checkout/success');
	}

	private function file_get_contents_curl($url) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_HEADER, 0);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //Set curl to return the data instead of printing it to the browser.
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);

		$data = curl_exec($ch);

		curl_close($ch);

		return $data;
	}

	private function validate($data = array()) {
		$this->data = array_merge($this->data, $this->load->language('payment/' . $this->name));

		// verify there was some response
		if (empty($data)) {
			$this->error = $this->language->get('error_no_data');
		}

		// verify totals match
		if (isset($data['cc'])) { // PDT
			$currency = $data['cc'];
		} elseif (isset($data['mc_currency'])) { // IPN
			$currency = $data['mc_currency'];
		} else { // Default
			$currency = $this->order_info['currency'];
		}

		if (isset($data['payment_gross']) && $data['payment_gross']) {
			$amount = $data['payment_gross'];
		} elseif (isset($data['mc_gross']) && $data['mc_gross']) {
			$amount = $data['mc_gross'];
		}

        if (isset($data['payment_status']) && $data['payment_status'] != 'Refunded' && ((float)floor($amount) != (float)floor($this->currency->format($this->order_info['total'], $currency, False, False)))) {
			$this->error = sprintf($this->language->get('error_amount_mismatch'), $amount, $this->order_info['total']);
		}

    	if (!$this->error) {
			return TRUE;
    	} else {
    		$this->log->write("PP_HOSTED :: VALIDATION FAILED : $this->error");
      		return FALSE;
    	}
	}

}
?>