<?php

	require_once(dirname(dirname(__FILE__)) . '/gateway.core.cls.5.php');
	require_once(dirname(__FILE__) . '/cashflows.cls.php');


	class Gateway extends GatewayCore
	{
		const PAYMENT_METHOD = 'paypal';

		// Load iDEAL settings
		public function __construct()
		{
			$this->init();
		}

		// Setup payment
		public function doSetup()
		{
			global $aIdealCheckout;

			$sHtml = '';

			// Look for proper GET's en POST's
			if(empty($_GET['order_id']) || empty($_GET['order_code']))
			{
				$sHtml .= '<p>Invalid transaction request.</p>';
			}
			else
			{
				$sOrderId = $_GET['order_id'];
				$sOrderCode = $_GET['order_code'];


				// Lookup transaction
				if($this->getRecordByOrder())
				{
					if(strcmp($this->oRecord['transaction_status'], 'SUCCESS') === 0)
					{
						$sHtml .= '<p>Transaction already completed</p>';
					}
					elseif((strcmp($this->oRecord['transaction_status'], 'OPEN') === 0) && !empty($this->oRecord['transaction_url']))
					{
						header('Location: ' . $this->oRecord['transaction_url']);
						exit;
					}
					else
					{
						$sReturnUrl = idealcheckout_getRootUrl(1) . 'idealcheckout/return.php?order_id=' . $this->oRecord['order_id'] . '&order_code=' . $this->oRecord['order_code'];
						$sReportUrl = idealcheckout_getRootUrl(1) . 'idealcheckout/report.php?order_id=' . $this->oRecord['order_id'] . '&order_code=' . $this->oRecord['order_code'];
						// $sReportUrl = idealcheckout_getRootUrl(1) . 'idealcheckout/report.php';
						$sLanguageCode = (empty($this->oRecord['language_code']) ? 'nl' : $this->oRecord['language_code']);

						$oCashFlows = new CashflowsPayment($this->aSettings['PASSWORD_KEY'], $this->aSettings['CONFIGURATION_ID']);

						if(!empty($this->aSettings['TEST_MODE']))
						{
							$oCashFlows->setTestmode();
						}

						$oCashFlows->setPaymentMethod(self::PAYMENT_METHOD);
						$oCashFlows->setLocale('nl_NL');
						$oCashFlows->setOrderDescription($this->oRecord['order_id'], $this->oRecord['transaction_description']);
						$oCashFlows->setOrderAmount($this->oRecord['transaction_amount']);
						$oCashFlows->setCurrencyCode($this->oRecord['currency_code']);
						$oCashFlows->setReturnUrl($sReturnUrl);
						$oCashFlows->setReportUrl($sReportUrl);


						$bCustomerDataError = false;
						$aCustomerData = array();

						$bProductDataError = false;
						$aProductData = array();

						if(!empty($this->oRecord['order_params']))
						{
							$aOrderParams = idealcheckout_unserialize($this->oRecord['order_params']);

							if(isset($aOrderParams['customer']) && isset($aOrderParams['customer']['shipment_first_name']) && isset($aOrderParams['customer']['shipment_last_name']) && isset($aOrderParams['customer']['shipment_street_name']) && isset($aOrderParams['customer']['shipment_street_number']) && isset($aOrderParams['customer']['shipment_zipcode']) && isset($aOrderParams['customer']['shipment_city']) && isset($aOrderParams['customer']['shipment_country_code']))
							{
								$aCustomerData['firstName'] = substr($aOrderParams['customer']['shipment_first_name'], 0, 20);
								$aCustomerData['middleName'] = '';
								$aCustomerData['lastName'] = substr($aOrderParams['customer']['shipment_last_name'], 0, 50);
								$aCustomerData['addressLine1'] = substr($aOrderParams['customer']['shipment_street_name'] . ' ' . $aOrderParams['customer']['shipment_street_number'], 0, 100);
								$aCustomerData['zipCode'] = substr($aOrderParams['customer']['shipment_zipcode'], 0, 10);
								$aCustomerData['city'] = substr($aOrderParams['customer']['shipment_city'], 0, 40);
								$aCustomerData['countryIso3166Alpha2'] = substr($aOrderParams['customer']['shipment_country_code'], 0, 2);
							}
							else
							{
								idealcheckout_log('Customer data is incomplete.', __FILE__, __LINE__);
								$bCustomerDataError = true;
							}

							if(isset($aOrderParams['products']) && is_array($aOrderParams['products']) && sizeof($aOrderParams['products']))
							{
								foreach($aOrderParams['products'] as $k => $v)
								{
									if(isset($v['description']) && isset($v['quantity']) && isset($v['price_incl']) && isset($v['vat']))
									{
										$aProduct = array();

										$aProduct['lineNumber'] = $k;
										$aProduct['type'] = (in_array('PHYSICAL', array('PHYSICAL')) ? 'PhysicalItem' : 'DigitalItem');
										$aProduct['name'] = substr(preg_replace('/([^a-zA-Z0-9_\- ]+)/', '', $v['description']), 0, 50);
										$aProduct['description'] = substr(preg_replace('/([^a-zA-Z0-9_\- ]+)/', '', $v['description']), 0, 100);
										$aProduct['quantity'] = strval($v['quantity']);
										$aProduct['unitPriceInclVat'] = CashflowsPayment::convertAmountToString($v['price_incl']);
										$aProduct['totalLineAmount'] = CashflowsPayment::convertAmountToString($v['price_incl']);

										$aProductData[] = $aProduct;
									}
									else
									{
										idealcheckout_log('Product data is incomplete.', __FILE__, __LINE__);
										idealcheckout_log($v, __FILE__, __LINE__);
										$bProductDataError = true;
									}
								}
							}
							else
							{
								idealcheckout_log('Product data is incomplete.', __FILE__, __LINE__);
								$bProductDataError = true;
							}


							if($bCustomerDataError || $bProductDataError)
							{
								idealcheckout_log('This application doesn\'t seem to support Cashflows.', __FILE__, __LINE__);
							}
							else
							{
								$oCashFlows->setBillingData($aCustomerData);
								$oCashFlows->setOrderLines($aProductData);
							}
						}

						if($oCashFlows->getTransaction())
						{
							$this->oRecord['transaction_params'] = $oCashFlows->getJsonResponse();
							$this->oRecord['transaction_url'] = $oCashFlows->getTransactionUrl();
							$this->oRecord['transaction_status'] = 'PENDING';

							if(empty($this->oRecord['transaction_log']) == false)
							{
								$this->oRecord['transaction_log'] .= "\n\n";
							}

							$this->oRecord['transaction_log'] .= 'Requesting transaction on ' . date('Y-m-d, H:i:s') . '; recieved ID: "' . $this->oRecord['transaction_id'] . '" and URL: "' . $this->oRecord['transaction_url'] . '".';
							$this->save();

							header('Location: ' . $this->oRecord['transaction_url']);
							exit;
						}
						else
						{
							$sHtml .= '<p>' . $oCashFlows->getJsonResponse() . '</p>';
						}
					}
				}
				else
				{
					$sHtml .= '<p>Invalid transaction request.</p>';
				}
			}

			idealcheckout_output($sHtml);
		}


		// Catch return
		public function doReturn()
		{
			$sHtml = '';

			if(empty($_GET['order_id']) || empty($_GET['order_code']) && empty($_GET['paymentjobref']))
			{
				$sHtml .= '<p>Invalid return request.</p>';
			}
			else
			{
				$sPaymentJobReference = $_GET['paymentjobref'];

				// Lookup record
				if($this->getRecordByOrder())
				{
					// Verify status
					$oCashFlows = new CashflowsPayment($this->aSettings['PASSWORD_KEY'], $this->aSettings['CONFIGURATION_ID']);

					if(!empty($this->aSettings['TEST_MODE']))
					{
						$oCashFlows->setTestmode();
					}

					if(strcmp($this->oRecord['transaction_status'], 'SUCCESS') !== 0)
					{
						$sTransactionStatus = $oCashFlows->getStatus($sPaymentJobReference);

						$this->oRecord['transaction_status'] = $sTransactionStatus;
						$this->oRecord['transaction_params'] = $oCashFlows->getJsonResponse();

						if(empty($this->oRecord['transaction_log']) == false)
						{
							$this->oRecord['transaction_log'] .= "\n\n";
						}

						$this->oRecord['transaction_log'] .= 'Executing StatusRequest on ' . date('Y-m-d, H:i:s') . ' for #' . $this->oRecord['transaction_id'] . '. Recieved: ' . $this->oRecord['transaction_status'];

						$this->save();

						// Handle status change
						if(function_exists('idealcheckout_update_order_status'))
						{
							idealcheckout_update_order_status($this->oRecord, 'doReturn');
						}

						// Set status message
						if(in_array($this->oRecord['transaction_status'], array('SUCCESS')))
						{
							if(!empty($this->oRecord['transaction_success_url']))
							{
								header('Location: ' . $this->oRecord['transaction_success_url']);
								exit;
							}

							$sHtml .= '<p>Uw betaling is met succes ontvangen.<br><input style="margin: 6px;" type="button" value="Terug naar de website" onclick="javascript: document.location.href = \'' . htmlspecialchars(idealcheckout_getRootUrl(1)) . '\'"></p>';
						}
						elseif(in_array($this->oRecord['transaction_status'], array('OPEN', 'PENDING')))
						{
							if(!empty($this->oRecord['transaction_pending_url']))
							{
								header('Location: ' . $this->oRecord['transaction_pending_url']);
								exit;
							}

							$sHtml .= '<p>Uw betaling is in behandeling.<br><input style="margin: 6px;" type="button" value="Terug naar de website" onclick="javascript: document.location.href = \'' . htmlspecialchars(idealcheckout_getRootUrl(1)) . '\'"></p>';
						}
						elseif(in_array($this->oRecord['transaction_status'], array('CANCELLED')))
						{
							if(!empty($this->oRecord['transaction_failure_url']))
							{
								header('Location: ' . $this->oRecord['transaction_failure_url']);
								exit;
							}

							$sHtml .= '<p>Uw betaling is geannuleerd. Probeer opnieuw te betalen.<br><input style="margin: 6px;" type="button" value="Verder" onclick="javascript: document.location.href = \'' . htmlspecialchars(idealcheckout_getRootUrl(1) . 'idealcheckout/setup.php?order_id=' . $this->oRecord['order_id'] . '&order_code=' . $this->oRecord['order_code']) . '\'"></p>';
						}
						else // if(strcasecmp($this->oRecord['transaction_status'], 'FAILURE') === 0)
						{
							if(!empty($this->oRecord['transaction_failure_url']))
							{
								header('Location: ' . $this->oRecord['transaction_failure_url']);
								exit;
							}

							$sHtml .= '<p>Uw betaling is mislukt. Probeer opnieuw te betalen.<br><input style="margin: 6px;" type="button" value="Verder" onclick="javascript: document.location.href = \'' . htmlspecialchars(idealcheckout_getRootUrl(1) . 'idealcheckout/setup.php?order_id=' . $this->oRecord['order_id'] . '&order_code=' . $this->oRecord['order_code']) . '\'"></p>';
						}
					}
					else
					{
						$sHtml .= '<p>Status SUCCESS already found, payment already processed.</p>';
					}
				}
				else
				{
					$sHtml .= '<p>Invalid return request.</p>';
				}
			}

			idealcheckout_output($sHtml);
		}


		// Catch report
		public function doReport()
		{
			$sHtml = '';

			$sJsonData = @file_get_contents('php://input');

			if(in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '94.215.210.107', '62.41.33.240', '::ffff:62.41.33.240')))
			{
				$sJsonData = json_encode(array('notifyType' => 'PaymentStatusChange', 'paymentJobReference' => '190821017339387912', 'paymentReference' => '190821117196777484'));
			}

			if(empty($sJsonData))
			{
				$sHtml .= '<p>Invalid notification call.</p>';
			}
			else
			{
				$aPostData = json_decode($sJsonData, true);

				$sPaymentJobReference = $aPostData['paymentJobReference'];

				if($this->getRecordByOrder())
				{
					// Verify status
					$oCashFlows = new CashflowsPayment($this->aSettings['PASSWORD_KEY'], $this->aSettings['CONFIGURATION_ID']);

					if(!empty($this->aSettings['TEST_MODE']))
					{
						$oCashFlows->setTestmode();
					}

					if(strcmp($this->oRecord['transaction_status'], 'SUCCESS') !== 0)
					{
						$sTransactionStatus = $oCashFlows->getStatus($sPaymentJobReference);

						$this->oRecord['transaction_status'] = $sTransactionStatus;
						$this->oRecord['transaction_params'] = $oCashFlows->getJsonResponse();

						if(empty($this->oRecord['transaction_log']) == false)
						{
							$this->oRecord['transaction_log'] .= "\n\n";
						}

						$this->oRecord['transaction_log'] .= 'Executing Callback StatusRequest on ' . date('Y-m-d, H:i:s') . ' for #' . $sPaymentJobReference . '. Recieved: ' . $this->oRecord['transaction_status'];

						$this->save();

						// Handle status change
						if(function_exists('idealcheckout_update_order_status'))
						{
							idealcheckout_update_order_status($this->oRecord, 'doReport');
						}
						else
						{
							if(in_array($this->oRecord['transaction_status'], array('SUCCESS')))
							{
								if(!empty($this->oRecord['transaction_success_url']))
								{
									idealcheckout_log('Calling success URL: ' . $this->oRecord['transaction_success_url'], __FILE__, __LINE__);
									idealcheckout_doHttpRequest($this->oRecord['transaction_success_url']);
								}
							}
							elseif(in_array($this->oRecord['transaction_status'], array('OPEN', 'PENDING')))
							{
								if(!empty($this->oRecord['transaction_pending_url']))
								{
									idealcheckout_log('Calling pending URL: ' . $this->oRecord['transaction_pending_url'], __FILE__, __LINE__);
									idealcheckout_doHttpRequest($this->oRecord['transaction_pending_url']);
								}
							}
							elseif(in_array($this->oRecord['transaction_status'], array('CANCELLED')))
							{
								if(!empty($this->oRecord['transaction_failure_url']))
								{
									idealcheckout_log('Calling cancel URL: ' . $this->oRecord['transaction_failure_url'], __FILE__, __LINE__);
									idealcheckout_doHttpRequest($this->oRecord['transaction_failure_url']);
								}
							}
							else // if(strcasecmp($this->oRecord['transaction_status'], 'FAILURE') === 0)
							{
								if(!empty($this->oRecord['transaction_failure_url']))
								{
									idealcheckout_log('Calling failure URL: ' . $this->oRecord['transaction_failure_url'], __FILE__, __LINE__);
									idealcheckout_doHttpRequest($this->oRecord['transaction_failure_url']);
								}
							}
						}
					}
					else
					{
						idealcheckout_log('Status SUCCESS already found, payment already processed.', __FILE__, __LINE__);
					}
				}
				else
				{
					idealcheckout_log('Invalid return request.', __FILE__, __LINE__);
				}
			}

			idealcheckout_output($sHtml);
		}
	}

?>