Location: PHPKode > projects > HikaShop > back/extensions/plg_hikashoppayment_paypal/paypal.php
<?php
/**
 * @package		HikaShop for Joomla!
 * @version		1.4.3
 * @author		hikashop.com
 * @copyright	(C) 2010 HIKARI SOFTWARE. All rights reserved.
 * @license		GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
 */
defined('_JEXEC') or die('Restricted access');
?>
<?php
class plgHikashoppaymentPaypal extends JPlugin
{
	var $accepted_currencies = array(
		'AUD','CAD','EUR','GBP','JPY','USD','NZD','CHF','HKD','SGD',
		'SEK','DKK','PLN','NOK','HUF','CZK','MXN','BRL','MYR','PHP',
		'TWD','THB','ILS'
	);
    var $debugData = array();
    function onPaymentDisplay(&$order,&$methods,&$usable_methods){
    	if(!empty($methods)){
    		foreach($methods as $method){
				if($method->payment_type!='paypal'){
					continue;
				}
				if(!empty($method->payment_zone_namekey)){
					$zoneClass=hikashop::get('class.zone');
	    			$zones = $zoneClass->getOrderZones($order);
					if(!in_array($method->payment_zone_namekey,$zones)){
						return true;
					}
				}
				$currencyClass = hikashop::get('class.currency');
				$null=null;
				if(!empty($order->total)){
					$currency_id = intval(@$order->total->prices[0]->price_currency_id);
					$currency = $currencyClass->getCurrencies($currency_id,$null);
					if(!empty($currency) && !in_array(@$currency[$currency_id]->currency_code,$this->accepted_currencies)){
						return true;
					}
				}
				$usable_methods[$method->ordering]=$method;
    		}
    	}
    	return true;
    }
    function onPaymentSave(&$cart,&$rates,&$payment_id){
    	$usable = array();
    	$this->onPaymentDisplay($cart,$rates,$usable); 
    	$payment_id = (int) $payment_id;
    	foreach($usable as $usable_method){
    		if($usable_method->payment_id==$payment_id){
    			return $usable_method;
    		}
    	}
    	return false;
    }
    function onAfterOrderConfirm(&$order,&$methods,$method_id){
    	$method =& $methods[$method_id];
		$tax_total = '';
		$discount_total = '';
		$currencyClass = hikashop::get('class.currency');
		$currencies=null;
		$currencies = $currencyClass->getCurrencies($order->order_currency_id,$currencies);
		$currency=$currencies[$order->order_currency_id];
		$user = hikashop::loadUser(true);
		$lang = &JFactory::getLanguage();
		$locale=strtolower(substr($lang->get('tag'),0,2));
		$notify_url = HIKASHOP_LIVE.'index.php?option=com_hikashop&ctrl=checkout&task=notify&notif_payment=paypal&tmpl=component&lang='.$locale;
		if(empty($method->payment_params->return_url)){
			$return_url =  HIKASHOP_LIVE.'index.php?option=com_hikashop&ctrl=checkout&task=after_end&order_id='.$order->order_id;
		}else{
			$return_url = $method->payment_params->return_url;
		}
		$cancel_url = HIKASHOP_LIVE.'index.php?option=com_hikashop&ctrl=order&task=cancel_order&order_id='.$order->order_id;
		$debug = $method->payment_params->debug;
		$vars = Array(
		"cmd" => "_ext-enter",
		"redirect_cmd" => "_cart",
		"upload" => "1",
		"business" => $method->payment_params->email,
		"receiver_email" => $method->payment_params->email,
		"invoice" => $order->order_id,
		"currency_code" => $currency->currency_code,
		"return" => $return_url,
		"notify_url" => $notify_url,
		"cancel_return" => $cancel_url,
		"undefined_quantity" => "0",
		"test_ipn" => $debug,
		"no_shipping" => "1",
		"no_note" => "1",
		"charset" => "utf-8"
		);
		if(!empty($method->payment_params->address_type)){
			$address_type = $method->payment_params->address_type.'_address';
			$app =& JFactory::getApplication();
			$address=$app->getUserState( HIKASHOP_COMPONENT.'.'.$address_type);
			if(!empty($address)){
				$vars["address_override"]='1';
				$cart = hikashop::get('class.cart');
				$cart->loadAddress($order->cart,$address,'object',$method->payment_params->address_type);
				$vars["first_name"]=@$order->cart->$address_type->address_firstname;
				$vars["last_name"]=@$order->cart->$address_type->address_lastname;
				$address1 = '';
				$address2 = '';
				if(!empty($order->cart->$address_type->address_street)){
					if(strlen($order->cart->$address_type->address_street)>100){
						$address1 = substr($order->cart->$address_type->address_street,0,99);
						$address2 = substr($order->cart->$address_type->address_street,99,199);
					}else{
						$address1 = $order->cart->$address_type->address_street;
					}
				}
				$vars["address1"]=$address1;
				$vars["address2"]=$address2;
				$vars["zip"]=@$order->cart->$address_type->address_post_code;
				$vars["city"]=@$order->cart->$address_type->address_city;
				$vars["state"]=@$order->cart->$address_type->address_state->zone_code_2;
				$vars["country"]=@$order->cart->$address_type->address_country->zone_code_2;
				$vars["email"]=$user->user_email;
				$vars["night_phone_b"]=@$order->cart->$address_type->address_telephone;
			}
		}
		if(!empty($method->payment_params->cpp_header_image)){
			$vars['cpp_header_image']=$method->payment_params->cpp_header_image;
		}
		$i = 1;
		$tax = 0;
		foreach($order->cart->products as $product){
			$vars["item_name_".$i]=substr($product->order_product_name,0,127);
			$vars["item_number_".$i]=$product->order_product_code;
			$vars["amount_".$i]=round($product->order_product_price,(int)$currency->currency_locale['int_frac_digits']);
			$vars["quantity_".$i]=$product->order_product_quantity;
			$tax+=round($product->order_product_tax,(int)$currency->currency_locale['int_frac_digits'])*$product->order_product_quantity;
			$i++;
		}
		if(bccomp($tax,0,5)){
			$vars['tax_cart']=$tax;
		}
		if(!empty($order->order_shipping_price)){
			$vars["item_name_".$i]=JText::_('HIKASHOP_SHIPPING');
			$vars["amount_".$i]=round($order->order_shipping_price,(int)$currency->currency_locale['int_frac_digits']);
			$vars["quantity_".$i]=1;
			$i++;
		}
		if(!empty($order->cart->coupon)){
			$vars["discount_amount_cart"]=round($order->cart->coupon->discount_value,(int)$currency->currency_locale['int_frac_digits']);
		}

		JHTML::_('behavior.mootools');
		$app =& JFactory::getApplication();
		$name = $method->payment_type.'_end.php';
    	$path = JPATH_THEMES.DS.$app->getTemplate().DS.'hikashoppayment'.DS.$name;
    	if(!file_exists($path)){
    		if(version_compare(JVERSION,'1.6','<')){
    			$path = JPATH_PLUGINS .DS.'hikashoppayment'.DS.$name;
    		}else{
    			$path = JPATH_PLUGINS .DS.'hikashoppayment'.DS.$method->payment_type.DS.$name;
    		}
    		if(!file_exists($path)){
    			return true;
    		}
    	}
    	require($path);
    	return true;
    }
    function onPaymentNotification(&$statuses){
    	$pluginsClass = hikashop::get('class.plugins');
		$elements = $pluginsClass->getMethods('payment','paypal');
		if(empty($elements)) return false;
		$element = reset($elements);
		if(!$element->payment_params->notification){
			return false;
		}
    	$vars = array();
    	$data = array();
    	$filter = & JFilterInput::getInstance();
    	foreach($_POST as $key => $value){
    		$key = $filter->clean($key);
    		if(preg_match("#^[0-9a-z_-]{1,30}$#i",$key)&&!preg_match("#^cmd$#i",$key)){
    			$value = JRequest::getString($key);
	    		$vars[$key]=$value;
	    		$data[]=$key.'='.urlencode($value);
    		}
    	}
    	$data = implode('&',$data).'&cmd=_notify-validate';
		if($element->payment_params->debug){
			echo print_r($vars,true)."\n\n\n";
		}    	
		$orderClass = hikashop::get('class.order');
		$dbOrder = $orderClass->get((int)@$vars['invoice']);
		if(empty($dbOrder)){
			echo "Could not load any order for your notification ".@$vars['invoice'];
			return false;
		}
		$order = null;
		$order->order_id = $dbOrder->order_id;
		$order->old_status->order_status=$dbOrder->order_status;
		$url = HIKASHOP_LIVE.'administrator/index.php?option=com_hikashop&ctrl=order&task=edit&order_id='.$order->order_id;
		$order_text = "\r\n".JText::sprintf('NOTIFICATION_OF_ORDER_ON_WEBSITE',hikashop::encode($dbOrder),HIKASHOP_LIVE);
		$order_text .= "\r\n".str_replace('<br/>',"\r\n",JText::sprintf('ACCESS_ORDER_WITH_LINK',$url));
		if($element->payment_params->debug){
			echo print_r($dbOrder,true)."\n\n\n";
		}    
		$mailer =& JFactory::getMailer();
		$config =& hikashop::config();
		$sender = array( 
		    $config->get('from_email'),
		    $config->get('from_name') );
		$mailer->setSender($sender);
		$mailer->addRecipient(explode(',',$config->get('payment_notification_email')));
    	if(!empty($element->payment_params->ips)){
    		$ip = hikashop::getIP();
    		$ips = str_replace(array('.','*',','),array('\.','[0-9]+','|'),$element->payment_params->ips);
    		if(!preg_match('#('.implode('|',$ips).')#',$ip)){
				$mailer->setSubject(JText::sprintf('NOTIFICATION_REFUSED_FOR_THE_ORDER','Paypal').' '.JText::sprintf('IP_NOT_VALID',hikashop::encode($dbOrder)));
				$body = str_replace('<br/>',"\r\n",JText::sprintf('NOTIFICATION_REFUSED_FROM_IP','Paypal',$ip,implode("\r\n",$element->payment_params->ips)))."\r\n\r\n".JText::sprintf('CHECK_DOCUMENTATION',HIKASHOP_HELPURL.'payment-paypal-error#ip').$order_text;
				$mailer->setBody($body);
				$mailer->Send();
	    		JError::raiseError( 403, JText::_( 'Access Forbidden' ));
	    		return false;
    		}
    	}
    	$url = parse_url($element->payment_params->url);
    	if(!isset($url['query'])){
			$url['query'] = '';
    	}
    	if(!isset($url['port'])){
    		if(!empty($url['scheme'])&&in_array($url['scheme'],array('https','ssl'))){
    			$url['port'] = 443;
    		}else{
				$url['port'] = 80;
    		}
    	}
    	if(!empty($url['scheme'])&&in_array($url['scheme'],array('https','ssl'))){
    		$url['host_socket'] = 'ssl://'.$url['host'];
    	}else{
    		$url['host_socket'] = $url['host'];
    	}
    	if($element->payment_params->debug){
			echo print_r($url,true)."\n\n\n";
		} 
	    $fp = fsockopen ( $url['host_socket'], $url['port'], $errno, $errstr, 30);
	    if (!$fp) {
			$mailer->setSubject(JText::sprintf('NOTIFICATION_REFUSED_FOR_THE_ORDER','Paypal').' '.JText::sprintf('PAYPAL_CONNECTION_FAILED',hikashop::encode($dbOrder)));
			$body = str_replace('<br/>',"\r\n",JText::sprintf('NOTIFICATION_REFUSED_NO_CONNECTION','Paypal'))."\r\n\r\n".JText::sprintf('CHECK_DOCUMENTATION',HIKASHOP_HELPURL.'payment-paypal-error#connection').$order_text;
			$mailer->setBody($body);
			$mailer->Send();
    		JError::raiseError( 403, JText::_( 'Access Forbidden' ));
    		return false;
	    }
	    $uri = $url['path'].($url['query']!='' ? '?' . $url['query'] : '');
    	$header = "POST $uri HTTP/1.0\r\n".
    	"User-Agent: PHP/".phpversion()."\r\n".
	    "Referer: ".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].@$_SERVER['QUERY_STRING']."\r\n".
	    "Server: ".$_SERVER['SERVER_SOFTWARE']."\r\n".
	    "Host: ".$url['host'].":".$url['port']."\r\n".
	    "Content-Type: application/x-www-form-urlencoded\r\n".
	    "Content-Length: ".strlen($data)."\r\n".
	    "Accept: */"."*\r\n\r\n";
	    fwrite($fp, $header . $data);
		$response = '';
		while (!feof($fp)) {
			$response .= fgets ($fp, 1024);
		}
		fclose ($fp);
		if($element->payment_params->debug){
			echo print_r($header,true)."\n\n\n";
			echo print_r($data,true)."\n\n\n";
			echo print_r($response,true)."\n\n\n";
		} 
		$response = substr($response, strpos($response, "\r\n\r\n") + strlen("\r\n\r\n"));
		$verified = preg_match( "#VERIFIED#i", $response);
		if(!$verified){
			if(preg_match("#INVALID#i", $response)){
				$mailer->setSubject(JText::sprintf('NOTIFICATION_REFUSED_FOR_THE_ORDER','Paypal').'invalid transaction');
				$body = JText::sprintf("Hello,\r\n A paypal notification was refused because it could not be verified by the paypal server")."\r\n\r\n".JText::sprintf('CHECK_DOCUMENTATION',HIKASHOP_HELPURL.'payment-paypal-error#invalidtnx').$order_text;
				$mailer->setBody($body);
				$mailer->Send();
				if($element->payment_params->debug){
					echo 'invalid transaction'."\n\n\n";
				} 
			}else{
				$mailer->setSubject(JText::sprintf('NOTIFICATION_REFUSED_FOR_THE_ORDER','Paypal').'invalid response');
				$body = JText::sprintf("Hello,\r\n A paypal notification was refused because the response from the paypal server was invalid")."\r\n\r\n".JText::sprintf('CHECK_DOCUMENTATION',HIKASHOP_HELPURL.'payment-paypal-error#invalidresponse').$order_text;
				$mailer->setBody($body);
				$mailer->Send();
				if($element->payment_params->debug){
					echo 'invalid response'."\n\n\n";
				} 
			}
			return false;
		}
		$completed = preg_match("#Completed#i", $vars['payment_status']);
		$pending = preg_match("#Pending#i", $vars['payment_status']);
		 if (!$completed && !$pending) {
			$body = str_replace('<br/>',"\r\n",JText::sprintf('PAYMENT_NOTIFICATION_STATUS','Paypal',$vars['payment_status'])).' '.JText::_('STATUS_NOT_CHANGED')."\r\n\r\n".JText::sprintf('CHECK_DOCUMENTATION',HIKASHOP_HELPURL.'payment-paypal-error#status').$order_text;
		 	$mailer->setSubject(JText::sprintf('PAYMENT_NOTIFICATION','Paypal',$vars['payment_status']));
			$mailer->setBody($body);
			$mailer->Send();
			if($element->payment_params->debug){
				echo 'payment '.$vars['payment_status']."\n\n\n";
			} 
			return false;
		 }
		$order->history->history_reason=JText::sprintf('AUTOMATIC_PAYMENT_NOTIFICATION');
		$order->history->history_notified=0;
		$order->history->history_amount=@$vars['mc_gross'].@$vars['mc_currency'];
		$order->history->history_payment_id = $element->payment_id;
		$order->history->history_payment_method =$element->payment_type;
		$order->history->history_data = ob_get_clean();
		$order->history->history_type = 'payment';
	 	$currencyClass = hikashop::get('class.currency');
		$currencies=null;
		$currencies = $currencyClass->getCurrencies($dbOrder->order_currency_id,$currencies);
		$currency=$currencies[$dbOrder->order_currency_id];
	 	$price_check = round($dbOrder->order_full_price, (int)$currency->currency_locale['int_frac_digits'] );
	 	if($price_check != @$vars['mc_gross'] || $currency->currency_code != @$vars['mc_currency']){
	 		$order->order_status = $element->payment_params->invalid_status;
	 		$orderClass->save($order);
	 		$mailer->setSubject(JText::sprintf('NOTIFICATION_REFUSED_FOR_THE_ORDER','Paypal').JText::_('INVALID_AMOUNT').$order_subject);
			$body = str_replace('<br/>',"\r\n",JText::sprintf('AMOUNT_RECEIVED_DIFFERENT_FROM_ORDER','Paypal',$order->history->history_amount,$price_check.$currency->currency_code))."\r\n\r\n".JText::sprintf('CHECK_DOCUMENTATION',HIKASHOP_HELPURL.'payment-paypal-error#amount').$order_text;
			$mailer->setBody($body);
			$mailer->Send();
	 		return false;
	 	}
	 	if($completed){
	 		$order->order_status = $element->payment_params->verified_status;
	 		$order->history->history_notified=1;
	 	}else{
	 		$order->order_status = $element->payment_params->pending_status;
	 		$order_text = JText::sprintf('CHECK_DOCUMENTATION',HIKASHOP_HELPURL.'payment-paypal-error#pending')."\r\n\r\n".$order_text;
	 	}
	 	$order->mail_status=$statuses[$order->order_status];
	 	$mailer->setSubject(JText::sprintf('PAYMENT_NOTIFICATION','Paypal',$vars['payment_status']).$order_subject);
		$body = str_replace('<br/>',"\r\n",JText::sprintf('PAYMENT_NOTIFICATION_STATUS','Paypal',$vars['payment_status'])).' '.JText::sprintf('ORDER_STATUS_CHANGED',$order->mail_status)."\r\n\r\n".$order_text;
		$mailer->setBody($body);
		$mailer->Send();
	 	$orderClass->save($order);
    	return true;
    }
    function onPaymentConfiguration(&$element){
    	$subtask = JRequest::getCmd('subtask','');  
    	if($subtask=='ips'){
    		$ips = null;
			echo implode(',',$this->_getIPList($ips));
			exit;
    	}else{
    		$this->paypal = JRequest::getCmd('name','paypal');  
			if(empty($element)){
				$element = null;
    			$element->payment_name='PayPal';
    			$element->payment_description='You can pay by credit card or paypal using this payment method';
    			$element->payment_images='MasterCard,VISA,Credit_card,American_Express,PayPal';
    			$element->payment_type=$this->paypal;
    			$element->payment_params=null;
    			$element->payment_params->url='https://www.paypal.com/cgi-bin/webscr';
    			$element->payment_params->notification=1;
    			$list=null;
    			$element->payment_params->ips=$this->_getIPList($list);
    			$element->payment_params->invalid_status='cancelled';
    			$element->payment_params->pending_status='created';
    			$element->payment_params->verified_status='confirmed';
    			$element = array($element);
    		}
	    	$bar = & JToolBar::getInstance('toolbar');
			JToolBarHelper::save();
			JToolBarHelper::apply();
			JToolBarHelper::cancel();
			JToolBarHelper::divider();
			$bar->appendButton( 'Pophelp','payment-paypal-form');
			hikashop::setTitle('Paypal','plugin','plugins&plugin_type=payment&task=edit&name='.$this->paypal);
			$app =& JFactory::getApplication();
			$app->setUserState( HIKASHOP_COMPONENT.'.payment_plugin_type', $this->paypal);
			$this->address = hikashop::get('type.address');
			$this->category = hikashop::get('type.categorysub');
			$this->category->type = 'status';
    	}
    }
    function onPaymentConfigurationSave(&$element){
    	if(!empty($element->payment_params->ips)){
    		$element->payment_params->ips=explode(',',$element->payment_params->ips);
    	}
		return true;
    }
    function _getIPList(&$ipList){
    	$ipList = array_merge(gethostbynamel('www.paypal.com'),gethostbynamel('notify.paypal.com'),gethostbynamel('ipn.sandbox.paypal.com'));
    	if(!empty($ipList)){
    		$newList = array();
	    	foreach($ipList as $k => $ip){
	    		$ipParts = explode('.',$ip);
	    		if(count($ipParts)==4){
	    			array_pop($ipParts);
	    			$ip = implode('.',$ipParts).'.*';
	    		}
	    		if(!in_array($ip,$newList)){
	    			$newList[]=$ip;
	    		}
	    	}
	    	$ipList = $newList;
    	}
    	return $ipList;
    }
}
Return current item: HikaShop