<?php
/******************************************************************************
  Authorize.net PHP class
  Written by: Tom Walsh
  Contact: tom at expresshosting dot net
  Description: Authorize.net class used to send information to authorize.net
               for credit card transactions. Written in PHP, and hopefully
               smart enough to determine if the host has cURL enabled either
               on the server or in PHP, and that cURL supports SSL connection.

  Usage:       With login and password:
                 $cc = new AuthorizeNet( $authorize_username, $authorize_password );
               With login and transaction key:
               $cc = new AuthorizeNet( $authorize_username, '', $authorize_transkey );

               $cc->custData(  $firstname, $lastname, $company, $address, $city,
                               $state, $zip, $country, $phone, $fax, $custid,
                               $custtaxid, $invoicenum, $description);
               $result = $cc->processCC( $amount, $ccnumber, $ccexp,
                                         $cctranstype, $cccvv2);

               $cctranstype is generally "AUTH_CAPTURE", or "AUTH", or "CAPTURE"
               $cccvv2 is the credit card hash code on the back of the card 
               (typically 3 digits for MC and Visa, 4 for AMEX)

               if( $result == true ) {
                    //approved
               } else {
                    // declined
               }

  Todo: Correct the error reporting from authorize.net. The system currently
        handles approvals and declines, but not errors. Need to improve that.

  License: BSD
  Licsene Copy:
                Copyright (c) 2007, ExpressPHP.com
                All rights reserved.

                Redistribution and use in source and binary forms, with or 
                without modification, are permitted provided that the following
                conditions are met:

                    * Redistributions of source code must retain the above 
                      copyright notice, this list of conditions and the
                      following disclaimer.
                    * Redistributions in binary form must reproduce the above 
                      copyright notice, this list of conditions and the 
                      following disclaimer in the documentation and/or other 
                      materials provided with the distribution.
                    * Neither the name of ExpressPHP.com nor the names of 
                      its contributors may be used to endorse or promote 
                      products derived from this software without specific 
                      prior written permission.

              THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
              CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
              INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
              MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
              DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
              BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
              EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
              TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
              DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
              ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
              OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
              OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
              POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/

class AuthorizeNet
{

    
// set class variables to null
    // Merchant Account Information
    
var $login_id       =    NULL;
    var 
$tran_key        =     NULL;
    var 
$password       =    NULL;
    var 
$version        =    NULL;
    
// Customer Data
    
var $first_name     =    NULL;
    var 
$last_name      =    NULL;
    var 
$company        =    NULL;
    var 
$address        =    NULL;
    var 
$city           =    NULL;
    var 
$state          =    NULL;
    var 
$zip            =    NULL;
    var 
$country        =    NULL;
    var 
$phone          =    NULL;
    var 
$fax            =    NULL;
    
// Additional Customer Data
    
var $cust_id        =    NULL;
    var 
$customer_ip    =    NULL;
    var 
$customer_tax_id=    NULL;
    
// Email Settings
    
var $email          =    NULL;
    var 
$email_customer =    false;
    var 
$merchant_email =    NULL;
    
// Invoice Information
    
var $invoice_num    =    NULL;
    var 
$description    =    NULL;
    
// Customer Shipping Address
    
var $ship_to_first_name     =    NULL;
    var 
$ship_to_last_name      =    NULL;
    var 
$ship_to_company        =    NULL;
    var 
$ship_to_address        =    NULL;
    var 
$ship_to_city           =    NULL;
    var 
$ship_to_state          =    NULL;
    var 
$ship_to_zip            =    NULL;
    var 
$ship_to_country        =    NULL;
    
// Transaction Data
    
var $amount                 =    NULL;
    var 
$currency_code          =    NULL;
    var 
$method                 =    NULL;
    var 
$type                   =    NULL;
    var 
$recurring_billing      =    NULL;
    
// Billing Info
    
var $bank_aba_code          =    NULL;
    var 
$bank_acct_num          =    NULL;
    var 
$bank_acct_type         =    NULL;
    var 
$bank_name              =    NULL;
    var 
$bank_acct_name         =    NULL;
    var 
$echeck_type            =    NULL;
    var 
$card_num               =    NULL;
    var 
$exp_date               =    NULL;
    var 
$card_code              =    NULL;
    var 
$trans_id               =    NULL;
    var 
$auth_code              =    NULL;
    
// Authorize.net specific information
    
var $location               =    NULL;
    var 
$error                  =    NULL;
    var 
$curltype               =    NULL;
    var 
$curllocation           =    NULL;
    var 
$nocurlssl              =    false;
    var 
$setcustinfo            =    false;
    var 
$returndata             =    NULL;
    
// Error reporting variables
    
var $isError                =      false;
    var 
$error_message            =     NULL;
    
    
// initialize the constructor
    
function authorizenet$login NULL$password NULL$tran_key NULL$version "3.1" )
    {
        
$this->customer_ip $_SERVER['REMOTE_ADDR'];
        
$this->location "https://secure.authorize.net/gateway/transact.dll";

        if( 
$login != NULL ) {
            
$this->setLoginId$login );
        } else {
            
$this->raiseError'You must provide a login to proceed.';
        }

        if( 
$password == NULL && $tran_key != NULL ) {
            
// We have been passed a tran_key
            
$this->setTransKey$tran_key );
        } elseif( 
$password != NULL && $tran_key == NULL ) {
            
// We have been passed a password
            
$this->setPassword$password );
        } else {
            
// We have an error
            
$this->raiseError'You must provide a password or a transaction key to proceed.' );
        }

        
$this->setVersion$version );

        
$whichcurl trimexec'/usr/bin/which curl' ) );
        
//check for curl in PHP
        
if ( function_exists'curl_init' ) ) {
            
$this->curltype "PHP";
            
$versiondata curl_version();
            if( 
is_string$versiondata ) ) {
                
//process the curl string to find the SSL
                
$this->nocurlssl = (stristr$versiondata'openssl' ) === false ) ? true false;
            } elseif ( 
is_array$versiondata ) ) {
                
// process the curl array (PHP5 returns an array)
                
$this->nocurlssl = ( stristr$versiondata'openssl' ) === false ) ? true false;
            } elseif ( !empty( 
$whichcurl ) ) {
                
$this->curltype "CURL";
                
$this->curllocation $whichcurl;
                
exec$this->curllocation ." -V"$versiondata );
                foreach( 
$versiondata as $line) {
                    if( 
stristr$line'openssl' ) !== false ) {
                        
$this->nocurlssl false;
                        break;
                    } else {
                        
$this->nocurlssl true;
                    }
                }
            }
        } else {
            
$this->raiseError'Unable to locate cURL. Please check that PHP is compiled with cURL or that you have the curl binary installed on your server.' );
        }

        if ( 
$this->nocurlssl ) {
            
$this->raiseError'cURL is installed, however it does not have SSL enabled. Please recomlpie cURL to include SSL support.' );
        }
     
    }

    function 
custData(  $firstname NULL,
                        
$lastname NULL,
                        
$company NULL,
                        
$address NULL,
                        
$city NULL,
                        
$state NULL,
                        
$zip NULL,
                        
$country NULL,
                        
$phone NULL,
                        
$fax NULL,
                        
$custid NULL,
                        
$custtaxid NULL,
                        
$invoicenum NULL,
                        
$description NULL )
    {
        
$this->setFirstName$firstname );
        
$this->setLastName$lastname );
        
$this->setCompany$company );
        
$this->setAddress$address );
        
$this->setCity$city );
        
$this->setState$state );
        
$this->setZip$zip );
        
$this->setCountry$country );
        
$this->setPhone$phone );
        
$this->setFax$fax );
        
$this->setCustID$custid );
        
$this->setCustomerTaxID$custtaxid );
        
$this->setInvoiceNum$invoicenum );
        
$this->setDescription$description );
        
$this->setcustinfo true;
    }
     
    function 
processCC$amount NULL,
                        
$ccnumber NULL,
                        
$ccexp NULL,
                        
$cctranstype NULL,
                        
$cccvv2 NULL )
    {
        
$data null;
        
$this->setMethod"CC" );
        
$this->setAmount$amount );
        
$this->setCardNum$ccnumber );
        
$this->setExpDate$ccexp );
        
$this->settheType$cctranstype );
        
$this->setCardCode$cccvv2 );

        
$data =& $this->getUrlData();

        
// Only process the information if there are no errors.
        
if( $this->hasError != true ) {
            if ( 
$this->curltype == "PHP" ) {
                
$returnstring $this->usePHPCurl$data );
            } elseif ( 
$this->curltype == "CURL" ) {
                
$returnstring $this->useCurl$data );
            }
        }
         
        
$returnarray = array();
        
$returnarray explode'|'$returnstring );
        
$responsecode $returnarray[2];
        if( 
$responsecode == ) {
                
$this->returndata = array( "text" => $returnarray[3],
                                           
"approval_code" => $returnarray[6],
                                           
"avs_code" => $returnarray[7],
                                           
"trans_id" => $returnarray[8],
                                           
"amount" => $returnarray[9],
                                           
"type" => $returnarray[10] );
                return 
true;
        } elseif ( 
$responsecode == ) {
                
$this->returndata = array( "text" => $returnarray[3],
                                           
"approval_code" => $returnarray[6],
                                           
"avs_code" => $returnarray[7],
                                           
"trans_id" => $returnarray[8],
                                           
"amount" => $returnarray[9],
                                           
"type" => $returnarray[10] );
                return 
false;
        } else {
                
$this->returndata $returnstring;
                return 
false;
        }
    }

    function 
processECheck$amount NULL,
                            
$bank_aba_code NULL,
                            
$bank_acct_num NULL,
                            
$bank_acct_type NULL,
                            
$bank_name NULL,
                            
$bank_acct_name NULL,
                            
$type NULL,
                            
$echeck_type NULL )
    {
        
$this->setMethod"ECHECK" );
        
$this->setBankABACode$bank_aba_code );
        
$this->setBankAcctNum$bank_acct_num );
        
$this->setBankName$bank_name );
        
$this->setBankAcctName$bank_acct_name );
        
$this->setEcheckType$echeck_type );

        
$data =& $this->getUrlData();

        if ( 
$this->curltype == "PHP" ) {
            
$returnstring $this->usePHPCurl$data );
        } elseif ( 
$this->curltype == "CURL" ) {
            
$returnstring $this->useCurl$data );
        }

        echo 
$returnstring;

        
$returnarray = array();
        
$returnarray explode'|'$returnstring );
        
$responsecode $returnarray[2];
        if( 
$responsecode == ) {
                return 
true;
        } else {
            if( 
$returnarray[3] ) {
                
$this->error $returnarray[3];
            } else {
                
$this->error $returnstring;
            }

            return 
false;
        }
    }

    function 
usePHPCurl( &$data )
    {

        
$returnstring "";
        
$curl curl_init();
        
curl_setopt$curlCURLOPT_URL$this->location );
        
curl_setopt$curlCURLOPT_RETURNTRANSFER);
        
curl_setopt$curlCURLOPT_POST);
        
curl_setopt$curlCURLOPT_TIMEOUT30 );
        
curl_setopt$curlCURLOPT_HEADER);
        
curl_setopt$curlCURLOPT_POSTFIELDS$data );
        
$returnstring curl_exec$curl );
        @
curl_close$curl );

        return 
$returnstring;

    }

    function 
useCurl( &$data )
    {

        
$returnstring "";
        
exec"$this->curllocation -d \"$data\" $this->location"$returnarray );
        if ( 
sizeof$returnarray ) ) {
            foreach( 
$returnarray as $item ) {
                
$returnstring .= $item;
            }
        } else {
            
$returnstring false;
        }

        return 
$returnstring;

    }
     
    function 
error() //return the error code from processing
    
{
        return 
$this->error;
    }

    function 
raiseError$text NULL ) {
        
// an error has occured
        
$this->isError true;
        
$this->error_message $text;
    }

    function 
hasError() {
        
// Do we have an error?
        
if( $this->isError == true ) {
            
// Yes we have an error
            
return true;
        } else {
            return 
false;
        }
    }

    function 
getError() {
        
// Return the last error
        
return $this->error_message;
    }
     
    function 
getUrlData()
    {
        if( 
$this->password == NULL ) {
            
// The password is null so we must be using a tran_key
            
$passtype    =    'x_tran_key';
            
$password    =    $this->tran_key;
        } else {
            
// The password wasn't null so we are using a password
            
$passtype    =    'x_password';
            
$password    =    $this->password;
        }
        
        
$data =
        
"x_login="                    $this->login_id .  
        
"&" $passtype '='         $password .
        
"&x_version="                 $this->version .
        
"&x_delim_data="              "TRUE" .  
        
"&x_delim_char="              "|" .
        
"&x_relay_response="          "FALSE" .
        
"&x_customer_ip="             $this->customer_ip;

        if( 
$this->setcustinfo ) {
             
$data .=
             
"&x_first_name="         $this->first_name .
             
"&x_last_name="          $this->last_name .
             
"&x_company="            $this->company .
             
"&x_address="            $this->address .
             
"&x_city="               $this->city .
             
"&x_state="              $this->state .
             
"&x_zip="                $this->zip .
             
"&x_country="            $this->country .
             
"&x_phone="              $this->phone .
             
"&x_fax="                $this->fax .
             
"&x_cust_id="            $this->cust_id .
             
"&x_customer_tax_id="    $this->customer_tax_id .
             
"&x_invoice_num="        $this->invoice_num .
             
"&x_description="        $this->description;
        }

        if( 
$this->method == "CC" ) {
            
$data .=
            
"&x_method="              $this->method .
            
"&x_amount="              $this->amount .
            
"&x_card_num="            $this->card_num .
            
"&x_exp_date="            $this->exp_date .
            
"&x_type="                $this->type;
            if( 
$this->card_code != "" ) {
                
$data .=
                
"&x_card_code="       $this->card_code;
            }
        }
         
        if( 
$this->method == "ECHECK" ) {
            
$data .=
            
"&x_method="              $this->method .
            
"&x_amount="              $this->amount .
            
"&x_bank_aba_code="       $this->bank_aba_code .
            
"&x_bank_acct_num="       $this->bank_acct_num .
            
"&x_bank_acct_type="      $this->bank_acct_type .
            
"&x_bank_name="           $this->bank_name .
            
"&x_bank_acct_name="      $this->bank_acct_name .
            
"&x_type="                $this->type .
            
"&x_echeck_type="         $this->echeck_type;
        }

        return 
$data;
    }

    function 
setLoginId$loginid ) {
        if( 
strlen$loginid ) > 20 ) {
            
$this->raiseError'Login ID is longer than 20.' );
        } else {
            
$this->login_id urlencode$loginid );
        }
    }

    function 
setTranKey$tran_key ) {
        if( 
strlen$tran_key ) > 16 ) {
            
$this->raiseError'Tran Key is longer tha 16.' );
        } else {
            
$this->tran_key urlencode$tran_key );
        }
    }

    function 
setPassword$password )
    {
    
$this->password urlencode$password );
    }

    function 
setVersion$version )
    {
    
$this->version urlencode$version );
    }

    function 
setFirstName$first_name )
    {
    
$this->first_name urlencode$first_name );
    }

    function 
setLastName$last_name )
    {
    
$this->last_name urlencode$last_name );
    }

    function 
setCompany$company )
    {
    
$this->company urlencode$company );
    }

    function 
setAddress $address )
    {
    
$this->address urlencode$address );
    }

    function 
setCity$city )
    {
    
$this->city urlencode$city );
    }

    function 
setState$state )
    {
    
$this->state urlencode$state );
    }

    function 
setZip$zip )
    {
    
$this->zip urlencode$zip );
    }

    function 
setCountry$country )
    {
    
$this->country urlencode$country );
    }

    function 
setPhone$phone )
    {
    
$this->phone urlencode$phone );
    }

    function 
setFax$fax )
    {
    
$this->fax urlencode$fax );
    }

    function 
setCustID$custid )
    {
    
$this->cust_id urlencode$custid );
    }

    function 
setCustomerTaxID$customer_tax_id )
    {
    
$this->customer_tax_id urlencode$customer_tax_id );
    }

    function 
setEmail$email )
    {
    
$this->email urlencode$email );
    }

    function 
setMerchantEmail$merchantemail )
    {
    
$this->merchant_email urlencode$merchantemail );
    }

    function 
setInvoiceNum$invoicenumber )
    {
    
$this->invoice_num urlencode$invoicenumber );
    }

    function 
setDescription$description )
    {
    
$this->description urlencode$description );
    }

    function 
setAmount$amount )
    {
    
$this->amount =  urlencode$amount );
    }

    function 
setCurrenyCode$currencycode )
    {
    
$this->currency_code urlencode$currencycode );
    }

    function 
setMethod$method )
    {
    
$this->method urlencode$method );
    }

    function 
settheType$type )
    {
    
$this->type urlencode$type );
    }

    function 
setBankABACode$bankabacode )
    {
    
$this->bank_aba_code urlencode$bankabacode );
    }

    function 
setBankAcctNum$bankacctnum )
    {
    
$this->bank_acct_num urlencode$bankacctnum );
    }

    function 
setBankAcctType$bankaccttype )
    {
    
$this->bank_acct_type urlencode$bankaccttype );
    }

    function 
setBankName$bankname )
    {
    
$this->bank_name urlencode$bankname );
    }

    function 
setBankAcctName$bankacctname )
    {
    
$this->bank_acct_name urlencode$bankacctname );
    }

    function 
setEcheckType$echecktype )
    {
    
$this->echeck_type urlencode$echecktype );
    }

    function 
setCardNum$ccnum )
    {
    
$this->card_num urlencode$ccnum );
    }

    function 
setExpDate$expdate )
    {
    
$this->exp_date urlencode$expdate );
    }

    function 
setCardCode$cardcode )
    {
    
$this->card_code urlencode$cardcode );
    }

    function 
setTransID$transid )
    {
    
$this->trans_id urlencode$transid );
    }

    function 
setAuthCode$authcode )
    {
    
$this->auth_code urlencode$authcode );
    }
     
}
?>