diff --git a/changelog.md b/changelog.md index 4dc83f73a..3fe31cd34 100755 --- a/changelog.md +++ b/changelog.md @@ -196,4 +196,7 @@ ## [2.0.2] - Remove WL Crypto payment method - Added setting to toggle order confirmation email sending -- Added feature to group card payment methods into unified "Card" payment method \ No newline at end of file +- Added feature to group card payment methods into unified "Card" payment method +- Fixed issue when newly enabled payment methods did not appear in checkout because default "all countries/currencies" restriction was not created on save +- Fixed issue when payment method country/currency dropdowns showed "0" instead of indicating that all countries/currencies are allowed +- BO : Added validation for Merchant Emails field (frontend + backend) to prevent saving invalid addresses diff --git a/controllers/admin/AdminSaferPayOfficialFieldsController.php b/controllers/admin/AdminSaferPayOfficialFieldsController.php deleted file mode 100755 index 7508d5986..000000000 --- a/controllers/admin/AdminSaferPayOfficialFieldsController.php +++ /dev/null @@ -1,90 +0,0 @@ - - *@copyright SIX Payment Services - *@license SIX Payment Services - */ - -use Invertus\SaferPay\Config\SaferPayConfig; - -require_once dirname(__FILE__) . '/../../vendor/autoload.php'; - -if (!defined('_PS_VERSION_')) { - exit; -} - -class AdminSaferPayOfficialFieldsController extends ModuleAdminController -{ - public function __construct() - { - parent::__construct(); - $this->bootstrap = true; - - $this->tpl_folder = 'field-option-settings/'; - $this->initOptions(); - } - - public function initContent() - { - parent::initContent(); - } - - public function initOptions() - { - $this->fields_options = [ - 'hosted_fields_settings' => [ - 'title' => $this->module->l('Hosted fields settings'), - 'icon' => 'icon-settings', - 'fields' => [ - SaferPayConfig::HOSTED_FIELDS_TEMPLATE . '_description' => [ - 'type' => 'desc', - 'class' => 'col-lg-12', - 'template' => 'field-hosted-field-template-desc.tpl', - ], - - SaferPayConfig::HOSTED_FIELDS_TEMPLATE => [ - 'type' => 'select-template', - 'name' => SaferPayConfig::HOSTED_FIELDS_TEMPLATE, - 'templateOptions' => [ - "{$this->module->getPathUri()}views/img/hosted-templates/template1.jpg", - "{$this->module->getPathUri()}views/img/hosted-templates/template2.jpg", - "{$this->module->getPathUri()}views/img/hosted-templates/template3.jpg", - ], - ], - ], - 'buttons' => [ - 'save_and_connect' => [ - 'title' => $this->module->l('Save'), - 'icon' => 'process-icon-save', - 'class' => 'btn btn-default pull-right', - 'type' => 'submit', - ], - ], - ], - ]; - } - - public function setMedia($isNewTheme = false) - { - parent::setMedia($isNewTheme); - - $this->addJS('modules/' . $this->module->name . '/views/js/admin/saferpay_fields.js'); - $this->addCSS('modules/' . $this->module->name . '/views/css/admin/saferpay_fields.css'); - } -} diff --git a/controllers/admin/AdminSaferPayOfficialSettingsController.php b/controllers/admin/AdminSaferPayOfficialSettingsController.php index 70b8e14ad..0d4f5ffcf 100755 --- a/controllers/admin/AdminSaferPayOfficialSettingsController.php +++ b/controllers/admin/AdminSaferPayOfficialSettingsController.php @@ -40,6 +40,7 @@ use Invertus\SaferPay\Service\SaferPayRestrictionCreator; use Invertus\SaferPay\Exception\Api\SaferPayApiException; use Invertus\SaferPay\Exception\Restriction\RestrictionException; +use Invertus\SaferPay\Logger\LoggerInterface; require_once dirname(__FILE__) . '/../../vendor/autoload.php'; @@ -178,6 +179,17 @@ public function ajaxProcessSaveCredentials() } } + $testMerchantEmails = $this->getStringValue($data, 'testMerchantEmails'); + $liveMerchantEmails = $this->getStringValue($data, 'liveMerchantEmails'); + $invalidEmail = $this->findInvalidEmail($testMerchantEmails) ?: $this->findInvalidEmail($liveMerchantEmails); + if ($invalidEmail !== null) { + $this->ajaxResponse(false, sprintf( + $this->module->l('Invalid merchant email address: %s', self::FILE_NAME), + $invalidEmail + )); + return; + } + // Credentials validated — now save $configuration->set(SaferPayConfig::TEST_MODE, $isTestMode ? 1 : 0); @@ -209,8 +221,8 @@ public function ajaxProcessSaveCredentials() // Auto-detect license features from Saferpay Management API $suffix = $isTestMode ? SaferPayConfig::TEST_SUFFIX : ''; - $licenseMessage = ''; $hasBusinessLicense = false; + $licenseFetchFailed = false; if (!empty($activeUsername) && !empty($activePassword) && !empty($activeCustomerId)) { try { @@ -227,18 +239,29 @@ public function ajaxProcessSaveCredentials() $configuration->set(SaferPayConfig::BUSINESS_LICENSE . $suffix, $hasBusinessLicense ? 1 : 0); } catch (\Exception $e) { $configuration->set(SaferPayConfig::BUSINESS_LICENSE . $suffix, 0); + $licenseFetchFailed = true; - $licenseMessage = ' ' . $this->module->l('Could not retrieve license information. Please verify your credentials.', self::FILE_NAME); + /** @var LoggerInterface $logger */ + $logger = $this->module->getService(LoggerInterface::class); + $logger->error('License fetch failed on credentials save: ' . $e->getMessage(), [ + 'context' => ['exception_class' => get_class($e)], + ]); } } else { $configuration->set(SaferPayConfig::BUSINESS_LICENSE . $suffix, 0); } + $message = $licenseFetchFailed + ? $this->module->l('Settings saved, but Saferpay Fields availability could not be confirmed. Please try again later or check the module Logs for details.', self::FILE_NAME) + : $this->module->l('Settings saved successfully.', self::FILE_NAME); + $this->ajaxResponse( true, - $this->module->l('Settings saved successfully.', self::FILE_NAME) . $licenseMessage, + $message, [ - 'hasBusinessLicense' => $hasBusinessLicense, + 'testHasBusinessLicense' => (bool) $configuration->get(SaferPayConfig::BUSINESS_LICENSE . SaferPayConfig::TEST_SUFFIX), + 'liveHasBusinessLicense' => (bool) $configuration->get(SaferPayConfig::BUSINESS_LICENSE), + 'warning' => $licenseFetchFailed, ] ); } @@ -312,7 +335,18 @@ public function ajaxProcessSaveGeneralSettings() $configuration->set(SaferPayConfig::SAFERPAY_ORDER_STATE_CHOICE_AWAITING_PAYMENT, $this->getIntValue($data, 'orderStateAwaitingPayment')); $configuration->set(SaferPayConfig::SAFERPAY_PAYMENT_DESCRIPTION, $this->getStringValue($data, 'paymentDescription')); - $configuration->set(SaferPayConfig::CONFIGURATION_NAME, $this->getStringValue($data, 'configurationName')); + + $configurationName = $this->getStringValue($data, 'configurationName'); + if ($configurationName !== '' && (strlen($configurationName) > 20 || !preg_match('/^[A-Za-z0-9.:\-_]+$/', $configurationName))) { + $this->ajaxResponse(false, $this->module->l('Only letters, numbers, dots, colons, hyphens, and underscores are allowed. Max 20 characters.', self::FILE_NAME)); + return; + } + $configuration->set(SaferPayConfig::CONFIGURATION_NAME, $configurationName); + $hostedFieldsTemplate = $this->getIntValue($data, 'hostedFieldsTemplate'); + if ($hostedFieldsTemplate < 1 || $hostedFieldsTemplate > 3) { + $hostedFieldsTemplate = SaferPayConfig::HOSTED_FIELDS_TEMPLATE_DEFAULT; + } + $configuration->set(SaferPayConfig::HOSTED_FIELDS_TEMPLATE, $hostedFieldsTemplate); $configuration->set(SaferPayConfig::SAFERPAY_ORDER_ID_OPTION, $this->getIntValue($data, 'orderIdOption')); $configuration->set(SaferPayConfig::SAFERPAY_DEBUG_MODE, !empty($data['debugMode']) ? 1 : 0); @@ -367,6 +401,13 @@ public function ajaxProcessSavePaymentMethods() $countries = isset($method['countries']) ? $method['countries'] : []; $currencies = isset($method['currencies']) ? $method['currencies'] : []; + if (empty($countries)) { + $countries = [SaferPayRestrictionCreator::RESTRICTION_ALL]; + } + if (empty($currencies)) { + $currencies = [SaferPayRestrictionCreator::RESTRICTION_ALL]; + } + $success = $restrictionCreator->updateRestriction( $paymentName, SaferPayRestrictionCreator::RESTRICTION_COUNTRY, @@ -523,8 +564,9 @@ private function collectSettingsData() 'liveFieldAccessToken' => (string) $configuration->get(SaferPayConfig::FIELDS_ACCESS_TOKEN), 'liveFieldJsUrl' => (string) $configuration->get(SaferPayConfig::FIELDS_LIBRARY), - // License (auto-detected) - 'hasBusinessLicense' => (bool) $configuration->get(SaferPayConfig::BUSINESS_LICENSE . SaferPayConfig::getConfigSuffix()), + // License (auto-detected, per environment) + 'testHasBusinessLicense' => (bool) $configuration->get(SaferPayConfig::BUSINESS_LICENSE . SaferPayConfig::TEST_SUFFIX), + 'liveHasBusinessLicense' => (bool) $configuration->get(SaferPayConfig::BUSINESS_LICENSE), // Payment Processing 'paymentBehavior' => (int) $configuration->get(SaferPayConfig::PAYMENT_BEHAVIOR), @@ -544,6 +586,8 @@ private function collectSettingsData() 'orderStateAwaitingPayment' => (int) $configuration->get(SaferPayConfig::SAFERPAY_ORDER_STATE_CHOICE_AWAITING_PAYMENT), 'paymentDescription' => (string) $configuration->get(SaferPayConfig::SAFERPAY_PAYMENT_DESCRIPTION), 'configurationName' => (string) $configuration->get(SaferPayConfig::CONFIGURATION_NAME), + 'hostedFieldsTemplate' => (int) $configuration->get(SaferPayConfig::HOSTED_FIELDS_TEMPLATE), + 'modulePath' => $this->module->getPathUri(), 'orderIdOption' => (int) $configuration->get(SaferPayConfig::SAFERPAY_ORDER_ID_OPTION), 'debugMode' => (bool) $configuration->get(SaferPayConfig::SAFERPAY_DEBUG_MODE), @@ -759,4 +803,24 @@ private function getIntValue($data, $key) { return isset($data[$key]) ? (int) $data[$key] : 0; } + + /** + * Returns the first invalid email in a comma-separated list, or null if all are valid. + */ + private function findInvalidEmail($emails) + { + if ($emails === '') { + return null; + } + foreach (explode(',', $emails) as $email) { + $email = trim($email); + if ($email === '') { + continue; + } + if (!\Validate::isEmail($email)) { + return $email; + } + } + return null; + } } diff --git a/controllers/front/notify.php b/controllers/front/notify.php index 35bb7d25f..667a1fd4d 100755 --- a/controllers/front/notify.php +++ b/controllers/front/notify.php @@ -158,7 +158,19 @@ public function postProcess() ]); die($this->module->l('Liability shift is false', self::FILE_NAME)); - } elseif ($paymentBehaviorWithout3D === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CAPTURE + } + + if ($paymentBehaviorWithout3D === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_AUTHORIZE) { + $logger->debug(sprintf('%s - Liability shift is false, order left authorized', self::FILE_NAME), [ + 'context' => [ + 'id_order' => $order->id, + ], + ]); + + die($this->module->l('Liability shift is false, order left authorized', self::FILE_NAME)); + } + + if ($paymentBehaviorWithout3D === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CAPTURE && SaferPayConfig::supportsOrderCapture($order->payment) && $transactionStatus !== TransactionStatus::CAPTURED ) { @@ -169,6 +181,8 @@ public function postProcess() 'id_order' => $order->id, ], ]); + + die($this->module->l('Liability shift is false, capturing order', self::FILE_NAME)); } } diff --git a/controllers/front/return.php b/controllers/front/return.php index f36c7fe22..a65984b32 100755 --- a/controllers/front/return.php +++ b/controllers/front/return.php @@ -274,7 +274,9 @@ private function executeTransaction($orderId, $selectedCard) */ private function getRedirectionToControllerUrl($controllerName) { - $cartId = $this->context->cart->id ? $this->context->cart->id : Tools::getValue('cartId'); + $cartId = (int) Tools::getValue('cartId') ?: (int) $this->context->cart->id; + $cart = new Cart($cartId); + $secureKey = Validate::isLoadedObject($cart) ? $cart->secure_key : $this->context->cart->secure_key; return $this->context->link->getModuleLink( $this->module->name, @@ -282,7 +284,7 @@ private function getRedirectionToControllerUrl($controllerName) [ 'cartId' => $cartId, 'orderId' => Order::getIdByCartId($cartId), - 'secureKey' => $this->context->cart->secure_key, + 'secureKey' => $secureKey, 'moduleId' => $this->module->id, ] ); @@ -339,7 +341,15 @@ private function createAndValidateOrder($assertResponseBody, $transactionStatus, if ($paymentBehaviorWithout3D === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL) { $orderStatusService->cancel($order); - } elseif ($paymentBehaviorWithout3D === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CAPTURE + + return; + } + + if ($paymentBehaviorWithout3D === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_AUTHORIZE) { + return; + } + + if ($paymentBehaviorWithout3D === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CAPTURE && SaferPayConfig::supportsOrderCapture($order->payment) && $transactionStatus !== TransactionStatus::CAPTURED ) { diff --git a/cypress/integration/01_ps1764.Module.Configure.cy.js b/cypress/integration/01_ps1764.Module.Configure.cy.js index b7313cb4c..f8988d2b8 100755 --- a/cypress/integration/01_ps1764.Module.Configure.cy.js +++ b/cypress/integration/01_ps1764.Module.Configure.cy.js @@ -117,14 +117,6 @@ it('04 Fields and Logs tabs are shown OK', () => { cy.get('.pstaggerAddTagInput').type('saferpay') cy.get('#module-search-button').click() cy.get('.btn-group > .btn-primary-reverse').click() //clicking the Congifure - cy.get('#subtab-AdminSaferPayOfficialFields').click() - cy.get('[id="configuration_form"]').should('be.visible') - cy.get('.field-container > :nth-child(1) > img').click() - cy.get(':nth-child(2) > img').click() - cy.get(':nth-child(3) > img').click() - cy.get('[class="alert alert-info"]').should('be.visible') - cy.get('[name="submitOptionsconfiguration"]').click() - cy.get('[class="alert alert-success"]').should('be.visible') cy.get('#subtab-AdminSaferPayOfficialLogs').click() cy.get('[id="form-saferpay_log"]').should('be.visible') }) diff --git a/cypress/integration/01_ps1770.Module.Configure.cy.js b/cypress/integration/01_ps1770.Module.Configure.cy.js index 9696c496c..1de0a18c6 100755 --- a/cypress/integration/01_ps1770.Module.Configure.cy.js +++ b/cypress/integration/01_ps1770.Module.Configure.cy.js @@ -117,14 +117,6 @@ it('04 Fields and Logs tabs are shown OK', () => { cy.get('.pstaggerAddTagInput').type('saferpay') cy.get('#module-search-button').click() cy.get('.btn-group > .btn-primary-reverse').click() //clicking the Congifure - cy.get('#subtab-AdminSaferPayOfficialFields').click() - cy.get('[id="configuration_form"]').should('be.visible') - cy.get('.field-container > :nth-child(1) > img').click() - cy.get(':nth-child(2) > img').click() - cy.get(':nth-child(3) > img').click() - cy.get('[class="alert alert-info"]').should('be.visible') - cy.get('[name="submitOptionsconfiguration"]').click() - cy.get('[class="alert alert-success"]').should('be.visible') cy.get('#subtab-AdminSaferPayOfficialLogs').click() cy.get('[id="form-saferpay_log"]').should('be.visible') }) diff --git a/cypress/integration/01_ps1784.Module.Configure.cy.js b/cypress/integration/01_ps1784.Module.Configure.cy.js index 8da2aae5b..716aa4837 100755 --- a/cypress/integration/01_ps1784.Module.Configure.cy.js +++ b/cypress/integration/01_ps1784.Module.Configure.cy.js @@ -117,14 +117,6 @@ it('04 Fields and Logs tabs are shown OK', () => { cy.get('.pstaggerAddTagInput').type('saferpay') cy.get('#module-search-button').click() cy.get('.btn-group > .btn-primary-reverse').click() //clicking the Congifure - cy.get('#subtab-AdminSaferPayOfficialFields').click() - cy.get('[id="configuration_form"]').should('be.visible') - cy.get('.field-container > :nth-child(1) > img').click() - cy.get(':nth-child(2) > img').click() - cy.get(':nth-child(3) > img').click() - cy.get('[class="alert alert-info"]').should('be.visible') - cy.get('[name="submitOptionsconfiguration"]').click() - cy.get('[class="alert alert-success"]').should('be.visible') cy.get('#subtab-AdminSaferPayOfficialLogs').click() cy.get('[id="form-saferpay_log"]').should('be.visible') }) diff --git a/cypress/integration/01_ps1786.Module.Configure.cy.js b/cypress/integration/01_ps1786.Module.Configure.cy.js index 0c8259a9d..863cb240b 100755 --- a/cypress/integration/01_ps1786.Module.Configure.cy.js +++ b/cypress/integration/01_ps1786.Module.Configure.cy.js @@ -117,14 +117,6 @@ it('04 Fields and Logs tabs are shown OK', () => { cy.get('.pstaggerAddTagInput').type('saferpay') cy.get('#module-search-button').click() cy.get('.btn-group > .btn-primary-reverse').click() //clicking the Congifure - cy.get('#subtab-AdminSaferPayOfficialFields').click() - cy.get('[id="configuration_form"]').should('be.visible') - cy.get('.field-container > :nth-child(1) > img').click() - cy.get(':nth-child(2) > img').click() - cy.get(':nth-child(3) > img').click() - cy.get('[class="alert alert-info"]').should('be.visible') - cy.get('[name="submitOptionsconfiguration"]').click() - cy.get('[class="alert alert-success"]').should('be.visible') cy.get('#subtab-AdminSaferPayOfficialLogs').click() cy.get('[id="form-saferpay_log"]').should('be.visible') }) diff --git a/saferpayofficial.php b/saferpayofficial.php index b0acd4630..dd997aa5e 100755 --- a/saferpayofficial.php +++ b/saferpayofficial.php @@ -55,7 +55,6 @@ class SaferPayOfficial extends PaymentModule const ADMIN_SAFERPAY_MODULE_CONTROLLER = 'AdminSaferPayOfficialModule'; const ADMIN_SETTINGS_CONTROLLER = 'AdminSaferPayOfficialSettings'; const ADMIN_PAYMENTS_CONTROLLER = 'AdminSaferPayOfficialPayment'; - const ADMIN_FIELDS_CONTROLLER = 'AdminSaferPayOfficialFields'; const ADMIN_ORDER_CONTROLLER = 'AdminSaferPayOfficialOrder'; const ADMIN_LOGS_CONTROLLER = 'AdminSaferPayOfficialLogs'; @@ -65,7 +64,7 @@ public function __construct($name = null) { $this->name = 'saferpayofficial'; $this->author = 'Invertus'; - $this->version = '2.0.2'; + $this->version = '2.1.1'; $this->module_key = '3d3506c3e184a1fe63b936b82bda1bdf'; $this->displayName = 'SaferpayOfficial'; $this->description = 'Saferpay Payment module'; diff --git a/src/Api/ApiRequest.php b/src/Api/ApiRequest.php index 72ebc144a..5df54cd59 100755 --- a/src/Api/ApiRequest.php +++ b/src/Api/ApiRequest.php @@ -114,14 +114,16 @@ public function get($url, $params = []) return json_decode($response->raw_body); } catch (Exception $exception) { - $this->logger->error($exception->getMessage(), [ - 'context' => [ - 'headers' => $this->getHeaders(), - ], - 'request' => $params, - 'response' => json_decode($response->raw_body), - 'exceptions' => ExceptionUtility::getExceptions($exception), - ]); + if ($response === null) { + $this->logger->error($exception->getMessage(), [ + 'context' => [ + 'headers' => $this->getHeaders(), + ], + 'request' => $params, + 'response' => null, + 'exceptions' => ExceptionUtility::getExceptions($exception), + ]); + } throw $exception; } @@ -170,12 +172,14 @@ public function getWithCredentials($url, $username, $password, $baseUrl, $params return json_decode($response->raw_body); } catch (Exception $exception) { - $this->logger->error($exception->getMessage(), [ - 'context' => [], - 'request' => $params, - 'response' => $response ? json_decode($response->raw_body) : null, - 'exceptions' => ExceptionUtility::getExceptions($exception), - ]); + if ($response === null) { + $this->logger->error($exception->getMessage(), [ + 'context' => [], + 'request' => $params, + 'response' => null, + 'exceptions' => ExceptionUtility::getExceptions($exception), + ]); + } throw $exception; } @@ -226,12 +230,14 @@ public function postWithCredentials($url, $username, $password, $baseUrl, $param return json_decode($response->raw_body); } catch (Exception $exception) { - $this->logger->error($exception->getMessage(), [ - 'context' => [], - 'request' => $params, - 'response' => $response ? json_decode($response->raw_body) : null, - 'exceptions' => ExceptionUtility::getExceptions($exception), - ]); + if ($response === null) { + $this->logger->error($exception->getMessage(), [ + 'context' => [], + 'request' => $params, + 'response' => null, + 'exceptions' => ExceptionUtility::getExceptions($exception), + ]); + } throw $exception; } diff --git a/src/Entity/index.php b/src/Entity/index.php deleted file mode 100755 index ee6227264..000000000 --- a/src/Entity/index.php +++ /dev/null @@ -1,31 +0,0 @@ - - *@copyright SIX Payment Services - *@license SIX Payment Services - */ -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/src/Install/AbstractInstaller.php b/src/Install/AbstractInstaller.php index cbe8d897d..2188841f0 100755 --- a/src/Install/AbstractInstaller.php +++ b/src/Install/AbstractInstaller.php @@ -63,12 +63,6 @@ public function tabs() 'module_tab' => true, 'visible' => false, ], - [ - 'name' => $this->module->l('Fields'), - 'class_name' => SaferPayOfficial::ADMIN_FIELDS_CONTROLLER, - 'parent_class_name' => SaferPayOfficial::ADMIN_SAFERPAY_MODULE_CONTROLLER, - 'module_tab' => true, - ], [ 'name' => $this->module->l('Order'), 'class_name' => SaferPayOfficial::ADMIN_ORDER_CONTROLLER, diff --git a/src/Service/Request/RequestObjectCreator.php b/src/Service/Request/RequestObjectCreator.php index a5c40a192..21fc39835 100755 --- a/src/Service/Request/RequestObjectCreator.php +++ b/src/Service/Request/RequestObjectCreator.php @@ -128,12 +128,10 @@ public function createPayment(Cart $cart, $totalPrice) $payment->setDescription($description); } - if ((int) \Configuration::get(SaferPayConfig::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION) && empty($order)) { - return $payment; + if (!empty($order)) { + $payment->setOrderReference($order->reference); } - $payment->setOrderReference($order->reference); - return $payment; } diff --git a/src/Service/SettingsTranslationService.php b/src/Service/SettingsTranslationService.php index 78a00b823..ae2de9990 100644 --- a/src/Service/SettingsTranslationService.php +++ b/src/Service/SettingsTranslationService.php @@ -85,6 +85,7 @@ private function getCommonTranslations() { return [ 'saveChanges' => $this->module->l('Save Changes', self::FILE_NAME), + 'saving' => $this->module->l('Saving...', self::FILE_NAME), 'enable' => $this->module->l('Enable', self::FILE_NAME), 'disable' => $this->module->l('Disable', self::FILE_NAME), 'search' => $this->module->l('Search...', self::FILE_NAME), @@ -121,6 +122,7 @@ private function getApiCredentialsTranslations() 'merchantEmails' => $this->module->l('Merchant Emails', self::FILE_NAME), 'enterMerchantEmails' => $this->module->l('Enter merchant email addresses (comma-separated)', self::FILE_NAME), 'separateEmails' => $this->module->l('These email addresses receive payment notification emails directly from SaferPay. Separate multiple email addresses with commas.', self::FILE_NAME), + 'invalidMerchantEmails' => $this->module->l('Invalid email address', self::FILE_NAME), 'saferpayFields' => $this->module->l('Saferpay Fields', self::FILE_NAME), 'saferpayFieldsDescription' => $this->module->l('Configure Saferpay Fields for inline payment form integration.', self::FILE_NAME), 'fieldAccessTokenInfo' => $this->module->l('Saferpay Field Access Token can be found in Saferpay Backoffice, navigate to', self::FILE_NAME), @@ -188,7 +190,7 @@ private function getPaymentProcessingTranslations() 'createWhenAuthorized' => $this->module->l('Create when authorized', self::FILE_NAME), 'beforeAuthorization' => $this->module->l('Before authorization', self::FILE_NAME), 'createBeforePayment' => $this->module->l('Create before payment', self::FILE_NAME), - 'cardDisplaySaving' => $this->module->l('Card Display & Saving', self::FILE_NAME), + 'cardDisplaySaving' => html_entity_decode($this->module->l('Card Display & Saving', self::FILE_NAME), ENT_QUOTES, 'UTF-8'), 'cardDisplayDescription' => $this->module->l('Configure how cards appear at checkout and whether customers can save them.', self::FILE_NAME), 'groupCardsLabel' => $this->module->l('Group debit/credit cards as \'Cards\' in checkout', self::FILE_NAME), 'groupCardsDescription' => $this->module->l('If enabled, all supported card brands will be grouped and shown as a single \'Cards\' payment method at checkout.', self::FILE_NAME), @@ -227,7 +229,13 @@ private function getGeneralSettingsTranslations() 'stylingDescription' => $this->module->l('Customize the appearance of the payment page.', self::FILE_NAME), 'configName' => $this->module->l('Payment Page configurations name', self::FILE_NAME), 'enterConfigName' => $this->module->l('Enter configuration name', self::FILE_NAME), - 'configNameDescription' => $this->module->l('This name is visible in payment page and also in payment confirmation email.', self::FILE_NAME), + 'configNameDescription' => html_entity_decode($this->module->l('Name of the Payment Page Configuration created in Saferpay Backoffice (Settings > Payment Page Configuration). Max 20 characters. Allowed: letters, numbers, dots, colons, hyphens, underscores.', self::FILE_NAME), ENT_QUOTES, 'UTF-8'), + 'hostedFieldInfo' => html_entity_decode($this->module->l('This style applies only to payment methods with "Custom form" enabled in the Payment Methods list. Methods without Custom form or paid with saved cards use the Saferpay-hosted payment page, whose appearance is controlled by "Payment Page configurations name".', self::FILE_NAME), ENT_QUOTES, 'UTF-8'), + 'hostedFieldStyle' => $this->module->l('Hosted field style', self::FILE_NAME), + 'hostedFieldStyleDescription' => $this->module->l('Select the card input form layout for the payment page.', self::FILE_NAME), + 'classicLayout' => $this->module->l('Classic Layout', self::FILE_NAME), + 'labeledLayout' => $this->module->l('Labeled Layout', self::FILE_NAME), + 'inlineLayoutWithCard' => $this->module->l('Inline Layout with Card', self::FILE_NAME), 'configuration' => $this->module->l('Configuration', self::FILE_NAME), 'configurationDescription' => $this->module->l('General module configuration settings.', self::FILE_NAME), 'description' => $this->module->l('Description', self::FILE_NAME), diff --git a/translations/en.php b/translations/en.php new file mode 100644 index 000000000..e69de29bb diff --git a/upgrade/install-1.0.3.php b/upgrade/install-1.0.3.php index 2574c76e5..b4938c7f3 100755 --- a/upgrade/install-1.0.3.php +++ b/upgrade/install-1.0.3.php @@ -57,12 +57,5 @@ function upgrade_module_1_0_3($module) ADD COLUMN `authorized` TINYINT(1) DEFAULT 0' ); - $installer = new \Invertus\SaferPay\Install\Installer($module); - $installer->installTab( - SaferPayOfficial::ADMIN_FIELDS_CONTROLLER, - SaferPayOfficial::ADMIN_SAFERPAY_MODULE_CONTROLLER, - $module->l('Fields') - ); - return $result; } diff --git a/views/templates/admin/partials/field-hosted-field-template-desc.tpl b/upgrade/install-2.1.1.php old mode 100755 new mode 100644 similarity index 75% rename from views/templates/admin/partials/field-hosted-field-template-desc.tpl rename to upgrade/install-2.1.1.php index 8314405ef..b7b39ae00 --- a/views/templates/admin/partials/field-hosted-field-template-desc.tpl +++ b/upgrade/install-2.1.1.php @@ -1,4 +1,5 @@ -{** + *@copyright SIX Payment Services *@license SIX Payment Services - *} -
- {l s='Choose which hosted field will be displayed on payment option selection with supported payment methods' mod='saferpayofficial'} -
+ */ + +if (!defined('_PS_VERSION_')) { + exit; +} + +function upgrade_module_2_1_1() +{ + $tabId = Tab::getIdFromClassName('AdminSaferPayOfficialFields'); + if ($tabId) { + $tab = new Tab($tabId); + $tab->delete(); + } + + return true; +} diff --git a/views/css/admin/logs_tab.css b/views/css/admin/logs_tab.css index 5bb36a92f..702cff1ec 100755 --- a/views/css/admin/logs_tab.css +++ b/views/css/admin/logs_tab.css @@ -73,10 +73,31 @@ border-bottom: solid 1px grey; pointer-events: all; display: flex; - justify-content: center; + justify-content: space-between; + align-items: center; max-height: 10vh; } +.log-modal-close { + background: none; + border: none; + font-size: 1.5rem; + cursor: pointer; + padding: 0.25rem 0.5rem; + line-height: 1; + color: #6b7280; + margin-right: 0.5rem; +} + +.log-modal-close:hover { + color: #111827; +} + +.log-modal-close:focus { + outline: 2px solid #2196F3; + outline-offset: 2px; +} + .log-modal-content { padding: 15px; height: 50vh; diff --git a/views/css/admin/payment_method.css b/views/css/admin/payment_method.css index 336eda6f0..9b0b08c91 100755 --- a/views/css/admin/payment_method.css +++ b/views/css/admin/payment_method.css @@ -43,6 +43,12 @@ width: 0; } +/* Visible focus indicator for keyboard navigation */ +.container-checkbox input:focus ~ .checkmark { + outline: 2px solid #2196F3; + outline-offset: 2px; +} + /* Create a custom checkbox */ .checkmark { position: absolute; diff --git a/views/css/admin/saferpay_fields.css b/views/css/admin/saferpay_fields.css deleted file mode 100755 index 064c2c333..000000000 --- a/views/css/admin/saferpay_fields.css +++ /dev/null @@ -1,49 +0,0 @@ -/** - *NOTICE OF LICENSE - * - *This source file is subject to the Open Software License (OSL 3.0) - *that is bundled with this package in the file LICENSE.txt. - *It is also available through the world-wide-web at this URL: - *http://opensource.org/licenses/osl-3.0.php - *If you did not receive a copy of the license and are unable to - *obtain it through the world-wide-web, please send an email - *to license@prestashop.com so we can send you a copy immediately. - * - *DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - *versions in the future. If you wish to customize PrestaShop for your - *needs please refer to http://www.prestashop.com for more information. - * - *@author INVERTUS UAB www.invertus.eu - *@copyright SIX Payment Services - *@license SIX Payment Services - */ - -/* HIDE RADIO */ -[type=radio] { - position: absolute; - opacity: 0; - width: 0; - height: 0; -} - -/* IMAGE STYLES */ -[type=radio] + img { - cursor: pointer; -} - -/* CHECKED STYLES */ -[type=radio]:checked + img { - outline: 2px solid #f00; -} - -.field-label { - flex: 0 0 23%; - margin-bottom:30px !important; -} - -.field-container { - display: flex; - flex-wrap: wrap; -} diff --git a/views/js/admin/log.js b/views/js/admin/log.js index 4a8eb769a..a16cecc4b 100644 --- a/views/js/admin/log.js +++ b/views/js/admin/log.js @@ -21,17 +21,65 @@ */ $(document).ready(function () { + function closeModal($modal) { + $modal.removeClass('open'); + var triggerButton = $modal.data('triggerButton'); + if (triggerButton) { + triggerButton.focus(); + } + } + $('.log-modal-overlay').on('click', function (event) { - $('.modal.open').removeClass('open'); + closeModal($(this).closest('.modal')); + event.preventDefault(); + }); + + $('.js-log-modal-close').on('click', function (event) { + closeModal($(this).closest('.modal')); event.preventDefault(); }); + $(document).on('keydown', function (event) { + var $openModal = $('.modal.open'); + if (!$openModal.length) { + return; + } + if (event.key === 'Escape') { + closeModal($openModal); + event.preventDefault(); + return; + } + if (event.key === 'Tab') { + var focusables = $openModal.find('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])').filter(':visible'); + if (!focusables.length) { + event.preventDefault(); + return; + } + var first = focusables.first()[0]; + var last = focusables.last()[0]; + if (event.shiftKey && document.activeElement === first) { + last.focus(); + event.preventDefault(); + } else if (!event.shiftKey && document.activeElement === last) { + first.focus(); + event.preventDefault(); + } else if (!$openModal[0].contains(document.activeElement)) { + first.focus(); + event.preventDefault(); + } + } + }); + $('.js-log-button').on('click', function (event) { var logId = $(this).data('log-id'); var informationType = $(this).data('information-type'); + var $modal = $('#' + $(this).data('target')); + + $modal.data('triggerButton', $(this)); // NOTE: opening modal - $('#' + $(this).data('target')).addClass('open'); + $modal.addClass('open'); + $modal.find('.js-log-modal-close').focus(); // NOTE: if information has been set already we don't need to call ajax again. if (!$('#log-modal-' + logId + '-' + informationType + ' .log-modal-content-data').hasClass('hidden')) { diff --git a/views/js/admin/saferpay_settings.js b/views/js/admin/saferpay_settings.js index 6407bc177..72f482b10 100755 --- a/views/js/admin/saferpay_settings.js +++ b/views/js/admin/saferpay_settings.js @@ -20,16 +20,23 @@ *@license SIX Payment Services */ -$(document).ready(function (e) { - $("input[name='SAFERPAY_CONFIGURATION_NAME']").keypress(function (e) { - //disable symbols +$(document).ready(function () { + var $configInput = $("input[name='SAFERPAY_CONFIGURATION_NAME']"); + + $configInput.attr('maxlength', 20); + + $configInput.keypress(function (e) { var txt = String.fromCharCode(e.which); - if (!txt.match(/[A-Za-z0-9&. ]/)) { - return false; - } - // disable space - if (e.keyCode === 32) { + if (!txt.match(/[A-Za-z0-9.:\-_]/)) { return false; } }); + + $configInput.on('paste', function (e) { + var $input = $(this); + setTimeout(function () { + var cleaned = $input.val().replace(/[^A-Za-z0-9.:\-_]/g, '').substring(0, 20); + $input.val(cleaned); + }, 0); + }); }); \ No newline at end of file diff --git a/views/js/admin/settings-app/src/components/settings/api-credentials.tsx b/views/js/admin/settings-app/src/components/settings/api-credentials.tsx index 5a3931901..d806211bc 100644 --- a/views/js/admin/settings-app/src/components/settings/api-credentials.tsx +++ b/views/js/admin/settings-app/src/components/settings/api-credentials.tsx @@ -35,6 +35,14 @@ export function ApiCredentials() { const fieldJsUrl = isTest ? settings.testFieldJsUrl : settings.liveFieldJsUrl const hasCredentials = username.length > 0 && password.length > 0 + const hasBusinessLicense = isTest ? settings.testHasBusinessLicense : settings.liveHasBusinessLicense + + const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ + const invalidEmails = merchantEmails + .split(',') + .map(e => e.trim()) + .filter(e => e.length > 0 && !EMAIL_RE.test(e)) + const merchantEmailsInvalid = invalidEmails.length > 0 const setField = (field: string, value: string | boolean) => { updateSettings({ [`${prefix}${field.charAt(0).toUpperCase() + field.slice(1)}`]: value } as Record) @@ -145,17 +153,23 @@ export function ApiCredentials() { {/* Username & Password */}
- + setField('username', e.target.value)} + required + aria-required="true" />
- +
setField('password', e.target.value)} className="sp-pr-10" + required + aria-required="true" />
)} {credentialStatus === 'valid' && ( -
+
{t('credentialsValid')}
@@ -233,7 +249,14 @@ export function ApiCredentials() { placeholder={t('enterMerchantEmails')} value={merchantEmails} onChange={(e) => setField('merchantEmails', e.target.value)} + aria-invalid={merchantEmailsInvalid} + className={merchantEmailsInvalid ? 'sp-border-destructive focus-visible:sp-ring-destructive' : ''} /> + {merchantEmailsInvalid && ( +

+ {t('invalidMerchantEmails')}: {invalidEmails.join(', ')} +

+ )}

{t('separateEmails')}

@@ -242,7 +265,7 @@ export function ApiCredentials() { - {settings.hasBusinessLicense && + {hasBusinessLicense && {t('saferpayFields')} {t('saferpayFieldsDescription')} @@ -250,12 +273,12 @@ export function ApiCredentials() {
- +

{t('saferpayFieldsIncluded')}

-

+

{t('saferpayFieldsIncludedDescription')}

@@ -330,7 +353,12 @@ export function ApiCredentials() { }
-
diff --git a/views/js/admin/settings-app/src/components/settings/email-notifications.tsx b/views/js/admin/settings-app/src/components/settings/email-notifications.tsx index 044239c82..d79d331ac 100644 --- a/views/js/admin/settings-app/src/components/settings/email-notifications.tsx +++ b/views/js/admin/settings-app/src/components/settings/email-notifications.tsx @@ -90,7 +90,7 @@ export function EmailNotifications() {
-
diff --git a/views/js/admin/settings-app/src/components/settings/general-settings.tsx b/views/js/admin/settings-app/src/components/settings/general-settings.tsx index 6dac7f145..52b795687 100644 --- a/views/js/admin/settings-app/src/components/settings/general-settings.tsx +++ b/views/js/admin/settings-app/src/components/settings/general-settings.tsx @@ -72,14 +72,60 @@ export function GeneralSettings() { updateSettings({ configurationName: e.target.value })} + onChange={(e) => { + const cleaned = e.target.value.replace(/[^A-Za-z0-9.:\-_]/g, '') + updateSettings({ configurationName: cleaned }) + }} />

{t('configNameDescription')}

+ + {/* Hosted field info banner */} +
+ +

+ {t('hostedFieldInfo')} +

+
+ + {/* Hosted field style selector */} +
+
+ + +

+ {t('hostedFieldStyleDescription')} +

+
+
+ { +
+
@@ -175,7 +221,7 @@ export function GeneralSettings() {
-
diff --git a/views/js/admin/settings-app/src/components/settings/payment-methods.tsx b/views/js/admin/settings-app/src/components/settings/payment-methods.tsx index bc3fc449f..99dfd735a 100644 --- a/views/js/admin/settings-app/src/components/settings/payment-methods.tsx +++ b/views/js/admin/settings-app/src/components/settings/payment-methods.tsx @@ -31,15 +31,28 @@ function MultiSelect({ [options, search], ) + const ALL_VALUE = 0 + + const validSelected = useMemo( + () => selected.filter((s) => s !== ALL_VALUE && options.some((o) => o.id === s)), + [selected, options], + ) + + const isAll = selected.includes(ALL_VALUE) || validSelected.length === 0 + const toggle = useCallback( (value: number) => { - onChange( - selected.includes(value) - ? selected.filter((s) => s !== value) - : [...selected, value], - ) + if (value === ALL_VALUE) { + onChange([ALL_VALUE]) + return + } + const base = isAll ? [] : validSelected + const next = base.includes(value) + ? base.filter((s) => s !== value) + : [...base, value] + onChange(next.length === 0 ? [ALL_VALUE] : next) }, - [selected, onChange], + [validSelected, isAll, onChange], ) return ( @@ -48,14 +61,18 @@ function MultiSelect({
- {selected.length > 0 && ( + {validSelected.length > 0 && (
{method.hasCustomForm && ( @@ -251,6 +269,7 @@ export function PaymentMethods() { updatePaymentMethod(method.name, { showCustomForm: checked })} + aria-label={`${t('customForm')} ${method.displayName}`} />
)} @@ -293,7 +312,7 @@ export function PaymentMethods() { {paymentMethods.length > 0 && (
-
diff --git a/views/js/admin/settings-app/src/components/settings/payment-processing.tsx b/views/js/admin/settings-app/src/components/settings/payment-processing.tsx index c19e98a45..3d26f72da 100644 --- a/views/js/admin/settings-app/src/components/settings/payment-processing.tsx +++ b/views/js/admin/settings-app/src/components/settings/payment-processing.tsx @@ -305,7 +305,7 @@ export function PaymentProcessing() {
-
diff --git a/views/js/admin/settings-app/src/components/settings/saferpay-settings.tsx b/views/js/admin/settings-app/src/components/settings/saferpay-settings.tsx index 0d8649911..93b02197c 100644 --- a/views/js/admin/settings-app/src/components/settings/saferpay-settings.tsx +++ b/views/js/admin/settings-app/src/components/settings/saferpay-settings.tsx @@ -24,6 +24,7 @@ export function SaferpaySettings() { @@ -31,6 +32,7 @@ export function SaferpaySettings() { @@ -38,6 +40,7 @@ export function SaferpaySettings() { @@ -45,6 +48,7 @@ export function SaferpaySettings() { @@ -52,6 +56,7 @@ export function SaferpaySettings() { diff --git a/views/js/admin/settings-app/src/components/settings/toast-container.tsx b/views/js/admin/settings-app/src/components/settings/toast-container.tsx index 39d96074d..0b5f905db 100644 --- a/views/js/admin/settings-app/src/components/settings/toast-container.tsx +++ b/views/js/admin/settings-app/src/components/settings/toast-container.tsx @@ -15,7 +15,9 @@ export function ToastContainer() { className={`sp-rounded-lg sp-border sp-px-4 sp-py-3 sp-shadow-lg sp-text-sm sp-animate-in sp-slide-in-from-bottom-2 ${ t.variant === 'destructive' ? 'sp-bg-destructive sp-text-destructive-foreground sp-border-destructive' - : 'sp-bg-emerald-600 sp-text-white sp-border-emerald-700' + : t.variant === 'warning' + ? 'sp-bg-amber-500 sp-text-white sp-border-amber-600' + : 'sp-bg-emerald-600 sp-text-white sp-border-emerald-700' }`} > {t.title &&
{t.title}
} diff --git a/views/js/admin/settings-app/src/context/settings-context.tsx b/views/js/admin/settings-app/src/context/settings-context.tsx index 47fd6f1f6..784cf7fb1 100644 --- a/views/js/admin/settings-app/src/context/settings-context.tsx +++ b/views/js/admin/settings-app/src/context/settings-context.tsx @@ -48,7 +48,7 @@ export function SettingsProvider({ children }: { children: React.ReactNode }) { }, []) const handleSave = useCallback(async ( - saveFn: () => Promise<{ success: boolean; message?: string }>, + saveFn: () => Promise<{ success: boolean; message?: string; warning?: boolean }>, label: string, section: SavingSection, ) => { @@ -56,7 +56,8 @@ export function SettingsProvider({ children }: { children: React.ReactNode }) { try { const result = await saveFn() if (result.success) { - toast({ title: result.message || t('savedSuccessfully', label), variant: 'default' }) + const variant = result.warning ? 'warning' : 'default' + toast({ title: result.message || t('savedSuccessfully', label), variant }) } else { toast({ title: result.message || t('failedToSave', label), variant: 'destructive' }) } @@ -91,10 +92,14 @@ export function SettingsProvider({ children }: { children: React.ReactNode }) { liveFieldJsUrl: currentSettings.liveFieldJsUrl, }) const data = result as unknown as Record - if (result.success && typeof data.hasBusinessLicense === 'boolean') { - setSettings((prev) => ({ ...prev, hasBusinessLicense: data.hasBusinessLicense as boolean })) + if (result.success) { + setSettings((prev) => ({ + ...prev, + ...(typeof data.testHasBusinessLicense === 'boolean' ? { testHasBusinessLicense: data.testHasBusinessLicense as boolean } : {}), + ...(typeof data.liveHasBusinessLicense === 'boolean' ? { liveHasBusinessLicense: data.liveHasBusinessLicense as boolean } : {}), + })) } - return result + return { ...result, warning: data.warning === true } }, 'API Credentials', 'credentials') }, [handleSave]) @@ -126,6 +131,7 @@ export function SettingsProvider({ children }: { children: React.ReactNode }) { orderStateAwaitingPayment: currentSettings.orderStateAwaitingPayment, paymentDescription: currentSettings.paymentDescription, configurationName: currentSettings.configurationName, + hostedFieldsTemplate: currentSettings.hostedFieldsTemplate, orderIdOption: currentSettings.orderIdOption, debugMode: currentSettings.debugMode, }), 'General Settings', 'generalSettings') diff --git a/views/js/admin/settings-app/src/globals.css b/views/js/admin/settings-app/src/globals.css index 084c1fe3b..b222286c7 100644 --- a/views/js/admin/settings-app/src/globals.css +++ b/views/js/admin/settings-app/src/globals.css @@ -14,7 +14,7 @@ --sp-secondary: 180 15% 95%; --sp-secondary-foreground: 220 20% 10%; --sp-muted: 180 12% 95%; - --sp-muted-foreground: 220 10% 46%; + --sp-muted-foreground: 220 12% 38%; --sp-accent: 180 25% 92%; --sp-accent-foreground: 180 51% 22%; --sp-destructive: 0 72% 51%; diff --git a/views/js/admin/settings-app/src/hooks/use-toast.ts b/views/js/admin/settings-app/src/hooks/use-toast.ts index ec2103412..f0af5fe04 100644 --- a/views/js/admin/settings-app/src/hooks/use-toast.ts +++ b/views/js/admin/settings-app/src/hooks/use-toast.ts @@ -7,7 +7,7 @@ export interface ToasterToast { id: string title?: string description?: string - variant?: 'default' | 'destructive' + variant?: 'default' | 'destructive' | 'warning' } type Action = diff --git a/views/js/admin/settings-app/src/types/index.ts b/views/js/admin/settings-app/src/types/index.ts index af64ab595..79bf8e2ae 100644 --- a/views/js/admin/settings-app/src/types/index.ts +++ b/views/js/admin/settings-app/src/types/index.ts @@ -33,8 +33,9 @@ export interface SaferpaySettingsData { liveFieldAccessToken: string liveFieldJsUrl: string - // License (read-only, auto-detected from API) - hasBusinessLicense: boolean + // License (read-only, auto-detected from API, per environment) + testHasBusinessLicense: boolean + liveHasBusinessLicense: boolean // Payment Processing paymentBehavior: number @@ -54,6 +55,8 @@ export interface SaferpaySettingsData { orderStateAwaitingPayment: number paymentDescription: string configurationName: string + hostedFieldsTemplate: number + modulePath: string orderIdOption: number debugMode: boolean diff --git a/views/templates/admin/field-option-settings/helpers/index.php b/views/templates/admin/field-option-settings/helpers/index.php deleted file mode 100755 index ee6227264..000000000 --- a/views/templates/admin/field-option-settings/helpers/index.php +++ /dev/null @@ -1,31 +0,0 @@ - - *@copyright SIX Payment Services - *@license SIX Payment Services - */ -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/views/templates/admin/field-option-settings/helpers/options/index.php b/views/templates/admin/field-option-settings/helpers/options/index.php deleted file mode 100755 index ee6227264..000000000 --- a/views/templates/admin/field-option-settings/helpers/options/index.php +++ /dev/null @@ -1,31 +0,0 @@ - - *@copyright SIX Payment Services - *@license SIX Payment Services - */ -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/views/templates/admin/field-option-settings/helpers/options/options.tpl b/views/templates/admin/field-option-settings/helpers/options/options.tpl deleted file mode 100755 index 4c100589d..000000000 --- a/views/templates/admin/field-option-settings/helpers/options/options.tpl +++ /dev/null @@ -1,70 +0,0 @@ -{** - *NOTICE OF LICENSE - * - *This source file is subject to the Open Software License (OSL 3.0) - *that is bundled with this package in the file LICENSE.txt. - *It is also available through the world-wide-web at this URL: - *http://opensource.org/licenses/osl-3.0.php - *If you did not receive a copy of the license and are unable to - *obtain it through the world-wide-web, please send an email - *to license@prestashop.com so we can send you a copy immediately. - * - *DISCLAIMER - * - * Do not edit or add to this file if you wish to upgrade PrestaShop to newer - *versions in the future. If you wish to customize PrestaShop for your - *needs please refer to http://www.prestashop.com for more information. - * - *@author INVERTUS UAB www.invertus.eu - *@copyright SIX Payment Services - *@license SIX Payment Services - *} - -{extends file="helpers/options/options.tpl"} - -{block name="input" append} - {if $field['type'] == 'password_input'} -
- -
- {/if} - {if $field['type'] == 'desc'} -
- {if $field['template'] == 'field-javascript-library-desc.tpl'} - {include file="../../../partials/field-javascript-library-desc.tpl"} - {/if} - - {if $field['template'] == 'field-access-token-desc.tpl'} - {include file="../../../partials/field-access-token-desc.tpl"} - {/if} - - {if $field['template'] == 'field-hosted-field-template-desc.tpl'} - {include file="../../../partials/field-hosted-field-template-desc.tpl"} - {/if} - {if $field['template'] == 'field-new-order-mail-desc.tpl'} - {include file="../../../partials/field-new-order-mail-desc.tpl"} - {/if} -
- {/if} - - {if $field['type'] == 'select-template'} - -
- {foreach from=$field['templateOptions'] key=key item=templateUrl} - {assign var='key' value=$key + 1} {* To have normal keys without 0 *} - - {/foreach} -
- - {/if} -{/block} diff --git a/views/templates/admin/field-option-settings/index.php b/views/templates/admin/field-option-settings/index.php deleted file mode 100755 index ee6227264..000000000 --- a/views/templates/admin/field-option-settings/index.php +++ /dev/null @@ -1,31 +0,0 @@ - - *@copyright SIX Payment Services - *@license SIX Payment Services - */ -header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); -header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); - -header('Cache-Control: no-store, no-cache, must-revalidate'); -header('Cache-Control: post-check=0, pre-check=0', false); -header('Pragma: no-cache'); - -header('Location: ../'); -exit; diff --git a/views/templates/admin/logs/log_modal.tpl b/views/templates/admin/logs/log_modal.tpl index 62cb43dd4..eadfc7fcd 100644 --- a/views/templates/admin/logs/log_modal.tpl +++ b/views/templates/admin/logs/log_modal.tpl @@ -19,7 +19,8 @@ *@copyright SIX Payment Services *@license SIX Payment Services *} -
{l s='View' mod='saferpayofficial'} -
+ -