diff --git a/doc/readme_en_oscommerce.pdf b/doc/readme_en_oscommerce.pdf new file mode 100644 index 0000000..195dddc Binary files /dev/null and b/doc/readme_en_oscommerce.pdf differ diff --git a/doc/readme_ru_oscommerce.pdf b/doc/readme_ru_oscommerce.pdf new file mode 100644 index 0000000..4f475e6 Binary files /dev/null and b/doc/readme_ru_oscommerce.pdf differ diff --git a/doc/remove.mp4 b/doc/remove.mp4 new file mode 100644 index 0000000..e11bce2 Binary files /dev/null and b/doc/remove.mp4 differ diff --git a/doc/upload_and_deploy.mp4 b/doc/upload_and_deploy.mp4 new file mode 100644 index 0000000..4458e5b Binary files /dev/null and b/doc/upload_and_deploy.mp4 differ diff --git a/source/License.md b/source/License.md new file mode 100644 index 0000000..4979403 --- /dev/null +++ b/source/License.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 PaynetEasy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/source/README.md b/source/README.md new file mode 100644 index 0000000..3433208 --- /dev/null +++ b/source/README.md @@ -0,0 +1,70 @@ +# PaynetEasy Payment Module for OsCommerce v4 + +This is a Payment Module for OsCommerce v4, that gives you the ability to process payments through payment service providers running on PaynetEasy. + +## Requirements + + * OsCommerce v4 + * PHP Versions >= 7.0.0 ![GitHub](https://img.shields.io/badge/php-%3E%3D7.0.0-lightgrey) + +*Note:* this module has been tested only with OsCommerce v4+. + +## Installation (App Shop / Local Storage) + + * Upload ```plugin-oscommerce.zip``` to a ```App Shop / Local Storage``` + + * Click + sign in Action column to Install module from there. + +## Installation (Manual) + + * Unpack zip. + + * Navigate project folder ```lib\common\modules\orderPayment``` and upload unpack contents from ```plugin-oscommerce``` there. + + * Move file ```ot_payneteasy.php``` from ```lib\common\modules\orderPayment``` to ```lib\common\modules\orderTotal``` if installer doesn't move. + + * Move file ```StoredCards.php``` from ```lib\common\modules\orderPayment``` to ```lib\frontend\design\boxes\account``` if installer doesn't move. + + * Move file ```stored-cards.tpl``` from ```lib\common\modules\orderPayment``` to ```lib\frontend\themes\basic\boxes\account``` if installer doesn't move. + +## Deletion + + * Go to ```App Shop / Local Storage``` delete module from there + + * For Manual Navigate folder ```lib\common\modules\orderPayment``` delete payneteasy folder and file from there + + * Go to ```lib\common\modules\orderTotal``` delete ot_payneteasy.php from there. + + * Go to ```lib\frontend\design\boxes\account``` delete StoredCards.php from there. + + * Go to ```lib\frontend\themes\basic\boxes\account``` delete stored-cards.tpl from there. + + * Remove Stored Cards Block references from these tables TABLE_DESIGN_BOXES, TABLE_DESIGN_BOXES_SETTINGS, design_boxes_cache + TABLE_TRANSLATION + +## Configuration + + * Login inside the __Admin Panel__ and go to ```Modules``` -> ```Payment``` -> ```Online``` + * Check the Payment Module Panel ```PaynetEasy``` is visible in the list of installed Payment Method, + apply filter Show not installed, if for In-Active module use Show inactive filter. + * Click to ```PaynetEasy Payment Method``` and click the button ```Edit``` under the right side panel to expand the available settings + * Set ```Enable PaynetPos``` to ```Yes```, set the correct credentials, select your prefered payment method and additional settings and click ```Update``` + + #### Enable SurchargeFee + * Next go to ```Modules``` -> ```Order structure``` + * Check the Module ```SurchargeFee``` is visible in the list of not installed, install it. + * Click to ```SurchargeFee``` and click the button ```Edit``` under the right side panel to expand the available settings + * Set ```Display Surcharge Fee``` to ```Yes```, Sort Order and click ```Update``` + * Drag ```SurchargeFee``` above the Total Module so that surcharge fee if enable must be calculated under grand total. + +## Test data + +If you setup the module with default values, you can ask your payneteasy manager + +### Test card details + +Use the following test cards to make successful test payment: + + Test Card: + + * Visa - 4444555566661111- CVV 123 - non 3d secude approved 321 - 3d secure approved 777 - declined Expiry Date - 12/25 diff --git a/source/distribution.json b/source/distribution.json new file mode 100644 index 0000000..34e62ea --- /dev/null +++ b/source/distribution.json @@ -0,0 +1,35 @@ +{ + "name": "PaynetEasy", + "description": "This is a Payment Module for Oscommerce, that gives you the ability to process payments through payment service providers running on PaynetEasy.", + "type": "payment", + "version": "2.0.0", + "authors": [ + { + "name": "Payneasy.com", + "email": "info@payneteasy.com", + "homepage": "https://payneteasy.com/", + "role": "Owner" + } + ], + "src": [ + { + "action": "add", + "type": "file", + "path": "payneteasy.php" + }, + { + "action": "add", + "type": "file", + "path": "ot_payneteasy.php" + }, + { + "action": "copy", + "type": "dir", + "path": "payneteasy" + } + ], + "require": { + "platform": "True" + }, + "class": "payneteasy" +} \ No newline at end of file diff --git a/source/ot_payneteasy.php b/source/ot_payneteasy.php new file mode 100644 index 0000000..4901961 --- /dev/null +++ b/source/ot_payneteasy.php @@ -0,0 +1,83 @@ +code = 'ot_payneteasy'; + $this->title = ''; + if (!defined('MODULE_ORDER_TOTAL_PAYNETEASY_STATUS')) { + $this->enabled = false; + return false; + } + $this->enabled = ((MODULE_ORDER_TOTAL_PAYNETEASY_STATUS == 'true') ? true : false); + $this->sort_order = MODULE_ORDER_TOTAL_PAYNETEASY_SORT_ORDER; + + $this->output = array(); + } + + function process($replacing_value = -1) { + $module = $this->manager->getPayment(); + + $this->output = []; + + if( MODULE_PAYMENT_PAYNETEASY_STATUS == 'True' && $module == "payneteasy" ) { + + $order = $this->manager->getOrderInstance(); + \common\helpers\Php8::nullArrProps($order->info, ['total_paid_exc_tax', 'total_paid_inc_tax', 'currency', 'currency_value']); + $currencies = \Yii::$container->get('currencies'); + $this->output = []; + } + } + + public function describe_status_key() { + return new ModuleStatus('MODULE_ORDER_TOTAL_PAYNETEASY_STATUS', 'true', 'false'); + } + + public function describe_sort_key() { + return new ModuleSortOrder('MODULE_ORDER_TOTAL_PAYNETEASY_SORT_ORDER'); + } + + public function configure_keys() { + return array( + 'MODULE_ORDER_TOTAL_PAYNETEASY_STATUS' => + array( + 'value' => 'true', + 'sort_order' => '1', + 'set_function' => 'tep_cfg_select_option(array(\'true\', \'false\'), ', + ), + 'MODULE_ORDER_TOTAL_PAYNETEASY_SORT_ORDER' => + array( + 'title' => 'Sort Order', + 'value' => '90', + 'description' => 'Sort order of display.', + 'sort_order' => '2', + ), + ); + } + +} diff --git a/source/payneteasy.php b/source/payneteasy.php new file mode 100644 index 0000000..2536516 --- /dev/null +++ b/source/payneteasy.php @@ -0,0 +1,842 @@ + 'PaynetEasy', + 'MODULE_PAYMENT_PAYNETEASY_TEXT_DESCRIPTION' => 'The PaynetEasy Payment Gateway enables merchants to accept credit card online during checkout.', + 'MODULE_PAYMENT_PAYNETEASY_ERROR' => 'There has been an error processing your credit card', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_JANUARY' => 'January', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_FEBRUARY' => 'February', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_MARCH' => 'March', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_APRIL' => 'April', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_MAY' => 'May', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_JUNE' => 'June', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_JULY' => 'July', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_AUGUST' => 'August', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_SEPTEMBER' => 'September', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_OCTOBER' => 'October', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_NOVEMBER' => 'November', + 'MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_DECEMBER' => 'December', + 'MODULE_PAYMENT_PAYNETEASY_RESPONSE_TEXT' => 'PaynetEasy payment completed for %1$s.%2$s Transaction ID: %3$s.%4$s Approval Code: %5$s.%6$s RRN: %7$s', + ]; + + /** + * class constructor + */ + function __construct($order_id = -1) { + parent::__construct(); + + $this->code = 'payneteasy'; + $this->title = MODULE_PAYMENT_PAYNETEASY_TEXT_TITLE; + $this->description = MODULE_PAYMENT_PAYNETEASY_TEXT_DESCRIPTION; + if (!defined('MODULE_PAYMENT_PAYNETEASY_STATUS')) { + $this->enabled = false; + return false; + } + + $this->sort_order = MODULE_PAYMENT_PAYNETEASY_SORT_ORDER; + $this->enabled = ((MODULE_PAYMENT_PAYNETEASY_STATUS == 'True') ? true : false); + $this->order_id = $order_id; + $this->order_status = MODULE_PAYMENT_PAYNETEASY_ORDER_STATUS_ID; + $this->paid_status = 0; + + //remove keys if validate key false in last submit + if( defined('MODULE_PAYMENT_PAYNETEASY_VALIDATEKEY') && MODULE_PAYMENT_PAYNETEASY_VALIDATEKEY == "No" ) { + tep_db_query("UPDATE ".TABLE_PLATFORMS_CONFIGURATION." SET configuration_value='' WHERE configuration_key='MODULE_PAYMENT_PAYNETEASY_ENDPOINT_ID' AND platform_id='".(int)$platform_id."'"); + tep_db_query("UPDATE ".TABLE_PLATFORMS_CONFIGURATION." SET configuration_value='' WHERE configuration_key='MODULE_PAYMENT_PAYNETEASY_CONTROL_KEY' AND platform_id='".(int)$platform_id."'"); + tep_db_query("UPDATE ".TABLE_PLATFORMS_CONFIGURATION." SET configuration_value='' WHERE configuration_key='MODULE_PAYMENT_PAYNETEASY_LOGIN' AND platform_id='".(int)$platform_id."'"); + tep_db_query("UPDATE ".TABLE_PLATFORMS_CONFIGURATION." SET configuration_value='' WHERE configuration_key='MODULE_PAYMENT_PAYNETEASY_AUTHTOKEN' AND platform_id='".(int)$platform_id."'"); + } + + if( $this->manager ) { + $platform_id = $this->manager->getPlatformId(); + $return_url = \Yii::$app->urlManager->createUrl('payneteasy/return-payment'); + $refund_url = \Yii::$app->urlManager->createUrl('payneteasy/refund-payment'); + $balancepayment_url = \Yii::$app->urlManager->createUrl('payneteasy/balance-payment'); + $opyID = \Yii::$app->request->get('opyID'); + $script = 'var payneteasy = { + platform_id : '.$platform_id.', + return_url : "'.$return_url.'", + refund_url : "'.$refund_url.'", + balancepayment_url : "'.$balancepayment_url.'", + opyID : "'.$opyID.'" + };'; + \Yii::$app->getView()->registerJs($script); + } + + if ($this->checkView() == "admin") { + $adminrefund = tep_catalog_href_link('lib/common/modules/orderPayment/payneteasy/js/adminrefund.js'); + $adminrefundcss = tep_catalog_href_link('lib/common/modules/orderPayment/payneteasy/css/adminrefund.css'); + \Yii::$app->getView()->registerJsFile($adminrefund); + \Yii::$app->getView()->registerCssFile($adminrefundcss); + } else { + $branddetection = tep_href_link('lib/common/modules/orderPayment/payneteasy/js/BrandDetection.js'); + $creditcard = tep_href_link('lib/common/modules/orderPayment/payneteasy/js/creditcard.js'); + $cc = tep_href_link('lib/common/modules/orderPayment/payneteasy/js/cc.js'); + $payneteasycss = tep_href_link('lib/common/modules/orderPayment/payneteasy/css/payneteasy.css'); + \Yii::$app->getView()->registerJsFile($branddetection); + \Yii::$app->getView()->registerJsFile($creditcard); + \Yii::$app->getView()->registerJsFile($cc); + \Yii::$app->getView()->registerCssFile($payneteasycss); + } + $this->update_status(); + } + + function getScriptName() { + global $PHP_SELF; + if (class_exists('\Yii') && is_object(\Yii::$app)) { + return \Yii::$app->controller->id; + } else { + return basename($PHP_SELF); + } + } + + function checkView() { + $view = "admin"; + if (tep_session_name() != 'tlAdminID') { + if ($this->getScriptName() == 'checkout' /* FILENAME_CHECKOUT_PAYMENT */) { + $view = "checkout"; + } else { + $view = "frontend"; + } + } + return $view; + } + + function update_status() { + if (($this->enabled == true) && ((int) MODULE_PAYMENT_PAYNETEASY_ZONE > 0)) { + $check_flag = false; + $check_query = tep_db_query("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_PAYMENT_PAYNETEASY_ZONE . "' and zone_country_id = '" . $this->billing['country']['id'] . "' order by zone_id"); + while ($check = tep_db_fetch_array($check_query)) { + if ($check['zone_id'] < 1) { + $check_flag = true; + break; + } elseif ($check['zone_id'] == $this->billing['zone_id']) { + $check_flag = true; + break; + } + } + + if ($check_flag == false) { + $this->enabled = false; + } + } + } + + function selection() { + + //if store currency not euro then ignore payneteasy payment gateway + $transaction_currency = \Yii::$app->settings->get('currency'); + if (strtolower($transaction_currency) != "eur") { + $this->enabled = false; + return false; + } + + $months_array = array(); + $months_array[0] = array('', 'Month'); + $months_array[1] = array('01', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_JANUARY); + $months_array[2] = array('02', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_FEBRUARY); + $months_array[3] = array('03', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_MARCH); + $months_array[4] = array('04', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_APRIL); + $months_array[5] = array('05', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_MAY); + $months_array[6] = array('06', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_JUNE); + $months_array[7] = array('07', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_JULY); + $months_array[8] = array('08', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_AUGUST); + $months_array[9] = array('09', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_SEPTEMBER); + $months_array[10] = array('10', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_OCTOBER); + $months_array[11] = array('11', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_NOVEMBER); + $months_array[12] = array('12', MODULE_PAYMENT_PAYNETEASY_CC_TEXT_MONTH_DECEMBER); + + $today = getdate(); + $years_array = array(); + $years_array[] = array('','Year'); + + for ($i = $today['year']; $i < $today['year'] + 10; $i++) { + $years_array[$i] = array(strftime('%Y', mktime(0, 0, 0, 1, 1, $i)), + strftime('%Y', mktime(0, 0, 0, 1, 1, $i))); + } + + if( strstr(MODULE_PAYMENT_PAYNETEASY_ACCEPTED_CARDS,'American Express') ) { + $amex = tep_href_link('lib/common/modules/orderPayment/payneteasy/images/amex.png'); + $logos .= ''; + } + if( strstr(MODULE_PAYMENT_PAYNETEASY_ACCEPTED_CARDS,'Visa') ) { + $visa = tep_href_link('lib/common/modules/orderPayment/payneteasy/images/visa.png'); + $logos .= ''; + } + if( strstr(MODULE_PAYMENT_PAYNETEASY_ACCEPTED_CARDS,'MasterCard') ) { + $mastercard = tep_href_link('lib/common/modules/orderPayment/payneteasy/images/mastercard.png'); + $logos .= ''; + } + if( strstr(MODULE_PAYMENT_PAYNETEASY_ACCEPTED_CARDS,'Discover') ) { + $discover = tep_href_link('lib/common/modules/orderPayment/payneteasy/images/discover.png'); + $logos .= ''; + } + if( strstr(MODULE_PAYMENT_PAYNETEASY_ACCEPTED_CARDS,'JCB') ) { + $jcb = tep_href_link('lib/common/modules/orderPayment/payneteasy/images/jcb.png'); + $logos .= ''; + } + if( strstr(MODULE_PAYMENT_PAYNETEASY_ACCEPTED_CARDS,'Diners') ) { + $diners = tep_href_link('lib/common/modules/orderPayment/payneteasy/images/diners.png'); + $logos .= ''; + } + + if ($this->checkView() == "admin") { + $paynetlogo = tep_catalog_href_link('lib/common/modules/orderPayment/payneteasy/logo/PaynetLogo.svg'); + } else { + $paynetlogo = tep_href_link('lib/common/modules/orderPayment/payneteasy/logo/PaynetLogo.svg'); + } + + $billing_address = $this->manager->getBillingAddress(); + + $customer_id = \Yii::$app->user->getId(); + + $script = ''; + + return array('id' => $this->code, + 'module' => (MODULE_PAYMENT_PAYNETEASY_SHOWLOGO=='Yes'?'':MODULE_PAYMENT_PAYNETEASY_FRONT_TITLE).$script + ); + + } + + public function install($platform_id) { + $languages_id = \common\classes\language::get_id(DEFAULT_LANGUAGE); + + $get_current_status_id = tep_db_fetch_array(tep_db_query( + "SELECT MAX(orders_status_id) AS current_max_id FROM ".TABLE_ORDERS_STATUS." " + )); + $new_status_id = intval($get_current_status_id['current_max_id'])+1; + + //check refunded order status if exist get id or insert then get id + $order_status_query = tep_db_query("SELECT orders_status_id FROM " . TABLE_ORDERS_STATUS . " WHERE orders_status_name = 'Refunded' AND language_id = '" . $languages_id . "'"); + if ( tep_db_num_rows($order_status_query) <= 0 ) { + tep_db_query( + "INSERT INTO ".TABLE_ORDERS_STATUS." (orders_status_id, orders_status_groups_id, language_id, orders_status_name, + orders_status_template, automated, orders_status_template_confirm, orders_status_template_sms, + order_evaluation_state_id, order_evaluation_state_default, orders_status_allocate_allow, + orders_status_release_deferred, orders_status_send_ga, comment_template_id, hidden) + VALUES (".$new_status_id.", 5, ".$languages_id.", 'Refunded', 'Order Status Update', 0, 'Order Status Update', '', 60, 0, 1, 0, -1, 0, 0)" + ); + } + + //check partial refunded order status if exist get id or insert then get id + $order_status_query = tep_db_query("SELECT orders_status_id FROM " . TABLE_ORDERS_STATUS . " WHERE orders_status_name = 'Partially refunded' AND language_id = '" . $languages_id . "'"); + if ( tep_db_num_rows($order_status_query) <= 0 ) { + tep_db_query( + "INSERT INTO ".TABLE_ORDERS_STATUS." (orders_status_id, orders_status_groups_id, language_id, orders_status_name, + orders_status_template, automated, orders_status_template_confirm, orders_status_template_sms, + order_evaluation_state_id, order_evaluation_state_default, orders_status_allocate_allow, + orders_status_release_deferred, orders_status_send_ga, comment_template_id, hidden) + VALUES (".$new_status_id.", 2, ".$languages_id.", 'Partially refunded', 'Order Status Update', 0, 'Order Status Update', '', 60, 0, 1, 0, -1, 0, 0)" + ); + } + + tep_db_query("CREATE TABLE `payneteasy_payments` (`paynet_order_id` int(11) NOT NULL, `merchant_order_id` int(11) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;"); + + //copy ot_payneteasy.php file to orderTotal module + if( file_exists(__DIR__."/ot_payneteasy.php") && copy(__DIR__."/ot_payneteasy.php",__DIR__."/../orderTotal/ot_payneteasy.php") ) { + unlink(__DIR__."/ot_payneteasy.php"); + } + + //check if table already exist or create new + $install_query = tep_db_query("Show tables like 'payneteasy_vault'"); + if ( tep_db_num_rows($install_query) <= 0 ) { + + tep_db_query("CREATE TABLE `payneteasy_vault` (`customer_id` int(11) NOT NULL, `vault_customer_id` int(11) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;"); + + tep_db_query("ALTER TABLE `payneteasy_vault` ADD PRIMARY KEY (`customer_id`,`vault_customer_id`);"); + + } + + parent::install($platform_id); + + } + + function process_button() { + return false; + } + + function _post_transaction() + { + + } + + function _start_transaction($order) + { + $billing = $order->billing; + $shipping = $order->delivery; + $customer = $order->customer; + + $payneteasy_card_number = $this->manager->get('payneteasy-card-number'); + $payneteasy_card_expiry_month = $this->manager->get('payneteasy-card-expiry-month'); + $payneteasy_card_expiry_year = $this->manager->get('payneteasy-card-expiry-year'); + $payneteasy_card_name = $this->manager->get('payneteasy-card-name'); + $payneteasy_card_cvv = $this->manager->get('payneteasy-card-cvv'); + $payneteasy_card_address = $this->manager->get('payneteasy-card-address'); + $payneteasy_card_zip = $this->manager->get('payneteasy-card-zip'); + $payneteasy_remote_address = $this->manager->get('payneteasy-remote-address'); + + $card_data = [ + 'credit_card_number' => $payneteasy_card_number?:'', + 'card_printed_name' => $payneteasy_card_name?:'', + 'expire_month' => $payneteasy_card_expiry_month?:'', + 'expire_year' => $payneteasy_card_expiry_year?:'', + 'cvv2' => $payneteasy_card_cvv?:'', + ]; + + $data = [ + 'client_orderid' => (string)$order->order_id, + 'order_desc' => 'Order # ' . $order->order_id, + 'amount' => $this->formatCurrencyRaw($order->info['total_inc_tax'], $order->info['currency']), + 'currency' => trim($order->info['currency'])?:'', + 'address1' => $payneteasy_card_address?:$billing["street_address"], + 'city' => $billing["city"]?:$shipping["city"], + 'zip_code' => $payneteasy_card_zip?:$billing["postcode"], + 'country' => $billing["country"]["iso_code_2"]?:$shipping["country"]["iso_code_2"], + 'phone' => $billing["telephone"]?:$shipping["telephone"], + 'email' => $customer["email_address"], + 'ipaddress' => $_SERVER['REMOTE_ADDR'], + 'cvv2' => $card_data['cvv2'], + 'credit_card_number' => $card_data['credit_card_number'], + 'card_printed_name' => $card_data['card_printed_name'], + 'expire_month' => $card_data['expire_month'], + 'expire_year' => $card_data['expire_year'], + 'first_name' => $customer['first_name'], + 'last_name' => $customer['last_name'], +// 'redirect_success_url' => HTTP_SERVER.'/checkout/success?order_id='.$order->order_id, + 'redirect_success_url' => tep_href_link('callback/webhooks.payment.' . $this->code, 'action=success&orders_id=' . $order->order_id, 'SSL'), +// 'redirect_fail_url' => HTTP_SERVER.'/checkout?payment_error=PaynetEasy&order_id='.$order->order_id, + 'redirect_fail_url' => tep_href_link('callback/webhooks.payment.' . $this->code, 'action=error&orders_id=' . $order->order_id, 'SSL'), +// 'redirect_url' => HTTP_SERVER.'/checkout/success?order_id='.$order->order_id, + 'redirect_url' => tep_href_link('callback/webhooks.payment.' . $this->code, 'action=success&orders_id=' . $order->order_id, 'SSL'), + 'server_callback_url' => tep_href_link('callback/webhooks.payment.' . $this->code, 'action=success&orders_id=' . $order->order_id, 'SSL'), + ]; + + $payment_payneteasy_endpoint_id = MODULE_PAYMENT_PAYNETEASY_ENDPOINT_ID; + + $payment_payneteasy_control_key = MODULE_PAYMENT_PAYNETEASY_CONTROL_KEY; + + $data['control'] = $this->signPaymentRequest($data, $payment_payneteasy_endpoint_id, $payment_payneteasy_control_key); + + $sandbox = MODULE_PAYMENT_PAYNETEASY_SANDBOX; + $action_url = MODULE_PAYMENT_PAYNETEASY_LIVE_URL; + + if ($sandbox == 'Yes') + $sandbox = true; + else + $sandbox = false; + + if ($sandbox) + $action_url = MODULE_PAYMENT_PAYNETEASY_SANDBOX_URL; + + $payment_payneteasy_payment_method = MODULE_PAYMENT_PAYNETEASY_PAYMENT_METHOD; + $payment_payneteasy_endpoint_id = MODULE_PAYMENT_PAYNETEASY_ENDPOINT_ID; + + $paynetApi = new PaynetApi( + MODULE_PAYMENT_PAYNETEASY_LOGIN, + MODULE_PAYMENT_PAYNETEASY_CONTROL_KEY, + $payment_payneteasy_endpoint_id, + $payment_payneteasy_payment_method, + $sandbox + ); + + if ($payment_payneteasy_payment_method == 'Form') { + $response = $paynetApi->saleForm( + $data, + $payment_payneteasy_payment_method, + $sandbox, + $action_url, + $payment_payneteasy_endpoint_id + ); + } elseif ($payment_payneteasy_payment_method == 'Direct') { + $response = $paynetApi->saleDirect( + $data, + $payment_payneteasy_payment_method, + $sandbox, + $action_url, + $payment_payneteasy_endpoint_id + ); + } + + tep_db_query( + "INSERT INTO payneteasy_payments (paynet_order_id, merchant_order_id) + VALUES (".$response['paynet-order-id'].", ".$response['merchant-order-id'].")" + ); + return $response; + } + + function _save_order() { + global $languages_id; + + if (!empty($this->order_id) && $this->order_id > 0) { + return; + } + + $order = $this->manager->getOrderInstance(); + + $order->save_order(); + + $order->save_details(); + + $order->save_products(false); + + $stock_updated = false; + + $this->order_id = $order->order_id; + } + + function before_process() + { + return false; + } + + function after_process() + { + $order = $this->manager->getOrderInstance(); + $response = $this->_start_transaction($order); + $status = $this->getPaymentStatus($order); + $reset_cart = false; + if (trim($status['status']) == 'processing') { + if (MODULE_PAYMENT_PAYNETEASY_PAYMENT_METHOD == 'Form') { + tep_redirect($response['redirect-url']); + } elseif (MODULE_PAYMENT_PAYNETEASY_PAYMENT_METHOD == 'Direct') { + if (MODULE_PAYMENT_PAYNETEASY_THREE_D_SECURE == 'Yes') { + print $status['html']; + } + } + } elseif (trim($status['status']) == 'approved' || $status['status'] == 'approved') { + $reset_cart = true; + $orderPayment = new \common\models\OrdersPayment(); + $orderPayment->orders_payment_module = $this->code; + $orderPayment->orders_payment_module_name = $this->title; + $orderPayment->orders_payment_transaction_id = $status['paynet-order-id']; + $orderPayment->orders_payment_id_parent = 0; + $orderPayment->orders_payment_order_id = $order->order_id; + $orderPayment->orders_payment_is_credit = 0; + $orderPayment->orders_payment_status = \common\helpers\OrderPayment::OPYS_SUCCESSFUL; + $orderPayment->orders_payment_amount = $this->formatCurrencyRaw($order->info['total_inc_tax'], $order->info['currency']); + $orderPayment->orders_payment_currency = trim($order->info['currency']); + $orderPayment->orders_payment_currency_rate = (float) $order->info['currency_value']; + $orderPayment->orders_payment_snapshot = json_encode(\common\helpers\OrderPayment::getOrderPaymentSnapshot($order)); + $orderPayment->orders_payment_transaction_status = 'OK'; + $orderPayment->orders_payment_transaction_commentary = ''; + $orderPayment->orders_payment_date_create = date('Y-m-d H:i:s'); + $orderPayment->orders_payment_transaction_full = json_encode($response); + $orderPayment->save(); + \common\helpers\Order::setStatus($order->order_id, 100006, [ + 'comments' => '', + 'customer_notified' => 0, + ]); + } elseif (trim($status['status']) == 'error' || $status['status'] == 'error') { + $reset_cart = true; + $orderPayment = new \common\models\OrdersPayment(); + $orderPayment->orders_payment_module = $this->code; + $orderPayment->orders_payment_module_name = $this->title; + $orderPayment->orders_payment_transaction_id = $status['paynet-order-id']; + $orderPayment->orders_payment_id_parent = 0; + $orderPayment->orders_payment_order_id = $order->order_id; + $orderPayment->orders_payment_is_credit = 0; + $orderPayment->orders_payment_status = \common\helpers\OrderPayment::OPYS_CANCELLED; + $orderPayment->orders_payment_amount = $this->formatCurrencyRaw($order->info['total_inc_tax'], $order->info['currency']); + $orderPayment->orders_payment_currency = trim($order->info['currency']); + $orderPayment->orders_payment_currency_rate = (float) $order->info['currency_value']; + $orderPayment->orders_payment_snapshot = json_encode(\common\helpers\OrderPayment::getOrderPaymentSnapshot($order)); + $orderPayment->orders_payment_transaction_status = ''; + $orderPayment->orders_payment_transaction_commentary = ''; + $orderPayment->orders_payment_date_create = date('Y-m-d H:i:s'); + $orderPayment->orders_payment_transaction_full = json_encode($status); + $orderPayment->save(); + \common\helpers\Order::setStatus($order->order_id, 5, [ + 'comments' => '', + 'customer_notified' => 0, + ]); + $error_url = tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'payment_error=' . $this->code . (tep_not_null($status['error-message']) ? '&error=' . $status['error-message'] : '') . '&' . tep_session_name() . '=' . tep_session_id(), 'SSL', false); + tep_redirect(tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'error_message=' . urlencode($result['data']['message']), 'SSL')); + tep_redirect($error_url); + } elseif (trim($status['status']) == 'declined') { + $reset_cart = true; + $orderPayment = new \common\models\OrdersPayment(); + $orderPayment->orders_payment_module = $this->code; + $orderPayment->orders_payment_module_name = $this->title; + $orderPayment->orders_payment_transaction_id = $status['paynet-order-id']; + $orderPayment->orders_payment_id_parent = 0; + $orderPayment->orders_payment_order_id = $order->order_id; + $orderPayment->orders_payment_is_credit = 0; + $orderPayment->orders_payment_status = \common\helpers\OrderPayment::OPYS_CANCELLED; + $orderPayment->orders_payment_amount = $this->formatCurrencyRaw($order->info['total_inc_tax'], $order->info['currency']); + $orderPayment->orders_payment_currency = trim($order->info['currency']); + $orderPayment->orders_payment_currency_rate = (float) $order->info['currency_value']; + $orderPayment->orders_payment_snapshot = json_encode(\common\helpers\OrderPayment::getOrderPaymentSnapshot($order)); + $orderPayment->orders_payment_transaction_status = ''; + $orderPayment->orders_payment_transaction_commentary = ''; + $orderPayment->orders_payment_date_create = date('Y-m-d H:i:s'); + $orderPayment->orders_payment_transaction_full = json_encode($status); + $orderPayment->save(); + \common\helpers\Order::setStatus($order->order_id, 5, [ + 'comments' => '', + 'customer_notified' => 0, + ]); + $error_url = tep_href_link(FILENAME_CHECKOUT_PAYMENT, 'payment_error=' . $this->code . (tep_not_null($status['error-message']) ? '&error=' . $status['error-message'] : '') . '&' . tep_session_name() . '=' . tep_session_id(), 'SSL', false); + tep_redirect($error_url); + } + if ($reset_cart) { + tep_db_query("DELETE FROM " . TABLE_CUSTOMERS_BASKET . " WHERE customers_id = '" . (int) $order->customer['id'] . "'"); + tep_db_query("DELETE FROM " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " WHERE customers_id = '" . (int) $order->customer['id'] . "'"); + } + } + + public function call_webhooks() { + $order = $this->manager->getOrderInstanceWithId('\common\classes\Order', (int)$_POST['merchant_order']); + $status = $this->getPaymentStatus($order); + if (trim($status['status']) == 'approved' || $status['status'] == 'approved') { + $orderPayment = new \common\models\OrdersPayment(); + $orderPayment->orders_payment_module = $this->code; + $orderPayment->orders_payment_module_name = $this->title; + $orderPayment->orders_payment_transaction_id = $status['paynet-order-id']; + $orderPayment->orders_payment_id_parent = 0; + $orderPayment->orders_payment_order_id = $order->order_id; + $orderPayment->orders_payment_is_credit = 0; + $orderPayment->orders_payment_status = \common\helpers\OrderPayment::OPYS_SUCCESSFUL; + $orderPayment->orders_payment_amount = $this->formatCurrencyRaw($order->info['total_inc_tax'], $order->info['currency']); + $orderPayment->orders_payment_currency = trim($order->info['currency']); + $orderPayment->orders_payment_currency_rate = (float) $order->info['currency_value']; + $orderPayment->orders_payment_snapshot = json_encode(\common\helpers\OrderPayment::getOrderPaymentSnapshot($order)); + $orderPayment->orders_payment_transaction_status = 'OK'; + $orderPayment->orders_payment_transaction_commentary = ''; + $orderPayment->orders_payment_date_create = date('Y-m-d H:i:s'); + $orderPayment->orders_payment_transaction_full = json_encode($status); + $orderPayment->save(); + \common\helpers\Order::setStatus($order->order_id, 100006, [ + 'comments' => '', + 'customer_notified' => 0, + ]); + tep_db_query("DELETE FROM " . TABLE_CUSTOMERS_BASKET . " WHERE customers_id = '" . (int) $order->customer['id'] . "'"); + tep_db_query("DELETE FROM " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " WHERE customers_id = '" . (int) $order->customer['id'] . "'"); + + tep_redirect(HTTP_SERVER.'/checkout/success?order_id='.$order->order_id); + } elseif (trim($status['status']) == 'error' || $status['status'] == 'error') { + $orderPayment = new \common\models\OrdersPayment(); + $orderPayment->orders_payment_module = $this->code; + $orderPayment->orders_payment_module_name = $this->title; + $orderPayment->orders_payment_transaction_id = $status['paynet-order-id']; + $orderPayment->orders_payment_id_parent = 0; + $orderPayment->orders_payment_order_id = $order->order_id; + $orderPayment->orders_payment_is_credit = 0; + $orderPayment->orders_payment_status = \common\helpers\OrderPayment::OPYS_CANCELLED; + $orderPayment->orders_payment_amount = $this->formatCurrencyRaw($order->info['total_inc_tax'], $order->info['currency']); + $orderPayment->orders_payment_currency = trim($order->info['currency']); + $orderPayment->orders_payment_currency_rate = (float) $order->info['currency_value']; + $orderPayment->orders_payment_snapshot = json_encode(\common\helpers\OrderPayment::getOrderPaymentSnapshot($order)); + $orderPayment->orders_payment_transaction_status = ''; + $orderPayment->orders_payment_transaction_commentary = ''; + $orderPayment->orders_payment_date_create = date('Y-m-d H:i:s'); + $orderPayment->orders_payment_transaction_full = json_encode($status); + $orderPayment->save(); + \common\helpers\Order::setStatus($order->order_id, 5, [ + 'comments' => '', + 'customer_notified' => 0, + ]); + echo '
'; + echo '

Error:

'; + echo $status['error-message']; + echo '

Return on homepage

'; + echo '
'; + tep_db_query("DELETE FROM " . TABLE_CUSTOMERS_BASKET . " WHERE customers_id = '" . (int) $order->customer['id'] . "'"); + tep_db_query("DELETE FROM " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " WHERE customers_id = '" . (int) $order->customer['id'] . "'"); + } elseif (trim($status['status']) == 'declined') { + $orderPayment = new \common\models\OrdersPayment(); + $orderPayment->orders_payment_module = $this->code; + $orderPayment->orders_payment_module_name = $this->title; + $orderPayment->orders_payment_transaction_id = $status['paynet-order-id']; + $orderPayment->orders_payment_id_parent = 0; + $orderPayment->orders_payment_order_id = $order->order_id; + $orderPayment->orders_payment_is_credit = 0; + $orderPayment->orders_payment_status = \common\helpers\OrderPayment::OPYS_CANCELLED; + $orderPayment->orders_payment_amount = $this->formatCurrencyRaw($order->info['total_inc_tax'], $order->info['currency']); + $orderPayment->orders_payment_currency = trim($order->info['currency']); + $orderPayment->orders_payment_currency_rate = (float) $order->info['currency_value']; + $orderPayment->orders_payment_snapshot = json_encode(\common\helpers\OrderPayment::getOrderPaymentSnapshot($order)); + $orderPayment->orders_payment_transaction_status = ''; + $orderPayment->orders_payment_transaction_commentary = ''; + $orderPayment->orders_payment_date_create = date('Y-m-d H:i:s'); + $orderPayment->orders_payment_transaction_full = json_encode($status); + $orderPayment->save(); + \common\helpers\Order::setStatus($order->order_id, 5, [ + 'comments' => '', + 'customer_notified' => 0, + ]); + echo '
'; + echo '

Your payment was declined

'; + echo $status['error-message']; + echo '

Return on homepage

'; + echo '
'; + tep_db_query("DELETE FROM " . TABLE_CUSTOMERS_BASKET . " WHERE customers_id = '" . (int) $order->customer['id'] . "'"); + tep_db_query("DELETE FROM " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " WHERE customers_id = '" . (int) $order->customer['id'] . "'"); + } + } + + function get_error() + { + $error = array('title' => 'Payment error', + 'error' => stripslashes(urldecode($_GET['error']))); + return $error; + } + + function pre_confirmation_check() + { + $payneteasy_card_number = $_POST['payneteasy-card-number']; + $payneteasy_card_number = str_replace(' ','',$payneteasy_card_number); + $payneteasy_card_expiry_month = $_POST['payneteasy-card-expiry-month']; + $payneteasy_card_expiry_year = $_POST['payneteasy-card-expiry-year']; + $payneteasy_card_name = $_POST['payneteasy-card-name']; + $payneteasy_card_cvv = $_POST['payneteasy-card-cvv']; + $payneteasy_card_address = $_POST['payneteasy-card-address']; + $payneteasy_card_zip = $_POST['payneteasy-card-zip']; + + $this->manager->set('payneteasy-card-number', $payneteasy_card_number); + $this->manager->set('payneteasy-card-expiry-month', $payneteasy_card_expiry_month); + $this->manager->set('payneteasy-card-expiry-year', $payneteasy_card_expiry_year); + $this->manager->set('payneteasy-card-name', $payneteasy_card_name); + $this->manager->set('payneteasy-card-cvv', $payneteasy_card_cvv); + $this->manager->set('payneteasy-card-address', $payneteasy_card_address); + $this->manager->set('payneteasy-card-zip', $payneteasy_card_zip); + $this->manager->set('payneteasy-remote-address', $_SERVER['REMOTE_ADDR']); + } + + function formatCurrencyRaw($total, $currency_code = null, $currency_value = null) { + + if (!isset($currency_code)) { + $currency_code = DEFAULT_CURRENCY; + } + + if (!isset($currency_value) || !is_numeric($currency_value)) { + $currencies = \Yii::$container->get('currencies'); + $currency_value = $currencies->currencies[$currency_code]['value']; + } + + return number_format(self::round($total * $currency_value, $currencies->currencies[$currency_code]['decimal_places']), $currencies->currencies[$currency_code]['decimal_places'], '.', ''); + } + + + function isOnline() { + return true; + } + + public function configure_keys() { + return array( + 'MODULE_PAYMENT_PAYNETEASY_STATUS' => array( + 'title' => 'Enable PaynetPos', + 'value' => 'True', + 'description' => 'Do you want to accept PaynetEasy payments?', + 'sort_order' => '1', + 'set_function' => 'tep_cfg_select_option(array(\'True\', \'False\'), ', + ), + 'MODULE_PAYMENT_PAYNETEASY_FRONT_TITLE' => array( + 'title' => 'Title', + 'value' => '', + 'description' => 'PaynetEasy APP Checkout Title', + 'sort_order' => '2', + ), + 'MODULE_PAYMENT_PAYNETEASY_SANDBOX_URL' => array( + 'title' => 'Gateway url (SANDBOX)', + 'value' => '', + 'description' => 'https://sandbox.payneteasy.com/ etc.', + 'sort_order' => '3', + ), + 'MODULE_PAYMENT_PAYNETEASY_LIVE_URL' => array( + 'title' => 'Gateway url (LIVE)', + 'value' => '', + 'description' => 'https://gate.payneteasy.com/ etc.', + 'sort_order' => '4', + ), + 'MODULE_PAYMENT_PAYNETEASY_THREE_D_SECURE' => array( + 'title' => '3D Secure', + 'value' => 'No', + 'description' => '3D Secure or Non 3D Secure (WORK ONLY WITH DIRECT INTEGRATION METHOD).', + 'sort_order' => '5', + 'set_function' => 'multiOption(\'dropdown\', array(\'Yes\', \'No\'), ', + ), + 'MODULE_PAYMENT_PAYNETEASY_ENDPOINT_ID' => array( + 'title' => 'Endpoint ID', + 'value' => '', + 'description' => 'Merchant ENDPOINT ID is required to call the API', + 'sort_order' => '6', + ), + 'MODULE_PAYMENT_PAYNETEASY_CONTROL_KEY' => array( + 'title' => 'Control Key', + 'value' => '', + 'description' => 'Merchant Control Key is required to call the API', + 'sort_order' => '7', + ), + 'MODULE_PAYMENT_PAYNETEASY_LOGIN' => array( + 'title' => 'Login', + 'value' => '', + 'description' => 'Request header used by the merchant resource for additional authentication when accessing the payment gateway.', + 'sort_order' => '8', + ), + 'MODULE_PAYMENT_PAYNETEASY_SANDBOX' => array( + 'title' => 'Use Sandbox', + 'value' => 'Yes', + 'description' => 'Set No if Production Keys are set OR Set Yes if Sandbox Keys are set then Live payments will not be taken.', + 'sort_order' => '9', + 'set_function' => 'multiOption(\'dropdown\', array(\'Yes\', \'No\'), ', + ), + 'MODULE_PAYMENT_PAYNETEASY_PAYMENT_METHOD' => array( + 'title' => 'Integration method', + 'value' => 'Direct', + 'description' => 'Select integration method (Direct or Form).', + 'sort_order' => '10', + 'set_function' => 'multiOption(\'dropdown\', array(\'Direct\', \'Form\'), ', + ), + 'MODULE_PAYMENT_PAYNETEASY_SHOWLOGO' => array( + 'title' => 'Show Logo', + 'value' => 'Yes', + 'description' => 'Set Yes to show logo at checkout page OR Set No to show only title while selecting payment method.', + 'sort_order' => '11', + 'set_function' => 'multiOption(\'dropdown\', array(\'Yes\', \'No\'), ', + ), + 'MODULE_PAYMENT_PAYNETEASY_ZONE' => array( + 'title' => 'Payment Zone', + 'value' => '0', + 'description' => 'If a zone is selected, only enable this payment method for that zone.', + 'sort_order' => '12', + 'use_function' => '\\common\\helpers\\Zones::get_zone_class_title', + 'set_function' => 'tep_cfg_pull_down_zone_classes(', + ), + 'MODULE_PAYMENT_PAYNETEASY_ORDER_STATUS_ID' => array( + 'title' => 'Set Order Status', + 'value' => '0', + 'description' => 'Set the status of orders made with this payment module to this value.', + 'sort_order' => '13', + 'set_function' => 'tep_cfg_pull_down_order_statuses(', + 'use_function' => '\\common\\helpers\\Order::get_order_status_name', + ), + 'MODULE_PAYMENT_PAYNETEASY_SORT_ORDER' => array( + 'title' => 'Sort order of display', + 'value' => '0', + 'description' => 'Sort order of PaynetEasy display. Lowest is displayed first.', + 'sort_order' => '14', + ), + 'MODULE_PAYMENT_PAYNETEASY_ACCEPTED_CARDS' => array( + 'title' => 'Accepted Cards', + 'value' => '', + 'description' => 'Allow Credit or Debit cards while purchasing at checkout page', + 'sort_order' => '15', + 'set_function' => "tep_cfg_select_multioption(array('American Express', 'Visa', 'MasterCard', 'Discover', 'JCB', 'Diners'),", + ), + ); + } + + + + public function describe_status_key() + { + return new ModuleStatus('MODULE_PAYMENT_PAYNETEASY_STATUS', 'True', 'False'); + } + + public function describe_sort_key() + { + return new ModuleSortOrder('MODULE_PAYMENT_PAYNETEASY_SORT_ORDER'); + } + + public function getPaymentStatus($order) + { + $paynet_order_id = tep_db_fetch_array(tep_db_query("SELECT paynet_order_id FROM payneteasy_payments WHERE merchant_order_id = '" . $order->order_id . "'")); + + $data = [ + 'login' => MODULE_PAYMENT_PAYNETEASY_LOGIN, + 'client_orderid' => (string)$order->order_id, + 'orderid' => $paynet_order_id['paynet_order_id'], + ]; + $data['control'] = $this->signStatusRequest($data, MODULE_PAYMENT_PAYNETEASY_LOGIN, MODULE_PAYMENT_PAYNETEASY_CONTROL_KEY); + + $sandbox = MODULE_PAYMENT_PAYNETEASY_SANDBOX; + $action_url = MODULE_PAYMENT_PAYNETEASY_LIVE_URL; + + if ($sandbox == 'Yes') + $sandbox = true; + else + $sandbox = false; + + if ($sandbox) + $action_url = MODULE_PAYMENT_PAYNETEASY_SANDBOX_URL; + + $paynetApi = new PaynetApi( + MODULE_PAYMENT_PAYNETEASY_LOGIN, + MODULE_PAYMENT_PAYNETEASY_CONTROL_KEY, + MODULE_PAYMENT_PAYNETEASY_ENDPOINT_ID, + MODULE_PAYMENT_PAYNETEASY_PAYMENT_METHOD, + $sandbox + ); + + $response = $paynetApi->status($data, MODULE_PAYMENT_PAYNETEASY_PAYMENT_METHOD, $sandbox, $action_url, MODULE_PAYMENT_PAYNETEASY_ENDPOINT_ID); + + if ( + !isset($response['status']) + ) { +// throw new Exception('No information about payment status.'); + } + + return $response; + } + + private function signStatusRequest($requestFields, $login, $merchantControl) + { + $base = ''; + $base .= $login; + $base .= $requestFields['client_orderid']; + $base .= $requestFields['orderid']; + + return $this->signString($base, $merchantControl); + } + + private function signPaymentRequest($data, $endpointId, $merchantControl) + { + $base = ''; + $base .= $endpointId; + $base .= $data['client_orderid']; + $base .= $data['amount'] * 100; + $base .= $data['email']; + + return $this->signString($base, $merchantControl); + } + + private function signString($s, $merchantControl) + { + return sha1($s . $merchantControl); + } + +} \ No newline at end of file diff --git a/source/payneteasy/Bootstrap.php b/source/payneteasy/Bootstrap.php new file mode 100644 index 0000000..0cb9f5e --- /dev/null +++ b/source/payneteasy/Bootstrap.php @@ -0,0 +1,35 @@ +id == 'app-backend') { + $app->controllerMap = array_merge($app->controllerMap, [ + 'payneteasy' => ['class' => __NAMESPACE__ . '\backend\controllers\PayneteasyController'], + ]); + } + } + } + +} \ No newline at end of file diff --git a/source/payneteasy/api/PaynetApi.php b/source/payneteasy/api/PaynetApi.php new file mode 100644 index 0000000..2074212 --- /dev/null +++ b/source/payneteasy/api/PaynetApi.php @@ -0,0 +1,131 @@ +login = $login; + $this->password = $password; + $this->endpoint = $endpoint; + $this->integration_method = $integration_method; + $this->type = $type; + } + + public function saleDirect($data, $integration_method, $type, $action_url, $endpoint) + { + return $this->execute('sale/' . $endpoint, $data, 'POST', $integration_method, $type, $action_url); + } + + public function return($data, $integration_method, $type, $action_url, $endpoint) + { + return $this->execute('return/' . $endpoint, $data, 'POST', $integration_method, $type, $action_url); + } + + public function status($data, $integration_method, $type, $action_url, $endpoint) + { + return $this->execute('status/' . $endpoint, $data, 'POST', $integration_method, $type, $action_url); + } + + public function saleForm($data, $integration_method, $type, $action_url, $endpoint) + { + return $this->execute('sale-form/' . $endpoint, $data, 'POST', $integration_method, $type, $action_url); + } + + protected function execute($action, $data, $method, $integration_method, $type, $action_url) { + return $this->curlRequestHandler($action, $data, $method, $integration_method, $type, $action_url); + } + + protected function curlRequestHandler($action, $data, $method, $integration_method, $type, $action_url) + { + $curl = curl_init($action_url.$this->url.$action); + + curl_setopt_array($curl, array + ( + CURLOPT_HEADER => 0, + CURLOPT_USERAGENT => 'Payneteasy-Client/1.0', + CURLOPT_SSL_VERIFYHOST => 0, + CURLOPT_SSL_VERIFYPEER => 0, + CURLOPT_POST => 1, + CURLOPT_RETURNTRANSFER => 1 + )); + + curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); + + $response = curl_exec($curl); + + if(curl_errno($curl)) + { + $error_message = 'Error occurred: ' . curl_error($curl); + $error_code = curl_errno($curl); + } + elseif(curl_getinfo($curl, CURLINFO_HTTP_CODE) != 200) + { + $error_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); + $error_message = "Error occurred. HTTP code: '{$error_code}'"; + } + + curl_close($curl); + + if (!empty($error_message)) + { + throw new \Exception($error_message, $error_code); + } + + if(empty($response)) + { + throw new \Exception('Host response is empty'); + } + + $responseFields = array(); + + parse_str($response, $responseFields); + + return $responseFields; + + } + + protected function parseHeadersToArray($rawHeaders) + { + $lines = explode("\r\n", $rawHeaders); + $headers = []; + foreach($lines as $line) { + if (strpos($line, ':') === false ){ + continue; + } + list($key, $value) = explode(': ', $line); + $headers[$key] = $value; + } + return $headers; + } + + protected function encode($data) + { + if (is_string($data)) { + return $data; + } + $result = json_encode($data); + $error = json_last_error(); + if ($error != JSON_ERROR_NONE) { + throw new \Exception('JSON Error: ' . json_last_error_msg()); + } + return $result; + } + + public static function prepareOrderId($orderId, $forUrl = false) + { + $orderId = str_replace(['/','#','?','|',' '], ['-'], $orderId); + if ($forUrl) { + $orderId = urlencode($orderId); + } + return $orderId; + } +} diff --git a/source/payneteasy/backend/controllers/PayneteasyController.php b/source/payneteasy/backend/controllers/PayneteasyController.php new file mode 100644 index 0000000..a7691f6 --- /dev/null +++ b/source/payneteasy/backend/controllers/PayneteasyController.php @@ -0,0 +1,338 @@ + ' '.$error_message.'', +// 'error' => true +// ); +// echo json_encode($result); +// exit(); + } + + public function actionRefundPayment() + { + + } + + function formatCurrencyRaw($total, $currency_code = null, $currency_value = null) + { + + if (!isset($currency_code)) { + $currency_code = DEFAULT_CURRENCY; + } + + if (!isset($currency_value) || !is_numeric($currency_value)) { + $currencies = \Yii::$container->get('currencies'); + $currency_value = $currencies->currencies[$currency_code]['value']; + } + + return number_format(self::round($total * $currency_value, $currencies->currencies[$currency_code]['decimal_places']), $currencies->currencies[$currency_code]['decimal_places'], '.', ''); + } + + public function actionBalancePayment() + { + if( \Yii::$app->request->isPost === FALSE ) return; + $post = \Yii::$app->request->post(); + $opyID = $post['opyID']; + $paymentRecord = \common\helpers\OrderPayment::getRecord($opyID); + if ($paymentRecord instanceof \common\models\OrdersPayment) { + $orderPaymentAmountAvailable = \common\helpers\OrderPayment::getAmountAvailable($paymentRecord); + $result = array( + 'amount' => sprintf("%1.2f",$orderPaymentAmountAvailable), + 'message' => 'Amount already refunded!', + 'error' => false + ); + echo json_encode($result); + } else { + $result = array( + 'error' => true + ); + echo json_encode($result); + } + } + + public function actionReturnPayment() + { + if( \Yii::$app->request->isPost === FALSE ) return; + + $post = \Yii::$app->request->post(); + + if( !$post['platform_id'] ) $this->showError('The Platform ID is missing.'); + elseif( !$post['opyID'] ) $this->showError('The Payment ID is missing.'); + elseif( !$post['uuid'] ) $this->showError('The UUID is missing.'); + elseif( !$post['amount'] ) $this->showError('The amount is missing.'); + elseif( !is_numeric($post['amount']) ) $this->showError('The amount is invalid.'); + +// $query = tep_db_query( +// "select configuration_key, configuration_value from " . TABLE_PLATFORMS_CONFIGURATION . " ". +// "where platform_id = '".intval($post['platform_id'])."' AND configuration_key in ( +// 'MODULE_PAYMENT_PAYNETEASY_FRONT_TITLE', +// 'MODULE_PAYMENT_PAYNETEASY_ENDPOINT_ID', +// 'MODULE_PAYMENT_PAYNETEASY_CONTROL_KEY', +// 'MODULE_PAYMENT_PAYNETEASY_LOGIN', +// 'MODULE_PAYMENT_PAYNETEASY_SANDBOX', +// )" +// ); +// +// while( $row = tep_db_fetch_array($query) ) { +// define($row["configuration_key"], $row["configuration_value"]); +// } + + $transactionId = ''; + + $order_id = 0; + $order_currency = ''; + $partialRefund = false; + $opyID = $post['opyID']; + $paymentRecord = \common\helpers\OrderPayment::getRecord($opyID); + if ($paymentRecord instanceof \common\models\OrdersPayment) { + $order_id = $paymentRecord["orders_payment_order_id"]; + $order_currency = $paymentRecord["orders_payment_currency"]; + $currency_value = $paymentRecord["orders_payment_currency_rate"]; + $payment = json_decode($paymentRecord["orders_payment_transaction_full"], true); + $transactionId = $payment["Transaction ID"]; + + $orderPaymentAmountAvailable = \common\helpers\OrderPayment::getAmountAvailable($paymentRecord); + if ($post['amount'] > $orderPaymentAmountAvailable) { + $post['amount'] = $orderPaymentAmountAvailable; + } + if ($post['amount'] <= 0) { + $this->showError('Amount already refunded!'); + } + if ($post['amount'] < $orderPaymentAmountAvailable) { + $partialRefund = true; + } + } else { + $this->showError('Parent payment record not found!'); + } + + if( !$order_id ) $this->showError('The order id is missing.'); + + $cartInstance = new \common\classes\shopping_cart((int)$order_id); + if (is_object($cartInstance)) { + $managerInstance = \common\services\OrderManager::loadManager($cartInstance); + if (is_object($managerInstance)) { + $orderInstance = $managerInstance->getOrderInstanceWithId('\common\classes\Order', (int)$order_id); + if (is_object($orderInstance)) { + Yii::$app->get('platform')->config((int)$post['platform_id'])->constant_up(); + $managerInstance->set('platform_id', (int)$post['platform_id']); + } + } + } + + $sandbox = MODULE_PAYMENT_PAYNETEASY_SANDBOX; + $action_url = MODULE_PAYMENT_PAYNETEASY_LIVE_URL; + + if ($sandbox == 'Yes') + $sandbox = true; + else + $sandbox = false; + + if ($sandbox) + $action_url = MODULE_PAYMENT_PAYNETEASY_SANDBOX_URL; + + $payment_payneteasy_payment_method = MODULE_PAYMENT_PAYNETEASY_PAYMENT_METHOD; + $payment_payneteasy_endpoint_id = MODULE_PAYMENT_PAYNETEASY_ENDPOINT_ID; + + $paynetApi = new PaynetApi( + MODULE_PAYMENT_PAYNETEASY_LOGIN, + MODULE_PAYMENT_PAYNETEASY_CONTROL_KEY, + $payment_payneteasy_endpoint_id, + $payment_payneteasy_payment_method, + $sandbox + ); + + $paynet_order_id = tep_db_fetch_array(tep_db_query("SELECT paynet_order_id FROM payneteasy_payments WHERE merchant_order_id = '" . $order_id . "'")); + + $data = [ + 'login' => MODULE_PAYMENT_PAYNETEASY_LOGIN, + 'client_orderid' => $order_id, + 'orderid' => $paynet_order_id['paynet_order_id'], + 'comment' => 'Order cancel' + ]; + + $data['control'] = $this->signPaymentRequest($data, $payment_payneteasy_endpoint_id, MODULE_PAYMENT_PAYNETEASY_CONTROL_KEY); + + $response = $paynetApi->return($data, $payment_payneteasy_payment_method, $sandbox, $action_url, $payment_payneteasy_endpoint_id); + + if( trim($response['type']) == "validation-error" ) { + $error_message = $response['error-message']; +// if( isset($response->desc) ) +// $error_message .= "
".$response->desc; + $result = array( + 'message' => ' '.$error_message.'', + 'error' => true + ); + echo json_encode($result); + } else { + $currencies = \Yii::$container->get('currencies'); +// $orders_payment_transaction_id = $response->txnid; +// $orders_payment_token = $response->token; +// $orders_payment_rrn = $response->rrn; +// $orders_payment_approval_code = $response->approval_code; +// +// $result = array ( +// "Transaction ID" => $orders_payment_transaction_id, +// "Token" => $orders_payment_token, +// "RRN" => $orders_payment_rrn, +// "Approval Code" => $orders_payment_approval_code +// ); +// +// $response_string = sprintf( +// 'PaynetPos payment %1$s for %2$s.%3$s Transaction ID: %4$s.%5$s Approval Code: %6$s.%7$s RRN: %8$s', +// "completed", +// $currencies->format($post['amount'], true, $order_currency, $currency_value), +// "
", +// $orders_payment_transaction_id, +// "
", +// $orders_payment_approval_code, +// "
", +// $orders_payment_rrn +// ); +// + $orderPayment = new \common\models\OrdersPayment(); + $orderPayment->orders_payment_module = 'payneteasy'; + $orderPayment->orders_payment_module_name = MODULE_PAYMENT_PAYNETEASY_FRONT_TITLE; + $orderPayment->orders_payment_transaction_id = $paynet_order_id['paynet_order_id']; + $orderPayment->orders_payment_id_parent = $opyID; + $orderPayment->orders_payment_order_id = $order_id; + $orderPayment->orders_payment_is_credit = 0; + $orderPayment->deferred = 0; + $orderPayment->orders_payment_status = \common\helpers\OrderPayment::OPYS_REFUNDED; + $orderPayment->orders_payment_amount = $post['amount']; + $orderPayment->orders_payment_currency = trim($order_currency); + $orderPayment->orders_payment_currency_rate = (float) $currency_value; + $orderPayment->orders_payment_snapshot = json_encode(\common\helpers\OrderPayment::getOrderPaymentSnapshot($orderInstance)); + $orderPayment->orders_payment_transaction_status = 'OK'; + $orderPayment->orders_payment_transaction_commentary = ''; + $orderPayment->orders_payment_date_create = date('Y-m-d H:i:s'); + $orderPayment->orders_payment_transaction_full = json_encode($response); + global $login_id; + $orderPayment->orders_payment_admin_create = (int)$login_id; + + if( $orderPayment->save() ) { + + $languages_id = \common\classes\language::get_id(DEFAULT_LANGUAGE); + + $updated = $orderInstance->updatePaidTotals(); + + if( !$partialRefund ) { + + //check refunded order status if exist get id or insert then get id + $order_status_query = tep_db_query("SELECT orders_status_id FROM " . TABLE_ORDERS_STATUS . " WHERE orders_status_name = 'Refunded' AND language_id = '" . $languages_id . "'"); + if ( tep_db_num_rows($order_status_query) > 0 ) { + $order_status = tep_db_fetch_array($order_status_query); + \common\helpers\Order::setStatus($order_id, (int)$order_status['orders_status_id'], [ + 'customer_notifsssied' => 1, + ]); + } + + } + + if( $partialRefund ) { + + //check partial refunded order status if exist get id or insert then get id + $order_status_query = tep_db_query("SELECT orders_status_id FROM " . TABLE_ORDERS_STATUS . " WHERE orders_status_name = 'Partially refunded' AND language_id = '" . $languages_id . "'"); + if ( tep_db_num_rows($order_status_query) > 0 ) { + $order_status = tep_db_fetch_array($order_status_query); + \common\helpers\Order::setStatus($order_id, (int)$order_status['orders_status_id'], [ + 'customer_notifsssied' => 1, + ]); + } + + } + +// $response_string = sprintf( +// '

Success!

The Payment %2$s has been %1$s successfully.%3$sTransaction ID: %4$s.%5$s Approval Code: %6$s.%7$s RRN: %8$s

', +// "refunded", +// $currencies->format($post['amount'], true, $order_currency, $currency_value), +// "

", +// $orders_payment_transaction_id, +// "
", +// $orders_payment_approval_code, +// "
", +// $orders_payment_rrn +// ); +// +// $result = array( +// 'message' => $response_string, +// 'error' => false +// ); +// echo json_encode($result); +// + } else { + + $result = array( + 'message' => ' Error while updating Order totals!', + 'error' => true + ); + echo json_encode($result); + + } + + } + } + + private function signPaymentRequest($requestFields, $endpointId, $merchantControl) + { + $base = ''; + $base .= $endpointId; + $base .= $requestFields['client_orderid']; + $base .= $requestFields['amount'] * 100; + $base .= $requestFields['email']; + + return $this->signString($base, $merchantControl); + } + + private function signString($s, $merchantControl) + { + return sha1($s . $merchantControl); + } + +} \ No newline at end of file diff --git a/source/payneteasy/css/adminrefund.css b/source/payneteasy/css/adminrefund.css new file mode 100644 index 0000000..294fbac --- /dev/null +++ b/source/payneteasy/css/adminrefund.css @@ -0,0 +1,129 @@ +.payneteasy-container { + width: 28em; + background-color: #ffffff; + padding: 2em 2em; + position: absolute; + transform: translate(-50%, -50%); + top: 50%; + left: 50%; + z-index: 99999; + text-align: center; + border-radius: 0.8em; + box-shadow: 0 45px 60px rgba(30, 22, 1, 0.3); +} +.payneteasy-container #timerbox { + display: none; +} +.payneteasy-container .badge { + font-weight: bold; + color: #000; + background: #ffb800; +} +.payneteasy-container .text-error { + color: #ff0000; + display: inline-block; +} +.payneteasy-container #resendcode { + color: #7952b3; + border:0px; + background: #ffffff; +} +.payneteasy-container .disabledresendcode { + opacity: 0.5; +} +.payneteasy-container .inputfield { + width: 100%; + display: flex; + margin-top: 1em; + margin-bottom: 2em; + justify-content: space-around; +} +.payneteasy-container .input { + height: 2em; + width: 2em; + border: 1px solid #dad9df; + outline: none; + text-align: center; + font-size: 1.5em; + border-radius: 0.2em; + background-color: #ffffff; + outline: none; + /*Hide number field arrows*/ + -moz-appearance: textfield; +} +.payneteasy-container input[type="number"]::-webkit-outer-spin-button, +.payneteasy-container input[type="number"]::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} +.payneteasy-container .input:disabled { + color: #89888b; +} +.payneteasy-container .input:focus { + border: 3px solid #ffb800; +} +.payneteasy-container .buttonbox { + margin: 1em auto; + display: block; + width: 100%; + text-align: center; +} +.payneteasy-container .buttonbox button { + margin-left: 4px; + margin-right: 4px; +} +.warn, +.warn::before, +.warn::after +{ + position: relative; + padding: 0; + margin: 0; +} + +.warn { + font-size: 25px; + margin-right: 5px; + display: inline-block; + color: transparent; +} + +.warn.warning { + display: inline-block; + top: 0.225em; + width: 1.15em; + height: 1.15em; + text-align: center; + overflow: hidden; + border: none; + background-color: transparent; + border-radius: 0.625em; +} + +.warn.warning::before { + content: ""; + display: block; + top: -0.08em; + left: 0.0em; + position: absolute; + border: transparent 0.6em solid; + border-bottom-color: #fd3; + border-bottom-width: 1em; + border-top-width: 0; + box-shadow: #999 0 1px 1px; +} + +.warn.warning::after { + display: block; + position: absolute; + top: 0.3em; + left: 0; + width: 100%; + padding: 0 1px; + text-align: center; + font-family: "Garamond"; + content: "!"; + font-size: 0.65em; + font-weight: bold; + color: #333; +} \ No newline at end of file diff --git a/source/payneteasy/css/payneteasy.css b/source/payneteasy/css/payneteasy.css new file mode 100644 index 0000000..348e734 --- /dev/null +++ b/source/payneteasy/css/payneteasy.css @@ -0,0 +1,89 @@ +#frmCheckout button[type="submit"]:disabled { + opacity:0.5; + cursor: not-allowed; +} +#frmCheckout button[type="submit"]:disabled, .w-checkout-continue-btn .or-text:first-of-type { + display:none +} +#paynetCcBox .logobox { + text-align:right; +} +#paynetCcBox .required-message-wrap { + display:none; + width:100%; +} +#paynetCcBox .payneteasy-cc-logo { + width:70px; + opacity:0.3; +} +#paynetCcBox .col-25 { + float:right; +} +#paynetCcBox .col-75 { + margin-right:10px; + float:left; + position:relative; +} +#paynetCcBox .col-75 { + float:left; +} +#paynetCcBox input[type=text],#paynetCcBox select,#paynetCcBox input[type=password] { + width:100%; + margin-bottom:0px; + resize:vertical; +} +#paynetCcBox .required-message-wrap { + margin-bottom:5px; +} +#paynetCcBox label { + padding:12px 12px 0px 0; + display:inline-block; +} +#paynetCcBox .container { + border-radius:5px; + background-color:#f2f2f2; + padding:20px; +} +#paynetCcBox .col-25 { + width:36%; + margin-right:4%; + position:relative; +} +#paynetCcBox .col-75 { + width:56%; +} +#paynetCcBox .col-100 { + width:96%; +} +#paynetCcBox .payneteasy-card-head, #paynetCcBox .payneteasy-card-head label { + cursor: pointer; + font-weight: bold; +} +#paynetCcBox .row-new-card { + margin-top: 10px; + border-top: 1px solid #ccc; +} +#paynetCcBox #new-card-panel { + display:block; + margin-left:4%; + width:96%; +} +#paynetCcBox .col-50-1 { + float:left; + width:48%; +} +#paynetCcBox .col-50-2 { + float:right; + width:48%; +} +#paynetCcBox .row:after { + content:""; + display:table; + clear:both; +} +@media screen and (max-width:600px) { + #paynetCcBox .col-25,#paynetCcBox .col-75 { + width:100%; + margin-top:0; + } +} \ No newline at end of file diff --git a/source/payneteasy/images/amex.png b/source/payneteasy/images/amex.png new file mode 100644 index 0000000..366f6e2 Binary files /dev/null and b/source/payneteasy/images/amex.png differ diff --git a/source/payneteasy/images/diners.png b/source/payneteasy/images/diners.png new file mode 100644 index 0000000..0134bf0 Binary files /dev/null and b/source/payneteasy/images/diners.png differ diff --git a/source/payneteasy/images/discover.png b/source/payneteasy/images/discover.png new file mode 100644 index 0000000..ac653f0 Binary files /dev/null and b/source/payneteasy/images/discover.png differ diff --git a/source/payneteasy/images/jcb.png b/source/payneteasy/images/jcb.png new file mode 100644 index 0000000..f70bfd5 Binary files /dev/null and b/source/payneteasy/images/jcb.png differ diff --git a/source/payneteasy/images/mastercard.png b/source/payneteasy/images/mastercard.png new file mode 100644 index 0000000..b274d7e Binary files /dev/null and b/source/payneteasy/images/mastercard.png differ diff --git a/source/payneteasy/images/visa.png b/source/payneteasy/images/visa.png new file mode 100644 index 0000000..7d21c22 Binary files /dev/null and b/source/payneteasy/images/visa.png differ diff --git a/source/payneteasy/js/BrandDetection.js b/source/payneteasy/js/BrandDetection.js new file mode 100644 index 0000000..888425e --- /dev/null +++ b/source/payneteasy/js/BrandDetection.js @@ -0,0 +1,109 @@ +PaynetEasyBrandDetection = function() { +}; + +PaynetEasyBrandDetection.prototype.option = +{ + 'minlength': 6 +}; + +PaynetEasyBrandDetection.prototype.creditcard = +{ + 'carte-bleue': { + 'pattern': /^(415006|497|407497|513)/, + 'cardlength': [13, 16], + 'luhn': false, + 'cvc': [3] + }, + 'carta-si': { + 'pattern': /^(45399[78]|432913|5255)/, + 'cardlength': [16], + 'luhn': false, + 'cvc': [3] + }, + 'dankort': { + 'pattern': /^(4571|5019)/, + 'cardlength': [16], + 'luhn': false, + 'cvc': [3] + }, + 'china-unionpay': { + 'pattern': /^(62|88)/, + 'cardlength': [16, 17, 18, 19], + 'luhn': false, + 'cvc': [3] + }, + 'discover': { + 'pattern': /^6(011|5)/, + 'cardlength': [16], + 'luhn': false, + 'cvc': [3] + }, + 'diners-club': { + 'pattern': /^3(0[0-5]|[68])/, + 'cardlength': [14], + 'luhn': false, + 'cvc': [3] + }, + 'maestro': { + 'pattern': /^(5018|5020|5038|5893|6304|6759|6761|6762|6763|0604|6390)/, + 'cardlength': [12, 13, 14, 15, 16, 17, 18, 19], + 'luhn': false, + 'cvc': [0, 3, 4] + }, + 'jcb': { + 'pattern': /^(2131|1800|35)/, + 'cardlength': [16], + 'luhn': false, + 'cvc': [3] + }, + 'amex': { + 'pattern': /^(3[47])/, + 'cardlength': [15], + 'luhn': false, + 'cvc': [3, 4] + }, + 'mastercard': { + 'pattern': /^(5[1-5])/, + 'cardlength': [16], + 'luhn': false, + 'cvc': [3] + }, + 'visa': { + 'pattern': /^(4)/, + 'cardlength': [13, 16], + 'luhn': false, + 'cvc': [3] + } +}; + +PaynetEasyBrandDetection.prototype.hasOwnProperty = function(property) { + return this[property] !== undefined; +}; + +PaynetEasyBrandDetection.prototype.detect = function(cardnumber) +{ + var brand = 'unknown'; + if (cardnumber.length >= this.option.minlength) { + for (var cardinfo in this.creditcard) { + if (this.creditcard[cardinfo].pattern.test(cardnumber)) { + brand = cardinfo; + break; + } + } + } + return brand; +}; + +PaynetEasyBrandDetection.prototype.validate = function(cardnumber) +{ + if (this.creditcard.hasOwnProperty(this.detect(cardnumber))) { + return this.creditcard[this.detect(cardnumber)].cardlength.indexOf(cardnumber.length) !== -1; + } + + return false; +}; + +PaynetEasyBrandDetection.prototype.luhn = function(cardnumber) +{ + //todo +}; \ No newline at end of file diff --git a/source/payneteasy/js/adminrefund.js b/source/payneteasy/js/adminrefund.js new file mode 100644 index 0000000..b0f4468 --- /dev/null +++ b/source/payneteasy/js/adminrefund.js @@ -0,0 +1,127 @@ +$(document).ready(function () { + + if( $('input[type="submit"]').length > 0 && $('input[type="submit"]').val() == "Update" ) { + $('#order_payment_edit').delegate('#refundbutton', 'click', function (e) { + var vamount = $('input[name=orders_payment_amount]').val(); + if( !vamount ) { + alert('Please enter valid amount.'); + $('input[name=orders_payment_amount]').focus(); + return; + } + else if( !$.isNumeric(vamount) ) { + alert('Please enter valid amount.'); + $('input[name=orders_payment_amount]').focus(); + $('input[name=orders_payment_amount]').select(); + return; + } + $(this).prop('disabled',true); + $.fn.returnPayment(); + }); + + $.fn.timerCount = function() { + var timer2 = "1:30"; + var interval = setInterval(function() { + var timer = timer2.split(':'); + var minutes = parseInt(timer[0], 10); + var seconds = parseInt(timer[1], 10); + --seconds; + minutes = (seconds < 0) ? --minutes : minutes; + seconds = (seconds < 0) ? 59 : seconds; + seconds = (seconds < 10) ? '0' + seconds : seconds; + $('#timebox').html('0'+minutes + ':' + seconds); + if (minutes < 0) clearInterval(interval); + if ((seconds <= 0) && (minutes <= 0)) { + clearInterval(interval); + $('#timerbox').hide(); + $("#resendcode").prop('disabled',false); + $("#resendcode").removeClass('disabledresendcode'); + } + timer2 = minutes + ':' + seconds; + }, 1000); + } + + $.fn.returnPayment = function() { + $.post(payneteasy.return_url, { platform_id: payneteasy.platform_id, opyID: payneteasy.opyID, amount: $('input[name=orders_payment_amount]').val() }, function( data ) { + data = JSON.parse(data); + console.log(data); + if(!data) { + if( data.message ) $("#resp").html(data.message); + } else { + $('input[name=payneteasy_uuid]').val(data.uuid); + } + }); + } + + + $('#order_payment_edit').delegate('#resendcode', 'click', function (e) { + e.preventDefault(); + $.each($('.input'), function (index, value) { + $(this).val(''); + }); + $("#resp").html(''); + }); + + $('#order_payment_edit').delegate('#donebutton', 'click', function (e) { + location.reload(); + }); + + $.fn.balancepayment = function() { + $.post(payneteasy.balancepayment_url, { opyID: payneteasy.opyID }, function( data ) { + data = JSON.parse(data); + if( !data.error && Number(data.amount) <= 0 ) { + $('#order_payment_edit input[type="submit"]').parent().append(''); + $('#order_payment_edit input[type="submit"]').hide(); + $('textarea[name="orders_payment_transaction_commentary"]').val(''); + } + else { + $('input[name=orders_payment_amount]').val(data.amount); + $('#order_payment_edit input[type="submit"]').parent().append(''); + $('textarea[name="orders_payment_transaction_commentary"]').val(''); + $('#order_payment_edit input[type="submit"]').show(); + } + }); + } + + $.fn.checkAllBox = function() { + var fullstring = ''; + $.each($('.input'), function (index, value) { + fullstring += $(this).val(); + }); + } + + $('#order_payment_edit').delegate('.input', 'input', function (e) { + $(this).val( + $(this) + .val() + .replace(/[^0-9]/g, "").substr(0,1) + ); + $.fn.checkAllBox(); + }); + + $('#order_payment_edit').delegate('.input', 'keyup', function (e) { + let key = e.keyCode || e.charCode; + if (key == 8 || key == 46 || key == 37 || key == 40) { + // Backspace or Delete or Left Arrow or Down Arrow + $(this).prev().focus(); + } else if (key == 38 || key == 39 || $(this).val() != "") { + // Right Arrow or Top Arrow or Value not empty + $(this).next().focus(); + } + }); + + $('#order_payment_edit').delegate('.input', 'paste', function (e) { + var obj = $('.input'); + var paste_data = e.originalEvent.clipboardData.getData("text"); + var paste_data_splitted = paste_data.split(""); + $.each(paste_data_splitted, function (index, value) { + obj.eq(index).val(value); + }); + }); + + setTimeout(function(){ + $.fn.balancepayment(); + }, 500); + + } + +}); \ No newline at end of file diff --git a/source/payneteasy/js/cc.js b/source/payneteasy/js/cc.js new file mode 100644 index 0000000..f01dc28 --- /dev/null +++ b/source/payneteasy/js/cc.js @@ -0,0 +1,269 @@ +$(document).ready(function () { + + $('form[name="one_page_checkout"]').submit(function (e) { + hideErrorBoxes(); + + var ccErrorFlag = true; + var cc = new PaynetEasyCC(); + + if (!cc.isValid($("#payneteasy-card-number").val())) { + $("#payneteasy-card-number-error").fadeIn('slow'); + ccErrorFlag = false; + } + + if (!cc.isExpirationDateValid($("#payneteasy-card-expiry-month").val(), $("#payneteasy-card-expiry-year").val())) { + $("#payneteasy-card-expiry-error").fadeIn('slow'); + ccErrorFlag = false; + } + + if ($("#payneteasy-card-name").val().length <= 0) { + $("#payneteasy-card-name-error").fadeIn('slow'); + ccErrorFlag = false; + } + + if (!cc.isSecurityCodeValid($("#payneteasy-card-number").val(), $("#payneteasy-card-cvv").val())) { + $("#payneteasy-card-cvv-error").fadeIn('slow'); + ccErrorFlag = false; + } + + if ($("#payneteasy-card-address").length > 0 && $("#payneteasy-card-address").val().length <= 0) { + $("#payneteasy-card-address-error").fadeIn('slow'); + ccErrorFlag = false; + } + + if ($("#payneteasy-card-zip").length > 0 && $("#payneteasy-card-zip").val().length <= 0) { + $("#payneteasy-card-zip-error").fadeIn('slow'); + ccErrorFlag = false; + } + + if (!ccErrorFlag) { + $('.w-checkout-continue-btn button[type=submit]').prop('disabled', false); + $('.w-checkout-continue-btn button[type=submit]').addClass('disabled-area'); + if( $('.hide-page').length > 0 ) $('.hide-page').remove(); + if( $('.fake-input').length > 0 ) $('.fake-input').remove(); + return ccErrorFlag; + } + return true; + }); + + window.PaynetEasyCreateCCForm = function() + { + if ( $('input[name=payment][value="payneteasy"]').length <= 0 ) return; + + if ($('input[name=payment][value="payneteasy"]').is(':checked')){ + console.log(payneteasy_payment_method); + if (payneteasy_payment_method == 'Direct') { + + if( $('#paynetCcBox').length > 0 ) $('#paynetCcBox').remove(); + var payneteasy_avs_string = ''; + var payneteasy_new_card = ''; + + // if( payneteasy_avs_options == 'zipandaddress' ) payneteasy_avs_string = '
Please enter address for verification.
Please enter zip for verification.
'; + // else if( payneteasy_avs_options == 'address' ) payneteasy_avs_string = '
Please enter address for verification.
'; + // else if( payneteasy_avs_options == 'zip' ) payneteasy_avs_string = '
Please enter zip for verification.
'; + + var formString = '
'+payneteasy_logos+'
'+payneteasy_new_card+'
Please enter a valid credit card number.
Please select valid expiration date.
Please enter name on credit card.
Please enter a valid CVV.
'; + $("
").attr('id','paynetCcBox').html(formString).appendTo($(".payment_class_payneteasy").parents('.type-1')[1]); + + for ( var cc_month_counter in payneteasy_cc_months ) { + var cc_month_value = payneteasy_cc_months[cc_month_counter][0]; + var cc_month_text = $("
").html(payneteasy_cc_months[cc_month_counter][1]).text(); + $('