<?php
namespace Roots\Sage\Authorize;

/*
D I S C L A I M E R                                                                                          
WARNING: ANY USE BY YOU OF THE SAMPLE CODE PROVIDED IS AT YOUR OWN RISK.                                                                                   
Authorize.Net provides this code "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.   
Authorize.Net owns and retains all right, title and interest in and to the Automated Recurring Billing intellectual property.
*/

class AuthorizeNET
{
  
   private  $g_apihost,$g_apipath,$g_transactionkey,$g_loginname,$g_mode;
   
   function __construct($login,$transaction_key,$test_mode){  // testMode,liveMode
        //@TODO  Change number 2928 to option api_page_id
		
        $this->g_loginname =$login; // "2Qs8W9rZA"; // Keep this secure.
        $this->g_transactionkey =$transaction_key; // "5887Rmp96uJjD38d"; // Keep this secure.
        //$this->g_apihost=$global_setting['authorize_mode'];
		//$this->g_mode=$test_mode; 
		/*
        if(strpos($global_setting['authorize_mode'],'test'))
        {
           $this->g_mode="testMode"; 
        }else{
            $this->g_mode="liveMode";
        }*/
		
        if($test_mode)
        {
           $this->g_apihost = "apitest.authorize.net";
           $this->g_mode="testMode";    
        }else{
           $this->g_apihost = "api.authorize.net";
           $this->g_mode="liveMode";
        }
        
        $this->g_apipath = "/xml/v1/request.api";
		
        //$this->g_apipath =$global_setting['authorize_path'];// "/xml/v1/request.api";
        
        /*
        $this->g_loginname = "6nwA87Uep"; // Keep this secure.
        $this->g_transactionkey = "2VWXvn25d67VwB2T"; // Keep this secure.
        $this->g_apihost = "api.authorize.net";
        $this->g_apipath = "/xml/v1/request.api";
        */
        
    }  
//function to send xml request to Api.
//There is more than one way to send https requests in PHP.
    function send_xml_request($content)
    {
    	return $this->send_request_via_fsockopen($this->g_apihost,$this->g_apipath,$content);
    }
  

//function to send xml request via fsockopen
//It is a good idea to check the http status code.
    function send_request_via_fsockopen($host,$path,$content)
    {
    	$posturl = "ssl://" . $host;
    	$header = "Host: $host\r\n";
    	$header .= "User-Agent: PHP Script\r\n";
    	$header .= "Content-Type: text/xml\r\n";
    	$header .= "Content-Length: ".strlen($content)."\r\n";
    	$header .= "Connection: close\r\n\r\n";
    	$fp = fsockopen($posturl, 443, $errno, $errstr, 30);
    	if (!$fp)
    	{
    		$body = false;
    	}
    	else
    	{
    		error_reporting(E_ERROR);
    		fputs($fp, "POST $path  HTTP/1.1\r\n");
    		fputs($fp, $header.$content);
    		fwrite($fp, $out);
    		$response = "";
    		while (!feof($fp))
    		{
    			$response = $response . fgets($fp, 128);
    		}
    		fclose($fp);
    		error_reporting(E_ALL ^ E_NOTICE);
    		
    		$len = strlen($response);
    		$bodypos = strpos($response, "\r\n\r\n");
    		if ($bodypos <= 0)
    		{
    			$bodypos = strpos($response, "\n\n");
    		}
    		while ($bodypos < $len && $response[$bodypos] != '<')
    		{
    			$bodypos++;
    		}
    		$body = substr($response, $bodypos);
    	}
    	return $body;
    }

    //function to send xml request via curl
    function send_request_via_curl($host,$path,$content)
    {
    	$posturl = "https://" . $host . $path;
    	$ch = curl_init();
    	curl_setopt($ch, CURLOPT_URL, $posturl);
    	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    	curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml"));
    	curl_setopt($ch, CURLOPT_HEADER, 1);
    	curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
    	curl_setopt($ch, CURLOPT_POST, 1);
    	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    	$response = curl_exec($ch);
    	return $response;
    }


//function to parse the api response
//The code uses SimpleXML. http://us.php.net/manual/en/book.simplexml.php 
//There are also other ways to parse xml in PHP depending on the version and what is installed.
    function parse_api_response($content)
    {
    	$parsedresponse = simplexml_load_string($content, "SimpleXMLElement", LIBXML_NOWARNING);
        /*if ("Ok" != $parsedresponse->messages->resultCode) {
    		echo "The operation failed with the following errors:<br>";
    		foreach ($parsedresponse->messages->message as $msg) {
    			echo "[" . htmlspecialchars($msg->code) . "] " . htmlspecialchars($msg->text) . "<br>";
    		}
    		echo "<br>";
    	}*/
    	return $parsedresponse;
    }

    function MerchantAuthenticationBlock() {
      return
            "<merchantAuthentication>".
            "<name>" . $this->g_loginname . "</name>".
            "<transactionKey>" . $this->g_transactionkey . "</transactionKey>".
            "</merchantAuthentication>";
    }
    
    
    function create_transaction($cardnumber, $date, $cvv, $amount, $InvoiceNum,$firtname,$lastname,$address,$city,$state,$zipcode){
       
    	$content = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
				"<createTransactionRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">".
					 $this->MerchantAuthenticationBlock().
					 "<refId>".$InvoiceNum."</refId>
					  <transactionRequest>
						<transactionType>authCaptureTransaction</transactionType>
						<amount>".$amount."</amount>
						<payment>
						  <creditCard>
							<cardNumber>".$cardnumber."</cardNumber>
							<expirationDate>".$date."</expirationDate>
							<cardCode>".$cvv."</cardCode>
						  </creditCard>
						</payment>
						<order>
						 <invoiceNumber>".$InvoiceNum."</invoiceNumber>
						 <description>Purchase Ticket</description>
						</order>
						<billTo>
						  <firstName>".$firtname."</firstName>
						  <lastName>".$lastname."</lastName>
						  <address>".$address."</address>
						  <city>".$city."</city>
						  <state>".$state."</state>
						  <zip>".$zipcode."</zip>
						  <country>USA</country>
						</billTo>
					  </transactionRequest>
					</createTransactionRequest>";
        
            $response = $this->send_xml_request($content);
    		$parsedresponse = $this->parse_api_response($response);
         
    		if ("Ok" == $parsedresponse->messages->resultCode) {
                // RETURN TRANSACTION ID
                if(isset($parsedresponse->transactionResponse))
                {
                    $responseCode=$parsedresponse->transactionResponse->responseCode;
					$transId=$parsedresponse->transactionResponse->transId;
					$responseReasonText=$parsedresponse->transactionResponse->messages->message->description;
          	        if("1" == $responseCode) {
          	             return array('response'=>true,"transaction_id"=>htmlspecialchars($transId));
                    }else{
                       return array('response'=>false,"error"=>htmlspecialchars($responseReasonText)); 
                    }
                } 
                 
    		}else{
    		      
                return array('response'=>false,"error"=>htmlspecialchars($parsedresponse->messages->message->text));
    		}
	}
	
	function create_transaction1($customer_id, $payment_id, $shipping_id, $amount, $InvoiceNum,$ccv=null){

        if($ccv !=null){
    	$content = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
    		"<createCustomerProfileTransactionRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">" .
    		$this->MerchantAuthenticationBlock().
    		"<transaction>".
    		    "<profileTransAuthCapture>".
    			"<amount>" . $amount . "</amount>". // should include tax, shipping, and everything.
    			"<shipping>".
    				"<amount>" . $amount . "</amount>".
    				"<name>Calling Card Purchase</name>".
    				"<description>Online Recharge Using CC in file.</description>".
    			"</shipping>".
    			"<customerProfileId>" . $customer_id . "</customerProfileId>".
    			"<customerPaymentProfileId>" . $payment_id . "</customerPaymentProfileId>".
    			"<customerShippingAddressId>" . $shipping_id . "</customerShippingAddressId>".
    			"<order>".
    				"<invoiceNumber>" . $InvoiceNum . "</invoiceNumber>".
    			"</order>".
                "<cardCode>".$ccv."</cardCode>".
    		    "</profileTransAuthCapture>".
    		"</transaction>".
    		"</createCustomerProfileTransactionRequest>";
        }else{
            $content = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
    		"<createCustomerProfileTransactionRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">" .
    		$this->MerchantAuthenticationBlock().
    		"<transaction>".
    		    "<profileTransAuthCapture>".
    			"<amount>" . $amount . "</amount>". // should include tax, shipping, and everything.
    			"<shipping>".
    				"<amount>" . $amount . "</amount>".
    				"<name>Calling Card Purchase</name>".
    				"<description>Online Recharge Using CC in file.</description>".
    			"</shipping>".
    			"<customerProfileId>" . $customer_id . "</customerProfileId>".
    			"<customerPaymentProfileId>" . $payment_id . "</customerPaymentProfileId>".
    			"<customerShippingAddressId>" . $shipping_id . "</customerShippingAddressId>".
    			"<order>".
    				"<invoiceNumber>" . $InvoiceNum . "</invoiceNumber>".
    			"</order>".
    		    "</profileTransAuthCapture>".
    		"</transaction>".
    		"</createCustomerProfileTransactionRequest>";
        }
    		
            $response = $this->send_xml_request($content);
    		$parsedresponse = $this->parse_api_response($response);
         
            
            //var_dump($parsedresponse);
    		if ("Ok" == $parsedresponse->messages->resultCode) {
                // RETURN TRANSACTION ID
                if(isset($parsedresponse->directResponse))
                {
                    $directResponseFields = explode(",", $parsedresponse->directResponse);
                    $responseCode = $directResponseFields[0]; // 1 = Approved 2 = Declined 3 = Error
        			$responseReasonCode = $directResponseFields[2]; // See http://www.authorize.net/support/AIM_guide.pdf
        			$responseReasonText = $directResponseFields[3];
        			$approvalCode = $directResponseFields[4]; // Authorization code
        			$transId = $directResponseFields[6];
          	        if("1" == $responseCode) {
          	             return array('response'=>true,"transaction_id"=>htmlspecialchars($transId));
                    }else{
                       return array('response'=>false,"error"=>htmlspecialchars($responseReasonText)); 
                    }
                } 
                 
    		}else{
    		      
                return array('response'=>false,"error"=>htmlspecialchars($parsedresponse->messages->message->text));
    		}
	}
    
    
    function create_profile_id($UserID,$email_address,$desc)
    {
        $content =
            	"<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
            	"<createCustomerProfileRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">" .
                	$this->MerchantAuthenticationBlock().
            	"<profile>".
            	"<merchantCustomerId>".$UserID."</merchantCustomerId>". // Your own identifier for the customer.
            	"<description>".$desc."</description>".
            	"<email>" . $email_address . "</email>".
            	"</profile>".
            	"</createCustomerProfileRequest>";
        
        $response = $this->send_xml_request($content);
        $parsedresponse =$this->parse_api_response($response);
      
        if ("Ok" == $parsedresponse->messages->resultCode) {
                return array('response'=>true,"profile_id"=>htmlspecialchars($parsedresponse->customerProfileId));
        }else{
           /// $html_error="The operation failed with the following errors : ";
            $html_error="";
            foreach ($parsedresponse->messages->message as $msg) {
    			 //$html_error .=" [" . htmlspecialchars($msg->code) . "] "; // htmlspecialchars($msg->text) . "<br>";
				 $html_error .= htmlspecialchars($msg->text) . "<br>";
    		}
            return array('response'=>false,"error"=>$html_error);
        }
    }
    function create_payment_id($profile_id,$billto)
    {       
        $content =
        	"<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
        	"<createCustomerPaymentProfileRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">" .
        	$this->MerchantAuthenticationBlock().
        	"<customerProfileId>" . $profile_id . "</customerProfileId>".
        	"<paymentProfile>".
            "<billTo>".
            "<firstName>".$billto['firstName']."</firstName>".
            "<lastName>".$billto['lastName']."</lastName>".
            "<company>".$billto['company']."</company>".
            "<address>".$billto['address']."</address>".
            "<city>".$billto['city']."</city>".
            "<state>".$billto['state']."</state>".
            "<zip>".$billto['zip']."</zip>".
            "<country>".$billto['country']."</country>".
            "<phoneNumber>".$billto['phoneNumber']."</phoneNumber>".
            "<faxNumber>".$billto['faxNumber']."</faxNumber>".
            "</billTo>".
        	"<payment>".
        	 "<creditCard>".
        	  "<cardNumber>".$billto['cardNumber']."</cardNumber>".
        	  "<expirationDate>".$billto['expirationDate']."</expirationDate>". // required format for API is YYYY-MM
              "<cardCode>".$billto['security-code']."</cardCode>".
        	 "</creditCard>".
        	"</payment>".
        	"</paymentProfile>".
        	"<validationMode>".$this->g_mode."</validationMode>". // or testMode
        	"</createCustomerPaymentProfileRequest>";
      
         $response = $this->send_xml_request($content);
        $parsedresponse =$this->parse_api_response($response);
        
         
        if ("Ok" == $parsedresponse->messages->resultCode) {
		  //return htmlspecialchars($parsedresponse->customerPaymentProfileId);
            return array('response'=>true,"payment_id"=>htmlspecialchars($parsedresponse->customerPaymentProfileId));
        }else{
           //$html_error="The operation failed with the following errors : "; 
		    $html_error="";
            foreach ($parsedresponse->messages->message as $msg) {
    			//$html_error .=" [" . htmlspecialchars($msg->code) . "] "; // htmlspecialchars($msg->text) . "<br>";
                $html_error .= htmlspecialchars($msg->text) . "<br>";
    		}
            return array('response'=>false,"error"=>$html_error);
        }                     
    }
    function get_payment_profile($profile_id,$payment_profile_id)
    {
        $content =
            	"<?xml version=\"1.0\" encoding=\"utf-8\"?>
                 <getCustomerPaymentProfileRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">".
            	  $this->MerchantAuthenticationBlock().
                  "<customerProfileId>".$profile_id."</customerProfileId>
                  <customerPaymentProfileId>".$payment_profile_id."</customerPaymentProfileId>
                </getCustomerPaymentProfileRequest>";
        $response = $this->send_xml_request($content);
        $parsedresponse =$this->parse_api_response($response);
       
        if ("Ok" == $parsedresponse->messages->resultCode) {
            return array('response'=>true,"billto"=>array('phonenumber'=>htmlspecialchars($parsedresponse->paymentProfile->billTo->phoneNumber),'zipcode'=>htmlspecialchars($parsedresponse->paymentProfile->billTo->zip),'address'=>htmlspecialchars($parsedresponse->paymentProfile->billTo->address)));    
        }else{
            return array('response'=>false,"error"=>"Can not get payment profile info.");
        }
    }
    function create_shipping_id($profile_id,$billto)
    {      
        $content =
            	"<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
            	"<createCustomerShippingAddressRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">" .
            	$this->MerchantAuthenticationBlock().
            	"<customerProfileId>" . $profile_id . "</customerProfileId>".
            	"<address>".
                "<firstName>".$billto['firstName']."</firstName>".
                "<lastName>".$billto['lastName']."</lastName>".
                "<company>".$billto['company']."</company>".
                "<address>".$billto['address']."</address>".
                "<city>".$billto['city']."</city>".
                "<state>".$billto['state']."</state>".
                "<zip>".$billto['zip']."</zip>".
                "<country>".$billto['country']."</country>".
                "<phoneNumber>".$billto['phoneNumber']."</phoneNumber>".
                "<faxNumber>".$billto['faxNumber']."</faxNumber>".
            	"</address>".
            	"</createCustomerShippingAddressRequest>";
        $response = $this->send_xml_request($content);
        $parsedresponse =$this->parse_api_response($response);
        
        if ("Ok" == $parsedresponse->messages->resultCode) {
		  //return htmlspecialchars($parsedresponse->customerAddressId);
          return array('response'=>true,"shipping_id"=>htmlspecialchars($parsedresponse->customerAddressId));
        }else{
            //$html_error="The operation failed with the following errors : ";
            $html_error="";
            foreach ($parsedresponse->messages->message as $msg) {
    			//$html_error .=" [" . htmlspecialchars($msg->code) . "] "; // htmlspecialchars($msg->text) . "<br>";
                $html_error .= htmlspecialchars($msg->text) . "<br>";
    		}
            return array('response'=>false,"error"=>$html_error);
        }  
    }
    function profile_delete($profile_id)
    {
        $content =
        	"<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
        	"<deleteCustomerProfileRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">" .
        	$this->MerchantAuthenticationBlock().
        	"<customerProfileId>" . $profile_id . "</customerProfileId>".
        	"</deleteCustomerProfileRequest>";
        $response = $this->send_xml_request($content);
        $parsedresponse =$this->parse_api_response($response);
        if ("Ok" == $parsedresponse->messages->resultCode) {
            return true;
        }else{
            return false;
        }
    }
    
}
?>
