<?php
/**
DOCS:
https://api.netcash.co.za/inbound-payments/pay-now/pay-now-ecommerce/

Netcash will always send a response to the Notify URL - this is asynchronous and this is the URL that should be used to write the transaction status to the database.

The Accept and Deline URL's are just synchronous responses to keep the user updated on the status of the transaction and, if there is a time delay from the bank (security), then the Accept URL will not contain important information such as the Trace ID - that will be sent to the Notify URL when ready.
**/
require_once(__DIR__.'/../includes/sysinit.php');
define('LOG_FILE_NAME', '000_Netcash_Payment');

require_once(SABLE_CLASS_PATH.'firebase_messaging.php');

function notifyUser($userCode, $message)
{
	$fcm = new FirebaseMessaging;
	$fcm->sendUserMessage('Gym Company Payment', $message, $userCode, SABLE_URL_ROOT.'signin');
	unset($fcm);
	//SableDebug::debugfetch('['.$userCode.'] '.$message, LOG_FILE_NAME);
}

function compareSecValue($val1, $val2)
{
	return ($val ?? 0) === ($val2 ?? 0);
}

$txnData = SableDBFunctions::getAjaxResponse($_POST['Extra1'], false); //do not delete the hash here, do it at the end of this file!
//SableDebug::debugfetch($txnData, LOG_FILE_NAME);
//SableDebug::debugfetch($_POST, LOG_FILE_NAME);
/** 
txnData = [
			'user_code'		=>	76,
			'user_email'	=>	'jeandre@rupetec.co.za',
			'user_cell'		=>	'0722128645',
			'amount'		=>	12.34,
			'reference'		=>	76:2022-06-20:13-15-28,
			'description'	=>	'Airtime Purchase',
			'redirect'		=>	1,
			'session_id'	=>  '2a2d6c4c1653c86a214a854ef1f9ad60',

			'file_path'		=>	'airtime/result.php',
			'param_data'	=>	[
									//from here each file will have its own parameters relevant to the call. This example is for the purchase of Airtime:
									'amount'	=> 6.00,
									'number'	=> '072212864',
									'product_id'=> 11097
								];
		];

**/

$refData = explode(':', $_POST['Reference']);
$userCode = $refData[0];
$payTs = DateTime::createFromFormat('Y-m-d H-i-s', $refData[1].' '.$refData[2]);

$ZARAmount		= 'R'.$_POST['Amount'];
$PayDescr		= $txnData['description'] ?? '';
$txnUserCode	= $txnData['user_code'] ?? 0;
$qry			= "select gym_name 
					from member_registration 
					inner join user on user.user_id = member_registration.user_id 
					inner join gyms on gyms.gym_id = member_registration.gym_id 
					where user.user_code = {$txnUserCode}";

$memberGymName	= $sableDB->getValue($qry);
$method 		= intval($_POST['Method']) ?? 0;
if ($method)
{
	$payMethod = $sableDB->getValue("select pay_type_name from netcash_pay_type where pay_type_id = {$method}");
}
else
{
	$payMethod = "Unknown";
}
$reason		= $_POST['Reason']; //isset($_POST['Reason']) ? intval($_POST['Reason']) : 'NULL';
$ccExpiry	= $_POST['ccExpiry'] ?? 0;
$expiryDate	= $ccExpiry ? "'".date('Y-m-d', strtotime($ccExpiry))."'" : 'NULL';
$success 	= strtolower($_POST['TransactionAccepted']) === "true" ? 1 : 0;

$ccMasked		= $_POST['ccMasked'] ?? '';
$ccHolder		= $_POST['ccHolder'] ?? '';
$requestTrace	= $_POST['RequestTrace'] ?? 0;

/**
Transaction trace
After the transaction has been delivered back to your servers you may want to check the result to make sure that what was posted back was in fact the same as the transaction data on the server. This can be done by sending a request that contains the ‘RequestTrace’ parameter to our severs that will return the transaction data to the calling service.
You would call the following URL: https://ws.netcash.co.za/PayNow/TransactionStatus/Check?RequestTrace=114.228862205218 where 114.228862205218 represents the ‘RequestTrace’ parameter and it would reply with a JSON string with the data that would look like this:

{“RequestTrace”:”114.228862205218″,”Amount”:”4.00″,”TransactionAccepted”:false, ”Reference”:”22, Reason”:”Invalid card number”}

{"RequestTrace":"77459.137797301","Amount":"12.34","Reason":"1","Reference":"46:20210608:090529","TransactionAccepted":false,"Logs":null,"Method":1}
**/
$txnok 			= 0;
$seccheckcnt	= 0;
$failMessage	= 'This payments security check has failed. This session has been terminated.';

if ($_POST['RequestTrace'] ?? 0) //if no "RequestTrace" then no transaction, so most likely cancelled.
{
	$url = 'https://ws.netcash.co.za/PayNow/TransactionStatus/Check?RequestTrace='.$_POST['RequestTrace'];
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_NOBODY, false);
	curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_HOST']);
	curl_setopt($ch, CURLOPT_POST, false);
	$result = curl_exec($ch);
	curl_close($ch);
	$trcdata = json_decode($result, true);

	$txnok = intval($trcdata['TransactionAccepted']);

	//Here we conduct our security checks:
	if ($txnok) 
	{
		//if ($trcdata['Reason'] 		!== $_POST['Reason']) $seccheckcnt++; //problem here?? "Declined" vs "1"
		if (compareSecValue($trcdata['RequestTrace'], $_POST['RequestTrace']))
		{
			$seccheckcnt++;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$trcdata['RequestTrace']}' but got '{$_POST['RequestTrace']}'", LOG_FILE_NAME);
		}
		
		if (compareSecValue($trcdata['Amount'] , $_POST['Amount']))
		{
			$seccheckcnt++;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$trcdata['Amount']}' but got '{$_POST['Amount']}'", LOG_FILE_NAME);
		}
		
		if (compareSecValue($trcdata['Reference'] , $_POST['Reference']))
		{
			$seccheckcnt++;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$trcdata['Reference']}' but got '{$_POST['Reference']}'", LOG_FILE_NAME);
		}
		
		if (compareSecValue($trcdata['Method'] , $_POST['Method']))
		{
			$seccheckcnt++;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$trcdata['Method']}' but got '{$_POST['Method']}'", LOG_FILE_NAME);
		}
		
		if (compareSecValue(($txnData['session_id'] ?? 0), $_POST['Extra2']))
		{
			$seccheckcnt++;
			$tsess = $txnData['session_id'] ?? 0;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$tsess}' but got '{$_POST['Extra2']}'", LOG_FILE_NAME);
		}
		
		$ucdec = SableSystem::SableDecode($_POST['Extra3']);
		if ($userCode != $ucdec)
		{
			$seccheckcnt++;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$userCode}' but got '{$ucdec}'", LOG_FILE_NAME);
		}

	}
	else
	{
		$failMessage = 'Transaction failed: '.$_POST['Reason'];
	}	
}
