<?php
	// prerequisites: php-soap, FNTH_parse_ini_string

	class OtpModel {
		protected $sPOSId = "#02299991";	// testacc
		protected $oCCobj = null;
		protected $cc_tran_id = 0;
		protected $sBackUrlFormatString = "";
		
		public function setBackUrlFormatString( $v ) { $this->sBackUrlFormatString = $v; }

		
		public function setPOSId( $s ) { $this->sPOSId = $s; }
		public function setCreditCardModelObject( $v ) { $this->oCCobj = $v; }

		public function __construct() {
			if (strpos( $_SERVER["SERVER_NAME"] , "darkside" )===false)
				$this->sPOSId = "02200186";	// eles media-online

			if (!defined( "WEBSHOP_LIB_DIR" )) define( "WEBSHOP_LIB_DIR" , sprintf( "%s/app" , $GLOBALS["site_base"] ) );
			if (!defined( "WEBSHOPSERVICE_CONFIGURATION_STRING" )) {
				$ini_template = new FNTHTemplate();
				$ini_template->setParam( "site_base" , $GLOBALS["site_base"] );
				$ini_template->setParam( "posid" , $this->sPOSId );
			
				$filename = sprintf( "%s/data/otpwebshop/config/otp_webshop_client.ini" , $GLOBALS["site_base"] );
				$config = $ini_template->renderFromTemplate( $filename );
				define( "WEBSHOPSERVICE_CONFIGURATION_STRING", $config );
			}
			require_once(WEBSHOP_LIB_DIR . '/iqsys/otpwebshop/WebShopService.php');
			require_once(WEBSHOP_LIB_DIR . '/iqsys/otpwebshop/util/RequestUtils.php');
			require_once(WEBSHOP_LIB_DIR . '/iqsys/otpwebshop/util/ConfigUtils.php');
		}

		public function getNextTransactionId( ) {
			$query = sprintf( "select nextval('otp_transactions_otp_transaction_id_seq') as num" );
			$field = FNTH_db_get_field( $query , "num" );
			if (!$field) $field = 0;
			return $field+1;
		}


		protected function generateTextualTransactionId( $tran_id ) {
			return sprintf( "%012d" , $tran_id );
		}

		protected function generateBackUrl( $tran_id ) {
			return sprintf( $this->sBackUrlFormatString , $tran_id );
		}

		public function startNewTransaction( $cc_tran_id , $price , $currency = "huf" , $comment ) {
			$real_comment = (isset( $GLOBALS["FNTH_codepage"] )) ?
				iconv( $GLOBALS["FNTH_codepage"] , "ISO-8859-2" , $comment ) :
				$comment;

			// lekerjuk a sajat transaction id-t
			$tran_id = $this->getNextTransactionId();

			// beszurjuk az adatbazisba
			$ins = array();
			$ins["otp_transaction_id"]=sprintf( "%d" , $tran_id );
			$ins["tranid"]=sprintf( "'%s'" , FNTH_db_addslashes( $this->generateTextualTransactionId( $tran_id ) ) );
			$ins["amount"]=sprintf( "%f", $price );
			$ins["currency"]=sprintf( "'%s'" , FNTH_db_addslashes( $currency ) );

			FNTH_db_free_result( FNTH_db_query( FNTH_db_generate_insert_query( "otp_transactions" , $ins ) ) );
			$otp_tran_id = $tran_id;

			// azonnal kitoltjuk, hogy megvan
			if (isset( $this->oCCobj ))
				if (method_exists( $this->oCCobj , "updateBankTransactionId" ))
						$this->oCCobj->updateBankTransactionId( $cc_tran_id , $otp_tran_id );

			ob_start();
			$service = new WebShopService();
			$posId = $this->sPOSId;
			$tranzAzon = $this->generateTextualTransactionId( $tran_id );
			$nyelvkod = "hu";	// RequestUtils::safeParam( $_REQUEST , "nyelvkod" );

			// Ügyfél átirányítása a vevõ oldali felületre
			$custPageTemplate = "https://www.otpbankdirekt.hu/webshop/do/webShopVasarlasInditas?posId={0}&azonosito={1}&nyelvkod={2}";
			$custPageTemplate = ConfigUtils::substConfigValue($custPageTemplate,
				array("0" => urlencode($posId),
					  "1" => urlencode($tranzAzon),
					  "2" => urlencode($nyelvkod)));

			header("Connection: close");
			header("Location: " . $custPageTemplate);
			header("Content-Length: " . ob_get_length());
			ob_end_flush();
			flush();
		
			// BackURL manipláció
			$backUrl = $this->generateBackUrl( $cc_tran_id );
			// Fizetési tranzakció elindítása
			$response = $service->fizetesiTranzakcio(
				$posId,
				$tranzAzon,
				$price,
				strtoupper( $currency ),	// RequestUtils::safeParam($postparams, 'devizanem'),
				$nyelvkod,
				true,	//RequestUtils::safeParam($postparams, 'nevKell'),
				false,	//RequestUtils::safeParam($postparams, 'orszagKell'),
				false,	//RequestUtils::safeParam($postparams, 'megyeKell'),
				false,	//RequestUtils::safeParam($postparams, 'telepulesKell'),
				false,	//RequestUtils::safeParam($postparams, 'iranyitoszamKell'),
				false,	//RequestUtils::safeParam($postparams, 'utcaHazszamKell'),
				false,	//RequestUtils::safeParam($postparams, 'mailCimKell'),
				false,	//RequestUtils::safeParam($postparams, 'kozlemenyKell'),
				true,	//RequestUtils::safeParam($postparams, 'vevoVisszaigazolasKell'),
				"",	//RequestUtils::safeParam($postparams, 'ugyfelRegisztracioKell'),
				"",	//RequestUtils::safeParam($postparams, 'regisztraltUgyfelId'),
				$real_comment,	//RequestUtils::safeParam($postparams, 'shopMegjegyzes'),
				$backUrl,
				"" //RequestUtils::safeParam($postparams, "ketlepcsosFizetes")
			);
			if ($response) {
				return $otp_tran_id;
				// syslog(LOG_NOTICE, "Haromszereplos fizetes keres kuldes: " . $posId . " - " . $tranzAzon . " - " . implode(" ; ",$response->getMessages()));
			} else {
				return false;
				// syslog(LOG_ERR, "Haromszereplos fizetes keres kuldes: " . $posId . " - " . $tranzAzon . " - NEM ERTELMEZHETO VALASZ!");
			}
		}

		protected function getErrorResponse( $responseCode ) {
			$errorMessages = array(
				'050' => 'A megadott kártyaadatok hibásak', 
				'051' => 'A megadott kártya lejárt', 
				'055' => 'A megadott kártya blokkolt.', 
				'056' => 'A megadott kártyaszám ismeretlen', 
				'057' => 'A megadott kártya elvesztett kártya', 
				'058' => 'A megadott kártyaszám érvénytelen', 
				'059' => 'A megadott kártya lejárt', 
				'069' => 'A megadott kártyaadatok hibásak', 
				'070' => 'A megadott kártyaszám érvénytelen, a BIN nem létezik', 
				'072' => 'A megadott kártya letiltott', 
				'074' => 'A megadott kártyaadatok hibásak', 
				'076' => 'A megadott kártyaadatok hibásak', 
				'082' => 'A megadott kártya terhelése a megadott összeggel nem lehetséges (jellemzõen vásárlási limittúllépés miatt)', 
				'089' => 'A megadott kártyaadatok hibásak, vagy nincs elég fedezet', 
				'097' => 'A megadott bankkártya nem aktív', 
				'200' => 'A megadott kártyaadatok hibásak', 
				'204' => 'A megadott kártya terhelése nem lehetséges', 
				'205' => 'Érvénytelen összegû vásárlás', 
				'206' => 'A megadott kártya az üzletági követelményeknek nem felel meg', 
				'901' => 'A megadott kártyaszám érvénytelen, a BIN nem létezik', 
				'902' => 'A megadott kártya lejárt', 
				'903' => 'A megadott bankkártya nem aktív', 
				'909' => 'A megadott kártya terhelése nem lehetséges', 
				'BASE24TIMEOUT' => 'A kártya autorizációs rendszer a beállított idõn belül nem küldött választ.', 
				'BINVISSZAUTASITVA' => 'A megadott kártyaszámmal a fizetési / regisztrálási tranzakció nem engedélyezett a bolt által igényelt bankkártya korlátozás miatt.', 
				'CDVKARTYA' => 'Hibás bankkártyaszám.',
				'DUPLAFIZETES' => 'A megadott tranzakció azonosító nem egyedi, azzal már létezik fizetési tranzakció.', 
				'DUPLALEZARAS' => 'A megadott tranzakció azonosítójú kétlépcsõs fizetés  már lezárásra került, vagy lezárása folyamatban van.', 
				'EXTREMDATUM' => 'Szélsõségesen távoli vagy érvénytelen dátum', 
				'FORMATUMBANKKARTYASZAM' => 'A megadott terhelendõ kártyaszám hibás formátumú', 
				'FORMATUMMENNYISEG' => 'A mennyiség mezõ formátuma nem megfelelõ.', 
				'FORMATUMTELEFONSZAM' => 'A megadott telefonszám nem értelmezhetõ telefonszámként.', 
				'FORMATUMTRANZAZON' => 'Hibás formátumú a megadott tranzakció azonosító.', 
				'HIANYZIKBANKKARTYASZAM' => 'A terhelendõ bankkártya száma nem került megadásra', 
				'HIANYZIKDATUM' => 'A bankkártya lejárat dátuma nem került megadásra', 
				'HIANYZIKLOGIKAI' => 'Kötelezõen kitöltendõ logikai értékû paraméter nem került megadása', 
				'HIANYZIKMENNYISEG' => 'Az összeg mezõ nem került kitöltésre', 
				'HIANYZIKNEV' => 'A név (bankkártya tulajdonos vagy vásárló neve) adat nem került kitöltésre', 
				'HIANYZIKNYELVKOD' => 'A nyelvkód nem került megadásra', 
				'HIANYZIKPOSAZONOSITO' => 'A Shop azonosító üres.', 
				'HIANYZIKSHOPKERESKEDOAZONOSITO' => 'AMEX kártyával történõ fizetés visszautasításra került', 
				'HIANYZIKSHOPPUBLIKUSKULCS' => 'A shop-hoz a Fizetõfelület rendszerében nem található a digitális aláírás ellenõrzéséhez szükséges publikus kulcs.', 
				'HIANYZIKTRANZAZON' => 'A tranzakció azonosító üres', 
				'HIBASCVCCVV' => 'A bankkártya ellenõrzõ (biztonsági) kódja nem vagy hibásan került megadásra', 
				'HIBASDATUM' => 'Hibás dátum formátum', 
				'HIBASDEVIZANEMKOD' => 'A devizanem kód hibás (nemlétezõ vagy nem támogatott devizanem szerepel benne).', 
				'HIBASKLIENSALAIRAS' => 'A kapott digitális aláírás nem hiteles, a tárolt publikus kulccsal ellenõrizve hibás ellenõrzõ összeg keletkezett.', 
				'HIBASLEJARATDATUMA' => 'Hibás formátumú a kártya lejárati dátuma.', 
				'HIBASNYELVKOD' => 'Hibás formátumú vagy hibás értékû nyelvkód érték (lásd ISO 639 nyelvkódokat)', 
				'HIBASPOSAZONOSITO' => 'Hibás formátumú a megadott shop azonosító (POS ID)', 
				'IDONTULIFELOLDAS' => 'A fizetés lezárása és a foglalás feloldása a türelmi idõszakún túl nem lehetséges.', 
				'IDONTULITERHELES' => 'A fizetés lezárása és a terhelés végrehajtása a türelmi idõszakún túl nem lehetséges.', 
				'INDULODATUMNAGYOBBAKTUALIS' => 'A szûrõ idõ intervallum alsó határa nem lehet késõbbi az aktuális idõpontnál.', 
				'KLIENSKODHIBA' => 'A Fizetõfelület tranzakcióiban a kliens kód csak "WEBSHOP lehet', 
				'LEZARTKETLEPCSOSFIZETES' => 'A megadott tranzakció azonosítójú kétlépcsõs fizetésre lezárásra (elutasításra/feloldásra) került, vagy lezárása folyamatban van.', 
				'LETEZOFIZETESITRANZAKCIO' => 'A megadott tranzakció azonosítóval már létezik fizetési tranzakció.',
				'MENNYISEGPOZITIV' => 'A mennyiség mezõ tartalma csak pozitív lehet', 
				'NEMENGWEBSHOPFUNKCIO' => 'A funkció a hívó bolt számára nem engedélyezett.', 
				'NEMKETLEPCSOSFIZETES' => 'A megadott tranzakció azonosító nem kétlépcsõs fizetésre vonatkozik.', 
				'NEMLEZARASRAVAROTRANZAKCIO' => 'A megadott tranzakció nem kétlépcsõs vagy nem a fizetés  lezárására várakozik.', 
				'NEMLOGIKAI' => 'A megadott logikai érték érvénytelen', 
				'NINCSILYENWEBSHOP' => 'A megadott azonosítóval (POS ID) nem létezik ismert shop', 
				'RENDSZERHIBA' => 'Súlyos Fizetõfelület-oldali hiba a folyamat feldolgozása közben. A folyamat beállítási vagy más belsõ probléma miatt nem tudott helyesen lefutni.', 
				'WEBSHOPIPNEMENGEDELYEZETT' => 'Az IP címrõl a Bank nem fogad el fizetõfelület tranzakció kéréseket', 
				'ZARODATUMNAGYOBBINDULO' => 'A szûrõ idõ intervallum felsõ határa nem lehet késõbbi az alsó határ idõpontnál.', 
				'NEMLETEZOWEBSHOPUGYFELAZON' => 'A megadott ügyfél regisztrációs azonosító nem létezik vagy deregisztrálásra került.'
			);
			if (!isset( $errorMessages[$responseCode] )) return false;
			return $errorMessages[$responseCode];
		}

		public function requestTransactionAck( $tran_id ) {
			$retval = array();
			$retval["status"]=CC_STATUS_SUCCESSFUL;

			$query = sprintf( "select * from otp_transactions where otp_transaction_id=%d" , $tran_id );
			$otp_tran = FNTH_db_get_row( $query );

			$posId = $this->sPOSId;
			$tranzAzon = $this->generateTextualTransactionId( $tran_id );
			$timedom = FNTH_convert_YmdHis_to_unix( $otp_tran["ctstamp"] );
			$service = new WebShopService();
			$response = $service->tranzakcioStatuszLekerdezes($posId, $tranzAzon, 1, $timedom-86400,$timedom+30*86400 );
			if (!$response) {
				$retval["status"]=CC_STATUS_UNAVAILABLE_ERROR;
				return $retval;
			}

			$answer = $response->getAnswer();
			if (!$response->isSuccessful() || !$answer || !count( $answer->getWebShopFizetesAdatok()) ) {
				$retval["status"]=CC_STATUS_UNAVAILABLE_ERROR2;
				return $retval;
			}

			$fizetesAdatok = $answer->getWebShopFizetesAdatok();
			$tranzAdatok = current($fizetesAdatok);

			$responseCode = $tranzAdatok->getPosValaszkod();
			$retval["responsecode"]=$responseCode;

			$successPosResponseCodes = array(
				"000", "00", "001", "002", "003", "004",
				"005", "006", "007", "008", "009", "010");

			if ($tranzAdatok->isSuccessful()) {
				$retval["status"]=CC_STATUS_SUCCESSFUL;
				return $retval;
			} else {
				switch ($responseCode) {
				case "VISSZAUTASITOTTFIZETES":
					$retval["status"]=CC_STATUS_CANCELED;
					$retval["errormessage"]="Visszautasított fizetés";
					return $retval;
				case "FIZETESTIMEOUT":
					$retval["errormessage"]="Time out - sikertelen kísérlet";
					$retval["status"]=CC_STATUS_CANCELED;
					return $retval;
				default:
					$error_message = $this->getErrorResponse( $responseCode );
					if ($error_message) {
						$retval["status"]=CC_STATUS_CANCELED;
						$retval["errormessage"]=$error_message;
						return $retval;
					} else {
						FNTHLog::logMessage( sprintf( "unknown OTP response code:<%s>" , $responseCode ) );
					}
					$retval["status"]=CC_STATUS_DECLINED;
					return $retval;
				}
			}
			return $retval;
		}

		public function finishTransaction( $tran_id ) {
			$response = $this->requestTransactionAck( $tran_id );
			$upd = array();
			if (isset( $response["responsecode"] )) {
				$upd["informations"]=sprintf( "'%s'" , FNTH_db_addslashes( serialize( $response ) ) );
			}
			switch ($response["status"]) {
			case CC_STATUS_SUCCESSFUL:
				$upd["paid_tstamp"]="now()";
				break;
			case CC_STATUS_CANCELED:
				$upd["cancel_tstamp"]="now()";
				if (isset( $response["errormessage"] ))
					$upd["comments"]=sprintf( "'%s'" , FNTH_db_addslashes( $response["errormessage"] ) );
				break;
			default:
				// valami hiba es megsem sikerul lekerdezni
				return $response["status"];
			}
			$query = FNTH_db_generate_update_query( "otp_transactions" , $upd , sprintf( "otp_transaction_id=%d",$tran_id ) );
			FNTH_db_free_result( FNTH_db_query( $query ) );
			return $response["status"];
		}
	}

?>
