<?php
/* Netpay-Democode fuer XML-Interface
   Modul:         refund_functions, Funktionen fuer Refund
   Author:        Ludwig Ertl  (ludwig.ertl@softwerker.at)
   Last modified: 10.01.2019
   History:       10.01.2019 - Initial version
*/

if (!isset($logins)) require_once('banks.inc.php');
$logfile="log.txt";

/*
  Parameters:
  ----------- 
  The following parameters are mandatory:
  TransactionId  [S]		  TransactionId from BankResponse 
  Amount         [F]
  opt            [A]		  The following settings are OPTIONAL:
  \____________________________________________________________________________
  Bank           [S]		  One of the idnetifiers in banks.inc.php, defaults
							  to SPARDAT if none given (backwards compat.)
  MerchantIBAN   [S]		  IBAN to be used for refund. If none is given, 
							  defaults to BeneficiaryAccountIdentifier
  RefundReference[S]		  Optional reference for refund
  _____________________________________________________________________________

  S...String
  F...Float
  A...Array

  Returns:
  --------
  array(
    'ErrorMsg'      =>  On failure, error description
    'StatusCode'    =>  0 on success, On bank error, error code
  )
*/
function EPS_Refund_Initiate($TransactionId, $Amount, $opt=array())
{
    global $banks, $BeneficiaryAccountIdentifier;

    $EPS_ret=array();
	$Currency='EUR';
    $xmldata = EPS_Refund_Header('EpsRefundRequest');
	$bank=$opt['Bank']?$opt['Bank']:"SPARDAT";
	if (!$opt['MerchantIBAN'])
		$opt['MerchantIBAN']=$banks[$bank]['account']['BeneficiaryAccountIdentifier']?$banks[$bank]['account']['BeneficiaryAccountIdentifier']:$BeneficiaryAccountIdentifier;
    $CreDtTm = gmdate('Y-m-d\TH:i:s\Z');  // gmdate('c') not supported in PHP 4
    $SHA256Fingerprint=EPS_SHA256($h=utf8_encode($banks[$bank]['account']['HaendlerPIN'].$CreDtTm.$TransactionId.$opt['MerchantIBAN'].$Amount.$Currency.$opt['RefundReference'].$banks[$bank]['account']['sapPopRequestor']));
	
    $xmldata .="<epsr:CreDtTm>$CreDtTm</epsr:CreDtTm>
<epsr:TransactionId>$TransactionId</epsr:TransactionId>
<epsr:MerchantIBAN>".$opt['MerchantIBAN']."</epsr:MerchantIBAN>
<epsr:Amount AmountCurrencyIdentifier=\"EUR\">".$Amount."</epsr:Amount>";
	if ($opt['RefundReference']) $xmldata.="<epsr:RefundReference>".$opt['RefundReference']."</epsr:RefundReference>";
	$xmldata.=EPS_Refund_AuthDetails($bank, $SHA256Fingerprint);
	$xmldata.="</epsr:EpsRefundRequest>";
//DEBUG
//	fwrite($h=fopen("test.xml", "w"), $xmldata);fclose($h); die("XML-Packet output was written to test.xml, halted.");

    return EPS_Refund_Transaction($xmldata, 'EPSref_characterData', $bank);
}

// --------------------------- [ STATIC FUNCTIONS ] ---------------------------

function EPS_Refund_Header($Tag)
{
    return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>".
    "<epsr:$Tag ".
	"xmlns:dsig=\"http://www.w3.org/2000/09/xmldsig#\" ".
    "xmlns:epsr=\"http://www.stuzza.at/namespaces/eps/refund/2018/09\" ".
    "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ".
    "xsi:schemaLocation=\"http://www.stuzza.at/namespaces/eps/refund/2018/09 EPSRefund-V26.xsd\">";
}

function EPS_Refund_AuthDetails($bank, $SHA256Fingerprint)
{
    global $banks;

    return "<epsr:AuthenticationDetails><epsr:UserId>".$banks[$bank]['account']['sapPopRequestor']."</epsr:UserId>".
        "<epsr:SHA256Fingerprint>$SHA256Fingerprint</epsr:SHA256Fingerprint></epsr:AuthenticationDetails>";
}

function EPS_SHA256($str)
{
    if (version_compare(PHP_VERSION,'5.1.2','>='))
        return hash('sha256', $str);
    if (function_exists('mhash') && defined('MHASH_SHA256'))
        return base64_encode(bin2hex(mhash(MHASH_SHA256, $str)));
    if (function_exists('sha256'))
        return sha256($str);
    else 
    {
        include ('ems_php4_sha256.inc.php');
        return strtoupper($hexStr);
    }
}

function EPS_Refund_Transaction($xmldata, $datahandler, $bank)
{
    global $currentTag, $EPS_ret;

	unset($currentTag);
	$xml_parser = xml_parser_create('UTF-8');
    xml_set_element_handler($xml_parser, 'EPSref_startElement', 'EPSref_endElement');
    xml_set_character_data_handler($xml_parser, $datahandler);

	if (!xml_parse($xml_parser, EPS_SendRequest($xmldata, $bank)))
	{
		$EPS_ret['StatusCode'] = '007';
	    $EPS_ret['ErrorMsg']=sprintf("XML error: %s in line %d",xml_error_string(xml_get_error_code($xml_parser)),xml_get_current_line_number($xml_parser));
	}
	xml_parser_free($xml_parser);

	return $EPS_ret;
}

function EPS_SendRequest($xmldata, $bank)
{
    global $banks;

	$Url = str_replace('/v2_5', '/v2_6', str_replace('/transinit/', '/refund/', $banks[$bank]['Login']));
	if ($pos = strpos($Url, '/eps/v'))
		$Url=substr($Url, 0, $pos+9);
    EPS_PutLog("(Request to $Url) Request packet:\n$xmldata");

    // Setup CURL
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $Url);
    curl_setopt($ch, CURLOPT_POST,1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, utf8_encode($xmldata));
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_HEADER,0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));

    // Abfrage durchfuehren
    $result=curl_exec ($ch);
    EPS_PutLog("(Request to EPS) Response:\n$result");
    curl_close ($ch);
    return $result;
}

function EPS_PutLog($text)
{
	global $netpay_debug, $logfile;

	if (isset($netpay_debug)) {
	    fputs(($fp=fopen($logfile,"a")),strftime("um: %d.%m.%Y %H:%M:%S",time()).": $text\n-------------------------------------------------------------------------------\n");
	    fclose($fp);
	}
}

function EPSref_startElement($parser, $name, $attrs)
{
    global $currentTag;
    $currentTag = $name;
}

function EPSref_endElement($parser, $name)
{
    global $currentTag;
    $currentTag = "";
}

function EPSref_characterData($parser, $data)
{
    global $currentTag, $EPS_ret;

    list($prefix, $tag)=explode(":", $currentTag, 2);
    if (!$tag) $tag=$currentTag;
    switch(strtoupper($tag))
    {
        case "STATUSCODE": $EPS_ret['StatusCode']=$data; break;
        case "ERRORMSG": $EPS_ret['ErrorMsg']=$data; break;
    }
}

?>