* Copyright 2001-2012 Strangecode, LLC
*
* This file is part of The Strangecode Codebase.
*
* The Strangecode Codebase is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* The Strangecode Codebase is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* The Strangecode Codebase. If not, see .
*/
/**
* AuthorizeNet.inc.php
*
* The AuthorizeNet class provides an abstract interface for communicating
* with authorize.net's AIM interface. Supports Auth.Net v3.1
*
* @author Quinn Comendant
* @version 1.0
* @date 2004-04-06
*/
// Example usage
// require_once 'codebase/lib/AuthorizeNet.inc.php';
//
// $authorizenet = new AuthorizeNet();
// $authorizenet->setParam(array(
// 'x_Login' => 'myaccount',
// 'x_Test_Request' => 'TRUE',
// 'x_First_Name' => 'John',
// 'x_Last_Name' => 'Doe',
// 'x_Amount' => '1.20',
// 'x_Card_Num' => '4111111111111111',
// 'x_Card_Code' => '123',
// 'x_Exp_Date' => '042008',
// 'x_Invoice_Num' => '100',
// 'x_Address' => '10 rue Levouvé',
// 'x_City' => 'SomeCity',
// 'x_State' => 'CA',
// 'x_Zip' => '75010',
// ));
//
// $result_code = $authorizenet->process(); // Returns one of: false = error, 1 = accepted, 2 = declined, 3 = error
// $result_array = $authorizenet->getResults();
//
// foreach ($result_array as $key => $value) {
// print "$key: $value
\n";
// }
class AuthorizeNet
{
public $post_url = ''; // The URL to post data to.
protected $_results = array();
protected $_params = array();
protected $_default_params = array(
'x_version' => '3.1',
'x_relay_response' => 'FALSE',
'x_delim_data' => 'TRUE',
'x_echo_data' => 'TRUE',
'x_adc_url' => 'FALSE',
'x_type' => 'AUTH_CAPTURE',
'x_method' => 'CC',
'x_login' => '',
'x_tran_key' => '',
'x_delim_char' => ',',
'x_encap_char' => '',
'md5_hash_salt' => '',
);
// Array of response names. Used in the results array.
protected $_result_fields = Array(
'x_response_code',
'x_response_subcode',
'x_response_reason_code',
'x_response_reason_text',
'x_auth_code',
'x_avs_code',
'x_trans_id',
'x_invoice_num',
'x_description',
'x_amount',
'x_method',
'x_type',
'x_cust_id',
'x_first_name',
'x_last_name',
'x_company',
'x_address',
'x_city',
'x_state',
'x_zip',
'x_country',
'x_phone',
'x_fax',
'x_email',
'x_ship_to_first_name',
'x_ship_to_last_name',
'x_ship_to_company',
'x_ship_to_address',
'x_ship_to_city',
'x_ship_to_state',
'x_ship_to_zip',
'x_ship_to_country',
'x_tax',
'x_duty',
'x_freight',
'x_tax_exempt',
'x_po_num',
'x_md5_hash',
'x_card_code'
);
/**
* Constructs a new authentication object.
*
* @access public
*
* @param optional array $_params A hash containing parameters.
*/
public function __construct($params = array())
{
$app =& App::getInstance();
if (!function_exists('curl_init')) {
trigger_error('AuthorizeNet error: curl not installed.', E_USER_ERROR);
}
// The authorize.net url to post to.
$this->post_url = isset($params['post_url']) ? $params['post_url'] : 'https://secure.authorize.net/gateway/transact.dll';
// Set default parameters.
$this->_params = $this->_default_params;
$this->setParam($params);
$this->setParam(array('md5_hash_salt' => $app->getParam('signing_key')));
}
/**
* Set (or overwrite existing) parameters by passing an array of new parameters.
*
* @access public
* @param array $params Array of parameters (key => val pairs).
*/
public function setParam($params)
{
$app =& App::getInstance();
if (isset($params) && is_array($params)) {
// Merge new parameters with old overriding only those passed.
$this->_params = array_merge($this->_params, $params);
} else {
$app->logMsg(sprintf('Parameters are not an array: %s', $params), LOG_ERR, __FILE__, __LINE__);
}
}
/**
* Return the value of a parameter, if it exists.
*
* @access public
* @param string $param Which parameter to return.
* @return mixed Configured parameter value.
*/
public function getParam($param)
{
$app =& App::getInstance();
if (array_key_exists($param, $this->_params)) {
return $this->_params[$param];
} else {
$app->logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
return null;
}
}
/**
* Submit parameters to gateway.
*
* @access public
*
* @return mixed False or x_response_code: false = error, 1 = accepted, 2 = declined, 3 = error
*/
public function process()
{
$app =& App::getInstance();
if (empty($this->_params['x_login'])) {
$this->_results['x_response_reason_text'] = _("Transaction gateway temporarily not available. Please try again later.");
$app->logMsg(sprintf('x_login not specified.', null), LOG_ERR, __FILE__, __LINE__);
return false;
}
if (empty($this->_params['x_card_num'])) {
$this->_results['x_response_reason_text'] = _("Transaction gateway temporarily not available. Please try again later.");
$app->logMsg(sprintf('x_card_num not specified.', null), LOG_ERR, __FILE__, __LINE__);
return false;
}
// Generate query string from params.
$q = '';
$delim = '';
foreach ($this->_params as $key=>$val) {
$q .= $delim . $key . '=' . urlencode($val);
$delim = '&';
}
// Setup curl and execute request.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->post_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $q);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
$result = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if (!$result) {
if ('' != $error) {
$app->logMsg(sprintf('Curl error: %s', $error), LOG_ERR, __FILE__, __LINE__);
}
return false;
}
return $this->_processResult($result);
}
/**
* Returns the results array. Returns a specific element if $key is provided.
*
* @access public
*
* @return array Returns the results array.
*/
public function getResult($key=null)
{
if (isset($key)) {
if (isset($this->_results[$key])) {
return $this->_results[$key];
} else {
return null;
}
} else {
return $this->_results;
}
}
/**
* Tests a returned md5 hash value with a locally computed one.
*
* @access public
*
* @return bool True if the hash is valid, false otherwise.
*/
public function validMD5Hash()
{
return (
mb_strtolower($this->getResult('x_md5_hash')) == mb_strtolower(md5(
$this->getParam('md5_hash_salt') .
$this->getParam('x_login') .
$this->getResult('x_trans_id') .
$this->getResult('x_amount')
))
);
}
/**
* Reset all variables. Call before beginning a new transaction.
*
* @access public
*/
public function reset()
{
$this->_results = Array();
$this->_params = $this->_default_params;
}
/**
* Process the result from the curl execution to create an associative array of returned data.
*
* @access private.
*
* @param mixed $result The result from the curl execution.
*
* @return integer Transaction result code.
*/
protected function _processResult($result)
{
$this->_results = Array();
$results = explode($this->getParam('x_delim_char'), $result);
$num = sizeof($this->_result_fields);
for ($i=0, $j=0; $i<$num; $i++) {
if (isset($this->_result_fields[$i])) {
$this->_results[$this->_result_fields[$i]] = $results[$i];
} else {
$j++;
$this->_results["x_custom_$j"] = $results[$i];
}
}
return $this->_results['x_response_code'];
}
}