517 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			517 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
 | 
						|
 | 
						|
/**
 | 
						|
 * LinkPoint processor
 | 
						|
 *
 | 
						|
 * PHP versions 4 and 5
 | 
						|
 *
 | 
						|
 * LICENSE: This source file is subject to version 3.0 of the PHP license
 | 
						|
 * that is available through the world-wide-web at the following URI:
 | 
						|
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
 | 
						|
 * the PHP License and are unable to obtain it through the web, please
 | 
						|
 * send a note to license@php.net so we can mail you a copy immediately.
 | 
						|
 *
 | 
						|
 * @category   Payment
 | 
						|
 * @package    Payment_Process
 | 
						|
 * @author     Joe Stump <joe@joestump.net>
 | 
						|
 * @copyright  1997-2005 The PHP Group
 | 
						|
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
 | 
						|
 * @version    CVS: $Revision: 1.13 $
 | 
						|
 * @link       http://pear.php.net/package/Payment_Process
 | 
						|
 * @link       http://www.linkpoint.net/
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
require_once('Payment/Process.php');
 | 
						|
require_once('Payment/Process/Common.php');
 | 
						|
require_once('Net/Curl.php');
 | 
						|
require_once('XML/Parser.php');
 | 
						|
 | 
						|
$GLOBALS['_Payment_Process_LinkPoint'] = array(
 | 
						|
    PAYMENT_PROCESS_ACTION_NORMAL   => 'SALE',
 | 
						|
    PAYMENT_PROCESS_ACTION_AUTHONLY => 'PREAUTH',
 | 
						|
    PAYMENT_PROCESS_ACTION_POSTAUTH => 'POSTAUTH'
 | 
						|
);
 | 
						|
 | 
						|
/**
 | 
						|
 * Payment_Process_LinkPoint
 | 
						|
 *
 | 
						|
 * This is a processor for LinkPoint's merchant payment gateway.
 | 
						|
 * (http://www.linkpoint.net/)
 | 
						|
 *
 | 
						|
 * *** WARNING ***
 | 
						|
 * This is BETA code, and has not been fully tested. It is not recommended
 | 
						|
 * that you use it in a production envorinment without further testing.
 | 
						|
 *
 | 
						|
 * @package Payment_Process
 | 
						|
 * @author Joe Stump <joe@joestump.net>
 | 
						|
 * @version @version@
 | 
						|
 */
 | 
						|
class Payment_Process_LinkPoint extends Payment_Process_Common
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * Front-end -> back-end field map.
 | 
						|
     *
 | 
						|
     * This array contains the mapping from front-end fields (defined in
 | 
						|
     * the Payment_Process class) to the field names DPILink requires.
 | 
						|
     *
 | 
						|
     * @see _prepare()
 | 
						|
     * @access private
 | 
						|
     */
 | 
						|
    var $_fieldMap = array(
 | 
						|
        // Required
 | 
						|
        'login'         => 'configfile',
 | 
						|
        'action'        => 'ordertype',
 | 
						|
        'invoiceNumber' => 'oid',
 | 
						|
        'customerId'    => 'x_cust_id',
 | 
						|
        'amount'        => 'chargetotal',
 | 
						|
        'name'          => '',
 | 
						|
        'zip'           => 'zip',
 | 
						|
        // Optional
 | 
						|
        'company'       => 'company',
 | 
						|
        'address'       => 'address1',
 | 
						|
        'city'          => 'city',
 | 
						|
        'state'         => 'state',
 | 
						|
        'country'       => 'country',
 | 
						|
        'phone'         => 'phone',
 | 
						|
        'email'         => 'email',
 | 
						|
        'ip'            => 'ip',
 | 
						|
    );
 | 
						|
 | 
						|
    /**
 | 
						|
    * $_typeFieldMap
 | 
						|
    *
 | 
						|
    * @author Joe Stump <joe@joestump.net>
 | 
						|
    * @access protected
 | 
						|
    */
 | 
						|
    var $_typeFieldMap = array(
 | 
						|
 | 
						|
           'CreditCard' => array(
 | 
						|
 | 
						|
                    'cardNumber' => 'cardnumber',
 | 
						|
                    'cvv'        => 'cvm',
 | 
						|
                    'expDate'    => 'expDate'
 | 
						|
 | 
						|
           ),
 | 
						|
 | 
						|
           'eCheck' => array(
 | 
						|
 | 
						|
                    'routingCode'   => 'routing',
 | 
						|
                    'accountNumber' => 'account',
 | 
						|
                    'type'          => 'type',
 | 
						|
                    'bankName'      => 'bank',
 | 
						|
                    'name'          => 'name',
 | 
						|
                    'driversLicense'      => 'dl',
 | 
						|
                    'driversLicenseState' => 'dlstate'
 | 
						|
 | 
						|
           )
 | 
						|
    );
 | 
						|
 | 
						|
    /**
 | 
						|
     * Default options for this processor.
 | 
						|
     *
 | 
						|
     * @see Payment_Process::setOptions()
 | 
						|
     * @access private
 | 
						|
     */
 | 
						|
    var $_defaultOptions = array(
 | 
						|
         'host'   => 'secure.linkpt.net',
 | 
						|
         'port'   => '1129',
 | 
						|
         'result' => 'LIVE'
 | 
						|
    );
 | 
						|
 | 
						|
    /**
 | 
						|
     * Has the transaction been processed?
 | 
						|
     *
 | 
						|
     * @type boolean
 | 
						|
     * @access private
 | 
						|
     */
 | 
						|
    var $_processed = false;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The response body sent back from the gateway.
 | 
						|
     *
 | 
						|
     * @access private
 | 
						|
     */
 | 
						|
    var $_responseBody = '';
 | 
						|
 | 
						|
    /**
 | 
						|
     * Constructor.
 | 
						|
     *
 | 
						|
     * @param  array  $options  Class options to set.
 | 
						|
     * @see Payment_Process::setOptions()
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    function __construct($options = false)
 | 
						|
    {
 | 
						|
        parent::__construct($options);
 | 
						|
        $this->_driver = 'LinkPoint';
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Process the transaction.
 | 
						|
     *
 | 
						|
     * @author Joe Stump <joe@joestump.net>
 | 
						|
     * @access public
 | 
						|
     * @return mixed Payment_Process_Result on success, PEAR_Error on failure
 | 
						|
     */
 | 
						|
    function &process()
 | 
						|
    {
 | 
						|
        if (!strlen($this->_options['keyfile']) ||
 | 
						|
            !file_exists($this->_options['keyfile'])) {
 | 
						|
            return PEAR::raiseError('Invalid key file');
 | 
						|
        }
 | 
						|
 | 
						|
        // Sanity check
 | 
						|
        $result = $this->validate();
 | 
						|
        if (PEAR::isError($result)) {
 | 
						|
            return $result;
 | 
						|
        }
 | 
						|
 | 
						|
        // Prepare the data
 | 
						|
        $result = $this->_prepare();
 | 
						|
        if (PEAR::isError($result)) {
 | 
						|
            return $result;
 | 
						|
        }
 | 
						|
 | 
						|
        // Don't die partway through
 | 
						|
        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
 | 
						|
 | 
						|
 | 
						|
        $xml = $this->_prepareQueryString();
 | 
						|
        if (PEAR::isError($xml)) {
 | 
						|
            return $xml;
 | 
						|
        }
 | 
						|
 | 
						|
        $url = 'https://'.$this->_options['host'].':'.$this->_options['port'].
 | 
						|
               '/LSGSXML';
 | 
						|
 | 
						|
        $curl = new Net_Curl($url);
 | 
						|
        $result = $curl->create();
 | 
						|
        if (PEAR::isError($result)) {
 | 
						|
            return $result;
 | 
						|
        }
 | 
						|
 | 
						|
        $curl->type = 'POST';
 | 
						|
        $curl->fields = $xml;
 | 
						|
        $curl->sslCert = $this->_options['keyfile'];
 | 
						|
 | 
						|
        // LinkPoint's staging server has a boned certificate. If they are
 | 
						|
        // testing against staging we need to turn off SSL host verification.
 | 
						|
        if ($this->_options['host'] == 'staging.linkpt.net') {
 | 
						|
            $curl->verifyPeer = false;
 | 
						|
            $curl->verifyHost = 0;
 | 
						|
        }
 | 
						|
 | 
						|
        $curl->userAgent = 'PEAR Payment_Process_LinkPoint 0.1';
 | 
						|
 | 
						|
        $result = &$curl->execute();
 | 
						|
        if (PEAR::isError($result)) {
 | 
						|
            return PEAR::raiseError('cURL error: '.$result->getMessage());
 | 
						|
        } else {
 | 
						|
            $curl->close();
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        $this->_responseBody = trim($result);
 | 
						|
        $this->_processed = true;
 | 
						|
 | 
						|
        // Restore error handling
 | 
						|
        PEAR::popErrorHandling();
 | 
						|
 | 
						|
        $response = &Payment_Process_Result::factory($this->_driver,
 | 
						|
                                                     $this->_responseBody,
 | 
						|
                                                     $this);
 | 
						|
 | 
						|
        if (!PEAR::isError($response)) {
 | 
						|
            $response->parse();
 | 
						|
        }
 | 
						|
 | 
						|
        return $response;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Prepare the POST query string.
 | 
						|
     *
 | 
						|
     * @access private
 | 
						|
     * @return string The query string
 | 
						|
     */
 | 
						|
    function _prepareQueryString()
 | 
						|
    {
 | 
						|
 | 
						|
        $data = array_merge($this->_options,$this->_data);
 | 
						|
 | 
						|
        $xml  = '<!-- Payment_Process order -->'."\n";
 | 
						|
        $xml .= '<order>'."\n";
 | 
						|
        $xml .= '<merchantinfo>'."\n";
 | 
						|
        $xml .= '  <configfile>'.$data['configfile'].'</configfile>'."\n";
 | 
						|
        $xml .= '  <keyfile>'.$data['keyfile'].'</keyfile>'."\n";
 | 
						|
        $xml .= '  <host>'.$data['authorizeUri'].'</host>'."\n";
 | 
						|
        $xml .= '  <appname>PEAR Payment_Process</appname>'."\n";
 | 
						|
        $xml .= '</merchantinfo>'."\n";
 | 
						|
        $xml .= '<orderoptions>'."\n";
 | 
						|
        $xml .= '  <ordertype>'.$data['ordertype'].'</ordertype>'."\n";
 | 
						|
        $xml .= '  <result>'.$data['result'].'</result>'."\n";
 | 
						|
        $xml .= '</orderoptions>'."\n";
 | 
						|
        $xml .= '<payment>'."\n";
 | 
						|
        $xml .= '  <subtotal>'.$data['chargetotal'].'</subtotal>'."\n";
 | 
						|
        $xml .= '  <tax>0.00</tax>'."\n";
 | 
						|
        $xml .= '  <shipping>0.00</shipping>'."\n";
 | 
						|
        $xml .= '  <chargetotal>'.$data['chargetotal'].'</chargetotal>'."\n";
 | 
						|
        $xml .= '</payment>'."\n";
 | 
						|
 | 
						|
        // Set payment method to eCheck if our payment type is eCheck.
 | 
						|
        // Default is Credit Card.
 | 
						|
        $data['x_method'] = 'CC';
 | 
						|
        switch ($this->_payment->getType())
 | 
						|
        {
 | 
						|
            case 'eCheck':
 | 
						|
                return PEAR::raiseError('eCheck not currently supported',
 | 
						|
                                        PAYMENT_PROCESS_ERROR_NOTIMPLEMENTED);
 | 
						|
 | 
						|
                $xml .= '<telecheck>'."\n";
 | 
						|
                $xml .= '  <routing></routing>'."\n";
 | 
						|
                $xml .= '  <account></account>'."\n";
 | 
						|
                $xml .= '  <checknumber></checknumber>'."\n";
 | 
						|
                $xml .= '  <bankname></bankname>'."\n";
 | 
						|
                $xml .= '  <bankstate></bankstate>'."\n";
 | 
						|
                $xml .= '  <dl></dl>'."\n";
 | 
						|
                $xml .= '  <dlstate></dlstate>'."\n";
 | 
						|
                $xml .= '  <accounttype>pc|ps|bc|bs</accounttype>'."\n";
 | 
						|
                $xml .= '<telecheck>'."\n";
 | 
						|
                break;
 | 
						|
            case 'CreditCard':
 | 
						|
                $xml .= '<creditcard>'."\n";
 | 
						|
                $xml .= '  <cardnumber>'.$data['cardnumber'].'</cardnumber>'."\n";
 | 
						|
                list($month,$year) = explode('/',$data['expDate']);
 | 
						|
                if (strlen($year) == 4) {
 | 
						|
                    $year = substr($year,2);
 | 
						|
                }
 | 
						|
 | 
						|
                $month = sprintf('%02d',$month);
 | 
						|
 | 
						|
                $xml .= '  <cardexpmonth>'.$month.'</cardexpmonth>'."\n";
 | 
						|
                $xml .= '  <cardexpyear>'.$year.'</cardexpyear>'."\n";
 | 
						|
                if (strlen($data['cvm'])) {
 | 
						|
                    $xml .= '  <cvmvalue>'.$data['cvm'].'</cvmvalue>'."\n";
 | 
						|
                    $xml .= '  <cvmindicator>provided</cvmindicator>'."\n";
 | 
						|
                }
 | 
						|
                $xml .= '</creditcard>'."\n";
 | 
						|
        }
 | 
						|
 | 
						|
        if (isset($this->_payment->firstName) &&
 | 
						|
            isset($this->_payment->lastName)) {
 | 
						|
            $xml .= '<billing>'."\n";
 | 
						|
            $xml .= '  <userid>'.$this->_payment->customerId.'</userid>'."\n";
 | 
						|
            $xml .= '  <name>'.$this->_payment->firstName.' '.$this->_payment->lastName.'</name>'."\n";
 | 
						|
            $xml .= '  <company>'.$this->_payment->company.'</company>'."\n";
 | 
						|
            $xml .= '  <address1>'.$this->_payment->address.'</address1>'."\n";
 | 
						|
            $xml .= '  <city>'.$this->_payment->city.'</city>'."\n";
 | 
						|
            $xml .= '  <state>'.$this->_payment->state.'</state>'."\n";
 | 
						|
            $xml .= '  <zip>'.$this->_payment->zip.'</zip>'."\n";
 | 
						|
            $xml .= '  <country>'.$this->_payment->country.'</country>'."\n";
 | 
						|
            $xml .= '  <phone>'.$this->_payment->phone.'</phone>'."\n";
 | 
						|
            $xml .= '  <email>'.$this->_payment->email.'</email>'."\n";
 | 
						|
            $xml .= '  <addrnum>'.$this->_payment->address.'</addrnum>'."\n";
 | 
						|
            $xml .= '</billing>'."\n";
 | 
						|
        }
 | 
						|
 | 
						|
        $xml .= '</order>'."\n";
 | 
						|
 | 
						|
        return $xml;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Payment_Process_Result_LinkPoint
 | 
						|
 *
 | 
						|
 * LinkPoint result class
 | 
						|
 *
 | 
						|
 * @author Joe Stump <joe@joestump.net>
 | 
						|
 * @package Payment_Process
 | 
						|
 */
 | 
						|
class Payment_Process_Result_LinkPoint extends Payment_Process_Result
 | 
						|
{
 | 
						|
 | 
						|
    var $_statusCodeMap = array('APPROVED' => PAYMENT_PROCESS_RESULT_APPROVED,
 | 
						|
                                'DECLINED' => PAYMENT_PROCESS_RESULT_DECLINED,
 | 
						|
                                'FRAUD' => PAYMENT_PROCESS_RESULT_FRAUD);
 | 
						|
 | 
						|
    /**
 | 
						|
     * LinkPoint status codes
 | 
						|
     *
 | 
						|
     * This array holds many of the common response codes. There are over 200
 | 
						|
     * response codes - so check the LinkPoint manual if you get a status
 | 
						|
     * code that does not match (see "Response Reason Codes & Response
 | 
						|
     * Reason Text" in the AIM manual).
 | 
						|
     *
 | 
						|
     * @see getStatusText()
 | 
						|
     * @access private
 | 
						|
     */
 | 
						|
    var $_statusCodeMessages = array(
 | 
						|
        'APPROVED' => 'This transaction has been approved.',
 | 
						|
        'DECLINED' => 'This transaction has been declined.',
 | 
						|
        'FRAUD' => 'This transaction has been determined to be fraud.');
 | 
						|
 | 
						|
    var $_avsCodeMap = array(
 | 
						|
        'YY' => PAYMENT_PROCESS_AVS_MATCH,
 | 
						|
        'YN' => PAYMENT_PROCESS_AVS_MISMATCH,
 | 
						|
        'YX' => PAYMENT_PROCESS_AVS_ERROR,
 | 
						|
        'NY' => PAYMENT_PROCESS_AVS_MISMATCH,
 | 
						|
        'XY' => PAYMENT_PROCESS_AVS_MISMATCH,
 | 
						|
        'NN' => PAYMENT_PROCESS_AVS_MISMATCH,
 | 
						|
        'NX' => PAYMENT_PROCESS_AVS_MISMATCH,
 | 
						|
        'XN' => PAYMENT_PROCESS_AVS_MISMATCH,
 | 
						|
        'XX' => PAYMENT_PROCESS_AVS_ERROR
 | 
						|
    );
 | 
						|
 | 
						|
    var $_avsCodeMessages = array(
 | 
						|
        'YY' => 'Address matches, zip code matches',
 | 
						|
        'YN' => 'Address matches, zip code does not match',
 | 
						|
        'YX' => 'Address matches, zip code comparison not available',
 | 
						|
        'NY' => 'Address does not match, zip code matches',
 | 
						|
        'XY' => 'Address comparison not available, zip code matches',
 | 
						|
        'NN' => 'Address comparison does not match, zip code does not match',
 | 
						|
        'NX' => 'Address does not match, zip code comparison not available',
 | 
						|
        'XN' => 'Address comparison not available, zip code does not match',
 | 
						|
        'XX' => 'Address comparison not available, zip code comparison not available'
 | 
						|
    );
 | 
						|
 | 
						|
    var $_cvvCodeMap = array('M' => PAYMENT_PROCESS_CVV_MATCH,
 | 
						|
                             'N' => PAYMENT_PROCESS_CVV_MISMATCH,
 | 
						|
                             'P' => PAYMENT_PROCESS_CVV_ERROR,
 | 
						|
                             'S' => PAYMENT_PROCESS_CVV_ERROR,
 | 
						|
                             'U' => PAYMENT_PROCESS_CVV_ERROR,
 | 
						|
                             'X' => PAYMENT_PROCESS_CVV_ERROR
 | 
						|
    );
 | 
						|
 | 
						|
    var $_cvvCodeMessages = array(
 | 
						|
        'M' => 'Card Code Match',
 | 
						|
        'N' => 'Card code does not match',
 | 
						|
        'P' => 'Not processed',
 | 
						|
        'S' => 'Merchant has indicated that the card code is not present on the card',
 | 
						|
        'U' => 'Issuer is not certified and/or has not proivded encryption keys',
 | 
						|
        'X' => 'No response from the credit card association was received'
 | 
						|
    );
 | 
						|
 | 
						|
    var $_fieldMap = array('r_approved'  => 'code',
 | 
						|
                           'r_error'  => 'message',
 | 
						|
                           'r_code'  => 'approvalCode',
 | 
						|
                           'r_ordernum'  => 'transactionId'
 | 
						|
    );
 | 
						|
 | 
						|
    function Payment_Process_Response_LinkPoint($rawResponse)
 | 
						|
    {
 | 
						|
        $this->Payment_Process_Response($rawResponse);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
    * parse
 | 
						|
    *
 | 
						|
    * @author Joe Stump <joe@joestump.net>
 | 
						|
    * @access public
 | 
						|
    * @return void
 | 
						|
    */
 | 
						|
    function parse()
 | 
						|
    {
 | 
						|
        $xml = new Payment_Processor_LinkPoint_XML_Parser();
 | 
						|
        $xml->parseString('<response>'.$this->_rawResponse.'</response>');
 | 
						|
        if (is_array($xml->response) && count($xml->response)) {
 | 
						|
            $this->avsCode = substr($xml->response['r_avs'],0,2);
 | 
						|
            $this->cvvCode = substr($xml->response['r_avs'],2,1);
 | 
						|
            $this->customerId = $this->_request->customerId;
 | 
						|
            $this->invoiceNumber = $this->_request->invoiceNumber;
 | 
						|
            $this->_mapFields($xml->response);
 | 
						|
 | 
						|
            // switch to DECLINED since a duplicate isn't *really* fraud
 | 
						|
            if(eregi('duplicate',$this->message)) {
 | 
						|
                $this->messageCode = 'DECLINED';
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Payment_Processor_LinkPoint_XML_Parser
 | 
						|
 *
 | 
						|
 * XML Parser for the LinkPoint response
 | 
						|
 *
 | 
						|
 * @author Joe Stump <joe@joestump.net>
 | 
						|
 * @package Payment_Process
 | 
						|
 */
 | 
						|
class Payment_Processor_LinkPoint_XML_Parser extends XML_Parser
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * $response
 | 
						|
     *
 | 
						|
     * @var array $response Raw response as an array
 | 
						|
     * @access public
 | 
						|
     */
 | 
						|
    var $response = array();
 | 
						|
 | 
						|
    /**
 | 
						|
     * $log
 | 
						|
     *
 | 
						|
     * @var string $tag Current tag
 | 
						|
     * @access private
 | 
						|
     */
 | 
						|
    var $tag = null;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Payment_Processor_LinkPoint_XML_Parser
 | 
						|
     *
 | 
						|
     * @author Joe Stump <joe@joestump.net>
 | 
						|
     * @access public
 | 
						|
     * @return void
 | 
						|
     * @see XML_Parser
 | 
						|
     */
 | 
						|
    function __construct()
 | 
						|
    {
 | 
						|
        $this->XML_Parser();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * startHandler
 | 
						|
     *
 | 
						|
     * @author Joe Stump <joe@joestump.net>
 | 
						|
     * @access public
 | 
						|
     * @param resource $xp XML processor handler
 | 
						|
     * @param string $elem Name of XML entity
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    function startHandler($xp, $elem, &$attribs)
 | 
						|
    {
 | 
						|
        $this->tag = $elem;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * endHandler
 | 
						|
     *
 | 
						|
     * @author Joe Stump <joe@joestump.net>
 | 
						|
     * @access public
 | 
						|
     * @param resource $xp XML processor handler
 | 
						|
     * @param string $elem Name of XML entity
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    function endHandler($xp, $elem)
 | 
						|
    {
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * defaultHandler
 | 
						|
     *
 | 
						|
     * @author Joe Stump <joe@joestump.net>
 | 
						|
     * @access public
 | 
						|
     * @param resource $xp XML processor handler
 | 
						|
     * @param string $data
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    function defaultHandler($xp,$data)
 | 
						|
    {
 | 
						|
        $this->response[strtolower($this->tag)] = $data;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
?>
 |