<?php
/***************************************************************************
*                                                                          *
* Copyright (c) 2005 ISPG Technologies (I) Pvt Ltd. All rights reserved.   *
*                                                                          *
* This  is  commercial  software,  only  users  who have purchased a valid *
* license  and  accept  to the terms of the  License Agreement can install *
* and use this program.                                                    *
*                                                                          *
****************************************************************************
* PLEASE READ THE FULL TEXT  OF THE SOFTWARE  LICENSE   AGREEMENT  IN  THE *
* "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE.            *
****************************************************************************/	//
	//$Id: MonerisModel.php, v 1.0 2011/06/14 20:52:11
	//
class MonerisModel extends PaymentModel
 { 
	public function process($order='',$orderItems='') 
	{
			$ObjCurrency		= new CurrencyModel();
			$ObjCountry     	= new CountryModel();
			$ObjState       	= new StateModel();
			parent::listPaymentSettingsValues($order['paymentSettingsGroupID']);	
			$payAmount				=	$order['orderTotalAmount'];
			$taxAmount				=	$order["orderTaxAmount"];
			$shippingAmount			=	$order["shippingAmount"];
			$supportedCurrencyID	= $order["purchasedCurrency"];
			
			$paymentCurrency 		= 	$this->settingsVars["payment_currency"];
			if ($paymentCurrency != '')
        	{
            	$paymentCurrency = str_replace(", ", ",", $paymentCurrency);
            	$currencyArr     = explode(",", $paymentCurrency);
        	}
			if(count($currencyArr)<1)
			{
				$this->isError 		= true;
				$this->errorMessage	= "Currency not configured , Please contact the site admin";
				return false;
			}
			else
			{
				$currencyFlag = false;
				$purchasedCurrencyDetails = $ObjCurrency->getCurrencyByCurrencyID($order["purchasedCurrency"]);
				$systemCurrencies 		=	$ObjCurrency->listCurrencyCodes();
				if(!in_array($purchasedCurrencyDetails['currencyCode'],$currencyArr))
				{
					foreach ($systemCurrencies as $key => $currency)
        			{
						if(in_array($currency['currencyCode'],$currencyArr))
						{
							$currencyFlag = true;
							$supportedCurrencyCode 	= $currency['currencyCode'];	
							$supportedCurrencyID 	= $currency['currencyID'];
							break;
						}
					}
					if($currencyFlag==true)
					{
						$payAmount = $ObjCurrency->convertValueCustom($payAmount,$order["purchasedCurrency"],$supportedCurrencyID);
						$taxAmount = $ObjCurrency->convertValueCustom($taxAmount,$order["purchasedCurrency"],$supportedCurrencyID);
						$shippingAmount = $ObjCurrency->convertValueCustom($shippingAmount,$order["purchasedCurrency"],
						$supportedCurrencyID);
						
					}
					else
					{
						$this->isError 		= true;
						$this->errorMessage	= "Currency not configured , Please contact the site admin";
						return false;
					}
					
				}
			}
			
			$taxAmount=number_format($taxAmount, 2, '.', '');
			
			$store_id 				= 	$this->settingsVars["payment_store_id"];
			$api_token 				= 	$this->settingsVars["payment_api_token"];
			$orderid 				= 	'ORDER-'.$order["masterOrderID"]*$order["masterOrderID"].'-'.rand(1000,10000);
			$amount 				= 	number_format($payAmount, 2, '.', '');
			$pan 					= 	$order['postData']["creditCardNumber"];
			$expirydate 			= 	substr($order['postData']["expYear"],2,2).$order['postData']["expMonth"];
			$crypttype 				= 	'7';
			$customerid 			=   $order["userID"];
			if($order['authValue']=='Authorization') 
			{
				$authOnly			=	'AUTH_ONLY';
				$monerisType 		=	'preauth';
			} 
			else 
			{				
				$authOnly			=	'AUTH_CAPTURE';	
				$monerisType 		=	'purchase';	
			}
			$mpgCustInfo = new mpgCustInfo();
			$email					=	$order['billingAddress']['billingEmail'];
			$mpgCustInfo->setEmail($email);
			$instructions 			=	"";
			$mpgCustInfo->setInstructions($instructions);	
			$address       			= $order['billingAddress']['billingAddress1'];
        	$address      		   .= ($order['billingAddress']['billingAddress2']!='') ? ', '.$order['billingAddress']['billingAddress2'] : '';
			
			$languageIDs['Current']=1;
			$country 		= $ObjCountry->getCountryDetails($order['billingAddress']['billingCountry'],$languageIDs);
			$countryName 	= $country['countryName'];
			if ($order['billingAddress']['billingState'] >0)
			{
				$getStateDetails = $ObjState->getStateDetails($languageIDs,$order['billingAddress']['billingState']);
				$stateName       = $getStateDetails['stateShortName'];
			}
			else
			{
				$stateName = $order['billingAddress']['billingProvince'];
			}
			
			$billing 				= array
											(
											'first_name' => $order['billingAddress']['billingFirstName'],
							   				'last_name' => $order['billingAddress']['billingLastName'],
							  				'company_name' => $order['siteDesc'],
							   				'address' => $address,
                              				'city' => $order['billingAddress']['billingCity'],
											'province' => $stateName,
											'postal_code' => $order['billingAddress']["billingZip"],
											'country' => $countryName,
											'phone_number' => $order['billingAddress']['billingPhone'],
											'fax' => '',
											'tax1' => $taxAmount,
											'tax2' => '',
											'tax3' => '',
											'shipping_cost' => $shippingAmount
											);
																		
											
			$mpgCustInfo->setBilling($billing);
			if(isset($order['shippingAddress']['shippingCountryID']) && $order['shippingAddress']['shippingCountryID']>0)
			{
				$shippingAddress       			= $order['shippingAddress']['shippingAddress1'];
				$shippingAddress      		   .= ($order['shippingAddress']['shippingAddress2']!='') ? ', '.$order['shippingAddress']['shippingAddress2'] : '';
				
				$country 		= $ObjCountry->getCountryDetails($order['shippingAddress']['shippingCountryID'],$languageIDs);
				$countryName 	= $country['countryName'];
				if ($order['shippingAddress']['shippingStateID'] >0)
				{
					$getStateDetails = $ObjState->getStateDetails($languageIDs,$order['shippingAddress']['shippingStateID']);
					$stateName       = $getStateDetails['stateShortName'];
				}
				else
				{
					$stateName = $order['shippingAddress']['shippingProvince'];
				}
				
				$shipping 				= array
												(
												'first_name' => $order['shippingAddress']['shippingFname'],
												'last_name' => $order['shippingAddress']['shippingLname'],
												'company_name' => $order['siteDesc'],
												'address' => $shippingAddress,
												'city' => $order['shippingAddress']['shippingCity'],
												'province' => $stateName,
												'postal_code' => $order['shippingAddress']["shippingZip"],
												'country' => $countryName,
												'phone_number' => '',
												'fax' => '',
												'tax1' => '',
												'tax2' => '',
												'tax3' => '',
												'shipping_cost' => $shippingAmount
												);
				$mpgCustInfo->setShipping($shipping);
			}
			if (!empty($orderItems))
			{
				foreach ($orderItems as $key => $ordItem)
				{
					$orderGiveAsGift = '';					
					
					if (isset($ordItem['orderGiveAsGift']) && $ordItem['orderGiveAsGift'] == 'Yes')
					{
						$orderGiveAsGift = ' (As Gift)';
					}
					$fldName = ($order['orderType'] == 'product') ? 'productOptionName' : 'itemName';
					if($currencyFlag==true)
					{
						$orderItemPrice = $ObjCurrency->convertValueCustom($orderItems[$key]['orderItemPrice'],
						$order["purchasedCurrency"],$supportedCurrencyID);
					}
					else
					{
						$orderItemPrice = $orderItems[$key]['orderItemPrice'];
					}
					$item 		= array 
													(
													'name'=>htmlentities($ordItem[$fldName]).$orderGiveAsGift,
													'quantity'=>$ordItem['orderItemQuantity'],
													'product_code'=>'',
													'extended_amount'=>$orderItemPrice
													);
												
					$mpgCustInfo->setItems($item);										
				}
				
			}
			//Pass Discount variables

			if ($order['orderPromoDiscountAmount'] > 0)
			{	
				if($currencyFlag==true)
				{
					$orderPromoDiscountAmount = $ObjCurrency->convertValueCustom($order['orderPromoDiscountAmount'],
					$order["purchasedCurrency"],$supportedCurrencyID);
				}
				else
				{
					$orderPromoDiscountAmount = $order['orderPromoDiscountAmount'];
				}
				$item 		= array 
													(
													'name'=>'Promo Code Discount',
													'quantity'=>1,
													'product_code'=>'',
													'extended_amount'=>$orderPromoDiscountAmount
													);
			    $mpgCustInfo->setItems($item);	
				
			}
			if ($order['orderUserCreditAmount'] > 0)
			{
				if($currencyFlag==true)
				{
					$orderUserCreditAmount = $ObjCurrency->convertValueCustom($order['orderUserCreditAmount'],
					$order["purchasedCurrency"],$supportedCurrencyID);
				}
				else
				{
					$orderUserCreditAmount = $order['orderUserCreditAmount'];
				}
				$item 		= array 
													(
													'name'=>'User Credit Discount',
													'quantity'=>1,
													'product_code'=>'',
													'extended_amount'=>$orderUserCreditAmount
													);
			    $mpgCustInfo->setItems($item);					
			}
			if ($order['orderOtherServiceCharge'] > 0)
			{
				if($currencyFlag==true)
				{
					$orderOtherServiceCharge = $ObjCurrency->convertValueCustom($order['orderOtherServiceCharge'],
					$order["purchasedCurrency"],$supportedCurrencyID);
				}
				else
				{
					$orderOtherServiceCharge = $order['orderOtherServiceCharge'];
				}
				$item 		= array 
													(
													'name'=>'Service Charge',
													'quantity'=>1,
													'product_code'=>'',
													'extended_amount'=>$orderOtherServiceCharge
													);
			    $mpgCustInfo->setItems($item);					
			}	
			$txnArray				= 	array(
												'type'		=> $monerisType,
												'order_id'	=> $orderid,
												'cust_id'	=> $customerid,
												'amount'	=> $amount,
												'pan'		=> $pan,
												'expdate'	=> $expirydate,
												'crypt_type'=> $crypttype
										  	 );
			$mpgTxn 				= 	new mpgTransaction($txnArray);
			
			$mpgTxn->setCustInfo($mpgCustInfo);
			$mpgRequest 			= 	new mpgRequest($mpgTxn);
			$mpgHttpPost 			= 	new mpgHttpsPost($store_id,$api_token,$mpgRequest,$this->settingsVars["payment_gateway_url"]);
			$mpgResponse			= 	$mpgHttpPost->getMpgResponse();
			//var_dump($mpgResponse);exit();
			$ResponseCode			=   $mpgResponse->getResponseCode();
			//var_dump($mpgHttpPost);exit();
			if($ResponseCode != "null" && $ResponseCode  >= 0 && $ResponseCode < 50)
			{		
				$transactionID		= 	$mpgResponse->getTxnNumber();		
				$paymentMethodName			=	$this->settingsVars["payment_method_name"];	
				$replyText 					=  ''; 
				$reply 						= $mpgResponse->getMpgResponseData();
				foreach($reply as $key => $values)
				{
					$replyText  		   .= $key.' : '.$values."\n";	
				}			
				parent::createTransaction($order, $mpgResponse->getTxnNumber(),$replyText , 
				"", $authOnly,0,$paymentMethodName,$supportedCurrencyID,$payAmount);								
				if($order['store_cc_info']=='Yes') 
				{									
					parent::saveCCdata($order['postData'],$order["userID"]);
				}
				$this->isError = false;
				$this->errorMessage = "";
				return "Pending";					
			} 
			else
			{
				$this->isError 		= true;
				$this->errorMessage	= "An error occurred : ".$mpgResponse->getMessage();		
			} 
			return !$this->isError;		
	}
	public function processCustom($order='') 
	{
			$ObjCurrency			= new CurrencyModel();
			parent::listPaymentSettingsValues($order['paymentSettingsGroupID']);	
			$getPaymentTransactionDetails = parent::getPaymentTransactionDetails(0,
			$order["masterOrderID"]);
			$purchasedCurrencyDetails = $ObjCurrency->getCurrencyByCurrencyID(
			$getPaymentTransactionDetails["paymentCurrencyID"]);
			$currencyCode			= $purchasedCurrencyDetails['currencyCode'];
			$paymentResponse		=  $getPaymentTransactionDetails['paymentResponse'];		
			$start = strpos($paymentResponse, 'ReceiptId : ');
			$end = strpos($paymentResponse, 'ReferenceNum');
			$orderid = trim(substr($paymentResponse, $start + 12, $end - $start - 12));
		
			$this->isError = false;
			//check is transaction completed
			if ($order["paymentType"] != "AUTH_ONLY" || $order["paymentStatus"]=='Received' )
			{
				$this->isError 		= true;
				$this->errorMessage = "Transaction already completed";
				return false;
			}
			$capturedTotalAmount 	=   $getPaymentTransactionDetails["convertedPaymentAmount"];
			$store_id 				= 	$this->settingsVars["payment_store_id"];
			$api_token 				= 	$this->settingsVars["payment_api_token"];
			$transactionID          =   $getPaymentTransactionDetails["transactionID"];
			$comp_amount 			= 	number_format($capturedTotalAmount, 2, '.', '');
			$crypttype 				= 	'7';				
			// ------ step 1) create transaction hash
			$txnArray				= 	array(
												'type'			=> 'completion',
												'txn_number'	=> $transactionID,
												'order_id'		=> $orderid,
												'comp_amount'	=> $comp_amount,
												'crypt_type'	=> $crypttype
										  	 );

			// ------ step 2) create a transaction object passing the hash created in step 1.
			$mpgTxn 				= 	new mpgTransaction($txnArray);
			// ------ step 3) create a mpgRequest object passing the transaction object created in step 2
			$mpgRequest 			= 	new mpgRequest($mpgTxn);
			// ------ step 4) create mpgHttpsPost object which does an https post
			$mpgHttpPost 			= 	new mpgHttpsPost($store_id,$api_token,$mpgRequest,
			$this->settingsVars["payment_gateway_url"]);
			// ------ step 5) get an mpgResponse object
			$mpgResponse			= 	$mpgHttpPost->getMpgResponse();
			$ResponseCode			=   $mpgResponse->getResponseCode();
			if($ResponseCode != "null" && $ResponseCode  >= 0 && $ResponseCode < 50)
			{						
					$paymentMethodName			=	$this->settingsVars["payment_method_name"];
					$replyText 					=  ''; 
					$reply 						= $mpgResponse->getMpgResponseData();
					foreach($reply as $key => $values)
					{
						$replyText  			.= $key.' : '.$values."\n";	
					}							
					parent::createTransaction($order,  $transactionID,
					"ORDER TYPE: PRIOR_AUTH_CAPTURE\n\n".$replyText, "", "AUTH_CAPTURE",
					0,$paymentMethodName,
					$getPaymentTransactionDetails["paymentCurrencyID"],$capturedTotalAmount);
					return "Success";								
			} 
			else
			{
					$this->logStart();
					$this->log($buffer,$this->settingsVars["payment_processor_id"]);
					$this->logFinish();
					$this->isError = true;
					if($ResponseCode == '')
					{
						$this->errorMessage = "Error occured while processing...Please try later.";					
					}
					else
					{
						$this->errorMessage = "We are sorry, but there has been an error processing this transaction.<br>Payment gateway response: ".$mpgResponse->getMessage();
					}
			} 				
			return !$this->isError;
	}
	
	
	public function processRefund($order='',$postValues='')
	{
		$ObjRefund		=	new RefundModel();
		$ObjCurrency	= new CurrencyModel();
		parent::listPaymentSettingsValues($postValues['paymentSettingsGroupID']);	
		$store_id 				= 	$this->settingsVars["payment_store_id"];
		$api_token 				= 	$this->settingsVars["payment_api_token"];
		$gatewayUrl				=	$this->settingsVars["payment_gateway_url"];
		
		$masterOrderID			=	$postValues['masterOrderID'];
		$refundTransactionID	=	$postValues['keyRefundTransactionID'];
		
		$getPaymentTxnDetails	= 	$this->getPaymentTransactionDetails(0,$masterOrderID);
		$paymentResponse		= 	$getPaymentTxnDetails['paymentResponse'];		
		$start					= 	strpos($paymentResponse, 'ReceiptId : ');
		$end 					= 	strpos($paymentResponse, 'ReferenceNum');
		$orderIdMoneris 		= 	trim(substr($paymentResponse, $start + 12, $end - $start - 12));
		
			
	//	$orderIdMoneris			= 	'DEAL-'.$order["orderID"]*$order["orderID"].'-'.rand(1000,10000);	// need to edit
		$refundAmt 				= 	number_format($order['orderTotalAmount'], 2, '.', '');
		
		$supportedCurrencyID = $order["purchasedCurrency"];
		$paymentCurrency	 = $this->settingsVars["payment_currency"];
		
		if ($paymentCurrency != '')
		{
			$paymentCurrency = str_replace(", ", ",", $paymentCurrency);
			$currencyArr     = explode(",", $paymentCurrency);
		}
		if(count($currencyArr)<1)
		{
			$this->isError 		= true;
			$this->errorMessage	= "Currency not configured , Please contact the site admin";
			//return false;
		}
		else
		{
			$currencyFlag = false;
			$purchasedCurrencyDetails 	= $ObjCurrency->getCurrencyByCurrencyID($order["purchasedCurrency"]);
			$currencyCode				= $purchasedCurrencyDetails['currencyCode'];
			$systemCurrencies 			= $ObjCurrency->listCurrencyCodes();
			if(!in_array($purchasedCurrencyDetails['currencyCode'],$currencyArr))
			{
				foreach ($systemCurrencies as $key => $currency)
				{
					if(in_array($currency['currencyCode'],$currencyArr))
					{
						$currencyFlag = true;
						$supportedCurrencyCode 	= $currency['currencyCode'];	
						$supportedCurrencyID 	= $currency['currencyID'];
						break;
					}
				}
				if($currencyFlag==true)
				{
					$refundAmt = $ObjCurrency->convertValueCustom($refundAmt,$order["purchasedCurrency"],$supportedCurrencyID);
				}
				else
				{
					$this->isError 		= true;
					$this->errorMessage	= "Currency not configured , Please contact the site admin";
					//return false;
				}
				
			}
		}
		$refundAmt 				= 	number_format($refundAmt, 2, '.', '');
		$txnNo					=	$postValues['apiPaymentTransactionID'];
		$monerisType 			=	'refund';
		$cryptType 				= 	'7';
		
		$txnArray				= 	array(
											'type'		=> $monerisType,
											'txn_number'=> $txnNo,
											'order_id'	=> $orderIdMoneris,
											'amount'	=> $refundAmt,
											'crypt_type'=> $cryptType
									  	 );
		
		$mpgTxn 				= 	new mpgTransaction($txnArray);
		$mpgRequest 			= 	new mpgRequest($mpgTxn);
		$mpgHttpPost 			= 	new mpgHttpsPost($store_id,$api_token,$mpgRequest,$gatewayUrl);
		$mpgResponse			= 	$mpgHttpPost->getMpgResponse();
		$ResponseCode			=   $mpgResponse->getResponseCode();
		$replyText 				=	''; 
		$reply 					=	$mpgResponse->getMpgResponseData();
		foreach($reply as $key => $values){ $replyText	.=	$key.' : '.$values."\n"; }
		
		if($ResponseCode != "null" && $ResponseCode  >= 0 && $ResponseCode < 50){		
			$arrXnResponse['transactionID']	= 	$mpgResponse->getTxnNumber();
			$arrXnResponse['refundResponse']=	$replyText;
			$arrXnResponse['refundAmount']	= 	$mpgResponse->getTransAmount();				
			$resUpdateRefund	=	$ObjRefund->updateRefundTransaction('',$refundTransactionID,$arrXnResponse,$masterOrderID);
			
			$this->isError 		=	false;
			$this->errorMessage =	"";
		}else{
			$arrXnResponse['transactionID']	= 	'';
			$arrXnResponse['refundResponse']=	$replyText;
			$arrXnResponse['refundAmount']	= 	'';				
			$resUpdateRefund	=	$ObjRefund->updateRefundTransaction('',$refundTransactionID,$arrXnResponse,$masterOrderID);
			
			$this->isError 		=	true;
			$this->errorMessage	=	"An error occurred : ".$mpgResponse->getMessage();		
		} 

		return !$this->isError;		
	}
	
	
}
#################### mpgGlobals ###########################################


class mpgGlobals
{

var $Globals=array(
                  'MONERIS_PROTOCOL' => 'https',
                  'MONERIS_HOST' => '',
                  'MONERIS_PORT' =>'443',
                  'MONERIS_FILE' => '/gateway2/servlet/MpgRequest',
                  'API_VERSION'  =>'MpgApi Version 2.02(php)',
                  'CLIENT_TIMEOUT' => '10'
                 );

 function mpgGlobals($host)
 {
  $this->Globals['MONERIS_HOST'] = $host;
 }


 function getGlobals()
 {
  return($this->Globals);
 }

}//end class mpgGlobals



###################### mpgHttpsPost #########################################

class mpgHttpsPost{

 var $api_token;
 var $store_id;
 var $mpgRequest;
 var $mpgResponse;

 function mpgHttpsPost($storeid,$apitoken,$mpgRequestOBJ,$host)
 {

  $this->store_id=$storeid;
  $this->api_token= $apitoken;
  $this->mpgRequest=$mpgRequestOBJ;

  $dataToSend=$this->toXML();
  //do post
  $g=new mpgGlobals($host);
  $gArray=$g->getGlobals();
  $url=$gArray['MONERIS_PROTOCOL']."://".
       $gArray['MONERIS_HOST'].":".
       $gArray['MONERIS_PORT'].
       $gArray['MONERIS_FILE'];
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL,$url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  curl_setopt ($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS,$dataToSend);
  curl_setopt($ch,CURLOPT_TIMEOUT,$gArray['CLIENT_TIMEOUT']);
  curl_setopt($ch,CURLOPT_USERAGENT,$gArray['API_VERSION']);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);
  $response=curl_exec ($ch);
  curl_close ($ch);
  if(!$response)
   {

     $response="<?xml version=\"1.0\"?><response><receipt>".
          "<ReceiptId>Global Error Receipt</ReceiptId>".
          "<ReferenceNum>null</ReferenceNum><ResponseCode>null</ResponseCode>".
          "<ISO>null</ISO> <AuthCode>null</AuthCode><TransTime>null</TransTime>".
          "<TransDate>null</TransDate><TransType>null</TransType><Complete>false</Complete>".
          "<Message>null</Message><TransAmount>null</TransAmount>".
          "<CardType>null</CardType>".
          "<TransID>null</TransID><TimedOut>null</TimedOut>".
          "</receipt></response>";
   }
  $this->mpgResponse=new mpgResponse($response);
 }

 function getMpgResponse()
 {
  return $this->mpgResponse;

 }

 function toXML( )
 {
	$xmlString	= '';	
	$req=$this->mpgRequest ;
	$reqXMLString=$req->toXML();
	$xmlString .="<?xml version=\"1.0\"?>".
               "<request>".
               "<store_id>$this->store_id</store_id>".
               "<api_token>$this->api_token</api_token>".
                $reqXMLString.
                "</request>";

	return ($xmlString);

 }

}//end class mpgHttpsPost



############# mpgResponse #####################################################


class mpgResponse{

 var $responseData;

 var $p; //parser

 var $currentTag;
 var $purchaseHash = array();
 var $refundHash;
 var $correctionHash = array();
 var $isBatchTotals;
 var $term_id;
 var $receiptHash = array();
 var $ecrHash = array();
 var $CardType;
 var $currentTxnType;
 var $ecrs = array();
 var $cards = array();
 var $cardHash= array();
 var $ACSUrl;
 function mpgResponse($xmlString)
 {
  $this->p = xml_parser_create();
  xml_parser_set_option($this->p,XML_OPTION_CASE_FOLDING,0);
  xml_parser_set_option($this->p,XML_OPTION_TARGET_ENCODING,"UTF-8");
  xml_set_object($this->p, $this);
  xml_set_element_handler($this->p,"startHandler","endHandler");
  xml_set_character_data_handler($this->p,"characterHandler");
  xml_parse($this->p,$xmlString);
  xml_parser_free($this->p);
 }//end of constructor


 function getMpgResponseData(){

   return($this->responseData);

 }


function getAvsResultCode()	{
	return ($this->responseData['AvsResultCode']);
}

function getCvdResultCode()	{
	return ($this->responseData['CvdResultCode']);
}


function getRecurSuccess(){

 return ($this->responseData['RecurSuccess']);
}

function getCardType(){

 return ($this->responseData['CardType']);

}

function getTransAmount(){

 return ($this->responseData['TransAmount']);

}

function getTxnNumber(){

 return ($this->responseData['TransID']);

}

function getReceiptId(){

 return ($this->responseData['ReceiptId']);

}

function getTransType(){

 return ($this->responseData['TransType']);

}

function getReferenceNum(){

 return ($this->responseData['ReferenceNum']);

}

function getResponseCode(){

 return ($this->responseData['ResponseCode']);

}

function getISO(){

 return ($this->responseData['ISO']);

}

function getBankTotals(){

 return ($this->responseData['BankTotals']);

}


function getMessage(){

 return ($this->responseData['Message']);

}


function getAuthCode(){

 return ($this->responseData['AuthCode']);

}

function getComplete(){

 return ($this->responseData['Complete']);

}

function getTransDate(){

 return ($this->responseData['TransDate']);

}

function getTransTime(){

 return ($this->responseData['TransTime']);

}

function getTicket(){

 return ($this->responseData['Ticket']);

}

function getTimedOut(){

 return ($this->responseData['TimedOut']);

}



function getTerminalStatus($ecr_no){

 return ($this->ecrHash[$ecr_no]);

}

function getPurchaseAmount($ecr_no,$card_type){

 return ($this->purchaseHash[$ecr_no][$card_type]['Amount']=="" ? 0:$this->purchaseHash[$ecr_no][$card_type]['Amount']);
}

function getPurchaseCount($ecr_no,$card_type){

 return ($this->purchaseHash[$ecr_no][$card_type]['Count']=="" ? 0:$this->purchaseHash[$ecr_no][$card_type]['Count']);
}

function getRefundAmount($ecr_no,$card_type){

 return ($this->refundHash[$ecr_no][$card_type]['Amount']=="" ? 0:$this->refundHash[$ecr_no][$card_type]['Amount']);
}

function getRefundCount($ecr_no,$card_type){

 return ($this->refundHash[$ecr_no][$card_type]['Count']=="" ? 0:$this->refundHash[$ecr_no][$card_type]['Count']);
}

function getCorrectionAmount($ecr_no,$card_type){

 return ($this->correctionHash[$ecr_no][$card_type]['Amount']=="" ? 0:$this->correctionHash[$ecr_no][$card_type]['Amount']);
}

function getCorrectionCount($ecr_no,$card_type){

 return ($this->correctionHash[$ecr_no][$card_type]['Count']=="" ? 0:$this->correctionHash[$ecr_no][$card_type]['Count']);
}

function getTerminalIDs(){

 return ($this->ecrs);

}

function getCreditCardsAll(){

 return (array_keys($this->cards));
}


function getCreditCards($ecr){

 return ($this->cardHash[$ecr]);
}



function characterHandler($parser,$data){

 if($this->isBatchTotals)
 {
   switch($this->currentTag)
    {
     case "term_id"    : {
                          $this->term_id=$data;
                          array_push($this->ecrs,$this->term_id);
                          $this->cardHash[$data]=array();
                          break;
                         }

     case "closed"     : {
                          $ecrHash=$this->ecrHash;
                          $ecrHash[$this->term_id]=$data;
                          $this->ecrHash = $ecrHash;
                          break;
                         }

     case "CardType"   : {
                          $this->CardType=$data;
                          $this->cards[$data]=$data;
                          array_push($this->cardHash[$this->term_id],$data) ;
                          break;
                         }

     case "Amount"     : {
                          if($this->currentTxnType == "Purchase")
                            {
                             $this->purchaseHash[$this->term_id][$this->CardType]['Amount']=$data;
                            }
                           else if( $this->currentTxnType == "Refund")
                            {
                              $this->refundHash[$this->term_id][$this->CardType]['Amount']=$data;
                            }

                           else if( $this->currentTxnType == "Correction")
                            {
                              $this->correctionHash[$this->term_id][$this->CardType]['Amount']=$data;
                            }
                           break;
                         }

    case "Count"     : {
                          if($this->currentTxnType == "Purchase")
                            {
                             $this->purchaseHash[$this->term_id][$this->CardType]['Count']=$data;
                            }
                           else if( $this->currentTxnType == "Refund")
                            {
                              $this->refundHash[$this->term_id][$this->CardType]['Count']=$data;

                            }

                           else if( $this->currentTxnType == "Correction")
                            {
                              $this->correctionHash[$this->term_id][$this->CardType]['Count']=$data;
                            }
                          break;
                         }



    }

 }
 else
 {
    $this->responseData[$this->currentTag] = (isset($this->responseData[$this->currentTag])?$this->responseData[$this->currentTag].$data:$data);
 }

}//end characterHandler



function startHandler($parser,$name,$attrs){

  $this->currentTag=$name;

  if($this->currentTag == "BankTotals")
   {
    $this->isBatchTotals=1;
   }
  else if($this->currentTag == "Purchase")
   {
    $this->purchaseHash[$this->term_id][$this->CardType]=array();
    $this->currentTxnType="Purchase";
   }
  else if($this->currentTag == "Refund")
   {
    $this->refundHash[$this->term_id][$this->CardType]=array();
    $this->currentTxnType="Refund";
   }
  else if($this->currentTag == "Correction")
   {
    $this->correctionHash[$this->term_id][$this->CardType]=array();
    $this->currentTxnType="Correction";
   }

}


function endHandler($parser,$name){


 $this->currentTag=$name;
 if($name == "BankTotals")
   {
    $this->isBatchTotals=0;
   }
 $this->currentTag="/dev/null";
}




}//end class mpgResponse


################## mpgRequest ###########################################################

class mpgRequest{
 var $txnTypes =array('purchase'=> array('order_id','cust_id', 'amount', 'pan', 'expdate', 'crypt_type'),
                      'refund' => array('order_id', 'amount', 'txn_number', 'crypt_type'),
					  'idebit_purchase'=>array('order_id','amount','idebit_track2'),
					  'idebit_refund'=>array('order_id','amount','txn_number'),
					  'purchase_reversal'=>array('order_id','amount'),
					  'refund_reversal'=>array('order_id','amount'),
                      'ind_refund' => array('order_id','cust_id', 'amount','pan','expdate', 'crypt_type'),
                      'preauth' =>array('order_id','cust_id', 'amount', 'pan', 'expdate', 'crypt_type'),
                      'completion' => array('order_id', 'comp_amount','txn_number', 'crypt_type'),
                      'purchasecorrection' => array('order_id', 'txn_number', 'crypt_type'),
                      'opentotals' => array('ecr_number'),
                      'batchclose' => array('ecr_number'),
                      'batchcloseall' => array() ,

                      'cavv_purchase'=> array('order_id','cust_id', 'amount', 'pan',
                                        'expdate', 'cavv'),
                      'cavv_preauth' =>array('order_id','cust_id', 'amount', 'pan',
                                        'expdate', 'cavv')
                    );
var $txnArray;
function mpgRequest($txn){
 	if(is_array($txn))
 	{
 	   $txn=$txn[0];
 	}
 	$this->txnArray=$txn;
}

function toXML()
{
 	$tmpTxnArray=$this->txnArray;
 	$txnArrayLen=count($tmpTxnArray); //total number of transactions
    $txnObj=$tmpTxnArray;
    $txn=$txnObj->getTransaction();	//call to a non-member function
    $txnType=array_shift($txn);
    $tmpTxnTypes=$this->txnTypes;
    $txnTypeArray=$tmpTxnTypes[$txnType];
    $txnTypeArrayLen=count($txnTypeArray); //length of a specific txn type
    $txnXMLString="";
    for($i=0;$i < $txnTypeArrayLen ;$i++)
	{
		 $txnXMLString  .="<$txnTypeArray[$i]>"   //begin tag
		                  .$txn[$txnTypeArray[$i]] // data
		                  . "</$txnTypeArray[$i]>"; //end tag
	}
	$txnXMLString = "<$txnType>$txnXMLString";
	$recur  = $txnObj->getRecur();
	if($recur != null)
	{
	     $txnXMLString .= $recur->toXML();
	}
	$avs  = $txnObj->getAvsInfo();
	if($avs != null)
	{
		 $txnXMLString .= $avs->toXML();
	}
   	$cvd  = $txnObj->getCvdInfo();
    if($cvd != null)
   	{
   		 $txnXMLString .= $cvd->toXML();
   	}
	$custInfo = $txnObj->getCustInfo();
	if($custInfo != null)
	{
         $txnXMLString .= $custInfo->toXML();
	}
    $txnXMLString .="</$txnType>";
    $txnXMLString .=$txnXMLString;
	return $txnXMLString;
 }//end toXML
}//end class


##################### mpgCustInfo #######################################################

class mpgCustInfo{
 var $level3template = array('cust_info'=>
           array('email','instructions',
                 'billing' => array ('first_name', 'last_name', 'company_name', 'address',
                                    'city', 'province', 'postal_code', 'country',
                                    'phone_number', 'fax','tax1', 'tax2','tax3',
                                    'shipping_cost'),
                 'shipping' => array('first_name', 'last_name', 'company_name', 'address',
                                   'city', 'province', 'postal_code', 'country',
                                   'phone_number', 'fax','tax1', 'tax2', 'tax3',
                                   'shipping_cost'),
                 'item'   => array ('name', 'quantity', 'product_code', 'extended_amount')
                )
           );
 var $level3data;
 var $email;
 var $instructions;
 function mpgCustInfo($custinfo=0,$billing=0,$shipping=0,$items=0)
 {
  if($custinfo)
   {
    $this->setCustInfo($custinfo);
   }
 }

 function setCustInfo($custinfo)
 {
  $this->level3data['cust_info']=array($custinfo);
 }


 function setEmail($email){
   $this->email=$email;
   $this->setCustInfo(array('email'=>$email,'instructions'=>$this->instructions));
 }

 function setInstructions($instructions){

   $this->instructions=$instructions;
   $this->setCustinfo(array('email'=>$this->email,'instructions'=>$instructions));
 }

 function setShipping($shipping)
 {
  $this->level3data['shipping']=array($shipping);
 }

 function setBilling($billing)
 {
  $this->level3data['billing']=array($billing);
 }

 function setItems($items)
 {
	if(isset($this->level3data['item']))
    {
		$index=count($this->level3data['item']);
		$this->level3data['item'][$index]=$items;
    }
	else
    {
		$this->level3data['item']=array($items);
    }
 }

 function toXML()
 {
  $xmlString=$this->toXML_low($this->level3template,"cust_info");
  return $xmlString;
 }

 function toXML_low($template,$txnType)
 {
	$xmlString	= '';
	for($x=0;$x<count($this->level3data[$txnType]);$x++)
	{
		 if($x>0)
		 {
		  $xmlString .="</$txnType><$txnType>";
		 }
		 $keys=array_keys($template);
		 for($i=0; $i < count($keys);$i++)
		 {
			$tag=$keys[$i];

			if(is_array($template[$keys[$i]]))
			{
			  $data=$template[$tag];
				if(isset($this->level3data[$tag]))
				{}
				else
				{
					continue;
				}
				$beginTag="<$tag>";
				$endTag="</$tag>";

			  $xmlString .=$beginTag;
			  {
				$returnString=$this->toXML_low($data,$tag);
				$xmlString .= $returnString;
			   }
			  $xmlString .=$endTag;
			}
			else
			{
			 $tag=$template[$keys[$i]];
			 $beginTag="<$tag>";
			 $endTag="</$tag>";
			 $data= (isset($this->level3data[$txnType][$x][$tag])?$this->level3data[$txnType][$x][$tag]:'');
			 $xmlString .=$beginTag.$data .$endTag;
			}

		 }//end inner for

	}//end outer for

    return $xmlString;
 }//end toXML_low

}//end class

#########################################mpgRecur################################################

class mpgRecur{
 var $params;
 var $recurTemplate = array('recur_unit','start_now','start_date','num_recurs','period','recur_amount');
 function mpgRecur($params)
 {
    $this->params = $params;
    if( (! $this->params['period']) )
    {
      $this->params['period'] = 1;
    }
 }

 function toXML()
 {
   $xmlString = "";
   foreach($this->recurTemplate as $tag)
   {
     $xmlString .= "<$tag>". $this->params[$tag] ."</$tag>";
   }
   return "<recur>$xmlString</recur>";
 }

}//end class

##################### mpgTransaction #######################################################
class mpgTransaction{
 var $txn;
 var $custInfo = null;
 var $avsInfo = null;
 var $cvdInfo = null;
 var $recur = null;
 function mpgTransaction($txn){
  $this->txn=$txn;
 }

function getCustInfo()
{
	return $this->custInfo;
}
function setCustInfo($custInfo){
	$this->custInfo = $custInfo;
 	array_push($this->txn,$custInfo);
}

function getCvdInfo()
{
	return (isset($this->cvd)?$this->cvd:NULL);
}
function setCvdInfo($cvd)
{
	$this->cvd = $cvd;
}

function getAvsInfo()
{
	return (isset($this->avs)?$this->avs:NULL);
}
function setAvsInfo($avs)
{
	$this->avs = $avs;
}

function getRecur()
{
	return (isset($this->recur)?$this->recur:NULL);
}
function setRecur($recur)
{
	$this->recur = $recur;
}

function getTransaction(){

 return (isset($this->txn)?$this->txn:NULL);
}

}//end class

##################### mpgAvsInfo #######################################################
class mpgAvsInfo
{

	var $params;
	var $avsTemplate = array('avs_street_number','avs_street_name','avs_zipcode');

	function mpgAvsInfo($params)
	{
		$this->params = $params;

		if( (! $this->params['period']) )
		{
			$this->params['period'] = 1;
		}
	}
	function toXML()
	{
		$xmlString = "";

		foreach($this->avsTemplate as $tag)
		{
			$xmlString .= "<$tag>". $this->params[$tag] ."</$tag>";
		}

		return "<avs_info>$xmlString</avs_info>";
	}

}//end class

##################### mpgCvdInfo #######################################################
class mpgCvdInfo
{

	var $params;
	var $cvdTemplate = array('cvd_indicator','cvd_value');

	function mpgCvdInfo($params)
	{
		$this->params = $params;

		if( (! $this->params['period']) )
		{
			$this->params['period'] = 1;
		}
	}

	function toXML()
	{
		$xmlString = "";

		foreach($this->cvdTemplate as $tag)
		{
			$xmlString .= "<$tag>". $this->params[$tag] ."</$tag>";
		}

		return "<cvd_info>$xmlString</cvd_info>";
	}

}//end class