<?php
defined( '_JEXEC' ) or die( 'Direct Access to this location is not allowed.' );
require_once( JPATH_SITE.'/components/com_dtregister/lib/class.payment.php');
class net extends Payment{
   
   var $byservice =  false  ;
   
  
    var $billing =  false ;
	
	function __construct() {
		global $godaddy_hosting ,$payway_merchant_id ,$payway_type ,$payway_cert , $payway_encrypt_key ;
		parent::__construct();
		
		
		$payway_type = "net";
		
		$this->godaddy_hosting = $godaddy_hosting;
		
		
		$this->customer_merchant = ($this->paymentmode=='test')?"TEST":$payway_merchant_id;
		$this->order_type = 'capture';	
		$this->url = "https://www.payway.com.au/";
		
		
		$this->certificate = $payway_cert ; // =  JPATH_SITE."/components/com_dtregister/cacerts.crt";
		
		$this->encrypt_key = $payway_encrypt_key;
		
   }
   
   function set_fields(){
      global $payway_billercode , $payway_username ,$payway_password , $payway_merchant_id ,
	  $payway_paypalemail , $Itemid ,$payway_notification_email ;
	  $session_id = $this->saveSession();
	  $mosConfig_live_site = JURI::root( false );
	  $this->fields = array();
	  
	  $this->fields['biller_code'] = $payway_billercode; 
	  $this->fields['username'] = $payway_username; 
	  $this->fields['password'] = $payway_password; 
	  $this->fields['merchant_id'] = $payway_merchant_id; 
	  $this->fields['paypal_email'] = $payway_paypalemail; 
	  $this->fields['payment_reference'] = (!isset($this->confirmNum)|| $this->confirmNum=="")?'':$this->confirmNum; 
	  $this->fields['payment_reference_change'] = 'false'; 
	  $this->fields['payment_amount'] = $this->cart->getAmount(); 
	  
	  $this->fields['payment_reference_text_help'] = $this->description; 
	  $this->fields['hidden_fields'] = 'payway_return,return'; 
	  $this->fields['return_link_url'] =  "{$mosConfig_live_site}components/com_dtregister/success.php?return=$session_id&Itemid=$Itemid&task=restore";

	  $this->fields['return_link_url_pre_payment'] =  "{$mosConfig_live_site}components/com_dtregister/success.php?return=$session_id&Itemid=$Itemid&task=cancel";

	  $this->fields['reply_link_url'] =  "{$mosConfig_live_site}components/com_dtregister/success.php?return=$session_id&Itemid=$Itemid&task=notification";
	  $this->fields['reply_link_email'] = $payway_notification_email ;
	  $this->fields['payway_return']  = $session_id;
	  $this->fields['return']  = $session_id;
	 // $this->fields['return'] = $session_id; 
	  
	   $this->token = $this->getToken($this->fields);
		
	  /*
	  $this->fields['username'] = $payway_username; 
	  $this->fields['username'] = $payway_username; 
	  $this->fields['username'] = $payway_username; 
	  $this->fields['username'] = $payway_username; 
	  */
	  
   }
   
   function process(){
      
	  $this->set_fields();
	  
	   $handOffUrl = $this->url . "MakePayment?biller_code=" .
                $this->fields['biller_code'] . "&token=" . urlencode( $this->token );
        debugLog( "Hand-off URL: " . $handOffUrl );

        session_write_close();
        header( "Location: " . $handOffUrl );
        exit;
	  
	  
	  
   }
   
    function success(){
	   
		if($_REQUEST['summary_code'] == "0"){
		    
			 $this->transactionId = $_REQUEST['payment_number'];
		   $process = DT_Session::get('Setting.process');
		   DT_Session::set($process.'.payment.transactionId', $this->transactionId);
				   return true;
		} else {
		 
		   $this->errorMsg = $_REQUEST['response_text'];
		   return false;
		}
		
	  
    }
   
     function notify(){
	   $headers = getallheaders();
	  if ( $headers['content-type'] == 'application/xml' )
{
    $xmlData = file_get_contents('php://input');
    $parser = new XMLThing( $xmlData );
    $response = $parser->parse();
    $entry_line = $dtime . " Server-to-server data: \r\n";
    while ( list( $key, $value ) = each( $response['PaymentResponse'] ) )
    {
        // We reccommend you don't log your password.
        if ( $key != 'password' )
        {
            $entry_line = $entry_line . '  ' . $key . ' = ' . $value . "\r\n";
        }
    }
    debugLog( $entry_line );
}
else
{
    $entry_line = $dtime . " Server-to-server post\r\nPOST Parameters: \r\n";
    foreach ( $_POST as $paramName => $paramValue )
    {
        if ( $paramName != 'password' )
        {
            $entry_line = $entry_line . '  ' . $paramName . ' = ' . $paramValue . "\r\n";
        }
    }
    $entry_line = $entry_line . "GET Parameters: \r\n";
    foreach ( $_GET as $paramName => $paramValue )
    {
        if ( $paramName != 'password' )
        {
            $entry_line = $entry_line . '  ' . $paramName . ' = ' . $paramValue . "\r\n";
        }
    }
    debugLog( $entry_line );

    if ( $_POST['username'] != $username || $_POST['password'] != $password )
    {
        header( "HTTP/1.1 403 Incorrect Username and Password" );
        echo "Incorrect Username and password";
		return false ;
    }
    else
    {
        // Save payment
$this->transactionId = $_REQUEST['payment_number'];
echo "Success";
		   $process = DT_Session::get('Setting.process');
		   DT_Session::set($process.'.payment.transactionId', $this->transactionId);
				  return true;
			  
        // If error results, return HTTP 500

        // Otherwise, just return success
        
    }
}
	      
   }
   
    function getToken( $parameters )
    {
       
        $payWayBaseUrl = $this->url;

        // Find the port setting, if any.
        $payWayUrl = $payWayBaseUrl;
        $port = 443;
        $portPos = strpos( $payWayBaseUrl, ":", 6 );
        $urlEndPos = strpos( $payWayBaseUrl, "/", 8 );
        if ( $portPos !== false && $portPos < $urlEndPos )
        {
            $port = (int)substr( $payWayBaseUrl, ((int)$portPos) + 1, ((int)$urlEndPos));
            $payWayUrl = substr( $payWayBaseUrl, 0, ((int)$portPos))
                . substr( $payWayBaseUrl, ((int)$urlEndPos), strlen($payWayBaseUrl));
            debugLog( "Found alternate port setting: " . $port );
        }

        $ch = curl_init( $payWayUrl . "RequestToken" );
        debugLog( "Configuring token request to : " . $payWayUrl . "RequestToken" );

        if ( $port != 443 )
        {
            curl_setopt( $ch, CURLOPT_PORT, $port );
            debugLog( "Set port to: " . $port );
        }

        curl_setopt( $ch, CURLOPT_FAILONERROR, true );
        curl_setopt( $ch, CURLOPT_FORBID_REUSE, true );
        curl_setopt( $ch, CURLOPT_FRESH_CONNECT, true );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
  
        // Set proxy information as required
        if ( !is_null( $proxyHost ) && !is_null( $proxyPort ) )
        {
            curl_setopt( $ch, CURLOPT_HTTPPROXYTUNNEL, true );
            curl_setopt( $ch, CURLOPT_PROXY, $proxyHost . ":" . $proxyPort );
            if ( !is_null( $proxyUser ) )
            {
                if ( is_null( $proxyPassword ) )
                {
                    curl_setopt( $ch, CURLOPT_PROXYUSERPWD, $proxyUser . ":" );
                }
                else
                {
                    curl_setopt( $ch, CURLOPT_PROXYUSERPWD, 
                        $proxyUser . ":" . $proxyPassword );
                }
            }
        }
  
        // Set timeout options
        curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 30 );
        curl_setopt( $ch, CURLOPT_TIMEOUT, 30 );
  
        // Set references to certificate files
       // curl_setopt( $ch, CURLOPT_CAINFO, $this->certificate );
  
        // Check the existence of a common name in the SSL peer's certificate
        // and also verify that it matches the hostname provided
       // curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 1 );   
	   
	    curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );   
  
        // Verify the certificate of the SSL peer
       // curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true );
	    curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
        
        // Build the parameters string to pass to PayWay
        $parametersString = '';
        $init = true;
        foreach ( $parameters as $paramName => $paramValue )
        {
            if ( $init )
            {
            		$init = false;
            }
            else
            {
                $parametersString = $parametersString . '&';
            }  
            $parametersString = $parametersString . urlencode($paramName) . '=' . urlencode($paramValue);
        }
        
        curl_setopt( $ch, CURLOPT_POSTFIELDS, $parametersString );
        
        debugLog( "Token Request POST: " . $parametersString );

        // Make the request  
        $responseText = curl_exec($ch);

        debugLog( "Token Response: " . $responseText );

        // Check the response for errors
        $errorNumber = curl_errno( $ch );
        if ( $errorNumber != 0 )
        {
            trigger_error( "CURL Error getting token: Error Number: " . $errorNumber . 
                ", Description: '" . curl_error( $ch ) . "'" );
            debugLog( "Errors: " . curl_error( $ch ) );
        }

        curl_close( $ch );

        // Split the response into parameters
        $responseParameterArray = explode( "&", $responseText );
        $responseParameters = array();
        foreach ( $responseParameterArray as $responseParameter )
        {
            list( $paramName, $paramValue ) = explode( "=", $responseParameter, 2 );
            $responseParameters[ $paramName ] = $paramValue;
        }

        if ( array_key_exists( 'error', $responseParameters ) )
        {
            trigger_error( "Error getting token: " . $responseParameters['error'] );
        }        
        else
        {
            return $responseParameters['token'];
        }
    }
}

function debugLog( $message )
{
    global $logDir;
    $logDir = JPATH_SITE.'/components/com_dtregister/lib/payment/';
    list($usec, $sec) = explode(" ", microtime());
    $dtime = date( "Y-m-d H:i:s." . sprintf( "%03d", (int)(1000 * $usec) ), $sec );
    $filename = $logDir . "/" . "net_" . date( "Ymd" ) . ".log";
    $fp = fopen( $filename, "a" ); 
    fputs( $fp, $dtime . ' ' . $message . "\r\n" ); 
    fclose( $fp );
}

 function pkcs5_unpad($text)
{
	$pad = ord($text{strlen($text)-1});
	if ($pad > strlen($text)) return false;
	if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
	return substr($text, 0, -1 * $pad);
}

function decrypt_parameters( $encryptedParametersText, $signatureText )
{   global $payway_encrypt_key  ;

	$key = base64_decode( $payway_encrypt_key  );
	$iv = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
	$td = mcrypt_module_open('rijndael-128', '', 'cbc', '');

	// Decrypt the parameter text
	mcrypt_generic_init($td, $key, $iv);
	$parametersText = mdecrypt_generic($td, base64_decode( $encryptedParametersText ) );
	$parametersText = pkcs5_unpad( $parametersText );
	mcrypt_generic_deinit($td);

	// Decrypt the signature value
	mcrypt_generic_init($td, $key, $iv);
	$hash = mdecrypt_generic($td, base64_decode( $signatureText ) );
	$hash = bin2hex( pkcs5_unpad( $hash ) );
	mcrypt_generic_deinit($td);

	mcrypt_module_close($td);

	// Compute the MD5 hash of the parameters
	$computedHash = md5( $parametersText );

	// Check the provided MD5 hash against the computed one
	if ( $computedHash != $hash )
	{
		trigger_error( "Invalid parameters signature" );
	}

	$parameterArray = explode( "&", $parametersText );
	$parameters = array();

	// Loop through each parameter provided
	foreach ( $parameterArray as $parameter )
	{
		list( $paramName, $paramValue ) = explode( "=", $parameter );
		$parameters[ urldecode( $paramName ) ] = urldecode( $paramValue );
	}
	return $parameters;
}


if (!function_exists('getallheaders'))
{
    function getallheaders()
    {
        foreach ($_SERVER as $name => $value)
        {
            if (substr($name, 0, 5) == 'HTTP_')
            {
                $headers[strtolower(str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))))] = $value;
            }
        }
        return $headers;
    }
}

// XML parser courtesy of wickedfather@hotmail.com
// From http://au2.php.net/manual/en/function.xml-parse-into-struct.php
class XMLThing
{
    var $rawXML;
    var $valueArray = array();
    var $keyArray = array();
    var $parsed = array();
    var $index = 0;
    var $attribKey = 'attributes';
    var $valueKey = 'value';
    var $cdataKey = 'cdata';
    var $isError = false;
    var $error = '';

    function XMLThing($xml = NULL)
    {
        $this->rawXML = $xml;
    }

    function parse($xml = NULL)
    {
        if (!is_null($xml))
        {
            $this->rawXML = $xml;
        }

        $this->isError = false;
         
        if (!$this->parse_init())
        {
            return false;
        }

        $this->index = 0;
        $this->parsed = $this->parse_recurse();
        $this->status = 'parsing complete';

        return $this->parsed;
    }

    function parse_recurse()
    {
        $found = array();
        $tagCount = array();

        while (isset($this->valueArray[$this->index]))
        {
            $tag = $this->valueArray[$this->index];
            $this->index++;

            if ($tag['type'] == 'close')
            {
                return $found;
            }

            if ($tag['type'] == 'cdata')
            {
                $tag['tag'] = $this->cdataKey;
                $tag['type'] = 'complete';
            }

            $tagName = $tag['tag'];

            if (isset($tagCount[$tagName]))
            {
                if ($tagCount[$tagName] == 1)
                {
                    $found[$tagName] = array($found[$tagName]);
                }
                 
                $tagRef =& $found[$tagName][$tagCount[$tagName]];
                $tagCount[$tagName]++;
            }
            else
            {
                $tagCount[$tagName] = 1;
                $tagRef =& $found[$tagName];
            }

            switch ($tag['type'])
            {
                case 'open':
                    $tagRef = $this->parse_recurse();

                    if (isset($tag['attributes']))
                    {
                        $tagRef[$this->attribKey] = $tag['attributes'];
                    }
                     
                    if (isset($tag['value']))
                    {
                        if (isset($tagRef[$this->cdataKey]))
                        {
                            $tagRef[$this->cdataKey] = (array)$tagRef[$this->cdataKey];
                            array_unshift($tagRef[$this->cdataKey], $tag['value']);
                        }
                        else
                        {
                            $tagRef[$this->cdataKey] = $tag['value'];
                        }
                    }
                    break;

                case 'complete':
                    if (isset($tag['attributes']))
                    {
                        $tagRef[$this->attribKey] = $tag['attributes'];
                        $tagRef =& $tagRef[$this->valueKey];
                    }

                    if (isset($tag['value']))
                    {
                        $tagRef = $tag['value'];
                    }
                    break;
            }
        }

        return $found;
    }

    function parse_init()
    {
        $this->parser = xml_parser_create();

        $parser = $this->parser;
        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
        xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
        if (!$res = (bool)xml_parse_into_struct($parser, $this->rawXML, $this->valueArray, $this->keyArray))
        {
            $this->isError = true;
            $this->error = 'error: '.xml_error_string(xml_get_error_code($parser)).' at line '.xml_get_current_line_number($parser);
        }
        xml_parser_free($parser);

        return $res;
    }
}


