source: branches/eli_branch/lib/AuthorizeNet.inc.php @ 527

Last change on this file since 527 was 447, checked in by anonymous, 11 years ago

Changed some global constants to class constants (in cases where backwards compatability wouldn't break).

File size: 9.5 KB
Line 
1<?php
2/**
3 * The Strangecode Codebase - a general application development framework for PHP
4 * For details visit the project site: <http://trac.strangecode.com/codebase/>
5 * Copyright 2001-2012 Strangecode, LLC
6 *
7 * This file is part of The Strangecode Codebase.
8 *
9 * The Strangecode Codebase is free software: you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as published by the
11 * Free Software Foundation, either version 3 of the License, or (at your option)
12 * any later version.
13 *
14 * The Strangecode Codebase is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * The Strangecode Codebase. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/**
24 * AuthorizeNet.inc.php
25 *
26 * The AuthorizeNet class provides an abstract interface for communicating
27 * with authorize.net's AIM interface. Supports Auth.Net v3.1
28 *
29 * @author  Quinn Comendant <quinn@strangecode.com>
30 * @version 1.0
31 * @date 2004-04-06
32 */
33
34// Example usage
35// require_once 'codebase/lib/AuthorizeNet.inc.php';
36//
37// $authorizenet = new AuthorizeNet();
38// $authorizenet->setParam(array(
39//     'x_Login' => 'myaccount',
40//     'x_Test_Request' => 'TRUE',
41//     'x_First_Name' => 'John',
42//     'x_Last_Name' => 'Doe',
43//     'x_Amount' => '1.20',
44//     'x_Card_Num' => '4111111111111111',
45//     'x_Card_Code' => '123',
46//     'x_Exp_Date' => '042008',
47//     'x_Invoice_Num' => '100',
48//     'x_Address' => '10 rue Levouvé',
49//     'x_City' => 'SomeCity',
50//     'x_State' => 'CA',
51//     'x_Zip' => '75010',
52// ));
53//
54// $result_code = $authorizenet->process(); // Returns one of: false = error, 1 = accepted, 2 = declined, 3 = error
55// $result_array = $authorizenet->getResults();
56//
57// foreach ($result_array as $key => $value) {
58//     print "$key: $value<br>\n";
59// }
60
61class AuthorizeNet {
62
63    public $post_url = ''; // The URL to post data to.
64    private $_results = array();
65    private $_params = array();
66    private $_default_params = array(
67        'x_version'         => '3.1',
68        'x_relay_response'  => 'FALSE',
69        'x_delim_data'      => 'TRUE',
70        'x_echo_data'       => 'TRUE',
71        'x_adc_url'         => 'FALSE',
72        'x_type'            => 'AUTH_CAPTURE',
73        'x_method'          => 'CC',
74        'x_login'           => '',
75        'x_tran_key'        => '',
76        'x_delim_char'      => ',',
77        'x_encap_char'      => '',
78        'md5_hash_salt'    => '',
79    );
80
81    // Array of response names. Used in the results array.
82    private $_result_fields = Array(
83        'x_response_code',
84        'x_response_subcode',
85        'x_response_reason_code',
86        'x_response_reason_text',
87        'x_auth_code',
88        'x_avs_code',
89        'x_trans_id',
90        'x_invoice_num',
91        'x_description',
92        'x_amount',
93        'x_method',
94        'x_type',
95        'x_cust_id',
96        'x_first_name',
97        'x_last_name',
98        'x_company',
99        'x_address',
100        'x_city',
101        'x_state',
102        'x_zip',
103        'x_country',
104        'x_phone',
105        'x_fax',
106        'x_email',
107        'x_ship_to_first_name',
108        'x_ship_to_last_name',
109        'x_ship_to_company',
110        'x_ship_to_address',
111        'x_ship_to_city',
112        'x_ship_to_state',
113        'x_ship_to_zip',
114        'x_ship_to_country',
115        'x_tax',
116        'x_duty',
117        'x_freight',
118        'x_tax_exempt',
119        'x_po_num',
120        'x_md5_hash',
121        'x_card_code'
122    );
123
124    /**
125     * Constructs a new authentication object.
126     *
127     * @access public
128     *
129     * @param optional array $_params  A hash containing parameters.
130     */
131    public function __construct($params = array())
132    {
133        $app =& App::getInstance();
134
135        if (!function_exists('curl_init')) {
136            trigger_error('AuthorizeNet error: curl not installed.', E_USER_ERROR);
137        }
138
139        // The authorize.net url to post to.
140        $this->post_url = isset($params['post_url']) ? $params['post_url'] : 'https://secure.authorize.net/gateway/transact.dll';
141
142        // Set default parameters.
143        $this->_params = $this->_default_params;
144        $this->setParam($params);
145
146        $this->setParam(array('md5_hash_salt' => $app->getParam('signing_key')));
147    }
148
149    /**
150     * Set (or overwrite existing) parameters by passing an array of new parameters.
151     *
152     * @access public
153     * @param  array    $params     Array of parameters (key => val pairs).
154     */
155    public function setParam($params)
156    {
157        $app =& App::getInstance();
158
159        if (isset($params) && is_array($params)) {
160            // Merge new parameters with old overriding only those passed.
161            $this->_params = array_merge($this->_params, $params);
162        } else {
163            $app->logMsg(sprintf('Parameters are not an array: %s', $params), LOG_ERR, __FILE__, __LINE__);
164        }
165    }
166
167    /**
168     * Return the value of a parameter, if it exists.
169     *
170     * @access public
171     * @param string $param        Which parameter to return.
172     * @return mixed               Configured parameter value.
173     */
174    public function getParam($param)
175    {
176        $app =& App::getInstance();
177
178        if (isset($this->_params[$param])) {
179            return $this->_params[$param];
180        } else {
181            $app->logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
182            return null;
183        }
184    }
185
186
187    /**
188     * Submit parameters to gateway.
189     *
190     * @access public
191     *
192     * @return mixed      False or x_response_code: false = error, 1 = accepted, 2 = declined, 3 = error
193     */
194    public function process()
195    {
196        $app =& App::getInstance();
197
198        if (empty($this->_params['x_login'])) {
199            $this->_results['x_response_reason_text'] = _("Transaction gateway temporarily not available. Please try again later.");
200            $app->logMsg(sprintf('x_login not specified.', null), LOG_ERR, __FILE__, __LINE__);
201            return false;
202        }
203        if (empty($this->_params['x_card_num'])) {
204            $this->_results['x_response_reason_text'] = _("Transaction gateway temporarily not available. Please try again later.");
205            $app->logMsg(sprintf('x_card_num not specified.', null), LOG_ERR, __FILE__, __LINE__);
206            return false;
207        }
208
209        // Generate query string from params.
210        $q = '';
211        $delim = '';
212        foreach ($this->_params as $key=>$val) {
213            $q .= $delim . $key . '=' . urlencode($val);
214            $delim = '&';
215        }
216
217        // Setup curl and execute request.
218        $ch = curl_init();
219        curl_setopt($ch, CURLOPT_URL, $this->post_url);
220        curl_setopt($ch, CURLOPT_HEADER, 0);
221        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
222        curl_setopt($ch, CURLOPT_POST, 1);
223        curl_setopt($ch, CURLOPT_POSTFIELDS, $q);
224        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
225        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
226        $result = curl_exec($ch);
227        $error = curl_error($ch);
228        curl_close($ch);
229
230        if (!$result) {
231            if ('' != $error) {
232                $app->logMsg(sprintf('Curl error: %s', $error), LOG_ERR, __FILE__, __LINE__);
233            }
234            return false;
235        }
236        return $this->_processResult($result);
237    }
238
239
240    /**
241     * Returns the results array. Returns a specific element if $key is provided.
242     *
243     * @access public
244     *
245     * @return array             Returns the results array.
246     */
247    public function getResult($key=null)
248    {
249        if (isset($key)) {
250            if (isset($this->_results[$key])) {
251                return $this->_results[$key];
252            } else {
253                return null;
254            }
255        } else {
256            return $this->_results;
257        }
258    }
259
260    /**
261     * Tests a returned md5 hash value with a locally computed one.
262     *
263     * @access public
264     *
265     * @return bool             True if the hash is valid, false otherwise.
266     */
267    public function validMD5Hash()
268    {
269        return (
270            mb_strtolower($this->getResult('x_md5_hash')) == mb_strtolower(md5(
271                $this->getParam('md5_hash_salt') .
272                $this->getParam('x_login') .
273                $this->getResult('x_trans_id') .
274                $this->getResult('x_amount')
275            ))
276        );
277    }
278
279    /**
280     * Reset all variables. Call before beginning a new transaction.
281     *
282     * @access public
283     */
284    public function reset()
285    {
286        $this->_results = Array();
287        $this->_params = $this->_default_params;
288    }
289
290    /**
291     * Process the result from the curl execution to create an associative array of returned data.
292     *
293     * @access private.
294     *
295     * @param  mixed $result    The result from the curl execution.
296     *
297     * @return integer      Transaction result code.
298     */
299    private function _processResult($result)
300    {
301        $this->_results = Array();
302
303        $results = explode($this->getParam('x_delim_char'), $result);
304
305        $num = sizeof($this->_result_fields);
306        for ($i=0, $j=0; $i<$num; $i++) {
307            if (isset($this->_result_fields[$i])) {
308                $this->_results[$this->_result_fields[$i]] = $results[$i];
309            } else {
310                $j++;
311                $this->_results["x_custom_$j"] = $results[$i];
312            }
313        }
314        return $this->_results['x_response_code'];
315    }
316}
Note: See TracBrowser for help on using the repository browser.