Sample code: PHP

ITN sample code

<?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 )
            $pfData[$key] = stripslashes( $val );
     
        // Dump the submitted variables and calculate security signature
        foreach( $pfData as $key => $val )
        {
           if( $key != 'signature' )
             $pfParamString .= $key .'='. urlencode( $val ) .'&';
        }
     
        // Remove the last '&' from the parameter string
        $pfParamString = substr( $pfParamString, 0, -1 );
        $pfTempParamString = $pfParamString;
         
        // If a passphrase has been set in the PayFast Settings, then it needs to be included in the signature string.
        $passPhrase = 'XXXXX'; //You need to get this from a constant or stored in you website
        if( !empty( $passPhrase ) )
        {
            $pfTempParamString .= '&passphrase='.urlencode( $passPhrase );
        }
        $signature = md5( $pfTempParamString );
     
        $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 => 2,
                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

<!--?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 );
    }
    ?>