From b5adaaa8f4cf1d7265058eb9ceebef1d4370e2ed Mon Sep 17 00:00:00 2001 From: Gytautas Zumaras Date: Mon, 16 Mar 2026 17:10:38 +0200 Subject: [PATCH 01/24] feat: add Capture option to 3D Secure failure behavior setting --- controllers/front/notify.php | 41 +++++++++++-------- controllers/front/return.php | 20 +++++++-- saferpayofficial.php | 2 +- src/Config/SaferPayConfig.php | 3 +- src/Service/SettingsTranslationService.php | 3 +- upgrade/install-2.0.3.php | 36 ++++++++++++++++ .../settings/payment-processing.tsx | 14 +++++++ 7 files changed, 96 insertions(+), 23 deletions(-) create mode 100644 upgrade/install-2.0.3.php diff --git a/controllers/front/notify.php b/controllers/front/notify.php index 870464e7..35bb7d25 100755 --- a/controllers/front/notify.php +++ b/controllers/front/notify.php @@ -140,27 +140,36 @@ public function postProcess() //NOTE must be left below assert action to get newest information. $order = new Order($orderId); + $paymentBehaviorWithout3D = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D); + if (!$assertResponseBody->getLiability()->getLiabilityShift() && - in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) && - (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D) === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL + in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) ) { /** @var SaferPayOrderStatusService $orderStatusService */ $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); - $orderStatusService->cancel($order); - - $logger->debug(sprintf('%s - Liability shift is false', self::FILE_NAME), [ - 'context' => [ - 'id_order' => $order->id, - ], - ]); - $logger->debug(sprintf('%s - liability shift is false', self::FILE_NAME), [ - 'context' => [ - 'id_order' => $order->id, - ], - ]); - - die($this->module->l('Liability shift is false', self::FILE_NAME)); + if ($paymentBehaviorWithout3D === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL) { + $orderStatusService->cancel($order); + + $logger->debug(sprintf('%s - Liability shift is false, canceling order', self::FILE_NAME), [ + 'context' => [ + 'id_order' => $order->id, + ], + ]); + + die($this->module->l('Liability shift is false', self::FILE_NAME)); + } elseif ($paymentBehaviorWithout3D === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CAPTURE + && SaferPayConfig::supportsOrderCapture($order->payment) + && $transactionStatus !== TransactionStatus::CAPTURED + ) { + $orderStatusService->capture($order); + + $logger->debug(sprintf('%s - Liability shift is false, capturing order', self::FILE_NAME), [ + 'context' => [ + 'id_order' => $order->id, + ], + ]); + } } //NOTE to get latest information possible and not override new information. diff --git a/controllers/front/return.php b/controllers/front/return.php index b5fc37c6..f36c7fe2 100755 --- a/controllers/front/return.php +++ b/controllers/front/return.php @@ -329,19 +329,31 @@ private function createAndValidateOrder($assertResponseBody, $transactionStatus, $orderId = Order::getIdByCartId($cartId); $order = new Order($orderId); + $paymentBehaviorWithout3D = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D); + if (!$assertResponseBody->getLiability()->getLiabilityShift() && - in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) && - (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D) === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL + in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) ) { /** @var SaferPayOrderStatusService $orderStatusService */ $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); - $orderStatusService->cancel($order); + + if ($paymentBehaviorWithout3D === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL) { + $orderStatusService->cancel($order); + } elseif ($paymentBehaviorWithout3D === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CAPTURE + && SaferPayConfig::supportsOrderCapture($order->payment) + && $transactionStatus !== TransactionStatus::CAPTURED + ) { + $orderStatusService->capture($order); + + return; + } } //NOTE to get latest information possible and not override new information. - $paymentMethod = $assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod();// if payment does not support order capture, it means it always auto-captures it (at least with accountToAccount payment), + $paymentMethod = $assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod(); + // if payment does not support order capture, it means it always auto-captures it (at least with accountToAccount payment), // so in this case if status comes back "captured" we just update the order state accordingly if (!SaferPayConfig::supportsOrderCapture($paymentMethod) && $transactionStatus === TransactionStatus::CAPTURED diff --git a/saferpayofficial.php b/saferpayofficial.php index b0acd463..75e49ed5 100755 --- a/saferpayofficial.php +++ b/saferpayofficial.php @@ -65,7 +65,7 @@ public function __construct($name = null) { $this->name = 'saferpayofficial'; $this->author = 'Invertus'; - $this->version = '2.0.2'; + $this->version = '2.0.3'; $this->module_key = '3d3506c3e184a1fe63b936b82bda1bdf'; $this->displayName = 'SaferpayOfficial'; $this->description = 'Saferpay Payment module'; diff --git a/src/Config/SaferPayConfig.php b/src/Config/SaferPayConfig.php index ae787999..b7168ab4 100755 --- a/src/Config/SaferPayConfig.php +++ b/src/Config/SaferPayConfig.php @@ -276,6 +276,7 @@ class SaferPayConfig const PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL = 0; const PAYMENT_BEHAVIOR_WITHOUT_3D_AUTHORIZE = 1; + const PAYMENT_BEHAVIOR_WITHOUT_3D_CAPTURE = 2; const SAFERPAY_CARDFORM_HOLDERNAME_REQUIRENCE = 'MANDATORY'; const SAFERPAY_DEBUG_MODE = 'SAFERPAY_DEBUG_MODE'; @@ -433,7 +434,7 @@ public static function getDefaultConfiguration() RequestHeader::SPEC_REFUND_VERSION => SaferPayConfig::API_VERSION, RequestHeader::RETRY_INDICATOR => 0, SaferPayConfig::PAYMENT_BEHAVIOR => 1, - SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D => 1, + SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D => 0, SaferPayConfig::SAFERPAY_ALLOW_SAFERPAY_SEND_CUSTOMER_MAIL => 1, SaferPayConfig::SAFERPAY_PAYMENT_DESCRIPTION => self::SAFERPAY_PAYMENT_DESCRIPTION_DEFAULT_VALUE, SaferPayConfig::FIELDS_LIBRARY => self::FIELDS_LIBRARY_DEFAULT_VALUE, diff --git a/src/Service/SettingsTranslationService.php b/src/Service/SettingsTranslationService.php index 03d1545f..40959186 100644 --- a/src/Service/SettingsTranslationService.php +++ b/src/Service/SettingsTranslationService.php @@ -174,11 +174,12 @@ private function getPaymentProcessingTranslations() 'chargeImmediately' => $this->module->l('Charge immediately', self::FILE_NAME), 'authorize' => $this->module->l('Authorize', self::FILE_NAME), 'reserveAndCaptureLater' => $this->module->l('Reserve and capture later', self::FILE_NAME), - 'behaviourWhen3dsFails' => $this->module->l('Behaviour when 3D Secure fails', self::FILE_NAME), + 'behaviourWhen3dsFails' => $this->module->l('Behavior when 3D Secure Payer Authentication was not successful and liability shift was not granted', self::FILE_NAME), 'behaviourWhen3dsDescription' => $this->module->l('Default payment behavior for payment without 3-D Secure.', self::FILE_NAME), 'cancel' => $this->module->l('Cancel', self::FILE_NAME), 'rejectPayment' => $this->module->l('Reject the payment', self::FILE_NAME), 'continueWithout3ds' => $this->module->l('Continue without 3DS', self::FILE_NAME), + 'captureWithout3ds' => $this->module->l('Charge immediately', self::FILE_NAME), 'restrictRefundAmount' => $this->module->l('Restrict RefundAmount to Captured Amount', self::FILE_NAME), 'restrictRefundDescription' => $this->module->l('If set to true, the refund will be rejected if the sum of authorized refunds exceeds the capture value.', self::FILE_NAME), 'orderCreationRule' => $this->module->l('Order creation rule', self::FILE_NAME), diff --git a/upgrade/install-2.0.3.php b/upgrade/install-2.0.3.php new file mode 100644 index 00000000..c221693b --- /dev/null +++ b/upgrade/install-2.0.3.php @@ -0,0 +1,36 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +if (!defined('_PS_VERSION_')) { + exit; +} + +/** + * Upgrade to 2.0.3: + * - Add "Capture" option for "Behavior without 3D Secure" setting. + * - Existing installs keep their current value (no overwrite). + */ +function upgrade_module_2_0_3() +{ + return true; +} 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 a24ad5ba..c19e98a4 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 @@ -113,6 +113,20 @@ export function PaymentProcessing() { {t('continueWithout3ds')} + From 6b92b9f7b4fdd79a151920600d3568406896265c Mon Sep 17 00:00:00 2001 From: Gytautas Zumaras Date: Mon, 16 Mar 2026 17:15:10 +0200 Subject: [PATCH 02/24] remove upgrade --- saferpayofficial.php | 2 +- upgrade/install-2.0.3.php | 36 ------------------------------------ 2 files changed, 1 insertion(+), 37 deletions(-) delete mode 100644 upgrade/install-2.0.3.php diff --git a/saferpayofficial.php b/saferpayofficial.php index 75e49ed5..b0acd463 100755 --- a/saferpayofficial.php +++ b/saferpayofficial.php @@ -65,7 +65,7 @@ public function __construct($name = null) { $this->name = 'saferpayofficial'; $this->author = 'Invertus'; - $this->version = '2.0.3'; + $this->version = '2.0.2'; $this->module_key = '3d3506c3e184a1fe63b936b82bda1bdf'; $this->displayName = 'SaferpayOfficial'; $this->description = 'Saferpay Payment module'; diff --git a/upgrade/install-2.0.3.php b/upgrade/install-2.0.3.php deleted file mode 100644 index c221693b..00000000 --- a/upgrade/install-2.0.3.php +++ /dev/null @@ -1,36 +0,0 @@ - - *@copyright SIX Payment Services - *@license SIX Payment Services - */ - -if (!defined('_PS_VERSION_')) { - exit; -} - -/** - * Upgrade to 2.0.3: - * - Add "Capture" option for "Behavior without 3D Secure" setting. - * - Existing installs keep their current value (no overwrite). - */ -function upgrade_module_2_0_3() -{ - return true; -} From 4e7eb47121cece54252e29ad8d866f30109c625f Mon Sep 17 00:00:00 2001 From: Gytautas Zumaras Date: Tue, 17 Mar 2026 10:23:51 +0200 Subject: [PATCH 03/24] feat: add Order reference on payment page toggle to control Description field value --- ...dminSaferPayOfficialSettingsController.php | 2 + src/Config/SaferPayConfig.php | 4 ++ src/Service/Request/RequestObjectCreator.php | 11 ++- src/Service/SettingsTranslationService.php | 4 ++ .../components/settings/general-settings.tsx | 68 +++++++++++++++---- .../src/context/settings-context.tsx | 1 + .../js/admin/settings-app/src/types/index.ts | 1 + 7 files changed, 77 insertions(+), 14 deletions(-) diff --git a/controllers/admin/AdminSaferPayOfficialSettingsController.php b/controllers/admin/AdminSaferPayOfficialSettingsController.php index bf6d10fe..70b8e14a 100755 --- a/controllers/admin/AdminSaferPayOfficialSettingsController.php +++ b/controllers/admin/AdminSaferPayOfficialSettingsController.php @@ -313,6 +313,7 @@ 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')); + $configuration->set(SaferPayConfig::SAFERPAY_ORDER_ID_OPTION, $this->getIntValue($data, 'orderIdOption')); $configuration->set(SaferPayConfig::SAFERPAY_DEBUG_MODE, !empty($data['debugMode']) ? 1 : 0); $this->ajaxResponse(true, $this->module->l('General settings saved successfully', self::FILE_NAME)); @@ -543,6 +544,7 @@ 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), + 'orderIdOption' => (int) $configuration->get(SaferPayConfig::SAFERPAY_ORDER_ID_OPTION), 'debugMode' => (bool) $configuration->get(SaferPayConfig::SAFERPAY_DEBUG_MODE), // Reference data diff --git a/src/Config/SaferPayConfig.php b/src/Config/SaferPayConfig.php index b7168ab4..793d0b8e 100755 --- a/src/Config/SaferPayConfig.php +++ b/src/Config/SaferPayConfig.php @@ -278,6 +278,8 @@ class SaferPayConfig const PAYMENT_BEHAVIOR_WITHOUT_3D_AUTHORIZE = 1; const PAYMENT_BEHAVIOR_WITHOUT_3D_CAPTURE = 2; + const SAFERPAY_ORDER_ID_OPTION = 'SAFERPAY_ORDER_ID_OPTION'; + const SAFERPAY_CARDFORM_HOLDERNAME_REQUIRENCE = 'MANDATORY'; const SAFERPAY_DEBUG_MODE = 'SAFERPAY_DEBUG_MODE'; @@ -440,6 +442,7 @@ public static function getDefaultConfiguration() SaferPayConfig::FIELDS_LIBRARY => self::FIELDS_LIBRARY_DEFAULT_VALUE, SaferPayConfig::FIELDS_LIBRARY . SaferPayConfig::TEST_SUFFIX => self::FIELDS_LIBRARY_TEST_DEFAULT_VALUE, self::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION => 0, + self::SAFERPAY_ORDER_ID_OPTION => 0, self::TEST_MODE => 1, self::HOSTED_FIELDS_TEMPLATE => self::HOSTED_FIELDS_TEMPLATE_DEFAULT, self::SAFERPAY_ORDER_STATE_CHOICE_AWAITING_PAYMENT => (int) Configuration::get( @@ -480,6 +483,7 @@ public static function getUninstallConfiguration() self::FIELDS_LIBRARY, self::FIELDS_LIBRARY . self::TEST_SUFFIX, self::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION, + self::SAFERPAY_ORDER_ID_OPTION, self::SAFERPAY_SEND_ORDER_CONF_MAIL, self::SAFERPAY_GROUP_CARDS, ]; diff --git a/src/Service/Request/RequestObjectCreator.php b/src/Service/Request/RequestObjectCreator.php index 6e961489..a5c40a19 100755 --- a/src/Service/Request/RequestObjectCreator.php +++ b/src/Service/Request/RequestObjectCreator.php @@ -118,13 +118,20 @@ public function createPayment(Cart $cart, $totalPrice) $payment = new Payment(); $payment->setValue($totalPrice); $payment->setCurrencyCode($currency['iso_code']); - $payment->setDescription((string) Configuration::get(SaferPayConfig::SAFERPAY_PAYMENT_DESCRIPTION)); + + $description = (string) Configuration::get(SaferPayConfig::SAFERPAY_PAYMENT_DESCRIPTION); + $orderIdOption = (int) Configuration::get(SaferPayConfig::SAFERPAY_ORDER_ID_OPTION); + + if ($orderIdOption === 0 && !empty($order)) { + $payment->setDescription($order->reference); + } else { + $payment->setDescription($description); + } if ((int) \Configuration::get(SaferPayConfig::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION) && empty($order)) { return $payment; } - /** This param is not mandatory, but recommended **/ $payment->setOrderReference($order->reference); return $payment; diff --git a/src/Service/SettingsTranslationService.php b/src/Service/SettingsTranslationService.php index 40959186..78a00b82 100644 --- a/src/Service/SettingsTranslationService.php +++ b/src/Service/SettingsTranslationService.php @@ -233,6 +233,10 @@ private function getGeneralSettingsTranslations() 'description' => $this->module->l('Description', self::FILE_NAME), 'enterDescription' => $this->module->l('Enter description', self::FILE_NAME), 'descriptionHelp' => $this->module->l('This description is visible in payment page also in payment confirmation email.', self::FILE_NAME), + 'orderReferenceOnPaymentPage' => $this->module->l('Order reference on payment page', self::FILE_NAME), + 'usePrestaShopOrderReference' => $this->module->l('Use PrestaShop Order reference (default)', self::FILE_NAME), + 'useDescriptionFieldValue' => $this->module->l('Use Description field value', self::FILE_NAME), + 'orderReferenceFallbackInfo' => html_entity_decode($this->module->l('When "Use PrestaShop Order reference" is selected and the order is not yet created (e.g. order creation after authorization), the Description field value is used as fallback.', self::FILE_NAME), ENT_QUOTES, 'UTF-8'), 'debugMode' => $this->module->l('Debug mode', self::FILE_NAME), 'debugModeDescription' => $this->module->l('Enable debug mode to see more information in logs.', self::FILE_NAME), ]; 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 70f74b73..6dac7f14 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 @@ -3,8 +3,9 @@ import { Label } from '@/components/ui/label' import { Input } from '@/components/ui/input' import { Button } from '@/components/ui/button' import { Switch } from '@/components/ui/switch' +import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' -import { Settings2, Paintbrush, ClipboardList, Loader2 } from 'lucide-react' +import { Settings2, Paintbrush, ClipboardList, Loader2, Info } from 'lucide-react' import { useSettings } from '@/context/settings-context' import { t } from '@/utils/translations' @@ -97,17 +98,60 @@ export function GeneralSettings() {
-
- - updateSettings({ paymentDescription: e.target.value })} - /> -

- {t('descriptionHelp')} + {/* Order reference on payment page */} +

+ + updateSettings({ orderIdOption: Number(val) })} + className="sp-flex sp-flex-col sp-gap-3" + > + + + +
+ + {settings.orderIdOption === 1 && ( +
+ + updateSettings({ paymentDescription: e.target.value })} + /> +

+ {t('descriptionHelp')} +

+
+ )} + + {/* Info banner */} +
+ +

+ {t('orderReferenceFallbackInfo')}

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 6abb19d3..47fd6f1f 100644 --- a/views/js/admin/settings-app/src/context/settings-context.tsx +++ b/views/js/admin/settings-app/src/context/settings-context.tsx @@ -126,6 +126,7 @@ export function SettingsProvider({ children }: { children: React.ReactNode }) { orderStateAwaitingPayment: currentSettings.orderStateAwaitingPayment, paymentDescription: currentSettings.paymentDescription, configurationName: currentSettings.configurationName, + orderIdOption: currentSettings.orderIdOption, debugMode: currentSettings.debugMode, }), 'General Settings', 'generalSettings') }, [handleSave]) diff --git a/views/js/admin/settings-app/src/types/index.ts b/views/js/admin/settings-app/src/types/index.ts index a8c88e05..af64ab59 100644 --- a/views/js/admin/settings-app/src/types/index.ts +++ b/views/js/admin/settings-app/src/types/index.ts @@ -54,6 +54,7 @@ export interface SaferpaySettingsData { orderStateAwaitingPayment: number paymentDescription: string configurationName: string + orderIdOption: number debugMode: boolean // Reference data From 64baef33c6637ff7e14326ea2d9a7af659dcd5f7 Mon Sep 17 00:00:00 2001 From: Gytautas Zumaras Date: Tue, 17 Mar 2026 15:47:09 +0200 Subject: [PATCH 04/24] feat: add ConfigSet field validation, move hosted field style to general settings --- .../AdminSaferPayOfficialFieldsController.php | 90 ------------------- ...dminSaferPayOfficialSettingsController.php | 15 +++- .../01_ps1764.Module.Configure.cy.js | 8 -- .../01_ps1770.Module.Configure.cy.js | 8 -- .../01_ps1784.Module.Configure.cy.js | 8 -- .../01_ps1786.Module.Configure.cy.js | 8 -- saferpayofficial.php | 3 +- src/Entity/index.php | 31 ------- src/Install/AbstractInstaller.php | 6 -- src/Service/Request/RequestObjectCreator.php | 6 +- src/Service/SettingsTranslationService.php | 10 ++- translations/en.php | 0 upgrade/install-1.0.3.php | 7 -- .../install-2.1.1.php | 23 +++-- views/css/admin/saferpay_fields.css | 49 ---------- views/js/admin/saferpay_settings.js | 23 +++-- .../components/settings/general-settings.tsx | 48 +++++++++- .../src/context/settings-context.tsx | 1 + .../js/admin/settings-app/src/types/index.ts | 2 + .../field-option-settings/helpers/index.php | 31 ------- .../helpers/options/index.php | 31 ------- .../helpers/options/options.tpl | 70 --------------- .../admin/field-option-settings/index.php | 31 ------- 23 files changed, 108 insertions(+), 401 deletions(-) delete mode 100755 controllers/admin/AdminSaferPayOfficialFieldsController.php delete mode 100755 src/Entity/index.php create mode 100644 translations/en.php rename views/templates/admin/partials/field-hosted-field-template-desc.tpl => upgrade/install-2.1.1.php (75%) mode change 100755 => 100644 delete mode 100755 views/css/admin/saferpay_fields.css delete mode 100755 views/templates/admin/field-option-settings/helpers/index.php delete mode 100755 views/templates/admin/field-option-settings/helpers/options/index.php delete mode 100755 views/templates/admin/field-option-settings/helpers/options/options.tpl delete mode 100755 views/templates/admin/field-option-settings/index.php diff --git a/controllers/admin/AdminSaferPayOfficialFieldsController.php b/controllers/admin/AdminSaferPayOfficialFieldsController.php deleted file mode 100755 index 7508d598..00000000 --- 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 70b8e14a..71ffd95e 100755 --- a/controllers/admin/AdminSaferPayOfficialSettingsController.php +++ b/controllers/admin/AdminSaferPayOfficialSettingsController.php @@ -312,7 +312,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); @@ -544,6 +555,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), diff --git a/cypress/integration/01_ps1764.Module.Configure.cy.js b/cypress/integration/01_ps1764.Module.Configure.cy.js index b7313cb4..f8988d2b 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 9696c496..1de0a18c 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 8da2aae5..716aa483 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 0c8259a9..863cb240 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 b0acd463..dd997aa5 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/Entity/index.php b/src/Entity/index.php deleted file mode 100755 index ee622726..00000000 --- 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 cbe8d897..2188841f 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 a5c40a19..21fc3983 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 78a00b82..58a315fb 100644 --- a/src/Service/SettingsTranslationService.php +++ b/src/Service/SettingsTranslationService.php @@ -188,7 +188,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 +227,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' => $this->module->l('Choose which hosted field will be displayed on payment option selection with supported payment methods.', self::FILE_NAME), + '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 00000000..e69de29b diff --git a/upgrade/install-1.0.3.php b/upgrade/install-1.0.3.php index 2574c76e..b4938c7f 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 8314405e..b7b39ae0 --- 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/saferpay_fields.css b/views/css/admin/saferpay_fields.css deleted file mode 100755 index 064c2c33..00000000 --- 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/saferpay_settings.js b/views/js/admin/saferpay_settings.js index 6407bc17..72f482b1 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/general-settings.tsx b/views/js/admin/settings-app/src/components/settings/general-settings.tsx index 6dac7f14..fc077be4 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')} +

+
+
+ { +
+
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 47fd6f1f..c4ce8f6c 100644 --- a/views/js/admin/settings-app/src/context/settings-context.tsx +++ b/views/js/admin/settings-app/src/context/settings-context.tsx @@ -126,6 +126,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/types/index.ts b/views/js/admin/settings-app/src/types/index.ts index af64ab59..436600c1 100644 --- a/views/js/admin/settings-app/src/types/index.ts +++ b/views/js/admin/settings-app/src/types/index.ts @@ -54,6 +54,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 ee622726..00000000 --- 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 ee622726..00000000 --- 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 4c100589..00000000 --- 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 ee622726..00000000 --- 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; From a766c174fed3508b6f694bb69972ab0943a784de Mon Sep 17 00:00:00 2001 From: Gytautas Zumaras Date: Fri, 20 Mar 2026 14:10:19 +0200 Subject: [PATCH 05/24] feat: add accessibility improvements for EAA compliance --- src/Service/SettingsTranslationService.php | 1 + views/css/admin/logs_tab.css | 23 +++++++++++++- views/css/admin/payment_method.css | 6 ++++ views/js/admin/log.js | 31 +++++++++++++++++-- .../components/settings/api-credentials.tsx | 4 +-- .../settings/email-notifications.tsx | 2 +- .../components/settings/general-settings.tsx | 2 +- .../components/settings/payment-methods.tsx | 4 +-- .../settings/payment-processing.tsx | 2 +- views/templates/admin/logs/log_modal.tpl | 12 ++++--- views/templates/front/credit_card.tpl | 5 +-- views/templates/front/credit_cards.tpl | 6 +++- .../hosted-templates/partials/all_errors.tpl | 8 ++--- .../partials/all_errors_16.tpl | 8 ++--- .../front/hosted-templates/template1.tpl | 24 +++++++++----- .../front/hosted-templates/template3.tpl | 26 ++++++++++------ views/templates/front/loading.tpl | 4 ++- views/templates/front/saferpay_iframe.tpl | 4 +-- views/templates/front/saferpay_wait.tpl | 3 +- views/templates/hook/admin/saferpay_order.tpl | 3 ++ .../hook/front/payment_with_cards.tpl | 4 +-- .../hook/front/saferpay_additional_info.tpl | 26 ++++++++++------ .../templates/hook/front/saferpay_payment.tpl | 2 +- 23 files changed, 149 insertions(+), 61 deletions(-) diff --git a/src/Service/SettingsTranslationService.php b/src/Service/SettingsTranslationService.php index 58a315fb..d657fdb0 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), diff --git a/views/css/admin/logs_tab.css b/views/css/admin/logs_tab.css index 5bb36a92..702cff1e 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 336eda6f..9b0b08c9 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/js/admin/log.js b/views/js/admin/log.js index 4a8eb769..481b07f9 100644 --- a/views/js/admin/log.js +++ b/views/js/admin/log.js @@ -21,17 +21,44 @@ */ $(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) { + if (event.key === 'Escape') { + var $openModal = $('.modal.open'); + if ($openModal.length) { + closeModal($openModal); + 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/settings-app/src/components/settings/api-credentials.tsx b/views/js/admin/settings-app/src/components/settings/api-credentials.tsx index 5a393190..15484be1 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 @@ -168,7 +168,7 @@ 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 044239c8..d79d331a 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 fc077be4..8a43d815 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 @@ -221,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 bc3fc449..01149c2a 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 @@ -48,7 +48,7 @@ function MultiSelect({ 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 c19e98a4..3d26f72d 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/templates/admin/logs/log_modal.tpl b/views/templates/admin/logs/log_modal.tpl index 62cb43dd..eadfc7fc 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'} -
+ -