Jump to content
Sign in to follow this  
yboti

authorize.net always returns "unspecified error"

Recommended Posts

After struggling for some time with an issue using the authorize.net payment module I have been able to narrow down an issue on GoDaddy servers. I am curious if others are having the same or a different experience. I have read the many posts on the topic here as well as on CRE Loaded forums, and have worked extensively with CRE Loaded support. Here is what I have learned.

 

On or about line 260, the file includes/modules/payment/authorizenet.php parses a string and sets a variable equal to the first value and calls it $x_response_code. It then compares that variable to the string literal "1". If there is no match the transaction is voided out and the appropriate error is supposed to be displayed. If it does match the voiding out process is skipped and the transaction is kept.

 

What I have experienced is simply that in no case will this test ever produce a match between a variable derived from an exploded string and a string literal. Since none of the matches work correctly the "undefined error" message is the only one that ever appears. And since the original code inadvertently eliminates the text message returned by authorize.net no additional information is ever displayed.

 

To overcome the issue I have simply created a "test set" of variables from a derived array and compare to them rather than to string literals. While this works it is just a very curious thing to me why a derived "abc" would be considered not equal to a string literal "abc". I found this to be the case with all comparison methods, BTW. Everything from strcmp to != acts the exact same way. Anyone with insight is welcome to educate me. For those experiencing the same issue who would like to test my fix, here are my changes (search the code for "YBOTI" to have all changes pointed out:

 

	function before_process() {
  global $response,$insert_id;

  // Change made by using ADC Direct Connection
  // YBOTI - this parses "1" and looses vars [1, 2, and 3] so it is commented out
  /*$response_vars = $response[0]);
  $x_response_code = $response_vars[0];
  $x_response_subcode = $response_vars[1];
  $x_response_reason_code = $response_vars[2];
  $x_response_reason_text = $response_vars[3];*/

  // YBOTI - Build an array of test variables
  $possible_vars = explode(',', '"1", "2", "3", ""');
  $x_approved = $possible_vars[0];
  $x_cvv_error = $possible_vars[1];
  $x_declined = $possible_vars[2];
  $x_no_reason = $possible_vars[3];

  // YBOTI - now build variables with all necessary parameters
  $x_response_code = $response[0];
  $x_response_subcode = $response[1];
  $x_response_reason_code = $response[2];
  $x_response_reason_text = $response[3];

  //check to see if the value is encapsulated; if so, remove
  $x_response_code = str_replace('|', '', $x_response_code);

  if ($x_response_code != $x_approved) { // YBOTI - Note variable compared in place of literal

	tep_db_query("delete from " . TABLE_ORDERS . " where orders_id = '" . (int)$insert_id . "'"); //Remove order
	if($x_response_code == $x_no_reason) { // YBOTI - Note variable compared in place of literal
	  tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode('The server cannot connect to Authorize.net.  Please check your cURL and server settings.'), 'SSL', true, false));
	} else if($x_response_code == $x_cvv_error) { // YBOTI - Note variable compared in place of literal
	  tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode($x_response_text) . urlencode(' (' . $x_response_reason_text . ') - ') . urlencode(MODULE_PAYMENT_AUTHORIZENET_TEXT_DECLINED_MESSAGE), 'SSL', true, false));
	} else if($x_response_code == $x_declined) { // YBOTI - Note variable compared in place of literal
	  tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode('There was an error processing your credit card ') . urlencode(' - (' . $x_response_reason_code . '): ' . $x_response_reason_text), 'SSL', true, false));
	} else {
	  tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode('There was an unspecified error processing your credit card!'), 'SSL', true, false));
	}
  }
}


Put a face on your business

Communicate through video

http://www.helloworld.com/yboti

Share this post


Link to post
Share on other sites

I know by now my ignorance is showing like a petticoat under a miniskirt. :blush: But I hope someone with more greater OSC understanding than I have will step up and fill me in. But here is what I learned from posts in another forum. The values being returned from authorize.net apparently are encapsulated in double-quotes. So what is happening is this. $x_response_code is not one character in length, but 3. Is is literally '"1"' or 'double-quote-one-double-quote'. So when you try to compare it to the string literal '1' the two are not equal. Which is why, when I built the elaborate structure above it worked. Because with it you are comparing two instances of 'double-quote-one-double-quote'. My guess is that either because of a setting somewhere the internal strings of the return are being encapsulated in quotes, not uncommon in CSV when indicating numbers should be interpreted as strings, OR, in some recent change or upgrade they began to encapsulate, or more likely changed the encapsulate character from a pipe to a double-quote.

 

A far easier solution to the problem would be to add a single line. There is already a line to eliminate return values encapsulated in pipes:

//check to see if the value is encapsulated; if so, remove

$x_response_code = str_replace('|', '', $x_response_code);

 

So simply add one more line to eliminate the double-quotes:

 

$x_response_code = str_replace('"', '', $x_response_code);

 

I still suggest eliminating the redundant explode because with it you are loosing important information for the customer if their transaction doe snot succeed.


Put a face on your business

Communicate through video

http://www.helloworld.com/yboti

Share this post


Link to post
Share on other sites

OK, a final reply in case anyone else runs into this. As it turns out Authorize.net has a settings page for "direct response" that allows you to define your "default field separator" as well as your "field encapsulation character". The code actually accounted for the possibility one's data might be encapsulated with a pipe, but not with any of the other 8 possibilities. Either these are new or they recently changed the default. At least I stumped the best experts. Even when I asked BOTH the software support as well as Authorize.net support using the specific wording "field encapsulation character" no lights came on. So without changing a single line of code, simply login to your authorize.net account, click Settings then direct response and choose the blank line to that it does not use anything to encapsulate your data - or use the pipe which is already accounted for.


Put a face on your business

Communicate through video

http://www.helloworld.com/yboti

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×