source: tags/2.1.5/lib/AuthorizeNet.inc.php

Last change on this file was 377, checked in by quinn, 14 years ago

Releasing trunk as stable version 2.1.5

File size: 9.4 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-2010 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    var $post_url = ''; // The URL to post data to.
64    var $_results = array();
65    var $_params = array();
66    var $_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    var $_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    function AuthorizeNet($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    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    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    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    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    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    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    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}
317?>
Note: See TracBrowser for help on using the repository browser.