diff --git a/includes/languages/english/modules/payment/authorizenet_cim.php b/includes/languages/english/modules/payment/authorizenet_cim.php index a26e51c..48aca42 100644 --- a/includes/languages/english/modules/payment/authorizenet_cim.php +++ b/includes/languages/english/modules/payment/authorizenet_cim.php @@ -7,7 +7,7 @@ released under GPU https://www.zen-cart.com/license/2_0.txt GNU Public License V2.0 - 04/2020 project: authorizenet_cim; file: authorizenet_cim.php; version 2.1.1 + 05/2023 project: authorizenet_cim; file: authorizenet_cim.php; version 2.3.3 */ define('MODULE_PAYMENT_AUTHORIZENET_CIM_TEXT_ADMIN_TITLE', @@ -43,6 +43,7 @@ define('MODULE_PAYMENT_AUTHORIZENET_CIM_TEXT_DECLINED_MESSAGE', 'Your credit card could not be authorized for this reason. Please correct the information and try again or contact us for further assistance.'); define('MODULE_PAYMENT_AUTHORIZENET_CIM_TEXT_ERROR', 'Credit Card Error!'); +define('MODULE_PAYMENT_AUTHORIZENET_CIM_FRAUD_WARNING', 'Sorry, due to the increasing amount of fraud we are forced to limit credit card usage.') define('MODULE_PAYMENT_AUTHORIZENET_CIM_ENTRY_REFUND_TITLE', 'Refund Transactions'); define('MODULE_PAYMENT_AUTHORIZENET_CIM_ENTRY_REFUND', 'You may refund money to the customer\'s credit card here:'); diff --git a/includes/modules/pages/card_update/header_php.php b/includes/modules/pages/card_update/header_php.php index 531fb36..d462a03 100644 --- a/includes/modules/pages/card_update/header_php.php +++ b/includes/modules/pages/card_update/header_php.php @@ -1,125 +1,135 @@ set_snapshot(); - zen_redirect(zen_href_link(FILENAME_LOGIN, '', 'SSL')); - } else { - // validate customer - if (zen_get_customer_validate_session($_SESSION['customer_id']) == false) { - $_SESSION['navigation']->set_snapshot(); - zen_redirect(zen_href_link(FILENAME_LOGIN, '', 'SSL')); - } - } - $customer_id = $_SESSION['customer_id']; - - $addressSelected = $_POST['address_selection'] ?? ''; - - require_once DIR_WS_MODULES . 'require_languages.php'; - - require_once DIR_FS_CATALOG . DIR_WS_LANGUAGES . $_SESSION['language'] . '/modules/payment/authorizenet_cim.php'; - require DIR_WS_MODULES . 'payment/authorizenet_cim.php'; - - $cim = new authorizenet_cim(); - $userProfile = $cim->getCustomerProfile($customer_id); - $user = $cim->getCustomer(); - - if ($userProfile == false) { - $messageStack->add_session(FILENAME_ACCOUNT, 'Sorry, you have no credit cards on file.', 'error'); - zen_redirect(zen_href_link(FILENAME_ACCOUNT, '', 'SSL')); - } - - if (isset($_POST['delete_cid'])) { - $payment_profile = $cim->checkValidPaymentProfile($customer_id, $_POST['delete_cid']); - if ($payment_profile['valid']) { - $delete_cid = $cim->deleteCustomerPaymentProfile($userProfile, $payment_profile['payment_profile_id']); - - $start = strpos($delete_cid, 'ERROR'); - $startE0040 = strpos($delete_cid, 'E00040'); - if (($start === false) || ($startE0040 !== false)) { - $messageStack->add_session(FILENAME_CARD_UPDATE, 'Your credit card has been deleted!', 'success'); - } else { - $messageStack->add_session(FILENAME_CARD_UPDATE, - 'There was a problem deleting your card. Please contact the store owner.', 'error'); - } - } else { - $messageStack->add_session(FILENAME_CARD_UPDATE, - 'There was a problem deleting your card. Please contact the store owner.', 'error'); - trigger_error('trying to delete card not part of cust: ' . $customer_id . ' card_cid: ' . $_POST['delete_cid']); - } - } - - if (isset($_POST['update_cid'])) { - $payment_profile = $cim->checkValidPaymentProfile($customer_id, $_POST['update_cid']); - $update_cid = $cim->updateCustomerPaymentProfile($userProfile, $payment_profile['payment_profile_id']); - - $start = strpos($update_cid, 'ERROR'); - if ($start === false) { - $messageStack->add_session(FILENAME_ACCOUNT, 'Your credit card has been UPDATED!', 'success'); - $cim->updateDefaultCustomerBillto($addressSelected); - zen_redirect(zen_href_link(FILENAME_ACCOUNT, '', 'SSL')); - } else { - $messageStack->add_session(FILENAME_CARD_UPDATE, 'Problem updating your card: ' . $update_cid, 'error'); - zen_redirect(zen_href_link(FILENAME_CARD_UPDATE, '', 'SSL')); - } - } - - if (isset($_POST['new_cid'])) { - $new_cid = $cim->createCustomerPaymentProfileRequest(); - - $start = strpos($new_cid, 'ERROR'); - if ($start === false) { - $messageStack->add_session(FILENAME_ACCOUNT, 'You have successfully added a new Credit Card!', 'success'); - $cim->updateDefaultCustomerBillto($addressSelected); - zen_redirect(zen_href_link(FILENAME_ACCOUNT, '', 'SSL')); - } else { - $messageStack->add_session(FILENAME_CARD_UPDATE, 'There was a problem adding your card: ' . $new_cid, - 'error'); - zen_redirect(zen_href_link(FILENAME_CARD_UPDATE, '', 'SSL')); - } - } - $today = getdate(); - for ($i = $today['year']; $i < $today['year'] + 10; $i++) { - $expires_year[] = [ - 'id' => strftime('%y', mktime(0, 0, 0, 1, 1, $i)), - 'text' => strftime('%Y', mktime(0, 0, 0, 1, 1, $i)) - ]; - } - for ($i = 1; $i < 13; $i++) { - $expires_month[] = [ - 'id' => sprintf('%02d', $i), - 'text' => strftime('%B', mktime(0, 0, 0, $i, 1, 2000)) - ]; - } - - if (($messageStack->size('card_update') > 0) && (($_REQUEST['action'] ?? '') !== 'delete')) { - echo $messageStack->output('card_update'); - $messageStack->reset(); - } - $h2_title = 'Select Billing Address for Credit Card or Enter New Billing Address'; - $div_id = 'cc_address'; - $new_address_title = 'New Bill-To Address'; - - $breadcrumb->add(NAVBAR_TITLE_1, zen_href_link(FILENAME_ACCOUNT, '', 'SSL')); - $breadcrumb->add(NAVBAR_TITLE); - - if (($_SESSION['emp_admin_login'] ?? false) === true) { - $cards_saved = $cim->getCustomerCardsAsArray($customer_id, true); - } else { - $cards_saved = $cim->getCustomerCardsAsArray($customer_id); - } - - $addresses_query = "SELECT address_book_id, entry_firstname as firstname, entry_lastname as lastname, + if (!zen_is_logged_in() || zen_in_guest_checkout()) { + $_SESSION['navigation']->set_snapshot(); + zen_redirect(zen_href_link(FILENAME_LOGIN, '', 'SSL')); + } else { + // validate customer + if (zen_get_customer_validate_session($_SESSION['customer_id']) == false) { + $_SESSION['navigation']->set_snapshot(); + zen_redirect(zen_href_link(FILENAME_LOGIN, '', 'SSL')); + } + } + $customer_id = $_SESSION['customer_id']; + + $customers_orders = $db->Execute("SELECT o.orders_id, o.date_purchased, o.order_total, o.currency, o.currency_value, + cgc.amount + FROM " . TABLE_ORDERS . " o + LEFT JOIN " . TABLE_COUPON_GV_CUSTOMER . " cgc ON o.customers_id = cgc.customer_id + WHERE customers_id = " . (int)$customer_id . " + ORDER BY date_purchased desc"); + + if ($customers_orders->RecordCount() < 1) { + zen_redirect(zen_href_link(FILENAME_ACCOUNT, '', 'SSL')); + } + $addressSelected = $_POST['address_selection'] ?? ''; + + require_once DIR_WS_MODULES . 'require_languages.php'; + + require_once DIR_FS_CATALOG . DIR_WS_LANGUAGES . $_SESSION['language'] . '/modules/payment/authorizenet_cim.php'; + require DIR_WS_MODULES . 'payment/authorizenet_cim.php'; + + $cim = new authorizenet_cim(); + $userProfile = $cim->getCustomerProfile($customer_id); + $user = $cim->getCustomer(); + + if ($userProfile == false) { + $messageStack->add_session(FILENAME_ACCOUNT, 'Sorry, you have no credit cards on file.', 'error'); + zen_redirect(zen_href_link(FILENAME_ACCOUNT, '', 'SSL')); + } + + if (isset($_POST['delete_cid'])) { + $payment_profile = $cim->checkValidPaymentProfile($customer_id, $_POST['delete_cid']); + if ($payment_profile['valid']) { + $delete_cid = $cim->deleteCustomerPaymentProfile($userProfile, $payment_profile['payment_profile_id']); + + $start = strpos($delete_cid, 'ERROR'); + $startE0040 = strpos($delete_cid, 'E00040'); + if (($start === false) || ($startE0040 !== false)) { + $messageStack->add_session(FILENAME_CARD_UPDATE, 'Your credit card has been deleted!', 'success'); + } else { + $messageStack->add_session(FILENAME_CARD_UPDATE, + 'There was a problem deleting your card. Please contact the store owner.', 'error'); + } + } else { + $messageStack->add_session(FILENAME_CARD_UPDATE, + 'There was a problem deleting your card. Please contact the store owner.', 'error'); + trigger_error('trying to delete card not part of cust: ' . $customer_id . ' card_cid: ' . $_POST['delete_cid']); + } + } + + if (isset($_POST['update_cid'])) { + $payment_profile = $cim->checkValidPaymentProfile($customer_id, $_POST['update_cid']); + $update_cid = $cim->updateCustomerPaymentProfile($userProfile, $payment_profile['payment_profile_id']); + + $start = strpos($update_cid, 'ERROR'); + if ($start === false) { + $messageStack->add_session(FILENAME_ACCOUNT, 'Your credit card has been UPDATED!', 'success'); + $cim->updateDefaultCustomerBillto($addressSelected); + zen_redirect(zen_href_link(FILENAME_ACCOUNT, '', 'SSL')); + } else { + $messageStack->add_session(FILENAME_CARD_UPDATE, 'Problem updating your card: ' . $update_cid, 'error'); + zen_redirect(zen_href_link(FILENAME_CARD_UPDATE, '', 'SSL')); + } + } + + if (isset($_POST['new_cid'])) { + $new_cid = $cim->createCustomerPaymentProfileRequest(); + + $start = strpos($new_cid, 'ERROR'); + if ($start === false) { + $messageStack->add_session(FILENAME_ACCOUNT, 'You have successfully added a new Credit Card!', 'success'); + $cim->updateDefaultCustomerBillto($addressSelected); + zen_redirect(zen_href_link(FILENAME_ACCOUNT, '', 'SSL')); + } else { + $messageStack->add_session(FILENAME_CARD_UPDATE, 'There was a problem adding your card: ' . $new_cid, + 'error'); + zen_redirect(zen_href_link(FILENAME_CARD_UPDATE, '', 'SSL')); + } + } + $today = getdate(); + for ($i = $today['year']; $i < $today['year'] + 10; $i++) { + $expires_year[] = [ + 'id' => strftime('%y', mktime(0, 0, 0, 1, 1, $i)), + 'text' => strftime('%Y', mktime(0, 0, 0, 1, 1, $i)), + ]; + } + for ($i = 1; $i < 13; $i++) { + $expires_month[] = [ + 'id' => sprintf('%02d', $i), + 'text' => strftime('%B', mktime(0, 0, 0, $i, 1, 2000)), + ]; + } + + if (($messageStack->size('card_update') > 0) && (($_REQUEST['action'] ?? '') !== 'delete')) { + echo $messageStack->output('card_update'); + $messageStack->reset(); + } + $h2_title = 'Select Billing Address for Credit Card or Enter New Billing Address'; + $div_id = 'cc_address'; + $new_address_title = 'New Bill-To Address'; + + $breadcrumb->add(NAVBAR_TITLE_1, zen_href_link(FILENAME_ACCOUNT, '', 'SSL')); + $breadcrumb->add(NAVBAR_TITLE); + + if (($_SESSION['emp_admin_login'] ?? false) === true) { + $cards_saved = $cim->getCustomerCardsAsArray($customer_id, true); + } else { + $cards_saved = $cim->getCustomerCardsAsArray($customer_id); + } + + $addresses_query = "SELECT address_book_id, entry_firstname as firstname, entry_lastname as lastname, entry_company as company, entry_street_address as street_address, entry_suburb as suburb, entry_city as city, entry_postcode as postcode, entry_state as state, entry_zone_id as zone_id, entry_country_id as country_id @@ -127,48 +137,48 @@ WHERE customers_id = :customersID ORDER BY firstname, lastname"; - $addresses_query = $db->bindVars($addresses_query, ':customersID', $customer_id, 'integer'); - $addresses = $db->Execute($addresses_query); - - while (!$addresses->EOF) { - $format_id = zen_get_address_format_id($addresses->fields['country_id']); - $addressArray[] = [ - 'firstname' => $addresses->fields['firstname'], - 'lastname' => $addresses->fields['lastname'], - 'address_book_id' => $addresses->fields['address_book_id'], - 'format_id' => $format_id, - 'address' => $addresses->fields - ]; - $addresses->MoveNext(); - } - $entry_query = "SELECT entry_country_id + $addresses_query = $db->bindVars($addresses_query, ':customersID', $customer_id, 'integer'); + $addresses = $db->Execute($addresses_query); + + while (!$addresses->EOF) { + $format_id = zen_get_address_format_id($addresses->fields['country_id']); + $addressArray[] = [ + 'firstname' => $addresses->fields['firstname'], + 'lastname' => $addresses->fields['lastname'], + 'address_book_id' => $addresses->fields['address_book_id'], + 'format_id' => $format_id, + 'address' => $addresses->fields, + ]; + $addresses->MoveNext(); + } + $entry_query = "SELECT entry_country_id FROM " . TABLE_ADDRESS_BOOK . " a, " . TABLE_CUSTOMERS . " c WHERE a.customers_id = :customersID AND a.customers_id = c.customers_id AND a.address_book_id = c.customers_default_address_id"; - $entry_query = $db->bindVars($entry_query, ':customersID', $_SESSION['customer_id'], 'integer'); - $entry = $db->Execute($entry_query); + $entry_query = $db->bindVars($entry_query, ':customersID', $_SESSION['customer_id'], 'integer'); + $entry = $db->Execute($entry_query); - if ($entry->EOF) { - $entry->fields['entry_country_id'] = '223'; - } - $zone_id = 0; + if ($entry->EOF) { + $entry->fields['entry_country_id'] = '223'; + } + $zone_id = 0; - $entry->fields['entry_gender'] = 'm'; - $entry->fields['entry_firstname'] = ''; - $entry->fields['entry_lastname'] = ''; - $entry->fields['entry_company'] = ''; - $entry->fields['entry_street_address'] = ''; - $entry->fields['entry_suburb'] = ''; - $entry->fields['entry_city'] = ''; - $entry->fields['entry_state'] = ''; - $entry->fields['entry_zone_id'] = 0; - $entry->fields['entry_postcode'] = ''; + $entry->fields['entry_gender'] = 'm'; + $entry->fields['entry_firstname'] = ''; + $entry->fields['entry_lastname'] = ''; + $entry->fields['entry_company'] = ''; + $entry->fields['entry_street_address'] = ''; + $entry->fields['entry_suburb'] = ''; + $entry->fields['entry_city'] = ''; + $entry->fields['entry_state'] = ''; + $entry->fields['entry_zone_id'] = 0; + $entry->fields['entry_postcode'] = ''; - $flag_show_pulldown_states = true; - $selected_country = 223; - $state_field_label = ENTRY_STATE; + $flag_show_pulldown_states = true; + $selected_country = 223; + $state_field_label = ENTRY_STATE; - include_once(DIR_WS_CLASSES . 'cc_validation.php'); + include_once(DIR_WS_CLASSES . 'cc_validation.php'); diff --git a/includes/modules/payment/authorizenet_cim.php b/includes/modules/payment/authorizenet_cim.php index 836a9ab..5509047 100644 --- a/includes/modules/payment/authorizenet_cim.php +++ b/includes/modules/payment/authorizenet_cim.php @@ -24,7 +24,7 @@ class authorizenet_cim extends base var $code, $title, $description, $enabled, $authorize = ''; - var $version = '2.3.2'; + var $version = '2.3.3'; var $params = []; var $success = false; var $error = true; @@ -40,8 +40,12 @@ class authorizenet_cim extends base var $testMode = false; var $solution = 'AAA183475'; - private $email; + // used for fraud prevention, put a limiter on the amount of time one can submit new credit cards; + // and after $logoff +1; send them to the account page. + private $delayTime = 60; + private $logOff = 3; + private $email; var $errorMessages = []; // zen-cart base payment functions @@ -592,7 +596,12 @@ function billtoAddress($response = null) $billto->setAddress($order->billing['street_address']); $billto->setCity($order->billing['city']); $billto->setState($order->billing['state']); - $billto->setZip($order->billing['postcode']); + $zip = $order->billing['postcode']; + if ($this->testMode) { + $zip = substr($order->billing['postcode'], 0, 5); +// $zip = '46208'; + } + $billto->setZip($zip); $billto->setCountry($order->billing['country']['title']); //$billto->setPhoneNumber(); //$billto->setfaxNumber(); @@ -650,6 +659,9 @@ function getAddressInfo() $return['city'] = $address->fields['entry_city']; $return['state'] = ((zen_not_null($address->fields['entry_state'])) ? $address->fields['entry_state'] : $address->fields['zone_name']); $return['postcode'] = $address->fields['entry_postcode']; + if ($this->testMode) { + $return['postcode'] = substr($address->fields['entry_postcode'], 0, 5); + } $return['country']['title'] = $address->fields['countries_name']; } } @@ -886,6 +898,25 @@ function setParameter($field = "", $value = null) $this->params[$field] = $value; } + private function checkEmailAddress(int $customerID, string $email) + { + global $db; + + $customerCheck = $db->Execute('select customers_email_address from ' . TABLE_CUSTOMERS . " WHERE customers_id = $customerID LIMIT 1"); + $error = false; + if ($customerCheck->EOF) { + $error = true; + } + if (!$error && $email !== $customerCheck->fields['customers_email_address']) { + $error = true; + } + if ($error) { + sleep(45); + trigger_error($customerID . ' was logged off and should be looked at!'); + zen_redirect(zen_href_link(FILENAME_LOGOFF, '', 'SSL', true, false)); + } + + } // functions that use the authorize API and return responses. function createCustomerProfileRequest() @@ -893,6 +924,9 @@ function createCustomerProfileRequest() global $customerID, $order; $customerID = $_SESSION['customer_id']; + $email = $order->customer['email_address'] ?? $_SESSION['customers_email_address']; + + $this->checkEmailAddress($customerID, $email); // Create a new CustomerProfileType and add the payment profile object $customerProfile = new AnetAPI\CustomerProfileType(); @@ -901,7 +935,7 @@ function createCustomerProfileRequest() if (!empty($this->email)) { $customerProfile->setEmail($this->email); } else { - $customerProfile->setEmail($order->customer['email_address'] ?? $_SESSION['customers_email_address']); + $customerProfile->setEmail($email); } //$customerProfile->setpaymentProfiles($paymentProfiles); //$customerProfile->setShipToList($shippingProfiles); @@ -943,13 +977,19 @@ function createCustomerProfileRequest() function createCustomerPaymentProfileRequest() { - global $order, $customerID; + global $order, $customerID, $messageStack; // for card_update - if (empty($customerID) && (!defined('IS_ADMIN_FLAG') || (IS_ADMIN_FLAG == 0))) { + if (empty($customerID) && (!IS_ADMIN_FLAG)) { $customerID = $_SESSION['customer_id']; } + if (!IS_ADMIN_FLAG) { +// $customerID = $_SESSION['customer_id']; + $email = $order->customer['email_address'] ?? $_SESSION['customers_email_address']; + $this->checkEmailAddress($customerID, $email); + } + if (!isset($this->params['customerProfileId']) || ($this->params['customerProfileId'] == 0)) { $customerProfileId = $this->getCustomerProfile($customerID); @@ -960,6 +1000,28 @@ function createCustomerPaymentProfileRequest() } } + + $currentTimeForTest = time(); + if (empty($_SESSION['createCard'])) { + $_SESSION['createCard'] = time(); + $_SESSION['logOff'] = 0; + $currentTimeForTest = time() + $this->delayTime + 3; + } + + $_SESSION['logOff'] ++; + if ($_SESSION['logOff'] > $this->logOff) { +// $messageStack->add_session(FILENAME_LOGOFF, 'Sorry, due to the increasing amount of fraud we are logging you off!', 'error'); + // once the session is destroyed, so is the messageStack! + trigger_error($customerID . ' was logged off and should be looked at!'); + zen_redirect(zen_href_link(FILENAME_LOGOFF, '', 'SSL', true, false)); + } + + if (($currentTimeForTest - $_SESSION['createCard']) < $this->delayTime) { + $messageStack->add_session(FILENAME_ACCOUNT, MODULE_PAYMENT_AUTHORIZENET_CIM_FRAUD_WARNING, 'error'); + zen_redirect(zen_href_link(FILENAME_ACCOUNT, '', 'SSL', true, false)); + } else { + $_SESSION['createCard'] = time(); + } // for card_update $exp_date = $this->convertExpDate($_POST['cc_year'] ?? '', $_POST['cc_month'] ?? ''); @@ -1173,7 +1235,7 @@ function chargeCustomerProfile($profileid, $paymentprofileid, $new_auth = false) if ($tresponse != null && $tresponse->getMessages() != null) { $error = false; $logData = "Transaction Response code : " . $tresponse->getResponseCode() . "\n"; - $logData .= " Charge Customer Profile APPROVED!" . "\n"; + $logData .= " Charge Customer Profile APPROVED :" . "\n"; $logData .= " Charge Customer Profile AUTH CODE : " . $tresponse->getAuthCode() . "\n"; $this->approvalCode = $tresponse->getAuthCode(); $logData .= " Charge Customer Profile TRANS ID : " . $tresponse->getTransId() . "\n"; @@ -1701,12 +1763,13 @@ function updateOrderAndPayment($customerID, $transID, $insertID, $approval, $sta $this->updateOrderInfo($insertID, $status, $initialAuthAmount); - $sql = "insert into " . TABLE_ORDERS_STATUS_HISTORY . " (comments, orders_id, orders_status_id, updated_by, date_added) values (:orderComments, :orderID, :orderStatus, :adminName, now() )"; +/* $sql = "insert into " . TABLE_ORDERS_STATUS_HISTORY . " (comments, orders_id, orders_status_id, updated_by, date_added) values (:orderComments, :orderID, :orderStatus, :adminName, now() )"; $sql = $db->bindVars($sql, ':orderComments', $comments, 'string'); $sql = $db->bindVars($sql, ':orderID', $insertID, 'integer'); $sql = $db->bindVars($sql, ':orderStatus', $status, 'integer'); $sql = $db->bindVars($sql, ':adminName', $this->cimUpdatedByAdminName(), 'string'); // $db->Execute($sql); +*/ zen_update_orders_history($insertID, $comments, $this->cimUpdatedByAdminName(), $status, -1); }