Payment_Process
[ class tree: Payment_Process ] [ index: Payment_Process ] [ all elements ]

Source for file AuthorizeNet.php

Documentation is available at AuthorizeNet.php

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  4.  
  5. /**
  6.  * Authorize.Net processor
  7.  *
  8.  * PHP versions 4 and 5
  9.  *
  10.  * LICENSE:
  11.  *
  12.  * Redistribution and use in source and binary forms, with or without modification,
  13.  * are permitted provided that the following conditions are met:
  14.  *
  15.  * 1. Redistributions of source code must retain the above copyright notice, this
  16.  *    list of conditions and the following disclaimer.
  17.  *
  18.  * 2. Redistributions in binary form must reproduce the above copyright notice,
  19.  *    this list of conditions and the following disclaimer in the documentation
  20.  *    and/or other materials provided with the distribution.
  21.  *
  22.  * 3. The name of the authors may not be used to endorse or promote products
  23.  *    derived from this software without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
  26.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  27.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  28.  * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  29.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  30.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  31.  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  32.  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34.  * POSSIBILITY OF SUCH DAMAGE.
  35.  *
  36.  * @category  Payment
  37.  * @package   Payment_Process
  38.  * @author    Joe Stump <joe@joestump.net>                                |
  39.  * @author    Philippe Jausions <Philippe.Jausions@11abacus.com>
  40.  * @copyright 1997-2008 The PHP Group
  41.  * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
  42.  * @version   CVS: $Id: AuthorizeNet.php 267241 2008-10-12 19:37:31Z jausions $
  43.  * @link      http://pear.php.net/package/Payment_Process
  44.  */
  45.  
  46. require_once 'Payment/Process.php';
  47. require_once 'Payment/Process/Common.php';
  48. require_once 'Net/Curl.php';
  49.  
  50. /**
  51.  * Defines global variables
  52.  */
  53. $GLOBALS['_Payment_Process_AuthorizeNet'= array(
  54.     PAYMENT_PROCESS_ACTION_NORMAL   => 'AUTH_CAPTURE',
  55.     PAYMENT_PROCESS_ACTION_AUTHONLY => 'AUTH_ONLY',
  56.     PAYMENT_PROCESS_ACTION_POSTAUTH => 'PRIOR_AUTH_CAPTURE',
  57.     PAYMENT_PROCESS_ACTION_VOID     => 'VOID'
  58. );
  59.  
  60. /**
  61.  * Payment_Process_AuthorizeNet
  62.  *
  63.  * This is a processor for Authorize.net's merchant payment gateway.
  64.  * (http://www.authorize.net/)
  65.  *
  66.  * *** WARNING ***
  67.  * This is BETA code, and has not been fully tested. It is not recommended
  68.  * that you use it in a production environment without further testing.
  69.  *
  70.  * @package    Payment_Process
  71.  * @author     Joe Stump <joe@joestump.net>
  72.  * @author     Philippe Jausions <Philippe.Jausions@11abacus.com>
  73.  * @version    @version@
  74.  * @link       http://www.authorize.net/
  75.  */
  76. {
  77.     /**
  78.      * Front-end -> back-end field map.
  79.      *
  80.      * This array contains the mapping from front-end fields (defined in
  81.      * the Payment_Process class) to the field names Authorize.Net requires.
  82.      *
  83.      * @see _prepare()
  84.      * @access private
  85.      */
  86.     var $_fieldMap = array(
  87.         // Required
  88.         'login'         => 'x_login',
  89.         'password'      => 'x_password',
  90.         'action'        => 'x_type',
  91.  
  92.         // Optional
  93.         'login'         => 'x_login',
  94.         'invoiceNumber' => 'x_invoice_num',
  95.         'customerId'    => 'x_cust_id',
  96.         'amount'        => 'x_amount',
  97.         'description'   => 'x_description',
  98.         'name'          => '',
  99.         'postalCode'    => 'x_zip',
  100.         'zip'           => 'x_zip',
  101.         'company'       => 'x_company',
  102.         'address'       => 'x_address',
  103.         'city'          => 'x_city',
  104.         'state'         => 'x_state',
  105.         'country'       => 'x_country',
  106.         'phone'         => 'x_phone',
  107.         'email'         => 'x_email',
  108.         'ip'            => 'x_customer_ip',
  109.     );
  110.  
  111.     /**
  112.      * $_typeFieldMap
  113.      *
  114.      * @author Joe Stump <joe@joestump.net>
  115.      * @access protected
  116.      */
  117.     var $_typeFieldMap = array(
  118.  
  119.            'CreditCard' => array(
  120.                 'firstName'  => 'x_first_name',
  121.                 'lastName'   => 'x_last_name',
  122.                 'cardNumber' => 'x_card_num',
  123.                 'cvv'        => 'x_card_code',
  124.                 'expDate'    => 'x_exp_date'
  125.            ),
  126.  
  127.            'eCheck' => array(
  128.                 'routingCode'   => 'x_bank_aba_code',
  129.                 'accountNumber' => 'x_bank_acct_num',
  130.                 'type'          => 'x_bank_acct_type',
  131.                 'bankName'      => 'x_bank_name'
  132.            )
  133.     );
  134.  
  135.     /**
  136.      * Default options for this processor.
  137.      *
  138.      * @see Payment_Process::setOptions()
  139.      * @access private
  140.      */
  141.     var $_defaultOptions = array(
  142.          'authorizeUri' => 'https://secure.authorize.net/gateway/transact.dll',
  143.          'x_delim_data' => 'TRUE',
  144.          'x_delim_char' => ',',
  145.          'x_encap_char' => '|',
  146.          'x_relay'      => 'FALSE',
  147.          'x_email_customer' => 'FALSE',
  148.          'x_currency_code'  => 'USD',
  149.          'x_version'        => '3.1'
  150.     );
  151.  
  152.     /**
  153.      * List of possible encapsulation characters
  154.      *
  155.      * @var string 
  156.      * @access private
  157.      */
  158.     var $_encapChars '|~#$^*_=+-`{}![]:";<>?/&';
  159.  
  160.     /**
  161.      * Has the transaction been processed?
  162.      *
  163.      * @type boolean
  164.      * @access private
  165.      */
  166.     var $_processed = false;
  167.  
  168.     /**
  169.      * The response body sent back from the gateway.
  170.      *
  171.      * @access private
  172.      */
  173.     var $_responseBody '';
  174.  
  175.     /**
  176.      * Constructor.
  177.      *
  178.      * @param  array  $options  Class options to set.
  179.      * @see Payment_Process::setOptions()
  180.      * @return void 
  181.      */
  182.     function __construct($options = false)
  183.     {
  184.         parent::__construct($options);
  185.         $this->_driver 'AuthorizeNet';
  186.         $this->_makeRequired('login''password''action');
  187.     }
  188.  
  189.     function Payment_Process_AuthorizeNet($options = false)
  190.     {
  191.         $this->__construct($options);
  192.     }
  193.  
  194.     /**
  195.      * Processes the transaction.
  196.      *
  197.      * Success here doesn't mean the transaction was approved. It means
  198.      * the transaction was sent and processed without technical difficulties.
  199.      *
  200.      * @return mixed Payment_Process_Result on success, PEAR_Error on failure
  201.      * @access public
  202.      */
  203.     function &process()
  204.     {
  205.         // Sanity check
  206.         $result $this->validate();
  207.         if (PEAR::isError($result)) {
  208.             return $result;
  209.         }
  210.  
  211.         // Prepare the data
  212.         $result $this->_prepare();
  213.         if (PEAR::isError($result)) {
  214.             return $result;
  215.         }
  216.  
  217.         $fields $this->_prepareQueryString();
  218.         if (PEAR::isError($fields)) {
  219.             return $fields;
  220.         }
  221.  
  222.         // Don't die partway through
  223.         PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
  224.  
  225.         $curl new Net_Curl($this->_options['authorizeUri']);
  226.         if (PEAR::isError($curl)) {
  227.             PEAR::popErrorHandling();
  228.             return $curl;
  229.         }
  230.         $result $curl->create();
  231.         if (PEAR::isError($result)) {
  232.             PEAR::popErrorHandling();
  233.             return $result;
  234.         }
  235.  
  236.         $curl->type = 'post';
  237.         $curl->fields = $fields;
  238.         $curl->userAgent = 'PEAR Payment_Process_AuthorizeNet @package_version@';
  239.  
  240.         if (isset($this->_options['curl_options'])) {
  241.             foreach ($this->_options['curl_options'as $key => $value{
  242.                 if (!$curl->setOption($key$value)) {
  243.                     PEAR::popErrorHandling();
  244.                     return PEAR::raiseError("Curl option ($key = $value) failed");
  245.                 }
  246.             }
  247.         }
  248.  
  249.  
  250.         $result $curl->execute();
  251.         if (PEAR::isError($result)) {
  252.             PEAR::popErrorHandling();
  253.             return $result;
  254.         else {
  255.             $curl->close();
  256.         }
  257.  
  258.         $this->_responseBody trim($result);
  259.         $this->_processed = true;
  260.  
  261.         // Restore error handling
  262.         PEAR::popErrorHandling();
  263.  
  264.         $response &Payment_Process_Result::factory($this->_driver,
  265.                                                      $this->_responseBody,
  266.                                                      &$this);
  267.  
  268.         if (!PEAR::isError($response)) {
  269.             $response->parse();
  270.  
  271.             $r $response->isLegitimate();
  272.             if (PEAR::isError($r)) {
  273.                 return $r;
  274.             elseif ($r === false{
  275.                 return PEAR::raiseError('Illegitimate response from gateway');
  276.             }
  277.         }
  278.         $response->action = $this->action;
  279.  
  280.         return $response;
  281.     }
  282.  
  283.     /**
  284.      * Processes a callback from payment gateway
  285.      *
  286.      * Success here doesn't mean the transaction was approved. It means
  287.      * the callback was received and processed without technical difficulties.
  288.      *
  289.      * @return mixed Payment_Process_Result on success, PEAR_Error on failure
  290.      */
  291.     function &processCallback()
  292.     {
  293.         $this->_responseBody $_POST;
  294.         $this->_processed = true;
  295.  
  296.         $response &Payment_Process_Result::factory($this->_driver,
  297.                             $this->_responseBody);
  298.         if (!PEAR::isError($response)) {
  299.             $response->_request =$this;
  300.             $response->parseCallback();
  301.  
  302.             $r $response->isLegitimate();
  303.             if (PEAR::isError($r)) {
  304.                 return $r;
  305.  
  306.             elseif ($r === false{
  307.                 return PEAR::raiseError('Illegitimate callback from gateway.');
  308.             }
  309.         }
  310.  
  311.         return $response;
  312.     }
  313.  
  314.     /**
  315.      * Get (completed) transaction status.
  316.      *
  317.      * @return string Two-digit status returned from gateway.
  318.      */
  319.     function getStatus()
  320.     {
  321.         return false;
  322.     }
  323.  
  324.     /**
  325.      * Prepare the POST query string.
  326.      *
  327.      * You will need PHP_Compat::str_split() if you run this processor
  328.      * under PHP 4.
  329.      *
  330.      * @access private
  331.      * @return string The query string
  332.      */
  333.     function _prepareQueryString()
  334.     {
  335.         $data array_merge($this->_options$this->_data);
  336.  
  337.         // Set payment method to eCheck if our payment type is eCheck.
  338.         // Default is Credit Card.
  339.         $data['x_method''CC';
  340.         if ($this->_payment->getType(== 'eCheck'{
  341.             $data['x_method''ECHECK';
  342.             switch ($this->_payment->type{
  343.                 case PAYMENT_PROCESS_CK_CHECKING:
  344.                     $data['x_bank_acct_type''CHECKING';
  345.                     break;
  346.                 case PAYMENT_PROCESS_CK_SAVINGS:
  347.                     $data['x_bank_acct_type''SAVINGS';
  348.                     break;
  349.             }
  350.         }
  351.  
  352.         // Keep a trace of characters we will get back
  353.         // so we can set an appropriate encapsulation character
  354.         $chars '';
  355.  
  356.         $return = array();
  357.         foreach ($data as $key => $val{
  358.             if (substr($key02== 'x_'
  359.                   && $key != 'x_encap_char'
  360.                   && strlen($val)) {
  361.                 $return[$key '=' rawurlencode($val);
  362.                 $chars .= $val;
  363.             }
  364.         }
  365.  
  366.         // Find an appropriate encapsulation character
  367.         $encap str_replace(array_unique(str_split($chars))''$data['x_encap_char']{0$this->_encapChars);
  368.  
  369.         if (strlen($encap== 0{
  370.             $encap $data['x_encap_char']{0};
  371.         else {
  372.             $encap $encap{0};
  373.         }
  374.         $this->_options['x_encap_char'$encap;
  375.         $return['x_encap_char=' rawurlencode($encap);
  376.  
  377.         return implode('&'$return);
  378.     }
  379.  
  380.     /**
  381.      * _handleName
  382.      *
  383.      * If it's an eCheck we need to combine firstName and lastName into a
  384.      * single account name.
  385.      *
  386.      * @author Joe Stump <joe@joestump.net>
  387.      * @access private
  388.      */
  389.     function _handleName()
  390.     {
  391.         if ($this->_payment->getType(== 'eCheck'{
  392.              $this->_data['x_bank_acct_name'$this->_payment->firstName.' '.$this->_payment->lastName;
  393.         }
  394.     }
  395. }
  396.  
  397.  
  398.  
  399.     var $_statusCodeMap = array('1' => PAYMENT_PROCESS_RESULT_APPROVED,
  400.                                 '2' => PAYMENT_PROCESS_RESULT_DECLINED,
  401.                                 '3' => PAYMENT_PROCESS_RESULT_OTHER,
  402.                                 '4' => PAYMENT_PROCESS_RESULT_REVIEW
  403.                                 );
  404.  
  405.     /**
  406.      * AuthorizeNet status codes
  407.      *
  408.      * This array holds many of the common response codes. There are over 200
  409.      * response codes - so check the AuthorizeNet manual if you get a status
  410.      * code that does not match (see "Response Reason Codes & Response
  411.      * Reason Text" in the AIM manual).
  412.      *
  413.      * @see getStatusText()
  414.      * @access private
  415.      */
  416.     var $_statusCodeMessages = array(
  417.           '1' => 'This transaction has been approved.',
  418.           '2' => 'This transaction has been declined.',
  419.           '3' => 'This transaction has been declined.',
  420.           '4' => 'This transaction has been declined.',
  421.           '5' => 'A valid amount is required.',
  422.           '6' => 'The credit card number is invalid.',
  423.           '7' => 'The credit card expiration date is invalid.',
  424.           '8' => 'The credit card has expired.',
  425.           '9' => 'The ABA code is invalid.',
  426.           '10' => 'The account number is invalid.',
  427.           '11' => 'A duplicate transaction has been submitted.',
  428.           '12' => 'An authorization code is required but not present.',
  429.           '13' => 'The merchant Login ID is invalid or the account is inactive.',
  430.           '14' => 'The Referrer or Relay Response URL is invalid.',
  431.           '15' => 'The transaction ID is invalid.',
  432.           '16' => 'The transaction was not found.',
  433.           '17' => 'The merchant does not accept this type of credit card.',
  434.           '18' => 'ACH transactions are not accepted by this merchant.',
  435.           '19' => 'An error occurred during processing. Please try again in 5 minutes.',
  436.           '20' => 'An error occurred during processing. Please try again in 5 minutes.',
  437.           '21' => 'An error occurred during processing. Please try again in 5 minutes.',
  438.           '22' => 'An error occurred during processing. Please try again in 5 minutes.',
  439.           '23' => 'An error occurred during processing. Please try again in 5 minutes.',
  440.           '24' => 'The Nova Bank Number or Terminal ID is incorrect. Call Merchant Service Provider.',
  441.           '25' => 'An error occurred during processing. Please try again in 5 minutes.',
  442.           '26' => 'An error occurred during processing. Please try again in 5 minutes.',
  443.           '27' => 'The transaction resulted in an AVS mismatch. The address provided does not match billing address of cardholder.',
  444.           '28' => 'The merchant does not accept this type of credit card.',
  445.           '29' => 'The PaymentTech identification numbers are incorrect. Call Merchant Service Provider.',
  446.           '30' => 'The configuration with the processor is invalid. Call Merchant Service Provider.',
  447.           '31' => 'The FDC Merchant ID or Terminal ID is incorrect. Call Merchant Service Provider.',
  448.           '32' => 'The merchant password is invalid or not present.',
  449.           '33' => 'Missing required field',
  450.           '34' => 'The VITAL identification numbers are incorrect. Call Merchant Service Provider.',
  451.           '35' => 'An error occurred during processing. Call Merchant Service Provider.',
  452.           '36' => 'The authorization was approved, but settlement failed.',
  453.           '37' => 'The credit card number is invalid.',
  454.           '38' => 'The Global Payment System identification numbers are incorrect. Call Merchant Service Provider.',
  455.           '39' => 'The supplied currency code is either invalid, not supported, not allowed for this merchant or doesn\'t have an exchange rate.',
  456.           '40' => 'This transaction must be encrypted.',
  457.           '41' => 'FraudScreen.net fraud score is higher than threshold set by merchant',
  458.           '42' => 'There is missing or invalid information in a required field.',
  459.           '43' => 'The merchant was incorrectly set up at the processor. Call your Merchant Service Provider.',
  460.           '44' => 'This transaction has been declined. Card Code filter error!',
  461.           '45' => 'This transaction has been declined. Card Code / AVS filter error!',
  462.           '46' => 'Your session has expired or does not exist. You must log in to continue working.',
  463.           '47' => 'The amount requested for settlement may not be greater than the original amount authorized.',
  464.           '48' => 'This processor does not accept partial reversals.',
  465.           '49' => 'A transaction amount greater than $99,999 will not be accepted.',
  466.           '50' => 'This transaction is awaiting settlement and cannot be refunded.',
  467.           '51' => 'The sum of all credits against this transaction is greater than the original transaction amount.',
  468.           '52' => 'The transaction was authorized, but the client could not be notified; the transaction will not be settled.',
  469.           '53' => 'The transaction type was invalid for ACH transactions.',
  470.           '54' => 'The referenced transaction does not meet the criteria for issuing a credit.',
  471.           '55' => 'The sum of credits against the referenced transaction would exceed the original debit amount.',
  472.           '56' => 'This merchant accepts ACH transactions only; no credit card transactions are accepted.',
  473.           '57' => 'An error occurred in processing. Please try again in 5 minutes.',
  474.           '58' => 'An error occurred in processing. Please try again in 5 minutes.',
  475.           '59' => 'An error occurred in processing. Please try again in 5 minutes.',
  476.           '60' => 'An error occurred in processing. Please try again in 5 minutes.',
  477.           '61' => 'An error occurred in processing. Please try again in 5 minutes.',
  478.           '62' => 'An error occurred in processing. Please try again in 5 minutes.',
  479.           '63' => 'An error occurred in processing. Please try again in 5 minutes.',
  480.           '64' => 'The referenced transaction was not approved.',
  481.           '65' => 'This transaction has been declined.',
  482.           '66' => 'The transaction did not meet gateway security guidelines.',
  483.           '67' => 'The given transaction type is not supported for this merchant.',
  484.           '68' => 'The version parameter is invalid.',
  485.           '69' => 'The transaction type is invalid. The value submitted in x_type was invalid.',
  486.           '70' => 'The transaction method is invalid.',
  487.           '71' => 'The bank account type is invalid.',
  488.           '72' => 'The authorization code is invalid.',
  489.           '73' => 'The driver\'s license date of birth is invalid.',
  490.           '74' => 'The duty amount is invalid.',
  491.           '75' => 'The freight amount is invalid.',
  492.           '76' => 'The tax amount is invalid.',
  493.           '77' => 'The SSN or tax ID is invalid.',
  494.           '78' => 'The Card Code (CVV2/CVC2/CID) is invalid.',
  495.           '79' => 'The driver\'s license number is invalid.',
  496.           '80' => 'The driver\'s license state is invalid.',
  497.           '81' => 'The merchant requested an integration method not compatible with the AIM API.',
  498.           '82' => 'The system no longer supports version 2.5; requests cannot be posted to scripts.',
  499.           '83' => 'The requested script is either invalid or no longer supported.',
  500.           '84' => 'This reason code is reserved or not applicable to this API.',
  501.           '85' => 'This reason code is reserved or not applicable to this API.',
  502.           '86' => 'This reason code is reserved or not applicable to this API.',
  503.           '87' => 'This reason code is reserved or not applicable to this API.',
  504.           '88' => 'This reason code is reserved or not applicable to this API.',
  505.           '89' => 'This reason code is reserved or not applicable to this API.',
  506.           '90' => 'This reason code is reserved or not applicable to this API.',
  507.           '91' => 'Version 2.5 is no longer supported.',
  508.           '92' => 'The gateway no longer supports the requested method of integration.',
  509.           '93' => 'A valid country is required.',
  510.           '94' => 'The shipping state or country is invalid.',
  511.           '95' => 'A valid state is required.',
  512.           '96' => 'This country is not authorized for buyers.',
  513.           '97' => 'This transaction cannot be accepted.',
  514.           '98' => 'This transaction cannot be accepted.',
  515.           '99' => 'This transaction cannot be accepted.',
  516.           '100' => 'The eCheck type is invalid.',
  517.           '101' => 'The given name on the account and/or the account type does not match the actual account.',
  518.           '102' => 'This request cannot be accepted.',
  519.           '103' => 'This transaction cannot be accepted.',
  520.           '104' => 'This transaction is currently under review.',
  521.           '105' => 'This transaction is currently under review.',
  522.           '106' => 'This transaction is currently under review.',
  523.           '107' => 'This transaction is currently under review.',
  524.           '108' => 'This transaction is currently under review.',
  525.           '109' => 'This transaction is currently under review.',
  526.           '110' => 'This transaction is currently under review.',
  527.           '111' => 'A valid billing country is required.',
  528.           '112' => 'A valid billing state/provice is required.',
  529.           '116' => 'The authentication indicator is invalid.',
  530.           '117' => 'The cardholder authentication value is invalid.',
  531.           '118' => 'The combination of authentication indicator and cardholder authentication value is invalid.',
  532.           '119' => 'Transactions having cardholder authentication values cannot be marked as recurring.',
  533.           '120' => 'An error occurred during processing. Please try again.',
  534.           '121' => 'An error occurred during processing. Please try again.',
  535.           '122' => 'An error occurred during processing. Please try again.',
  536.           '127' => 'The transaction resulted in an AVS mismatch. The address provided does not match billing address of cardholder.',
  537.           '141' => 'This transaction has been declined.',
  538.           '145' => 'This transaction has been declined.',
  539.           '152' => 'The transaction was authorized, but the client could not be notified; the transaction will not be settled.',
  540.           '165' => 'This transaction has been declined.',
  541.           '170' => 'An error occurred during processing. Please contact the merchant.',
  542.           '171' => 'An error occurred during processing. Please contact the merchant.',
  543.           '172' => 'An error occurred during processing. Please contact the merchant.',
  544.           '173' => 'An error occurred during processing. Please contact the merchant.',
  545.           '174' => 'The transaction type is invalid. Please contact the merchant.',
  546.           '175' => 'The processor does not allow voiding of credits.',
  547.           '180' => 'An error occurred during processing. Please try again.',
  548.           '181' => 'An error occurred during processing. Please try again.',
  549.           '200' => 'This transaction has been declined.',
  550.           '201' => 'This transaction has been declined.',
  551.           '202' => 'This transaction has been declined.',
  552.           '203' => 'This transaction has been declined.',
  553.           '204' => 'This transaction has been declined.',
  554.           '205' => 'This transaction has been declined.',
  555.           '206' => 'This transaction has been declined.',
  556.           '207' => 'This transaction has been declined.',
  557.           '208' => 'This transaction has been declined.',
  558.           '209' => 'This transaction has been declined.',
  559.           '210' => 'This transaction has been declined.',
  560.           '211' => 'This transaction has been declined.',
  561.           '212' => 'This transaction has been declined.',
  562.           '213' => 'This transaction has been declined.',
  563.           '214' => 'This transaction has been declined.',
  564.           '215' => 'This transaction has been declined.',
  565.           '216' => 'This transaction has been declined.',
  566.           '217' => 'This transaction has been declined.',
  567.           '218' => 'This transaction has been declined.',
  568.           '219' => 'This transaction has been declined.',
  569.           '220' => 'This transaction has been declined.',
  570.           '221' => 'This transaction has been declined.',
  571.           '222' => 'This transaction has been declined.',
  572.           '223' => 'This transaction has been declined.',
  573.           '224' => 'This transaction has been declined.',
  574.           '243' => 'Recurring billing is not allowed for this eCheck.Net type',
  575.           '244' => 'This eCheck.Net type is not allowed for this Bank Account Type.',
  576.           '245' => 'This eCheck.Net type is not allowed when using the payment gateway hosted payment form.',
  577.           '246' => 'This eCheck.Net type is not allowed.',
  578.           '247' => 'This eCheck.Net type is not allowed.',
  579.           '250' => 'This transaction has been declined.',
  580.           '251' => 'This transaction has been declined.',
  581.           '252' => 'Your order has been received. Thank you for your business!',
  582.           '253' => 'Your order has been received. Thank you for your business!',
  583.           '254' => 'This transaction has been declined.',
  584.           '261' => 'An error occurred during processing. Please try again'
  585.     );
  586.  
  587.     var $_avsCodeMap = array(
  588.         'A' => PAYMENT_PROCESS_AVS_MISMATCH,
  589.         'B' => PAYMENT_PROCESS_AVS_ERROR,
  590.         'E' => PAYMENT_PROCESS_AVS_ERROR,
  591.         'G' => PAYMENT_PROCESS_AVS_NOAPPLY,
  592.         'N' => PAYMENT_PROCESS_AVS_MISMATCH,
  593.         'P' => PAYMENT_PROCESS_AVS_NOAPPLY,
  594.         'R' => PAYMENT_PROCESS_AVS_ERROR,
  595.         'S' => PAYMENT_PROCESS_AVS_ERROR,
  596.         'U' => PAYMENT_PROCESS_AVS_ERROR,
  597.         'W' => PAYMENT_PROCESS_AVS_MISMATCH,
  598.         'X' => PAYMENT_PROCESS_AVS_MATCH,
  599.         'Y' => PAYMENT_PROCESS_AVS_MATCH,
  600.         'Z' => PAYMENT_PROCESS_AVS_MISMATCH
  601.     );
  602.  
  603.     var $_avsCodeMessages = array(
  604.         'A' => 'Address matches, postal code does not',
  605.         'B' => 'Address information not provided',
  606.         'E' => 'Address Verification System Error',
  607.         'G' => 'Non-U.S. Card Issuing Bank',
  608.         'N' => 'No match on street address nor postal code',
  609.         'P' => 'Address Verification System not applicable',
  610.         'R' => 'Retry - System unavailable or timeout',
  611.         'S' => 'Service not supported by issuer',
  612.         'U' => 'Address information unavailable',
  613.         'W' => '9-digit postal code matches, street address does not',
  614.         'X' => 'Address and 9-digit postal code match',
  615.         'Y' => 'Address and 5-digit postal code match',
  616.         'Z' => '5-digit postal code matches, street address does not'
  617.     );
  618.  
  619.     var $_cvvCodeMap = array('M' => PAYMENT_PROCESS_CVV_MATCH,
  620.                              'N' => PAYMENT_PROCESS_CVV_MISMATCH,
  621.                              'P' => PAYMENT_PROCESS_CVV_ERROR,
  622.                              'S' => PAYMENT_PROCESS_CVV_ERROR,
  623.                              'U' => PAYMENT_PROCESS_CVV_ERROR
  624.     );
  625.  
  626.     var $_cvvCodeMessages = array(
  627.         'M' => 'CVV code matches',
  628.         'N' => 'CVV code does not match',
  629.         'P' => 'CVV code was not processed',
  630.         'S' => 'CVV code should have been present',
  631.         'U' => 'Issuer unable to process request',
  632.     );
  633.  
  634.     var $_fieldMap = array('0'  => 'code',
  635.                            '2'  => 'messageCode',
  636.                            '3'  => 'message',
  637.                            '4'  => 'approvalCode',
  638.                            '5'  => 'avsCode',
  639.                            '6'  => 'transactionId',
  640.                            '7'  => 'invoiceNumber',
  641.                            '8'  => 'description',
  642.                            '9'  => 'amount',
  643.                            '12' => 'customerId',
  644.                            '37' => 'md5Hash',
  645.                            '38' => 'cvvCode'
  646.     );
  647.  
  648.     /**
  649.      * To hold the MD5 hash returned
  650.      *
  651.      * @var string 
  652.      * @access private
  653.      */
  654.     var $_md5Hash;
  655.  
  656.     function Payment_Process_Response_AuthorizeNet($rawResponse)
  657.     {
  658.         $this->Payment_Process_Response($rawResponse);
  659.     }
  660.  
  661.     /**
  662.      * Parses the data received from the payment gateway
  663.      *
  664.      * @access public
  665.      */
  666.     function parse()
  667.     {
  668.         $delim $this->_request->getOption('x_delim_char');
  669.         $encap $this->_request->getOption('x_encap_char');
  670.  
  671.         $responseArray explode($encap $delim $encap$this->_rawResponse);
  672.         if ($responseArray === false{
  673.             return array();
  674.         }
  675.  
  676.         $count count($responseArray- 1;
  677.         if ($responseArray[0]{0== $encap{
  678.             $responseArray[0substr($responseArray[0]1);
  679.         }
  680.         if (substr($responseArray[$count]-1== $encap{
  681.             $responseArray[$countsubstr($responseArray[$count]0-1);
  682.         }
  683.  
  684.         // Save some fields in private members
  685.         $map array_flip($this->_fieldMap);
  686.         $this->_md5Hash $responseArray[$map['md5Hash']];
  687.         $this->_amount  $responseArray[$map['amount']];
  688.  
  689.         $this->_mapFields($responseArray);
  690.  
  691.         // Adjust result code/message if needed based on raw code
  692.         switch ($this->messageCode{
  693.             case 33:
  694.                 // Something is missing so we send the raw message back
  695.                 $this->_statusCodeMessages[33$this->message;
  696.                 break;
  697.             case 11:
  698.                 // Duplicate transactions
  699.                 $this->code = PAYMENT_PROCESS_RESULT_DUPLICATE;
  700.                 break;
  701.             case 4:
  702.             case 41:
  703.             case 250:
  704.             case 251:
  705.                 // Fraud detected
  706.                 $this->code = PAYMENT_PROCESS_RESULT_FRAUD;
  707.                 break;
  708.         }
  709.     }
  710.  
  711.     /**
  712.      * Parses the data received from the payment gateway callback
  713.      *
  714.      * @access public
  715.      * @author Philippe Jausions <Philippe.Jausions@11abacus.com>
  716.      */
  717.     function parseCallback()
  718.     {
  719.         $this->code          = $this->_rawResponse['x_response_code'];
  720.         $this->messageCode   = $this->_rawResponse['x_response_reason_code'];
  721.         $this->message       = $this->_rawResponse['x_response_reason_text'];
  722.         $this->approvalCode  = $this->_rawResponse['x_auth_code'];
  723.         $this->avsCode       = $this->_rawResponse['x_avs_code'];
  724.         $this->transactionId = $this->_rawResponse['x_trans_id'];
  725.         $this->invoiceNumber = $this->_rawResponse['x_invoice_num'];
  726.         $this->description   $this->_rawResponse['x_description'];
  727.         $this->_amount       $this->_rawResponse['x_amount'];
  728.         $this->customerId    = $this->_rawResponse['x_cust_id'];
  729.         $this->_md5Hash      $this->_rawResponse['x_MD5_Hash'];
  730.         $this->cvvCode       = $this->_rawResponse['x_cvv2_resp_code'];
  731.         $map array_flip($GLOBALS['_Payment_Process_AuthorizeNet']);
  732.         $this->action        $map[strtoupper($this->_rawResponse['x_type'])];
  733.     }
  734.  
  735.     /**
  736.      * Validates the legitimacy of the response
  737.      *
  738.      * To be able to validate the response, the md5Value option
  739.      * must have been set in the processor. If the md5Value is not set this
  740.      * function will fail gracefully, but this MAY CHANGE IN THE FUTURE!
  741.      *
  742.      * Check if the response is legitimate by matching MD5 hashes.
  743.      * To avoid MD5 mismatch while the key is being renewed
  744.      * the md5Value can be an array with 2 indexes: "new" and "old"
  745.      * respectively holding the new and old MD5 values.
  746.      *
  747.      * Note: If you're having problem passing this check: be aware that
  748.      * the login name is CASE-SENSITIVE!!! (even though you can log in
  749.      * using it all lowered case...)
  750.      *
  751.      * @return mixed TRUE if response is legitimate, FALSE if not, PEAR_Error on error
  752.      * @access public
  753.      * @author Philippe Jausions <Philippe.Jausions@11abacus.com>
  754.      */
  755.     function isLegitimate()
  756.     {
  757.         $md5Value $this->_request->getOption('md5Value');
  758.         if (!$md5Value{
  759.             // For now fail gracefully if it is not set.
  760.             return true;
  761.         }
  762.  
  763.         $fields $this->_request->login . $this->transactionId
  764.                     . $this->_amount;
  765.         if (is_array($md5Value)) {
  766.             if (strcasecmp($this->_md5Hashmd5($md5Value['new'$fields)) == 0 ||
  767.                 strcasecmp($this->_md5Hashmd5($md5Value['old'$fields)) == 0{
  768.  
  769.                 return true;
  770.             }
  771.         elseif (strcasecmp($this->_md5Hashmd5($md5Value $fields)) == 0{
  772.             return true;
  773.         }
  774.         return false;
  775.     }
  776. }
  777.  
  778. ?>

Documentation generated on Mon, 25 Oct 2010 14:30:20 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.