<?php

/*============================ Disclaimer ====================================

Copyright 2004 Dialect Solutions Holdings.  All rights reserved.

This document is provided by Dialect Holdings on the basis that you will treat
it as confidential.

No part of this document may be reproduced or copied in any form by any means
without the written permission of Dialect Holdings.  Unless otherwise expressly
agreed in writing, the information contained in this document is subject to
change without notice and Dialect Holdings assumes no responsibility for any
alteration to, or any error or other deficiency, in this document.

All intellectual property rights in the Document and in all extracts and things
derived from any part of the Document are owned by Dialect and will be assigned
to Dialect on their creation. You will protect all the intellectual property
rights relating to the Document in a manner that is equal to the protection
you provide your own intellectual property.  You will notify Dialect
immediately, and in writing where you become aware of a breach of Dialect's
intellectual property rights in relation to the Document.

The names "Dialect", "QSI Payments" and all similar words are trademarks of
Dialect Holdings and you must not use that name or any similar name.

Dialect may at its sole discretion terminate the rights granted in this
document with immediate effect by notifying you in writing and you will
thereupon return (or destroy and certify that destruction to Dialect) all
copies and extracts of the Document in its possession or control.

Dialect does not warrant the accuracy or completeness of the Document or its
content or its usefulness to you or your merchant customers.   To the extent
permitted by law, all conditions and warranties implied by law (whether as to
fitness for any particular purpose or otherwise) are excluded.  Where the
exclusion is not effective, Dialect limits its liability to $100 or the
resupply of the Document (at Dialect's option).

Data used in examples and sample data files are intended to be fictional and
any resemblance to real persons or companies is entirely coincidental.

Dialect does not indemnify you or any third party in relation to the content or
any use of the content as contemplated in these terms and conditions.

Mention of any product not owned by Dialect does not constitute an endorsement
of that product.

This document is governed by the laws of New South Wales, Australia and is
intended to be legally binding.

==============================================================================
 
This example assumes that a form has been sent to this example with the
required fields. The example then processes the command and displays the
receipt or error to a HTML page in the users web browser.

@author Dialect Payment Solutions Pty Ltd Group 

==============================================================================

Version 3.1

==============================================================================

  Please refer to the following guides for more information:
      1. Payment Client Integration Guide
         This details how to integrate with Payment Client 3.0.
      2. Payment Client Reference Guide
         This guide details all the input and return parameters that are used
         by the Payment Client and Payment Server for a Payment Client
         integration.
      3. Payment Client Install Guide
         This guide details the installation of Payment Client 3.0 and related
         issues.
 
  For a definitive list of QSI Response Codes please refer to the Payment
  Client Reference Guide. For a list of the QSI Response Codes used in this
  example please refer to the 'getResponseDescription' sub.
 
  This example assumes that a form has been sent to this example with the
  required fields. The example then processes the command and displays the
  result or error to a HTML page in the users web browser.*/
 

// Initialisation
// ==============

// Define Constants
// ----------------
// This is the time that the example will allow for the socket to complete
// sending a command to the Payment Client in seconds

// Set flag that this is a parent file
	define( '_FEXEC', 1 );
	
	
require('includes/application_top.php');

if (!tep_session_is_registered('customer_id')){
	tep_redirect(tep_href_link(FILENAME_LOGIN, '', 'SSL'));
}
$SHORT_SOCKET_TIMEOUT = 2;
$LONG_SOCKET_TIMEOUT  = 100;

// This is the status character in the socket response that indicates that a
// command was run successfully
$OK = "1";

// Define Variables
// ----------------
// Set exception and socket response values
$exception = "";
$cmdResponse = "";

// this debug parameter simply allows the user to see the sockets
// commands going to/from the Payment Client socket listener. 
// This is not required for production code.
$getDebug = array_key_exists("DebugOn", $_POST) ? $_POST["DebugOn"] : "0";

//   if debug = true then sockets information output to screen
//   if debug = false then NO sockets information output to screen
$debug = false;
if ($getDebug == "1") {
	$debug = true;
}

// Set error message flag and socket created OK flag
$errorExists = false;
$socketCreated = true;

/* The following fields are the input fields for the command, please
* refer to the Payment Client Reference Guide for more information on
* the fields.
*/
$merchTxnRef     = "";
$orderInfo       = "";
$merchantID      = "";
$purchaseAmount  = "";

// receipt variables
$qsiResponseCode = "";
$receiptNo       = "";
$acqResponseCode = "";
$authorizeID     = "";
$batchNo         = "";
$amount          = "";
$transactionNr   = ""; 
$cardType        = ""; 
$cscResultCode   = "";
$acqCSCRespCode  = "";
$cscRequestCode  = "";

// *********************
// START OF MAIN PROGRAM
// *********************

// Step 1 - Connect to the Payment Client
// ======================================
// Payment Client IP number. In a production system you would not pass 
// in this value, but hard it into the program
$payClientIP = array_key_exists("HostName", $_POST) ? $_POST["HostName"] : "";

// Payment Client Port number. In a production system you would not pass 
// in this value, but hard it into the program
$payClientPort = intval(array_key_exists("Port", $_POST) ? $_POST["Port"] : "");

// Initialise the Payment Client socket connection
$payClientSocket = -1;

// Create the socket connection to the Payment Client
$errno = "";
$errstr = "";

// This is the time (in seconds) that the example will allow for the socket to
// complete sending a command to the Payment Client(refer to Payment Client
// Integration Guide)
$payClientTimeout = $SHORT_SOCKET_TIMEOUT;

// create the socket connection
if (strlen($payClientIP) > 0 && $payClientPort > 0) {
    $payClientSocket = @fsockopen($payClientIP, $payClientPort, $errno, $errstr, $payClientTimeout);
} else {
    $payClientPort = $payClientPort != 0 ? $payClientPort : "";
    $message = "(44) Incorrect data to create a socket connection to Payment Client - Host:$payClientIP Port:$payClientPort";     
    //$message = sprintf(ERR_SOCKET_CONNECTION_HOST,$payClientIP,$payClientPort);

	$errorExists = true;
    $socketCreated = false;
}

if (!$errorExists && $payClientSocket < 1) {
    // Display an error page as the socket connection failed
    $message = "(45) Failed to create a socket connection to Payment Client - Host:$payClientIP Port:$payClientPort";
    //$message =  sprintf(ERR_SOCKET_CONNECTION_HOST_45,$payClientIP,$payClientPort);
	$errorExists = true;
    $socketCreated = false;
};


// Step 2 - Test the Payment Client socket was created successfully
// ================================================================
// Test the communication to the Payment Client using an "echo" command.
// This is a local command that only communicates to the Payment Client and
// nothing is sent to the Payment Server.
if (!$errorExists) {
   $cmdResponse = sendCommand($payClientSocket,"1,Test",$debug);
    if (substr($cmdResponse,2) != "echo:Test") {
        // Display an error as the communication to the Payment Client failed
       $message = "(5) Failed to complete echo test to Payment Client - should be: Should be: '1,echo:Test', but received: '$cmdResponse'";
        //$message = sprintf(ERR_PAYMENT_CLIENT,$cmdResponse);
		$errorExists = true;
    }
}

// Step 3 - Prepare to Generate and Send Digital Order
// ===================================================
// Add any supplementary data to the Digital Order. This is a local command that
// only communicates to the Payment Client and nothing is sent to the Payment
// Server.

// add merchTxnRef
$merchTxnRef = $_POST["MerchTxnRef"];
if (!$errorExists) {
    if (strlen($merchTxnRef) > 0) { 
        $cmdResponse = sendCommand($payClientSocket, "7,MerchTxnRef,$merchTxnRef", $debug);
        if (substr($cmdResponse,0,1) != $OK) {
            // Display an error message as the command failed
           $message = "(6) Failed to add supplementary data using addDigitalOrderField command - MerchTxnRef. Response=".$cmdResponse;
           //$message = sprintf(ERR_MERCHAND_TXN_REF,$cmdResponse);
		    $errorExists = true;
        }
    }
}

// add card number
if (!$errorExists) {
    $cardNumber = $_POST["Ecom_Payment_Card_Number"];
    if (strlen($cardNumber) > 0) { 
        $cmdResponse = sendCommand($payClientSocket, "7,CardNum,$cardNumber", $debug);
        if (substr($cmdResponse,0,1) != $OK) {
            // Display an error message as the command failed
            $message = "(6) Failed to add supplementary data using addDigitalOrderField command - CardNum. Response=".$cmdResponse;
            //$message = sprintf(ERR_CARD_NUM,$cmdResponse);
			$errorExists = true;
        }
    }
}

// add card expiry
if (!$errorExists) {
	$cardMonth = $_POST["Ecom_Payment_Card_Month"];
	$cardYear  = $_POST["Ecom_Payment_Card_Year"];
	/*
	* We have the expiry month and year, but the Payment Client requires
	* a 4 digit expiry year/month (YYMM). We construct this from the
	* information we already have.
	*/
	$cardExpiry = "";
	if (strlen($cardYear) > 2) {
		$cardExpiry = substr($cardYear, (strlen($cardYear)-2)) . $cardMonth;
	} else {
		$cardExpiry = $cardYear.$cardMonth;
	}
    if (strlen($cardExpiry) > 0) { 
        $cmdResponse = sendCommand($payClientSocket, "7,CardExp,$cardExpiry", $debug);
        if (substr($cmdResponse,0,1) != $OK) {
            // Display an error message as the command failed
            $message = "(6) Failed to add supplementary data using addDigitalOrderField command - CardExp. Response=".$cmdResponse;
            //$message = sprintf(ERR_CARD_EXPIRY,$cmdResponse);
			$errorExists = true;
        }
    }
}

// add card security code
if (!$errorExists) {
    $cscValue = $_POST["Ecom_Card_Security_Code"];
    if (strlen($cscValue) > 0) {
        $cmdResponse = sendCommand($payClientSocket, "7,CardSecurityCode,$cscValue", $debug);
        if (substr($cmdResponse,0,1) != $OK) {
            // Display an error message as the command failed
            $message = "(6) Failed to add supplementary data using addDigitalOrderField command - CardSecurityCode. Response=".$cmdResponse;
            //$message = sprintf(ERR_CARD_SECURITY_CODE,$cmdResponse);
			$errorExists = true;
        }
    }
}

// DO NOT implement the below feature as it is not supported by your bank and will prevent processing
//if (!$errorExists) {
//    $cscLevel = $_POST["CSCLevel"];
//    if (strlen($cscLevel) > 0) {
//        $cmdResponse = sendCommand($payClientSocket, "7,CSCLevel,$cscLevel", $debug);
//        if (substr($cmdResponse,0,1) != $OK) {
//            // Display an error message as the command failed
//            $message = "(6) Failed to add supplementary data using addDigitalOrderField command - CSCLevel. Response=".$cmdResponse;
//            $errorExists = true;
//        }
//    }
//}

// add ticket number
if (!$errorExists) {
    $ticketNo = $_POST["TicketNo"];
    if (strlen($ticketNo) > 0) {
        $cmdResponse = sendCommand($payClientSocket, "7,TicketNo,$ticketNo", $debug);
        if (substr($cmdResponse,0,1) != $OK) {
            // Display an error message as the command failed
            $message = "(6) Failed to add supplementary data using addDigitalOrderField command - TicketNo. Response=".$cmdResponse;
            //$message = sprintf(ERR_TICKET_NO,$cmdResponse);
			$errorExists = true;
        }
    }
}

// Step 4 - Generate and Send Digital Order (& receive DR)
// *******************************************************
// Set the socket timeout value to long value for the primary
// command as it sends and receives data to the Payment Server.
// All other commands only work locally with the Payment Client
$payClientTimeout = $LONG_SOCKET_TIMEOUT;

// This is the only command that communicates with the Payment Server.
// All other commands only communicate locally with the Payment Client.
$orderInfo   = $_POST["OrderInfo"];
$merchantID  = $_POST["MerchantID"];
$amount      = $_POST["PurchaseAmount"];
$locale     = "en";
if (!$errorExists) {
	// (This primary command also receives the encrypted Digital Receipt)
    $cmdResponse = sendCommand($payClientSocket,"6,$orderInfo,$merchantID,$amount,$locale,",$debug);
    if (substr($cmdResponse,0,1) != $OK) {
        // Retrieve the Payment Client Error (There may be none to retrieve)
        $cmdResponse = sendCommand($payClientSocket,"4,PaymentClient.Error",$debug);
		
		if (substr($cmdResponse,0,1) == $OK) {
            $exception = substr($cmdResponse,2);
        }
        // Display an error message as the command failed
        $message = "(11) Digital Order has not created correctly - sendMOTODigitalOrder($orderInfo,$merchantID,$amount,en,) failed.";
        //$message = sprintf(ERR_DIGITAL_ORDER,$orderInfo,$merchantID,$amount,$locale);
		$errorExists = true;
    }
}

// Step 5 - Check the Digital Receipt to see if there is a valid result
// ====================================================================
// Use the "nextResult" command to check if the Payment Client contains a
// valid Hash table containing the receipt results.
if (!$errorExists) {
	// Set the socket timeout value back to the short value for the
	// following supplementary commands
	$payClientTimeout = $SHORT_SOCKET_TIMEOUT;

	$cmdResponse = sendCommand($payClientSocket,"5",$debug);
    if (substr($cmdResponse,0,1) != $OK) {
        // Retrieve the Payment Client Error (There may be none to retrieve)
        if ($payClientSocket != "") {
            $cmdResponse = sendCommand($payClientSocket,"4,PaymentClient.Error",$debug);
            if (substr($cmdResponse,0,1) == $OK) {
                $exception = substr($cmdResponse,2);
            }
        }
        // Display an error message as the command failed
        $message = "(12) No Results for Digital Receipt";
		//$message = ERR_DIGITAL_RECEIPT;
        $errorExists = true;
    }
}

// Step 6 - Get the result data from the Digital Receipt
// =====================================================
// Check the QSIResponseCode for the transaction from the Payment Client Hash
// table. This is the most important result field and indicates the status of 
// the transaction. If the QSIResponseCode doesn't exist, this is an error
// condition.
$qsiResponseCode = "null";
if (!$errorExists) {
    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.QSIResponseCode", $debug);
    if (substr($cmdResponse,0,1) != $OK) {
        // Display an error message as the command failed
        $message = "(23) No result for this field: 'DigitalReceipt.QSIResponseCode'. Received: .$cmdResponse";
        //$message = sprintf(ERR_DIGITALRECEIPT_QSIRESPONSECODE,$cmdResponse);
		$errorExists = true;
    } else {
        $qsiResponseCode = substr($cmdResponse,2);
    }
}

// If the QSIResponseCode is '0' the transaction is successful.
// If the QSIResponseCode is not '0' the transaction has beed declined or an 
// error condition was detected, such as the customer typed in an invalid card
// number.
if (!$errorExists) {
    if ($qsiResponseCode != "0") {
        // The response may contain an error message so find out what the error
        // is. 'DigitalReceipt.ERROR' may not contain any error information as 
        // the transaction may have simply been declined - 'Insufficient Funds'
        // (QSIResponseCode='5',no further error message required)
		$errorExists = true;
		$message= "(24) Error detected by Payment Server. ";
		if ($qsiResponseCode=="7"){
			$cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.ERROR", $debug);
			if (substr($cmdResponse,0,1) == $OK) {
				$exception = substr($cmdResponse,2);
				$message = "(24) Error detected by Payment Server " . $exception;
				//$message = ERR_PAYMENT_SERVER;
				$errorExists = true;
			}
		} else {
			$message= "(24) Error detected by Payment Server: " . getResponseDescription($qsiResponseCode);
		}
    }
}


// Use the "getAvailableFieldKeys" command to obtain a list of keys available
// within the Payment Client Hash table containing the receipt results.
// This is a local command that only communicates to the Payment Client and
// nothing is sent to the Payment Server. The keys will not be used or displayed here. 
$receiptKeys = "";
if (!$errorExists) {
    $cmdResponse = sendCommand($payClientSocket,"33,",$debug);
    $receiptKeys = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";
	$rstor=time();
	tep_write_payment_response($r,$receiptKeys);
	$receiptKeys = str_replace( ",", "<br/>",$receiptKeys);
}

// In a production system the sent values and the receive
// values could be checked to make sure they are the same.
if (!$errorExists) {
    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.MerchTxnRef",$debug);
    $merchTxnRef = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

	$cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.MerchantId",$debug);
    $merchantID = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.OrderInfo",$debug);
    $orderInfo = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.PurchaseAmountInteger",$debug);
    $amount = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.Locale",$debug);
    $locale = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.ReceiptNo",$debug);
    $receiptNo = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.TransactionNo",$debug);
    $transactionNr = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.AcqResponseCode",$debug);
    $acqResponseCode = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.AuthorizeId",$debug);
    $authorizeID = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.BatchNo",$debug);
    $batchNo = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.CardType",$debug);
    $cardType = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.CSCResultCode",$debug);
    $cscResultCode = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.AcqCSCRespCode",$debug);
    $acqCSCRespCode = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";

    $cmdResponse = sendCommand($payClientSocket,"4,DigitalReceipt.CSCRequestCode",$debug);
    $cscRequestCode = substr($cmdResponse,0,1) == $OK ? substr($cmdResponse,2) : "No Value Returned";
}

// Step 7 - We are finished with the Payment Client so tidy up
// ===========================================================
// Close the socket connection to the Payment Client
if ($socketCreated) {
    close($payClientSocket);
}

// *********************
// END OF MAIN PROGRAM
// *********************

// FINISH TRANSACTION - Process the Response Data
// ==============================================
// For the purposes of demonstration, we simply display the Result fields on a
// web page.

// This is the display title for 'Receipt' page 
$title = $_POST["Title"];

/* The URL link for the receipt to do another transaction.
 * Note: This is ONLY used for this example and is not required for 
 * production code.  */
$againLink  = $HTTP_REFERER;

if (!$errorExists) {
    tep_redirect(tep_href_link(FILENAME_CHECKOUT_PROCESS, 'payment_return1=' . $receiptNo . '&payment_return2=' . $transactionNr .'&rstor=' . $rstor , 'SSL', true));
} else {
	tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'payment_error=commbank&error=' . urlencode($message), 'SSL'));
}
// End Processing

// =============================================================================

// This subroutine sends the command to the Payment Client and retrieves the
// response for the main body of the example. If an error is encountered
// an error page is displayed.
//
// @param $payClientSocket - The Payment Client socket
// @param $command  - String that will be sent to the Payment Client Socket
// @param $debug - If this is true, output commands to screen
//
// @return String containing the Payment Client response
function sendCommand($payClientSocket, $command, $debug) {

    global $payClientTimeout;
    socket_set_timeout($payClientSocket, $payClientTimeout);

    if ($debug) {
		$replaceChars = array(" ", "<", ">", "\n");
		$replacementChars = array("&nbsp;", "&lt;", "&gt;", "<br/>");
		$sendcommand = str_replace($replaceChars, $replacementChars, $command);
        print("<font color='#FF0066'>Sent : ".$sendcommand."</font><br/>");
    }
    
    // output the data to the socket & read in the response
    $buf = $command . "\n";
    $response = fputs($payClientSocket, $buf) == strlen($buf);    
    if (!$response) {
        // Display an error as there has been a communication error
        return "(46) Socket communication error - received: no response, sent: '$command'";
    }    
    
    // Set the time to stop reading using the globale timeout variable
    $stop=time() + $payClientTimeout;
    $reply="";
    while (!strpos($reply,"\n")) {
	    // Check to see if we have timed out
        if (time() >= $stop) {
            return "(49) Socket communication error: socket timed out waiting for reply - sent: '$command'";
        }
        $reply .= fgets($payClientSocket, 4096);
    }
    
    if ($debug) {
        print("<font color='#008800'>Recd: ".$reply."</font><br/><br/>");
    }

    // return the socket response
     return chop($reply);
}

//  ----------------------------------------------------------------------------


// This function closes the socket
//
// @param $payClientSocket The Payment Client socket
function close($payClientSocket) {
    $buf = "99";
    $response = fputs($payClientSocket, $buf) == strlen($buf);    
    fclose($payClientSocket);
}

//  ----------------------------------------------------------------------------

// This function uses the QSI Response code retrieved from the Digital
// Receipt and returns an appropriate description for the QSI Response Code
//
// @param $responseCode String containing the QSI Response Code
//
// @return String containing the appropriate description
//
function getResponseDescription($responseCode) {

    switch ($responseCode) {
        case "0" : $result = "Transaction Successful"; break;
        case "?" : $result = "Transaction status is unknown"; break;
        case "1" : $result = "Transaction Declined"; break;
        case "2" : $result = "Bank Declined Transaction"; break;
        case "3" : $result = "No Reply from Bank"; break;
        case "4" : $result = "Expired Card"; break;
        case "5" : $result = "Insufficient funds"; break;
        case "6" : $result = "Error Communicating with Bank"; break;
        case "7" : $result = "Payment Server detected an error"; break;
        case "8" : $result = "Transaction Type Not Supported"; break;
        case "9" : $result = "Bank declined transaction (Do not contact Bank)"; break;
        case "A" : $result = "Transaction Aborted"; break;
        case "C" : $result = "Transaction Cancelled"; break;
        case "D" : $result = "Deferred transaction has been received and is awaiting processing"; break;
        case "F" : $result = "3D Secure Authentication failed"; break;
        case "I" : $result = "Card Security Code verification failed"; break;
        case "L" : $result = "Shopping Transaction Locked (Please try the transaction again later)"; break;
        case "N" : $result = "Cardholder is not enrolled in Authentication scheme"; break;
        case "P" : $result = "Transaction has been received by the Payment Adaptor and is being processed"; break;
        case "R" : $result = "Transaction was not processed - Reached limit of retry attempts allowed"; break;
        case "S" : $result = "Duplicate SessionID (Amex Only)"; break;
        case "T" : $result = "Address Verification Failed"; break;
        case "U" : $result = "Card Security Code Failed"; break;
        case "V" : $result = "Address Verification and Card Security Code Failed"; break;
        default  : $result = "Unable to be determined"; 
    }
    return $result;
}

//  ----------------------------------------------------------------------------

// This function uses the QSI AVS Result Code retrieved from the Digital
// Receipt and returns an appropriate description for this code.

// @param avsResultCode String containing the QSI AVS Result Code
// @return description String containing the appropriate description

function displayAVSResponse($avsResultCode) {
    
    if ($avsResultCode != "") { 
        switch ($avsResultCode) {
            Case "Unsupported" : $result = "AVS not supported or there was no AVS data provided"; break;
            Case "X"  : $result = "Exact match - address and 9 digit ZIP/postal code"; break;
            Case "Y"  : $result = "Exact match - address and 5 digit ZIP/postal code"; break;
            Case "S"  : $result = "Service not supported or address not verified (international transaction)"; break;
            Case "G"  : $result = "Issuer does not participate in AVS (international transaction)"; break;
            Case "A"  : $result = "Address match only"; break;
            Case "W"  : $result = "9 digit ZIP/postal code matched, Address not Matched"; break;
            Case "Z"  : $result = "5 digit ZIP/postal code matched, Address not Matched"; break;
            Case "R"  : $result = "Issuer system is unavailable"; break;
            Case "U"  : $result = "Address unavailable or not verified"; break;
            Case "E"  : $result = "Address and ZIP/postal code not provided"; break;
            Case "N"  : $result = "Address and ZIP/postal code not matched"; break;
            Case "0"  : $result = "AVS not requested"; break;
            default   : $result = "Unable to be determined"; 
        }
    } else {
        $result = "null response";
    }
    return $result;
}

//  ----------------------------------------------------------------------------

// This function uses the QSI CSC Result Code retrieved from the Digital
// Receipt and returns an appropriate description for this code.

// @param cscResultCode String containing the QSI CSC Result Code
// @return description String containing the appropriate description

function displayCSCResponse($cscResultCode) {
    
    if ($cscResultCode != "") {
        switch ($cscResultCode) {
            Case "Unsupported" : $result = "CSC not supported or there was no CSC data provided"; break;
            Case "M"  : $result = "Exact code match"; break;
            Case "S"  : $result = "Merchant has indicated that CSC is not present on the card (MOTO situation)"; break;
            Case "P"  : $result = "Code not processed"; break;
            Case "U"  : $result = "Card issuer is not registered and/or certified"; break;
            Case "N"  : $result = "Code invalid or not matched"; break;
            default   : $result = "Unable to be determined"; break;
        }
    } else {
        $result = "null response";
    }
    return $result;
}

//  -----------------------------------------------------------------------------
?>