Table of Contents
PHP
ITN Sample Code
- payfast_itn.php
<?php /** * Notes: * - All lines with the suffix "// DEBUG" are for debugging purposes and * can safely be removed from live code. * - Remember to set PAYFAST_SERVER to LIVE for production/live site */ // General defines define( 'PAYFAST_SERVER', 'TEST' ); // Whether to use "sandbox" test server or live server define( 'USER_AGENT', 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)' ); // User Agent for cURL // Messages // Error define( 'PF_ERR_AMOUNT_MISMATCH', 'Amount mismatch' ); define( 'PF_ERR_BAD_SOURCE_IP', 'Bad source IP address' ); define( 'PF_ERR_CONNECT_FAILED', 'Failed to connect to PayFast' ); define( 'PF_ERR_BAD_ACCESS', 'Bad access of page' ); define( 'PF_ERR_INVALID_SIGNATURE', 'Security signature mismatch' ); define( 'PF_ERR_CURL_ERROR', 'An error occurred executing cURL' ); define( 'PF_ERR_INVALID_DATA', 'The data received is invalid' ); define( 'PF_ERR_UKNOWN', 'Unkown error occurred' ); // General define( 'PF_MSG_OK', 'Payment was successful' ); define( 'PF_MSG_FAILED', 'Payment has failed' ); // Notify PayFast that information has been received header( 'HTTP/1.0 200 OK' ); flush(); // Variable initialization $pfError = false; $pfErrMsg = ''; $filename = 'notify.txt'; // DEBUG $output = ''; // DEBUG $pfParamString = ''; $pfHost = ( PAYFAST_SERVER == 'LIVE' ) ? 'www.payfast.co.za' : 'sandbox.payfast.co.za'; //// Dump the submitted variables and calculate security signature if( !$pfError ) { $output = "Posted Variables:\n\n"; // DEBUG // Strip any slashes in data foreach( $_POST as $key => $val ) $_POST[$key] = stripslashes( $val ); foreach( $_POST as $key => $val ) { $output .= $key .'='. $val ."\r\n"; // DEBUG if( $key != 'signature' ) $pfParamString .= $key .'='. urlencode( $val ) .'&'; } $output .= "\n\n"; // DEBUG // Remove the last '&' from the parameter string $pfParamString = substr( $pfParamString, 0, -1 ); $signature = md5( $pfParamString ); $result = ( $_POST['signature'] == $signature ); $output .= "Security Signature:\n\n"; // DEBUG $output .= "- posted = ". $_POST['signature'] ."\n"; // DEBUG $output .= "- calculated = ". $signature ."\n"; // DEBUG $output .= "- result = ". ( $result ? 'SUCCESS' : 'FAILURE' ) ."\n"; // DEBUG } //// Verify source IP if( !$pfError ) { $validHosts = array( 'www.payfast.co.za', 'sandbox.payfast.co.za', 'w1w.payfast.co.za', 'w2w.payfast.co.za', ); $validIps = array(); foreach( $validHosts as $pfHostname ) { $ips = gethostbynamel( $pfHostname ); if( $ips !== false ) $validIps = array_merge( $validIps, $ips ); } // Remove duplicates $validIps = array_unique( $validIps ); if( !in_array( $_SERVER['REMOTE_ADDR'], $validIps ) ) { $pfError = true; $pfErrMsg = PF_ERR_BAD_SOURCE_IP; } } //// Connect to server to validate data received if( !$pfError ) { // Use cURL (If it's available) if( function_exists( 'curl_init' ) ) { $output .= "\n\nUsing cURL\n\n"; // DEBUG // Create default cURL object $ch = curl_init(); // Base settings $curlOpts = array( // Base options CURLOPT_USERAGENT => USER_AGENT, // Set user agent CURLOPT_RETURNTRANSFER => true, // Return output as string rather than outputting it CURLOPT_HEADER => false, // Don't include header in output CURLOPT_SSL_VERIFYHOST => true, CURLOPT_SSL_VERIFYPEER => false, // Standard settings CURLOPT_URL => 'https://'. $pfHost . '/eng/query/validate', CURLOPT_POST => true, CURLOPT_POSTFIELDS => $pfParamString, ); curl_setopt_array( $ch, $curlOpts ); // Execute CURL $res = curl_exec( $ch ); curl_close( $ch ); if( $res === false ) { $pfError = true; $pfErrMsg = PF_ERR_CURL_ERROR; } } // Use fsockopen else { $output .= "\n\nUsing fsockopen\n\n"; // DEBUG // Construct Header $header = "POST /eng/query/validate HTTP/1.0\r\n"; $header .= "Host: ". $pfHost ."\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen( $pfParamString ) . "\r\n\r\n"; // Connect to server $socket = fsockopen( 'ssl://'. $pfHost, 443, $errno, $errstr, 10 ); // Send command to server fputs( $socket, $header . $pfParamString ); // Read the response from the server $res = ''; $headerDone = false; while( !feof( $socket ) ) { $line = fgets( $socket, 1024 ); // Check if we are finished reading the header yet if( strcmp( $line, "\r\n" ) == 0 ) { // read the header $headerDone = true; } // If header has been processed else if( $headerDone ) { // Read the main response $res .= $line; } } } } //// Get data from server if( !$pfError ) { // Parse the returned data $lines = explode( "\n", $res ); $output .= "\n\nValidate response from server:\n\n"; // DEBUG foreach( $lines as $line ) // DEBUG $output .= $line ."\n"; // DEBUG } //// Interpret the response from server if( !$pfError ) { // Get the response from PayFast (VALID or INVALID) $result = trim( $lines[0] ); $output .= "\nResult = ". $result; // DEBUG // If the transaction was valid if( strcmp( $result, 'VALID' ) == 0 ) { // Process as required } // If the transaction was NOT valid else { // Log for investigation $pfError = true; $pfErrMsg = PF_ERR_INVALID_DATA; } } // If an error occurred if( $pfError ) { $output .= "\n\nAn error occurred!"; $output .= "\nError = ". $pfErrMsg; } //// Write output to file // DEBUG file_put_contents( $filename, $output ); // DEBUG ?>
PDT Sample Code
- payfast_pdt.php
<?php define( 'SANDBOX', 1 ); // Variable Initialization $pmtToken = isset( $_GET['pt'] ) ? $_GET['pt'] : null; if( !empty( $pmtToken ) ) { // Variable Initialization $error = false; $authToken = '<YOUR_PDT_KEY>'; $req = 'pt='. $pmtToken .'&at='. $authToken; $data = array(); $host = SANDBOX ? 'sandbox.payfast.co.za' : 'www.payfast.co.za'; //// Connect to server if( !$error ) { // Construct Header $header = "POST /eng/query/fetch HTTP/1.0\r\n"; $header .= 'Host: '. $host ."\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= 'Content-Length: '. strlen( $req ) ."\r\n\r\n"; // Connect to server $socket = fsockopen( 'ssl://'. $host, 443, $errno, $errstr, 10 ); if( !$socket ) { $error = true; print( 'errno = '. $errno .', errstr = '. $errstr ); } } //// Get data from server if( !$error ) { // Send command to server fputs( $socket, $header . $req ); // Read the response from the server $res = ''; $headerDone = false; while( !feof( $socket ) ) { $line = fgets( $socket, 1024 ); // Check if we are finished reading the header yet if( strcmp( $line, "\r\n" ) == 0 ) { // read the header $headerDone = true; } // If header has been processed else if( $headerDone ) { // Read the main response $res .= $line; } } // Parse the returned data $lines = explode( "\n", $res ); } //// Interpret the response from server if( !$error ) { $result = trim( $lines[0] ); // If the transaction was successful if( strcmp( $result, 'SUCCESS' ) == 0 ) { // Process the reponse into an associative array of data for( $i = 1; $i < count( $lines ); $i++ ) { list( $key, $val ) = explode( "=", $lines[$i] ); $data[urldecode( $key )] = stripslashes( urldecode( $val ) ); } } // If the transaction was NOT successful else if( strcmp( $result, 'FAIL' ) == 0 ) { // Log for investigation $error = true; // } } //// Process the payment if( !$error ) { // Get the data from the new array as needed $nameFirst = $data['name_first']; $nameLast = $data['name_last']; $amountGross = $data['amount_gross']; // Once you have access to this data, you should perform a number of // checks to ensure the transaction is "correct" before processing it. // - Check the payment_status is Completed // - Check the pf_transaction_id has not already been processed // - Check the merchant_id is correct for your account // Process payment // } // Close socket if successfully opened if( $socket ) fclose( $socket ); } ?>
Trace: • php