Hello, desparately need some help here. I'm using AIM in PHP, and have used it on dozens of sites, but now am having inconsistent responses from Authorize.net. 90% of my transactions work, but there are occasional transactions that settle successfully but never send the response code to my server. I have been round and round with Authorize about this, but they offer no suggestion and insist that problem must be on my end. The strange part is that it only happens on this site and only when a transaction settles successfully, and only about 10% of the time, which is far too much. The result is that my site never records the sale and my client is very angry at having to chase down what customers had ordered. Here is the essential code:
<?
if($cc_name && $cc_number && $cc_type && $cc_expirationMonth && $cc_expirationYear && $cvv_number){
$DEBUGGING = 1; # Display additional information to track down problems
$TESTING = 0; # Set the testing flag so that transactions are not live
$ERROR_RETRIES = 2; # Number of transactions to post if soft errors occur
$auth_net_login_id = "xxxxxx";
$auth_net_tran_key = "xxxxxxxx";
$auth_net_url = "https://secure.authorize.net/gateway/transact.dll";
$authnet_values = array(
"x_login" => $auth_net_login_id,
"x_version" => "3.1",
"x_delim_char" => "|",
"x_delim_data" => "TRUE",
"x_url" => "FALSE",
"x_type" => "AUTH_CAPTURE",
"x_method" => "CC",
"x_tran_key" => $auth_net_tran_key,
"x_test_request" => "FALSE",
"x_relay_response" => "FALSE",
"x_card_num" => "$cc_number",
"x_exp_date" => "$exp",
"x_card_code" => "$cvv_number",
"x_amount" => "$grandTotal",
"x_first_name" => "$f_name",
"x_last_name" => "$l_name",
"x_address" => "$address",
"x_city" => "$city",
"x_state" => "$state",
"x_zip" => "$zip",
"x_country" => "USA",
"x_ship_to_first_name" => "$f_name",
"x_ship_to_last_name" => "$l_name",
"x_ship_to_address" => "$s_address",
"x_ship_to_city" => "$s_city",
"x_ship_to_state" => "$s_state",
"x_ship_to_zip" => "$s_zip",
"x_phone" => "$phone",
"x_email" => "$email",
"x_merchant_email" => "TRUE",
);
$fields = "";
foreach( $authnet_values as $key => $value ) $fields .= "$key=" . urlencode( $value ) . "&";
//$ch = curl_init("https://test.authorize.net/gateway/transact.dll"); //NOT VALID
//$ch = curl_init("https://certification.authorize.net/gateway/transact.dll"); //RUN TEST TRANSACTIONS
$ch = curl_init("https://secure.authorize.net/gateway/transact.dll");
### Uncomment the line ABOVE for test accounts or BELOW for live merchant accounts
### $ch = curl_init("https://secure.authorize.net/gateway/transact.dll");
curl_setopt($ch, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
curl_setopt($ch, CURLOPT_POSTFIELDS, rtrim( $fields, "& " )); // use HTTP POST to send form data
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response. ###
$resp = curl_exec($ch); //execute post and get results
curl_close ($ch);
$text = $resp;
$tok = explode("|", $resp);
if(($tok[0] == '1') || ($tok[0] == '4')){
$url = 'thankyou.php';
header("Location: $url");
exit;
}else{
//echo $text;
$_SESSION['cc_number'] = substr($_SESSION['cc_number'], -4);
$_SESSION['cvv_number'] = NULL;
$path = $_SERVER['DOCUMENT_ROOT'];
$logPath = str_replace('/web/content','/logs', $path);
$errorDate = date('r');
$session = print_r($_SESSION, true);
$text .= "\nSession - $session";
error_log("\n\nCart error on {$errorDate} - {$text}", 3, "{$logPath}/cart_errors.log");
$message = $tok[3];
}
}else{
$message = 'Please fill out all credit card fields.';
}
?>
Again, every single instance contains a transaction error successfully records in my error log, but several successful transactions each week fail to return and then go to my "thankyou.php" page. This integration has worked many times for me, and I have tried multiple methods of fixing the problem, but I am out of ideas. Any help is greatly appreciated.
10-03-2011 12:53 PM
Not a php developer. But how did you know "several successful transactions each week fail to return and then go to my "thankyou.php" page". Could it be failing in thankyou.php?
10-03-2011 01:50 PM
I would have error logs for thankyou.php if there were fails on that page. I had a few early on when I was testing the site, but none that relate to these transactions. I wish that Authorize had error logs, that would make all of this much easier.
10-03-2011 01:54 PM
Can you post the thankyou.php code? Maybe some of our php expert here can see something.
10-03-2011 01:58 PM
Happy to, though I really doubt this is the problem as for a while I was logging every transaction that returned a 1 or 4 from Authorize.net in the same way that I log errors:
<?
if(($tok[0] == '1') || ($tok[0] == '4')){
//echo $text;
$_SESSION['cc_number'] = substr($_SESSION['cc_number'], -4);
$_SESSION['cvv_number'] = NULL;
$path = $_SERVER['DOCUMENT_ROOT'];
$logPath = str_replace('/web/content','/logs', $path);
$errorDate = date('r');
$session = print_r($_SESSION, true);
$text .= "\nSession - $session";
error_log("\n\nCart transaction on {$errorDate} - {$text}", 3, "{$logPath}/cart_success.log");
$message = $tok[3];
$url = 'thankyou.php';
header("Location: $url");
exit;
}else{
//echo $text;
$_SESSION['cc_number'] = substr($_SESSION['cc_number'], -4);
$_SESSION['cvv_number'] = NULL;
$path = $_SERVER['DOCUMENT_ROOT'];
$logPath = str_replace('/web/content','/logs', $path);
$errorDate = date('r');
$session = print_r($_SESSION, true);
$text .= "\nSession - $session";
error_log("\n\nCart error on {$errorDate} - {$text}", 3, "{$logPath}/cart_errors.log");
$message = $tok[3];
}
?>
In this scenario I would still get successful transactions in Authorize, but no error log and no success log.
There is a lot of code that shouldn't be displayed publicly in the thankyou.php file, but if a php expert thinks that it can help them with the knowledge that I occasionally don't get either log using the code above then I will do my best to censor the code and post it here while leaving enough of the code to troubleshoot with. Just let me know, I really appreciate it.
10-03-2011 02:17 PM
What I would suggest is logging how long it takes to do the Authorize.net part (the CURL section). My wild guess is that there's communication problems between your host and Authorize.net, in which case you should some transactions that run relatively quickly and then others that take much longer (and some that don't get logged). If this happens only on successful transactions, you could theoretically put the CURL in a timeout block set to something reasonable and then go ahead and okay the transaction. You could also try going into the php.ini and setting your max execution time values somewhat higher.
10-03-2011 08:41 PM
Thanks TJPride. I increased the max execution time, so we'll see how that goes. I would I put the cURL in a timeout block for successful transactions only?
10-04-2011 06:51 AM
The way the timeout block would work is you'd set it to fail after 25 seconds or something reasonable and then act as if it was successful in those instances (since you say it only times out on successful transactions). But I've done some research and the available options for PHP (fork, wrapping a secondary script, etc.) seem to be overly complicated. Easiest thing will probably be to set the CURLOPT_TIMEOUT value in cURL. You can then have some sort of automated routine that checks later for false positives, just in case, and unmarks them as complete.
10-05-2011 06:34 AM