Scripts

Ideal Professional

Code voor de implementatie van iDEAL Professional (voorheen Basic), geschikt voor PHP 5. Voor meer achtergrond informatie over iDEAL installatie, zie: Ideal Basic De 'standaard code' van de bank zijn vervangen voor eigen geschreven classes, geschikt voor PHP 5. Net als in de tutorial van Ideal Basic bestaat het proces uit 3 stappen (step1.php, step2.php en step3.php IdealRequest (algemene class) Algemene functionaliteit. IssuerRequest (extends IdealRequest) Helpt bij het opvragen van de lijst met banken. TransactionRequest (extends IdealRequest) Helpt bij het opzetten van een transactie. StatusRequest (extends IdealRequest) Helpt bij het opvragen van de status van een transactie. Cerificaten Plaats je privé certificaat (private.cer) en je privé sleutel (private.key) samen met de publieke certificaten (rabobank.cer, ingbank.cer, enz) in 1 map. Zorg dat de map niet toegankelijk is voor de bezoekers van uw website. Stel met setSecurePath het pad in naar deze map. Upload je private.cer ook in je iDEAL Dashboard van je bank (zowel LIVE als TEST omgeving). Code downloaden Alle code kun je eenvoudig downloaden via: ideal.php5.zip Aanvraag/oproep Ik ben nog op zoek naar de publieke certificaten van de Fortis en SNS Bank. Ook ben ik voor deze banken nog op zoek naar de URLs voor communicatie met de hun server (zowel TEST als LIVE server). Als iemand deze voor me heeft hoor ik het graag... Het blijkt dat de fortis alleen een ideal oplossing biedt via www.neossolution.com (een alle-betaalmethoden-in-1 oplossing). De SNS bank biedt helemaal geen ondersteuning voor IDEAL.

ideal-professional
FILE: ideal.cls.php
[code]
<?php

	class IdealRequest
	{
		private $aErrors = array();

		// Security settings
		protected $sSecurePath;
		protected $sPrivateKeyPass;
		protected $sPrivateKeyFile;
		protected $sPrivateCertificateFile;
		protected $sPublicCertificateFile;

		// Account settings
		protected $sAquirerUrl;
		protected $sMerchantId;
		protected $sSubId;

		// Constants
		protected $LF = "\n";
		protected $CRLF = "\r\n";

		public function __construct()
		{
			$this->sPrivateKeyFile = 'private.key';
			$this->sPrivateCertificateFile = 'private.cer';
		}

		// Should point to directory with .cer and .key files
		public function setSecurePath($sPath)
		{
			$this->sSecurePath = $sPath;
		}

		// Set password to generate signatures
		public function setPrivateKey($sPass)
		{
			$this->sPrivateKeyPass = $sPass;
		}

		// Set MerchantID id and SubID
		public function setMerchant($sMerchantId, $sSubId = 0)
		{
			$this->sMerchantId = $sMerchantId;
			$this->sSubId = $sSubId;
		}

		// Set aquirer (Use: Rabobank, ING Bank, etc)
		public function setAquirer($sIssuer, $bTestMode = false)
		{
			if(stripos($sIssuer, 'rabo') !== false) // Rabobank
			{
				$this->sPublicCertificateFile = 'rabobank.cer';
				$this->sAquirerUrl = 'ssl://ideal' . ($bTestMode ? 'test' : '') . '.rabobank.nl:443/ideal/iDeal';
			}
			elseif(stripos($sIssuer, 'ing') !== false) // ING Bank
			{
				$this->sPublicCertificateFile = 'ingbank.cer';
				$this->sAquirerUrl = 'ssl://ideal' . ($bTestMode ? 'test' : '') . '.secure-ing.com:443/ideal/iDeal';
			}
			elseif(stripos($sIssuer, 'abn') !== false) // ABN Amro
			{
				$this->sPublicCertificateFile = 'abnamro.cer';
				$this->sAquirerUrl = 'ssl://idealm-et.abnamro.nl:443/';
			}
			elseif(stripos($sIssuer, 'fortis') !== false) // Fortis Bank
			{
				$this->sPublicCertificateFile = 'fortisbank.cer';
				// $this->sAquirerUrl = 'ssl://;
			}
			elseif(stripos($sIssuer, 'sns') !== false) // SNS Bank
			{
				$this->sPublicCertificateFile = 'snsbank.cer';
				// $this->sAquirerUrl = 'ssl://';
			}
			else // Unknown issuer
			{
				$this->setError('Unknown aquirer. Please use Rabobank, ING Bank, ABN Amro, SNS Bank or Fortis.', false, __FILE__, __LINE__);
				return false;
			}
		}




		// Error functions
		protected function setError($sDesc, $sCode = false, $sFile = 0, $sLine = 0)
		{
			$this->aErrors[] = array('desc' => $sDesc, 'code' => $sCode, 'file' => $sFile, 'line' => $sLine);
		}

		public function getErrors()
		{
			return $this->aErrors;
		}

		public function hasErrors()
		{
			return (sizeof($this->aErrors) ? true : false);
		}



		protected function checkConfiguration($settings = array('sSecurePath', 'sPrivateKeyPass', 'sPrivateKeyFile', 'sPrivateCertificateFile', 'sPublicCertificateFile', 'sAquirerUrl', 'sMerchantId'))
		{
			$bOk = true;

			for($i = 0; $i < sizeof($settings); $i++)
			{
				// echo $settings[$i] . ' = ' . $this->$settings[$i] . '<br>';

				if(empty($this->$settings[$i]))
				{
					$bOk = false;
					$this->setError('Setting ' . $settings[$i] . ' was not configurated.', false, __FILE__, __LINE__);
				}
			}

			return $bOk;
		}



		// Utils
		protected function postToHost($url, $data, $timeout = 30)
		{
			$idx = strrpos($url, ':');
			$host = substr($url, 0, $idx);
			$url = substr($url, $idx + 1);
			$idx = strpos($url, '/');
			$port = substr($url, 0, $idx);
			$path = substr($url, $idx);

			$fsp = fsockopen($host, $port, $errno, $errstr, $timeout);
			$res = '';
			
			if($fsp)
			{
				fputs($fsp, 'POST ' . $path . ' HTTP/1.0' . $this->CRLF);
				fputs($fsp, 'Accept: text/html' . $this->CRLF);
				fputs($fsp, 'Accept: charset=ISO-8859-1' . $this->CRLF);
				fputs($fsp, 'Content-Length:' . strlen($data) . $this->CRLF);
				fputs($fsp, 'Content-Type: text/html; charset=ISO-8859-1' . $this->CRLF . $this->CRLF);
				fputs($fsp, $data, strlen($data));

				while(!feof($fsp))
				{
					$res .= fgets($fsp, 128);
				}

				fclose($fsp);
			}
			else
			{
				$this->setError($errstr, $errno, __FILE__, __LINE__);
			}

			return $res;
		}

		protected function parseFromXml($key, $xml)
		{
			$begin = 0;
			$end = 0;
			$begin = strpos($xml, '<' . $key . '>');
			
			if($begin === false)
			{
				return false;
			}

			$begin += strlen($key) + 2;
			$end = strpos($xml, '</' . $key . '>');

			if($end === false)
			{
				return false;
			}

			$result = substr($xml, $begin, $end - $begin);
			$result = $this->unescapeXml($result);

			return utf8_decode($result);
		}

		protected function removeSpaceCharacters($string)
		{
			return preg_replace('/\s/', '', $string);
		}

		protected function escapeXml($string)
		{
			$string = str_replace('&', '&amp;', $string);
			$string = str_replace('<', '&lt;', $string);
			$string = str_replace('>', '&gt;', $string);
			$string = str_replace('"', '&quot;', $string);
			return $string;
		}

		protected function unescapeXml($string)
		{
			$string = str_replace('&quot;', '"', $string);
			$string = str_replace('&lt;', '<', $string);
			$string = str_replace('&gt;', '>', $string);
			$string = str_replace('&amp;', '&', $string);
			return $string;
		}



		// Security functions
		protected function getCertificateFingerprint($bPublicCertificate = false)
		{
			if($fp = fopen($this->sSecurePath . ($bPublicCertificate ? $this->sPublicCertificateFile : $this->sPrivateCertificateFile), 'r'))
			{
				$sRawData = fread($fp, 8192);
				fclose($fp);

				$sData = openssl_x509_read($sRawData);

				if(!openssl_x509_export($sData, $sData))
				{
					$this->setError('Error in certificate ' . $this->sSecurePath . $this->sPrivateCertificateFile, false, __FILE__, __LINE__);
					return false;
				}
			
				$sData = str_replace('-----BEGIN CERTIFICATE-----', '', $sData);
				$sData = str_replace('-----END CERTIFICATE-----', '', $sData);

				return strtoupper(sha1(base64_decode($sData)));
			}
			else
			{
				$this->setError('Certificate file ' . $this->sSecurePath . $this->sPrivateCertificateFile . ' not found.', false, __FILE__, __LINE__);
			}
		}

		protected function getSignature($sMessage)
		{
			$sMessage = preg_replace('/\s/', '', $sMessage);

			if($fp = fopen($this->sSecurePath . $this->sPrivateKeyFile, 'r'))
			{
				$sRawData = fread($fp, 8192);
				fclose($fp);

				$sPrivateKey = openssl_get_privatekey($sRawData, $this->sPrivateKeyPass);
				$sSignature = '';

				openssl_sign($sMessage, $sSignature, $sPrivateKey);
				openssl_free_key($sPrivateKey);

				return $sSignature;
			}
		}

		protected function verifySignature($sData, $sSignature)
		{
			$bOk = false;

			if($fp = fopen($this->sSecurePath . $this->sPublicCertificateFile, 'r'))
			{
				$sRawData = fread($fp, 8192);
				fclose($fp);

				$sPublicKey = openssl_get_publickey($sRawData);
				$bOk = (openssl_verify($sData, $sSignature, $sPublicKey) ? true : false);
				openssl_free_key($sPublicKey);
			}

			return $bOk;
		}
	}




	class IssuerRequest extends IdealRequest
	{
		public function __construct()
		{
			parent::__construct();
		}

		// Execute request (Lookup issuer list)
		public function doRequest()
		{
			if($this->checkConfiguration())
			{
				$sTimestamp = gmdate('Y-m-d') . 'T' . gmdate('H:i:s') . '.000Z';
				$sMessage = $this->removeSpaceCharacters($sTimestamp . $this->sMerchantId . $this->sSubId);

				$sToken = $this->getCertificateFingerprint();
				$sTokenCode = base64_encode($this->getSignature($sMessage));

				$sXmlMessage = '<?xml version="1.0" encoding="UTF-8" ?>' . $this->LF
				. '<DirectoryReq xmlns="http://www.idealdesk.com/Message" version="1.1.0">' . $this->LF
				. '<createDateTimeStamp>' . utf8_encode($sTimestamp) . '</createDateTimeStamp>' . $this->LF
				. '<Merchant>' . $this->LF
				. '<merchantID>' . utf8_encode($this->sMerchantId) . '</merchantID>' . $this->LF
				. '<subID>' . utf8_encode($this->sSubId) . '</subID>' . $this->LF
				. '<authentication>SHA1_RSA</authentication>' . $this->LF
				. '<token>' . utf8_encode($sToken) . '</token>' . $this->LF
				. '<tokenCode>' . utf8_encode($sTokenCode) . '</tokenCode>' . $this->LF
				. '</Merchant>' . $this->LF
				. '</DirectoryReq>';

				$sXmlReply = $this->postToHost($this->sAquirerUrl, $sXmlMessage, 10);

				if($sXmlReply)
				{
					if($this->parseFromXml('errorCode', $sXmlReply)) // Error found
					{
						// Add error to error-list
						$this->setError($this->parseFromXml('errorMessage', $sXmlReply), $this->parseFromXml('errorCode', $sXmlReply), __FILE__, __LINE__);					
					}
					else
					{
						$aIssuerList = array();

						while(strpos($sXmlReply, '<issuerID>'))
						{							
							$sIssuerId = $this->parseFromXml('issuerID', $sXmlReply);
							$sIssuerName = $this->parseFromXml('issuerName', $sXmlReply);
							$sIssuerList = $this->parseFromXml('issuerList', $sXmlReply);

							if(strcmp($sIssuerList, 'Short') === 0)
							{
								$aIssuerList[$sIssuerId] = $sIssuerName;
							}

							$sXmlReply = substr($sXmlReply, strpos($sXmlReply, '</issuerList>') + 13);
						}

						return $aIssuerList;
					}
				}
			}

			return false;
		}
	}




	class TransactionRequest extends IdealRequest
	{
		protected $sOrderId;
		protected $sOrderDescription;
		protected $iOrderAmount;
		protected $sReturnUrl;
		protected $sIssuerId;
		protected $sEntranceCode;

		// Transaction info
		protected $sTransactionId;
		protected $sTransactionUrl;

		public function __construct()
		{
			parent::__construct();

			// Random EntranceCode
			$this->sEntranceCode = sha1(rand(1000000, 9999999));
		}

		public function setOrderId($sOrderId)
		{
			$this->sOrderId = substr($sOrderId, 0, 16);
		}

		public function setOrderDescription($sOrderDescription)
		{
			$this->sOrderDescription = substr($sOrderDescription, 0, 32);
		}

		public function setOrderAmount($fOrderAmount)
		{
			$this->iOrderAmount = round($fOrderAmount * 100);
		}

		public function setReturnUrl($sReturnUrl)
		{
			$this->sReturnUrl = substr($sReturnUrl, 0, 512);
		}

		public function setIssuerId($sIssuerId)
		{
			$this->sIssuerId = $sIssuerId;
		}

		public function setEntranceCode($sEntranceCode)
		{
			$this->sEntranceCode = substr($sEntranceCode, 0, 40);
		}

		// Execute request (Setup transaction)
		public function doRequest()
		{
			if($this->checkConfiguration() && $this->checkConfiguration(array('sOrderId', 'sOrderDescription', 'iOrderAmount', 'sReturnUrl', 'sReturnUrl', 'sIssuerId', 'sEntranceCode')))
			{
				$sTimestamp = gmdate('Y-m-d') . 'T' . gmdate('H:i:s') . '.000Z';
				$sMessage = $this->removeSpaceCharacters($sTimestamp . $this->sIssuerId . $this->sMerchantId . $this->sSubId . $this->sReturnUrl . $this->sOrderId . $this->iOrderAmount . 'EUR' . 'nl' . $this->sOrderDescription . $this->sEntranceCode);
				$sToken = $this->getCertificateFingerprint();
				$sTokenCode = $this->getSignature($sMessage);
				$sTokenCode = base64_encode($sTokenCode);

				$sXmlMessage = '<?xml version="1.0" encoding="UTF-8" ?>' . $this->LF
				. '<AcquirerTrxReq xmlns="http://www.idealdesk.com/Message" version="1.1.0">' . $this->LF
				. '<createDateTimeStamp>' . utf8_encode($sTimestamp) .  '</createDateTimeStamp>' . $this->LF
				. '<Issuer>' . $this->LF
				. '<issuerID>' . utf8_encode($this->sIssuerId) . '</issuerID>' . $this->LF
				. '</Issuer>' . $this->LF
				. '<Merchant>' . $this->LF 
				. '<merchantID>' . utf8_encode($this->sMerchantId) . '</merchantID>' . $this->LF
				. '<subID>' . utf8_encode($this->sSubId) . '</subID>' . $this->LF
				. '<authentication>SHA1_RSA</authentication>' . $this->LF
				. '<token>' . utf8_encode($sToken) . '</token>' . $this->LF
				. '<tokenCode>' . utf8_encode($sTokenCode) . '</tokenCode>' . $this->LF
				. '<merchantReturnURL>' . utf8_encode($this->escapeXml($this->sReturnUrl)) . '</merchantReturnURL>' . $this->LF
				. '</Merchant>' . $this->LF
				. '<Transaction>' . $this->LF
				. '<purchaseID>' . utf8_encode($this->escapeXml($this->sOrderId)) . '</purchaseID>' . $this->LF
				. '<amount>' . utf8_encode($this->iOrderAmount) . '</amount>' . $this->LF
				. '<currency>EUR</currency>' . $this->LF
				. '<expirationPeriod>PT30M</expirationPeriod>' . $this->LF
				. '<language>nl</language>' . $this->LF
				. '<description>' . utf8_encode($this->escapeXml($this->sOrderDescription)) . '</description>' . $this->LF
				. '<entranceCode>' . utf8_encode($this->escapeXml($this->sEntranceCode)) . '</entranceCode>' . $this->LF
				. '</Transaction>' . $this->LF 
				. '</AcquirerTrxReq>';

				$sXmlReply = $this->postToHost($this->sAquirerUrl, $sXmlMessage, 10);

				if($sXmlReply)
				{
					if($this->parseFromXml('errorCode', $sXmlReply)) // Error found
					{
						// Add error to error-list
						$this->setError($this->parseFromXml('errorMessage', $sXmlReply), $this->parseFromXml('errorCode', $sXmlReply), __FILE__, __LINE__);					
					}
					else
					{
						$this->sTransactionId = $this->parseFromXml('transactionID', $sXmlReply);
						$this->sTransactionUrl = html_entity_decode($this->parseFromXml('issuerAuthenticationURL', $sXmlReply));

						return $this->sTransactionId;
					}
				}
			}

			return false;
		}

		// Start transaction
		public function doTransaction()
		{
			if((sizeof($this->aErrors) == 0) && $this->sTransactionId && $this->sTransactionUrl)
			{
				header('Location: ' . $this->sTransactionUrl);
				exit;
			}

			$this->setError('Please setup a valid transaction request first.', false, __FILE__, __LINE__);
			return false;
		}
	}




	class StatusRequest extends IdealRequest
	{
		// Account info
		protected $sAccountCity;
		protected $sAccountName;
		protected $sAccountNumber;

		// Transaction info
		protected $sTransactionId;
		protected $sTransactionStatus;

		public function __construct()
		{
			parent::__construct();
		}

		// Set transaction id
		public function setTransactionId($sTransactionId)
		{
			$this->sTransactionId = $sTransactionId;
		}

		// Get account city
		public function getAccountCity()
		{
			if(!empty($this->sAccountCity))
			{
				return $this->sAccountCity;
			}

			return '';
		}

		// Get account name
		public function getAccountName()
		{
			if(!empty($this->sAccountName))
			{
				return $this->sAccountName;
			}

			return '';
		}

		// Get account number
		public function getAccountNumber()
		{
			if(!empty($this->sAccountNumber))
			{
				return $this->sAccountNumber;
			}

			return '';
		}

		// Execute request
		public function doRequest()
		{
			if($this->checkConfiguration() && $this->checkConfiguration(array('sTransactionId')))
			{
				$sTimestamp = gmdate('Y-m-d') . 'T' . gmdate('H:i:s') . '.000Z';
				$sMessage = $this->removeSpaceCharacters($sTimestamp . $this->sMerchantId . $this->sSubId . $this->sTransactionId);
				$sToken = $this->getCertificateFingerprint();
				$sTokenCode = $this->getSignature($sMessage);
				$sTokenCode = base64_encode($sTokenCode);

				$sXmlMessage = '<?xml version="1.0" encoding="UTF-8" ?>' . $this->LF
				. '<AcquirerStatusReq xmlns="http://www.idealdesk.com/Message" version="1.1.0">' . $this->LF
				. '<createDateTimeStamp>' . utf8_encode($sTimestamp) . '</createDateTimeStamp>' . $this->LF
				. '<Merchant>' 
				. '<merchantID>' . utf8_encode($this->sMerchantId) . '</merchantID>' . $this->LF
				. '<subID>' . utf8_encode($this->sSubId) . '</subID>' . $this->LF
				. '<authentication>SHA1_RSA</authentication>' . $this->LF
				. '<token>' . utf8_encode($sToken) . '</token>' . $this->LF
				. '<tokenCode>' . utf8_encode($sTokenCode) . '</tokenCode>' . $this->LF
				. '</Merchant>' . $this->LF
				. '<Transaction>' 
				. '<transactionID>' . utf8_encode($this->sTransactionId) . '</transactionID>' . $this->LF
				. '</Transaction>' 
				. '</AcquirerStatusReq>';

				$sXmlReply = $this->postToHost($this->sAquirerUrl, $sXmlMessage, 10);

				if($sXmlReply)
				{
					if($this->parseFromXml('errorCode', $sXmlReply)) // Error found
					{
						// Add error to error-list
						$this->setError($this->parseFromXml('errorMessage', $sXmlReply), $this->parseFromXml('errorCode', $sXmlReply), __FILE__, __LINE__);					
					}
					else
					{
						$sTimestamp = $this->parseFromXml('createDateTimeStamp', $sXmlReply);
						$sTransactionId = $this->parseFromXml('transactionID', $sXmlReply);
						$sTransactionStatus = $this->parseFromXml('status', $sXmlReply);

						$sAccountNumber = $this->parseFromXml('consumerAccountNumber', $sXmlReply);
						$sAccountName = $this->parseFromXml('consumerName', $sXmlReply);
						$sAccountCity = $this->parseFromXml('consumerCity', $sXmlReply);

						$sMessage = $this->removeSpaceCharacters($sTimestamp . $sTransactionId . $sTransactionStatus . $sAccountNumber);

						$sSignature = base64_decode($this->parseFromXml('signatureValue', $sXmlReply));
						$sFingerprint = $this->parseFromXml('fingerprint', $sXmlReply);

						if(strcasecmp($sFingerprint, $this->getCertificateFingerprint(true)) !== 0)
						{
							// Invalid Fingerprint
							$this->setError('Unknown fingerprint.', false, __FILE__, __LINE__);
						}
						elseif($this->verifySignature($sMessage, $sSignature) == false)
						{
							// Invalid Fingerprint
							$this->setError('Bad signature.', false, __FILE__, __LINE__);
						}
						else
						{
							// $this->sTransactionId = $sTransactionId;
							$this->sTransactionStatus = strtoupper($sTransactionStatus);

							$this->sAccountCity = $sAccountCity;
							$this->sAccountName = $sAccountName;
							$this->sAccountNumber = $sAccountNumber;

							return $this->sTransactionStatus;
						}
					}
				}
			}

			return false;
		}
	}
?>
[/code]




FILE: step1.php
[code]
<?php

	// Invoegen van classes
	require_once(dirname(__FILE__) . '/ideal.cls.php');

	$oIssuerRequest = new IssuerRequest();

	// Algemene iDEAL instellingen
	$oIssuerRequest->setSecurePath(dirname(__FILE__) . '/ssl/'); // Verwijst naar de beveiligde map met certificaten e.d.
	$oIssuerRequest->setPrivateKey('PrivateKeyPass'); // Het wachtwoord waarmee private.key is gegenereerd.
	$oIssuerRequest->setAquirer('Rabobank', true); // Je bank (Rabobank, ING Bank, etc)
	$oIssuerRequest->setMerchant('YourMerchantId', '0'); // Je MerchantID/SubId


	// Opvragen van order informatie.
	$sOrderId = rand(1000000, 9999999); // Uniek order ID
	$sOrderDescription = 'Order omschrijving'; // Omschrijving
	$fOrderAmount = rand(100, 99999) / 100; // Bedrag (in decimaal!!)


	// Opvragen van alle beschikbare iDEAL banken.
	$sIssuerOptions = '';

	if($aIssuerList = $oIssuerRequest->doRequest())
	{
		// Maak een keuzelijst met banken
		foreach($aIssuerList as $k => $v)
		{
			$sIssuerOptions .= '<option value="' . $k . '">' . htmlentities($v) . '</option>';
		}
	}
	else
	{
		$sIssuerOptions .= '<option value="0">-</option>';

		// Je kunt $oIssuerRequest->getErrors() gebruiken om de lijst met opgetreden fouten op te vragen.
		print_r($oIssuerRequest->getErrors());
	}

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
	<head>
		<title>iDEAL - Stap 1: Opvragen van beschikbare iDEAL banken.</title>
	</head>
	<body>
		<form action="step2.php" method="post">
			<h1>Uw iDEAL transactie</h1>
			<p><b>Order ID:<br /><input type="text" name="order_id" size="30" value="<?php echo $sOrderId; ?>"><br /><br />Order omschrijving:<br /><textarea rows="8" name="order_description" cols="40"><?php echo $sOrderDescription; ?></textarea><br /><br />Order bedrag:<br /><input name="order_amount" size="30" type="text" value="<?php echo number_format($fOrderAmount, 2, '.', ''); ?>"> (EUR)<br /><br />Kies uw bank:<br /><select name="order_issuer" size="1"><?php echo $sIssuerOptions; ?></select><br /><br /><br /><input name="_submit" type="submit" value="verder &gt;&gt;"></b></p>
		</form>
	</body>
</html>
[/code]




FILE: step2.php
[code]
<?php

	// Opvragen van order informatie uit POST data.
	$sOrderId = $_POST['order_id']; // Unieke verwijzing naar de order
	$sOrderDescription = substr($_POST['order_description'], 0, 32); // Maximaal 32 karakters
	$fOrderAmount = $_POST['order_amount']; // Bedrag in CENTEN!
	$sIssuerId = $_POST['order_issuer']; // ID van de geselecteerde bank

	// De URL waar de bezoeker naar toe wordt gestuurd nadat de ideal betaling is afgerond (of bij fouten)
	$sReturnUrl = 'http://www.domeinnaam.nl/step3.php';

	// Genereer een zelf op te geven EntranceCode (tot 40 karakters)
	$sEntranceCode = sha1($sOrderId . '_' . date('YmdHis'));



	// Invoegen van classes
	include(dirname(__FILE__) . '/ideal.cls.php');

	$oTransactionRequest = new TransactionRequest();

	// Algemene iDEAL instellingen
	$oTransactionRequest->setSecurePath(dirname(__FILE__) . '/ssl/'); // Verwijst naar de beveiligde map met certificaten e.d.
	$oTransactionRequest->setPrivateKey('PrivateKeyPass'); // Het wachtwoord waarmee private.key is gegenereerd.
	$oTransactionRequest->setAquirer('Rabobank', true); // Je bank (Rabobank, ING Bank, etc)
	$oTransactionRequest->setMerchant('YourMerchantId', '0'); // Je MerchantID/SubId


	// Order instellingen
	$oTransactionRequest->setOrderId($sOrderId);
	$oTransactionRequest->setOrderDescription($sOrderDescription);
	$oTransactionRequest->setOrderAmount($fOrderAmount);

	$oTransactionRequest->setReturnUrl($sReturnUrl);
	$oTransactionRequest->setIssuerId($sIssuerId);
	$oTransactionRequest->setEntranceCode($sEntranceCode);


	if($sTransactionId = $oTransactionRequest->doRequest()) // Voer het transactie verzoek uit (bij succes ontvang je een TransactionID)
	{
		// Sla de TransactieID, EntranceCode en overige order informatie op (bijv. in de database).
		// ...

		// Ga verder met de transactie (de bezoeker wordt doorgestuurd naar de website van zijn/haar bank)
		$oTransactionRequest->doTransaction();
	}

	// Je kunt $oTransactionRequest->getErrors() gebruiken om de lijst met opgetreden fouten op te vragen.
	print_r($oTransactionRequest->getErrors());

?>
[/code]




FILE: step3.php
[code]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
	<head>
		<title>iDEAL - Stap 3: Opvragen van de transactie status.</title>
	</head>
	<body>
<?php

	// Zoek het TransactieID en EntranceCode op in $_GET
	$sTransactionId = $_GET['trxid'];
	$sEntranceCode = $_GET['ec'];


	// Controlleer of de TransactieID/EntranceCode combinatie bestaat in de database
	if(true) // Transactie bestaat/geldig
	{
		// Invoegen van classes
		include(dirname(__FILE__) . '/ideal.cls.php');

		$oStatusRequest = new StatusRequest();

		// Algemene iDEAL instellingen
		$oStatusRequest->setSecurePath(dirname(__FILE__) . '/ssl/'); // Verwijst naar de beveiligde map met certificaten e.d.
		$oStatusRequest->setPrivateKey('PrivateKeyPass'); // Het wachtwoord waarmee private.key is gegenereerd.
		$oStatusRequest->setAquirer('Rabobank', true); // Je bank (Rabobank, ING Bank, etc)
		$oStatusRequest->setMerchant('YourMerchantId', '0'); // Je MerchantID/SubId

		// Transactie instellingeN
		$oStatusRequest->setTransactionId($sTransactionId); // Het ID van de transactie waarvan je de status wilt controleren.

		// Vraag de status van de transactie op (SUCCESS, CANCELLED, FAILURE, OPEN, EXPIRED)
		if($sStatus = $oStatusRequest->doRequest())
		{
			// Update status rapportage (bijv. in de database).
			// ...

			echo '<p>Uw betaling via iDEAL heeft als status ' . $sStatus . '.</p>';

			if(strcasecmp($sStatus, 'SUCCESS') === 0) // Indien SUCCESS, worden ook enkele bankgegevens van de bezoeker meegegeven
			{
				echo '<p><b>Uw bankrekening gegevens</b><br>Rekeningnummer: ' . $oStatusRequest->getAccountNumber() . '<br>T.n.v.: ' . $oStatusRequest->getAccountName() . '<br>Te: ' . $oStatusRequest->getAccountCity() . '</p>';
			}
		}
		else
		{
			// Je kunt $oStatusRequest->getErrors() gebruiken om de lijst met opgetreden fouten op te vragen.
			print_r($oStatusRequest->getErrors());
		}
	}

?>
	</body>
</html>
[/code]

Reacties

0
Nog geen reacties.