Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

Credit Card error message not showing


Avec

Recommended Posts

When there is a problem with credit card validation, such as incorrect number (check sum), there is supposed to be a general error message and a detail message based on what shows up in the URL.

 

Here is the code from includes/modules/payment/cc_cvv2.php

 function get_error() {
  $error = array('title' => MODULE_PAYMENT_CC_CVV2_TEXT_ERROR,
				 'error' => stripslashes(urldecode($_GET['error'])));

 

The title portion works, pulling the text as prescribed. The error part does not work. An example of the URL is:

 

https://www.mysite.com/checkout_payment.php?payment_error=cc&error=Unable+to+match+the+credit+card+number+given+with+any+known+type+of+credit+card.&cc_owner=Tom+Synder&cc_expires_month=01&cc_expires_year=13

 

Any help appreciated.

Link to comment
Share on other sites

@@Avec

 

You should check PCI DSS Compliance laws and policies in your state. In most of North America, it is illegal to process credit cards directly on your website and to process them 'off-line'.

 

 

 

Chris

Link to comment
Share on other sites

@@Avec

 

You should check PCI DSS Compliance laws and policies in your state. In most of North America, it is illegal to process credit cards directly on your website and to process them 'off-line'.

 

 

 

Chris

 

Thank you for your concern, but our method does not differ from any other site that does not use a gateway which I image is not a small percentage. Based on the compliance information I have, we are compliant.

 

In looking for an answer to this question on this board, I have seen that many, many legitimate coding questions almost instantly is side-tracked into a discussion (or more adversarial) about PCI compliance. Again, thank you for your concern, but if we can keep the thread on topic, it would be appreciated.

Link to comment
Share on other sites

@@Avec

 

The reason most manual credit card processing questions become discussions is because website designer / developers/ friends helping friends are being charged and convicted of installing credit card modules that are not PCI DSS compliant. The modules on this website ARE NOT compliant and the module that was bundled with v2.2 RC2a was NOT compliant. In fact, even the core code of v2.3.3 has to be changed when a compliant module is installed to ensure the transaction is processed within compliance. So your statement that "our method does not differ from any other site that does not use a gateway which I image is not a small percentage" is incorrect and as enforcement increases and fines and criminal action is taken against store owners and 'website creators' you will find more and more becoming certified.

 

 

 

Chris

 

ps. Even those who may seek to help you on this forum with your question could be held liable.

Link to comment
Share on other sites

So, do you have an answer to my original question? I think I was clear about my question - which was about an error message. Either you know or don't. Again, I appreciate the concern, but please stick to the original topic

Link to comment
Share on other sites

I am having the same problem with the "This transaction has been declined" message not showing up to let the customer know that his card did not go through.

It just redirects them to the check out options page with no error message telling them that the order was not processed.

I am using Authorize.net payment module. Cards are processed or declined normally otherwise but it just will not show the the error message like it should when a card is declined.

I was told by my host provider that it could that I need a private ssl instead of a shared ssl and that will cost extra money. Why would my shared ssl be a problem all of a sudden when it worked before?

Link to comment
Share on other sites

Hi

Your SSL would not affect this. Have a look at http://www.oscommerce.com/community/contributions,4091 there's a change in there that may help you (if you look at the file includes/modules/payment/authorizenet_aim.php there's a point in there where the response from AuthNet gets split up into an array - about line 733 - and it's sending the fourth element in the array back to checkout_payment using the error function which is just below it.

 

Maybe that'll help?

 

Bob

Link to comment
Share on other sites

  • 1 month later...

Bob,

My authorizenet_aim.php doeen't have a line 733, it only goes to 389. but I did see this in the code I hightlighted in bold below:

 

// Evaluates the Credit Card Type for acceptance and validity of the Credit Card Number and Expiry Date

function pre_confirmation_check() {

global $_POST;

 

include(DIR_WS_CLASSES . 'cc_validation.php');

 

$cc_validation = new cc_validation();

$result = $cc_validation->validate($_POST['authorizenet_aim_cc_number'], $_POST['authorizenet_aim_cc_expires_month'], $_POST['authorizenet_aim_cc_expires_year'], $_POST['authorizenet_aim_cc_cvv']);

$error = '';

switch ($result) {

case -1:

$error = sprintf(TEXT_CCVAL_ERROR_UNKNOWN_CARD, substr($cc_validation->cc_number, 0, 4));

break;

case -2:

case -3:

case -4:

$error = TEXT_CCVAL_ERROR_INVALID_DATE;

break;

case false:

$error = TEXT_CCVAL_ERROR_INVALID_NUMBER;

break;

}

 

if ( ($result == false) || ($result < 1) ) {

$payment_error_return = 'payment_error=' . $this->code . '&error=' . urlencode($error) . '&authorizenet_aim_cc_owner=' . urlencode($_POST['authorizenet_aim_cc_owner']) . '&authorizenet_aim_cc_expires_month=' . $_POST['authorizenet_aim_cc_expires_month'] . '&authorizenet_aim_cc_expires_year=' . $_POST['authorizenet_aim_cc_expires_year'];

 

tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, $payment_error_return, 'SSL', true, false));

}

 

$this->cc_card_type = $cc_validation->cc_type;

$this->cc_card_number = $cc_validation->cc_number;

$this->cc_expiry_month = $cc_validation->cc_expiry_month;

$this->cc_expiry_year = $cc_validation->cc_expiry_year;

}

 

// Display Credit Card Information on the Checkout Confirmation Page

function confirmation() {

global $_POST;

 

if (MODULE_PAYMENT_AUTHORIZENET_AIM_USE_CVV == 'True') {

$confirmation = array(//'title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CATALOG_TITLE, // Redundant

'fields' => array(array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_TYPE,

'field' => $this->cc_card_type),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_OWNER,

'field' => $_POST['authorizenet_aim_cc_owner']),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_NUMBER,

'field' => substr($this->cc_card_number, 0, 4) . str_repeat('X', (strlen($this->cc_card_number) - 8)) . substr($this->cc_card_number, -4)),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_EXPIRES,

'field' => strftime('%B, %Y', mktime(0,0,0,$_POST['authorizenet_aim_cc_expires_month'], 1, '20' . $_POST['authorizenet_aim_cc_expires_year']))),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CVV,

'field' => $_POST['authorizenet_aim_cc_cvv'])));

} else {

$confirmation = array(//'title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CATALOG_TITLE, // Redundant

'fields' => array(array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_TYPE,

'field' => $this->cc_card_type),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_OWNER,

'field' => $_POST['authorizenet_aim_cc_owner']),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_NUMBER,

'field' => substr($this->cc_card_number, 0, 4) . str_repeat('X', (strlen($this->cc_card_number) - 8)) . substr($this->cc_card_number, -4)),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_EXPIRES,

'field' => strftime('%B, %Y', mktime(0,0,0,$_POST['authorizenet_aim_cc_expires_month'], 1, '20' . $_POST['authorizenet_aim_cc_expires_year'])))));

}

 

return $confirmation;

}

Link to comment
Share on other sites

Hi there - the line you've found is in the pre_confirmation_check() function so it's designed to sit before the checkout_confirmation page and run through the card numbers etc using the built in .js checking system) and chuck the customer back to the payment page if it finds a basic error (the javascript runs through the Luhn formula as applies to CC numbers so will pick up a miss-typed number).

 

Have a look here - this looks like your module http://addons.oscommerce.com/info/4091

 

Maybe the last update would help?

 

Basically from reading through the modules there it seems that Authorize.net change the response delimeters from time to time - the code you need is in the function before_process() which is called into play in the checkout_process.php file before the order gets written to the database - in there you'll see this (or similar)

  if ($this->response[0] != '1') {
    tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode($this->response[3]) . ' - ' . urlencode(MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_DECLINED_MESSAGE), 'SSL', true, false));
  }

That's looking at the return message from Auth.net and if the first chunk is not equal to 1 is returning you to the payment page with the error message being equal to the fourth chunk of the return plus the text held in MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_DECLINED_MESSAGE. If you have no text defined as MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_DECLINED_MESSAGE then try defining some and see if that shows up - if it does then urlencode($this->response[3]) is empty - if nothing shows up then it looks like the error handling side of things is stuffed

Link to comment
Share on other sites

Thanks for the response. I found two groups of code that are related to what you wrote below.. The second group which is closest to what you mentioned looks like it is commented out with a // before it.

 

if ( ($result == false) || ($result < 1) ) {

$payment_error_return = 'payment_error=' . $this->code . '&error=' . urlencode($error) . '&authorizenet_aim_cc_owner=' . urlencode($_POST['authorizenet_aim_cc_owner']) . '&authorizenet_aim_cc_expires_month=' . $_POST['authorizenet_aim_cc_expires_month'] . '&authorizenet_aim_cc_expires_year=' . $_POST['authorizenet_aim_cc_expires_year'];

 

tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, $payment_error_return, 'SSL', true, false));

}

 

$this->cc_card_type = $cc_validation->cc_type;

$this->cc_card_number = $cc_validation->cc_number;

$this->cc_expiry_month = $cc_validation->cc_expiry_month;

$this->cc_expiry_year = $cc_validation->cc_expiry_year;

}

 

// Display Credit Card Information on the Checkout Confirmation Page

function confirmation() {

global $_POST;

 

if (MODULE_PAYMENT_AUTHORIZENET_AIM_USE_CVV == 'True') {

$confirmation = array(//'title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CATALOG_TITLE, // Redundant

'fields' => array(array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_TYPE,

'field' => $this->cc_card_type),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_OWNER,

'field' => $_POST['authorizenet_aim_cc_owner']),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_NUMBER,

'field' => substr($this->cc_card_number, 0, 4) . str_repeat('X', (strlen($this->cc_card_number) - 8)) . substr($this->cc_card_number, -4)),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_EXPIRES,

'field' => strftime('%B, %Y', mktime(0,0,0,$_POST['authorizenet_aim_cc_expires_month'], 1, '20' . $_POST['authorizenet_aim_cc_expires_year']))),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CVV,

'field' => $_POST['authorizenet_aim_cc_cvv'])));

} else {

$confirmation = array(//'title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CATALOG_TITLE, // Redundant

'fields' => array(array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_TYPE,

'field' => $this->cc_card_type),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_OWNER,

'field' => $_POST['authorizenet_aim_cc_owner']),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_NUMBER,

'field' => substr($this->cc_card_number, 0, 4) . str_repeat('X', (strlen($this->cc_card_number) - 8)) . substr($this->cc_card_number, -4)),

array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_CREDIT_CARD_EXPIRES,

'field' => strftime('%B, %Y', mktime(0,0,0,$_POST['authorizenet_aim_cc_expires_month'], 1, '20' . $_POST['authorizenet_aim_cc_expires_year'])))));

}

 

return $confirmation;

}

 

function process_button() {

// Hidden fields on the checkout confirmation page

$process_button_string = tep_draw_hidden_field('cc_owner', $_POST['authorizenet_aim_cc_owner']) .

tep_draw_hidden_field('cc_expires', $this->cc_expiry_month . substr($this->cc_expiry_year, -2)) .

tep_draw_hidden_field('cc_type', $this->cc_card_type) .

tep_draw_hidden_field('cc_number', $this->cc_card_number);

if (MODULE_PAYMENT_AUTHORIZENET_AIM_USE_CVV == 'True') {

$process_button_string .= tep_draw_hidden_field('cc_cvv', $_POST['authorizenet_aim_cc_cvv']);

}

 

$process_button_string .= tep_draw_hidden_field(tep_session_name(), tep_session_id());

 

return $process_button_string;

return false;

}

 

function before_process() {

global $_POST, $response, $db, $order;

 

// DATA PREPARATION SECTION

unset($submit_data); // Cleans out any previous data stored in the variable

 

// Create a string that contains a listing of products ordered for the description field

$description = '';

for ($i=0; $i<sizeof($order->products); $i++) {

$description .= $order->products[$i]['name'] . '(qty: ' . $order->products[$i]['qty'] . ') + ';

}

// Strip the last "\n" from the string

$description = substr($description, 0, -2);

 

// Create a variable that holds the order time

$order_time = date("F j, Y, g:i a");

 

// Calculate the next expected order id

$last_order_id = tep_db_query("select * from " . TABLE_ORDERS . " order by orders_id desc limit 1");

$new_order_id = $last_order_id->fields['orders_id'];

$new_order_id = ($new_order_id + 1);

 

// Populate an array that contains all of the data to be submitted

$submit_data = array(

x_login => MODULE_PAYMENT_AUTHORIZENET_AIM_LOGIN, // The login name as assigned to you by authorize.net

x_tran_key => MODULE_PAYMENT_AUTHORIZENET_AIM_TXNKEY, // The Transaction Key (16 digits) is generated through the merchant interface

x_relay_response => 'FALSE', // AIM uses direct response, not relay response

x_delim_data => 'TRUE', // The default delimiter is a comma

x_version => '3.1', // 3.1 is required to use CVV codes

x_type => MODULE_PAYMENT_AUTHORIZENET_AIM_AUTHORIZATION_TYPE == 'Authorize' ? 'AUTH_ONLY': 'AUTH_CAPTURE',

x_method => 'CC', //MODULE_PAYMENT_AUTHORIZENET_AIM_METHOD == 'Credit Card' ? 'CC' : 'ECHECK',

x_amount => number_format($order->info['total'], 2),

x_card_num => $_POST['cc_number'],

x_exp_date => $_POST['cc_expires'],

x_card_code => $_POST['cc_cvv'],

x_email_customer => MODULE_PAYMENT_AUTHORIZENET_AIM_EMAIL_CUSTOMER == 'True' ? 'TRUE': 'FALSE',

x_email_merchant => MODULE_PAYMENT_AUTHORIZENET_AIM_EMAIL_MERCHANT == 'True' ? 'TRUE': 'FALSE',

x_cust_id => $_SESSION['customer_id'],

x_invoice_num => $new_order_id,

x_first_name => $order->billing['firstname'],

x_last_name => $order->billing['lastname'],

x_company => $order->billing['company'],

x_address => $order->billing['street_address'],

x_city => $order->billing['city'],

x_state => $order->billing['state'],

x_zip => $order->billing['postcode'],

x_country => $order->billing['country']['title'],

x_phone => $order->customer['telephone'],

x_email => $order->customer['email_address'],

x_ship_to_first_name => $order->delivery['firstname'],

x_ship_to_last_name => $order->delivery['lastname'],

x_ship_to_address => $order->delivery['street_address'],

x_ship_to_city => $order->delivery['city'],

x_ship_to_state => $order->delivery['state'],

x_ship_to_zip => $order->delivery['postcode'],

x_ship_to_country => $order->delivery['country']['title'],

x_description => $description,

// Merchant defined variables go here

Date => $order_time,

IP => $_SERVER['REMOTE_ADDR'],

Session => tep_session_id());

 

if(MODULE_PAYMENT_AUTHORIZENET_AIM_TESTMODE == 'Test') {

$submit_data['x_test_request'] = 'TRUE';

} else {

 

$submit_data['x_test_request'] = 'FALSE';

 

}

 

// concatenate the submission data and put into variable $data

while(list($key, $value) = each($submit_data)) {

$data .= $key . '=' . urlencode(ereg_replace(',', '', $value)) . '&';

}

 

// Remove the last "&" from the string

$data = substr($data, 0, -1);

 

 

// Post order info data to Authorize.net

// cURL must be compiled into PHP

// Connection must be https

// Test or Live Server address set

// using 'Test' or 'Live' mode in

// osCommerce admin panel

 

 

unset($response);

 

if (MODULE_PAYMENT_AUTHORIZENET_AIM_TESTMODE == 'Test') {

$url = 'https://secure.authorize.net/gateway/transact.dll'; // If this does not work then change 'secure' to 'certification' on this line

} else {

$url = 'https://secure.authorize.net/gateway/transact.dll';

}

 

$ch = curl_init();

 

curl_setopt($ch, CURLOPT_URL,$url);

 

curl_setopt($ch, CURLOPT_VERBOSE, 0);

 

curl_setopt($ch, CURLOPT_POST, 1);

 

curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

 

curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);

 

if(MODULE_PAYMENT_AUTHORIZENET_AIM_CURL_PROXY != 'none') {

curl_setopt ($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);

curl_setopt ($ch, CURLOPT_PROXY,MODULE_PAYMENT_AUTHORIZENET_AIM_CURL_PROXY);

}

 

$authorize = curl_exec($ch);

 

curl_close ($ch);

 

$response = split('\,', $authorize);

 

// Parse the response code and text for custom error display

$response_code = explode(',', $response[0]);

$response_text = explode(',', $response[3]);

$x_response_code = $response_code[0];

$x_response_text = $response_text[0];

// If the response code is not 1 (approved) then redirect back to the payment page with the appropriate error message

if ($x_response_code != '1') {

 

tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . $x_response_text . ' - ' . urlencode(MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_DECLINED_MESSAGE), 'SSL', true, false));

}

}

 

function after_process() {

return false;

}

 

function get_error() {

global $_GET;

 

$error = array('title' => MODULE_PAYMENT_AUTHORIZENET_AIM_TEXT_ERROR,

'error' => stripslashes(urldecode($_GET['error'])));

 

return $error;

}

 

function check() {

 

if (!isset($this->_check)) {

$check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_AUTHORIZENET_AIM_STATUS'");

$this->_check = tep_db_num_rows($check_query);

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...