<?php
/**
DOCS:
https://api.netcash.co.za/inbound-payments/pay-now/pay-now-ecommerce/
**/
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($_POST, 'netcash_payments');
/**
NOTIFY URL:
===========

Field No:	Field Name:				Type		Description:
---------	----------------------	---------	-----------------------------------------------------------------------------------
1			TransactionAccepted		Boolean		“true” means the transaction was successful
2			CardHolderIpAddr		AN			This is the original IP the request was made from
3			RequestTrace			AN			This is a unique trace id for the transaction. This id can be used to retrieve 
												additional information from the 3rd Party transaction logs
4			Reference				AN			This is the unique reference that you sent Netcash in the original request
5			Extra1					AN			This is the extra field you sent up in the m4 variable when you made the request 
												that we return for you to integrate into your own system.
6			Extra2					AN			This is the extra field you sent up in the m5 variable when you made the request 
												that we return for you to integrate into your own system.
7			Extra3					AN			This is the extra field you sent up in the m6 variable when you made the request 
												that we return for you to integrate into your own system.
8			Amount					N			This is the amount that you sent Netcash in the original request
9			Method					N			1 Credit card
												2 			Bank EFT
												3 			Retail
												4 			Ozow
												5 			MasterPass
												6 			Visa Checkout
												7			Masterpass QR
10			ccToken					AN			Credit Card Vault GUiD
11			ccHolder				AN			Credit Cardholder name
12			ccMasked				AN			Masked Credit Card number
13			ccExpiry				N			Credit Card expiry date MMCCYY

ACCEPT URL:
===========

Field No:	Field Name:				Type		Description:
---------	----------------------	---------	-----------------------------------------------------------------------------------
1			TransactionAccepted		Boolean		“true” means the transaction was successful
2			CardHolderIpAddr		AN			This is the original IP the request was made from
3			RequestTrace			AN			This is a unique trace id for the transaction. This id can be used to retrieve 
												additional information from the 3rd Party transaction logs
4			Reference				AN			This is the unique reference that you sent Netcash in the original request
5			Extra1					AN			This is the extra field you sent up in the m4 variable when you made the request 
												that we return for you to integrate into your own system.
6			Extra2					AN			This is the extra field you sent up in the m5 variable when you made the request 
												that we return for you to integrate into your own system.
7			Extra3					AN			This is the extra field you sent up in the m6 variable when you made the request 
												that we return for you to integrate into your own system.
8			Amount					N			This is the amount that you sent Netcash in the original request
9			Method					N			1 Credit card
												2 			Bank EFT
												3 			Retail
												4 			Ozow
												5 			MasterPass
												6 			Visa Checkout
												7			Masterpass QR
10			ccToken					AN			Credit Card Vault GUiD
11			ccHolder				AN			Credit Cardholder name
12			ccMasked				AN			Masked Credit Card number
13			ccExpiry				N			Credit Card expiry date MMCCYY

DECLINE URL:
============

Field No:	Field Name:				Type		Description:
---------	----------------------	---------	-----------------------------------------------------------------------------------
1			TransactionAccepted		Boolean		“true” means the transaction was successful
2			CardHolderIpAddr		AN			This is the original IP the request was made from
3			RequestTrace			AN			This is a unique trace id for the transaction. This id can be used to retrieve 
												additional information from the 3rd Party transaction logs
4			Reference				AN			This is the unique reference that you sent Netcash in the original request
5			Extra1					AN			This is the extra field you sent up in the m4 variable when you made the request 
												that we return for you to integrate into your own system.
6			Extra2					AN			This is the extra field you sent up in the m5 variable when you made the request 
												that we return for you to integrate into your own system.
7			Extra3					AN			This is the extra field you sent up in the m6 variable when you made the request 
												that we return for you to integrate into your own system.
8			Amount					N			This is the amount that you sent Netcash in the original request
9			Reason					AN			This is the unpaid reason

REDIRECT URL:
============

Field No:	Field Name:				Type		Description:
---------	----------------------	---------	-----------------------------------------------------------------------------------
1			TransactionAccepted		Boolean		“true” means the transaction was successful
2			CardHolderIpAddr		AN			This is the original IP the request was made from
3			RequestTrace			AN			This is a unique trace id for the transaction. This id can be used to retrieve 
												additional information from the 3rd Party transaction logs
4			Reference				AN			This is the unique reference that you sent Netcash in the original request
5			Extra1					AN			This is the extra field you sent up in the m4 variable when you made the request 
												that we return for you to integrate into your own system.
6			Extra2					AN			This is the extra field you sent up in the m5 variable when you made the request 
												that we return for you to integrate into your own system.
7			Extra3					AN			This is the extra field you sent up in the m6 variable when you made the request 
												that we return for you to integrate into your own system.
8			Amount					N			This is the amount that you sent Netcash in the original request
9			Reason					AN			This is the unpaid reason
10			Method					N			1	Credit card
												2 	Bank EFT
												3 	Retail
												4 	Ozow
												5 	MasterPass
												6 	Visa Checkout
												7	Masterpass QR

URLS:
Accept url:		This is the URL that the browser is sent to if the transaction is successful.
Decline url:	This is the URL that the browser is sent to if the transaction is declined. 
				If a card transaction is cancelled by the card holder during the payment process, the page will redirect to the decline url page.
Notify url:		This is the URL that Netcash will call for transactions like EFT and Retail where the payment is not able to be captured in real time.
				These payments will be picked up when they are made and Netcash will notify your system through this URL.
Redirect url:	This is the URL that the browser is sent to once the complete button is clicked on the EFT and Retail payment screens on Netcash.
				This could/would return the customer to your site while you are waiting for a payment to be made.

**/

/**
    [TransactionAccepted] => false
    [Reason] => Declined
    [CardHolderIpAddr] => 41.13.250.160
    [RequestTrace] => 77459.137796931
    [Reference] => 46:20210608:060238
    [Extra1] => {hash value}
    [Extra2] => 2a2d6c4c1653c86a214a854ef1f9ad60 (Session Id)
    [Extra3] => user_code, base64_Encoded
    [Amount] => 12.34
    [Method] => 1
    [type] => DEPOSITRECEIPT
**/

$txnData = SableDBFunctions::getAjaxResponse($_POST['Extra1'], false); //do not delete the hash here, do it at the end of this file!
SableDebug::debugfetch($txnData, "netcash_reply");

/** 
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'
								];
		];

**/

$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'];
$memberGymName	= $sableDB->getValue("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 = {$userCode}");

$payMethod = $sableDB->getValue('select pay_type_name from netcash_pay_type where pay_type_id = '.intval($_POST['Method']));
$reason = $_POST['Reason']; //isset($_POST['Reason']) ? intval($_POST['Reason']) : 'NULL';

$ccExpiry = $_POST['ccExpiry'] ?? 0;
$expiryDate	= date('Y-m-d', strtotime($ccExpiry));
$success 	= strtolower($_POST['TransactionAccepted']) === "true" ? 1 : 0;

$ccMasked		= $_POST['ccMasked'] ?? '';
$ccHolder		= $_POST['ccHolder'] ?? '';
$method 		= intval($_POST['Method']) ?? 0;
$requestTrace	= $_POST['RequestTrace'] ?? 0;

$sql =	'update netcash_payment set 
		np_success = '.$success.', 
		np_reason = "'.$reason.'", 
		np_trace_id = "'.$requestTrace.'", 
		np_payment_type = '.$method.', 
		np_description = "'.$PayDescr.'", 
		np_cardholder_name = "'.$ccHolder.'",
		np_card_no = "'.$ccMasked.'",
		np_card_expiry = '.$expiryDate.' 
		where (np_user = "'.$userCode.'") and (np_date = "'.$payTs->format('Y-m-d H:i:s').'")';
		
$res = $sableDB->updateQuery($sql);
SableDebug::debugfetch($res, "netcash_reply");
//Security Check

/**
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}
**/

if ($_POST['RequestTrace'] ?? 0) //if no "RequestTrace" then no transaction, so most likely cancelled.
{
	SableDebug::debugfetch($_POST, "netcash_reply");
	// https://ws.netcash.co.za/PayNow/TransactionStatus/Check?RequestTrace=114.228862205218 
	$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);

	$seccheckcnt = 0;

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

	/** debugging
	SableDebug::debugfetch($_POST, 		'netcash_payments');
	SableDebug::debugfetch($trcdata, 	'netcash_payments');
	**/

	$failMessage = 'This payments security check has failed. This session has been terminated.';
	if ($txnok) 
	{
		//if ($trcdata['Reason'] 		!== $_POST['Reason']) $seccheckcnt++; //problem here?? "Declined" vs "1"
		if ($trcdata['RequestTrace'] !== $_POST['RequestTrace']) 
		{
			$seccheckcnt++;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$trcdata['RequestTrace']} but got '{$_POST['RequestTrace']}'", "netcash_reply");
		}
		
		if ($trcdata['Amount'] !== $_POST['Amount'])
		{
			$seccheckcnt++;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$trcdata['Amount']} but got '{$_POST['Amount']}'");
		}
		
		if ($trcdata['Reference'] !== $_POST['Reference'])
		{
			$seccheckcnt++;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$trcdata['Reference']} but got '{$_POST['Reference']}'", "netcash_reply");
		}
		
		if ($trcdata['Method'] != $_POST['Method'])
		{
			$seccheckcnt++;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$trcdata['Method']} but got '{$_POST['Method']}'", "netcash_reply");
		}
		
		if ($txnData['session_id'] !== $_POST['Extra2'])
		{
			$seccheckcnt++;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$txnData['session_id']} but got '{$_POST['Extra2']}'", "netcash_reply");
		}
		
		$ucdec = SableSystem::SableDecode($_POST['Extra3']);
		if ($userCode != $ucdec)
		{
			$seccheckcnt++;
			SableDebug::debugfetch("Security Check Failure: Expecting '{$userCode} but got '{$ucdec}'", "netcash_reply");
		}

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

	$sql =	'update netcash_payment 
			set reason_code = '.intval($trcdata['Method']).' 
			where (np_user = '.$userCode.') and (np_date = "'.$payTs->format('Y-m-d H:i:s').'")';

	$res = $sableDB->updateQuery($sql);
	SableDebug::debugfetch($res, "netcash_reply");

	if ($seccheckcnt) 
	{
		SableDebug::debugfetch($seccheckcnt, "netcash_reply");
		notifyUser($userCode, $failMessage);
		SableGeneralFunctions::revertToLoginPage($failMessage);
	}

	//initialise with 'Unknown - something went wrong' message:
	$dispIcon	= 'fas fa-exclamation-triangle';
	$dispTitle	= 'Something Went Wrong';
	$dispCap	= 'Your payment could not be confirmed.';

	SableDebug::debugfetch($txnok, "netcash_reply");
	SableDebug::debugfetch($success, "netcash_reply");
	if ($txnok && $success)
	{
		/*
		!! Notify iTensity of the successful payment here so that we can have a new balance when the user returns to the dashboard!!
		Array
		(
			[TransactionAccepted] => true
			[Reason] => Success 
			[CardHolderIpAddr] => 41.13.66.178 
			[RequestTrace] => 77459.177504026 
			[Reference] => 3620220618_103805 
			[Extra1] => {HASH VALUE} 
			[Extra2] => 4383f8a368c7769d5debc637caab8069 
			[Extra3] => Airtime Purchase
			[Amount] => 12.34 
			[Method] => 1 )
		*/	
		notifyUser($userCode, $PayDescr.' payment successful. Thank you!');
		$dispIcon	= 'fas fa-smile-beam';
		$dispTitle	= 'Thank You!';
		$dispCap	= 'Your payment was successful.';
	}
	else
	{
		notifyUser($userCode, $failMessage);
		$dispIcon	= 'fas fa-frown';
		$dispTitle	= 'Payment Unsuccessful';
		$dispCap	= '<p>Unfortunately your online payment was unsuccessful. Please try again, or use an alternative payment method.</p>
					<p><span class="gym4free">gym4free</span> benefits will not be available if your account is in arrears.</p>
					<p>Please contact Gym Company '.$memberGymName.' for further assistance.</p>';
		//SableGeneralFunctions::divertFromPage('home/', $failMessage);
	}
}
else
{
	$txnok		= 0;
	$dispIcon	= 'fas fa-ban';
	$dispTitle	= 'Transaction Cancelled';
	$dispCap	= '<p>The transaction was not processed.</p>
				<p><span class="gym4free">gym4free</span> benefits will not be available if your account is in arrears.</p>
				<p>Please contact Gym Company '.$memberGymName.' for further assistance.</p>';
	//SableGeneralFunctions::divertFromPage('home/', $failMessage);
}
<div class="forms" style="min-height: 15px !important;">
	<div class="container forms-grids">
		<div class="row forms-grid">
			<div class="col-md-12">
				<h3 class="title"><i class="<?= $dispIcon ?>" aria-hidden="true"></i>&nbsp;<?= $dispTitle ?></h3>
				<p></p>
			</div>
		</div>
		<div class="row forms-grid">
			<div class="col-md-12">
				<p></p>
				<h2 class="sub"><?= $dispCap ?></h2>
			</div>
		</div>
		<div class="row forms-grid">
			<div class="col-md-12">
				<p></p>
				<h3 class="sub">Payment Details:</h3>
			</div>
		</div>
		<div class="row forms-grid">
			<div class="col-xs-3 col-md-2"><strong>Method:</strong></div>
			<div class="col-xs-8 col-md-10"><?= $payMethod ?></div>
		</div>
		<div class="row forms-grid">
			<div class="col-xs-3 col-md-2"><strong>Description:</strong></div>
			<div class="col-xs-8 col-md-10"><?= $PayDescr ?></div>
		</div>		
		<div class="row forms-grid">
			<div class="col-xs-3 col-md-2"><strong>Amount:</strong></div>
			<div class="col-xs-8 col-md-10"><?= $ZARAmount ?></div>
		</div>
		
		<?php
		/**
		echo('--POST--<br>');
		print_r($_POST);
		echo('<br>');
		print_r('ok: '.$txnok);
		echo('<br>');
		print_r('success: '.$success);
		echo('--DATA--<br>');
		print_r($txnData);
		**/
		if ($txnok && $success)
		{
			//only allow a redirect if the transaction was successful.
			if ($txnData['redirect'])
			{
				include_once($txnData['file_path']); //will now use $txnData['param_data'] as the fields required for this file
		?>
		<div class="row forms-grid">
			<div class="col-xs-3 col-md-2"><strong>Result:</strong></div>		
			<div class="col-xs-8 col-md-10"><?= $result ?></div>
		</div>
		<?php
			}
		}
		?>
		
		<div class="row forms-grid">
			<div class="col-md-12">
				<p></p>
			</div>
		</div>
		<!--// buttons 
		<div class="row forms-grid">
			<div class="col-md-2">
				<input type="button" id="btnCancel" value="Back"
				class="submit" onclick="window.location = '<?php SableSystem::printCallPageLink('/home/'); ?>'"/>
			</div>
		</div>
		 buttons //-->		
	</div>
</div>
<?php
SableDBFunctions::deleteAjaxResponse($_POST['Extra1']); //cleanup
