diff --git a/config/services/client.xml b/config/services/client.xml
index 73148c93..4e2053e8 100644
--- a/config/services/client.xml
+++ b/config/services/client.xml
@@ -90,5 +90,14 @@
method="create"/>
payplug_wero
+
+
+
+ payplug_uhf
+
diff --git a/config/twig_hooks/admin.yaml b/config/twig_hooks/admin.yaml
index ebd3dc54..0683e861 100644
--- a/config/twig_hooks/admin.yaml
+++ b/config/twig_hooks/admin.yaml
@@ -44,6 +44,12 @@ sylius_twig_hooks:
'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.payplug_wero': &weroGateway
live_checkbox: *liveCheckbox
+ 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.payplug_uhf': &uhfGateway
+ live_checkbox: *liveCheckbox
+ hf_identifier_default: &hfIdentifierDefault
+ template: '@PayPlugSyliusPayPlugPlugin/admin/payment_method/form/hf_identifier_default.html.twig'
+ priority: -1
+
'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.payplug':
<<: *payplugGateway
renew_oauth: &renewOAuth
@@ -67,3 +73,6 @@ sylius_twig_hooks:
'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.payplug_wero':
<<: *weroGateway
renew_oauth: *renewOAuth
+ 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.payplug_uhf':
+ <<: *uhfGateway
+ renew_oauth: *renewOAuth
diff --git a/src/Gateway/Form/Extension/UhfGatewayConfigurationTypeExtension.php b/src/Gateway/Form/Extension/UhfGatewayConfigurationTypeExtension.php
new file mode 100644
index 00000000..21bc13ea
--- /dev/null
+++ b/src/Gateway/Form/Extension/UhfGatewayConfigurationTypeExtension.php
@@ -0,0 +1,38 @@
+add(UhfGatewayFactory::HF_IDENTIFIER_DEFAULT, TextType::class, [
+ 'label' => 'payplug_sylius_payplug_plugin.ui.hf_identifier_default_label',
+ 'required' => true,
+ 'validation_groups' => AbstractGatewayConfigurationType::VALIDATION_GROUPS,
+ 'constraints' => [
+ new NotBlank([]),
+ ],
+ ])
+ ;
+ }
+
+ public static function getExtendedTypes(): iterable
+ {
+ return [UhfGatewayConfigurationType::class];
+ }
+}
diff --git a/src/Gateway/Form/Type/UhfGatewayConfigurationType.php b/src/Gateway/Form/Type/UhfGatewayConfigurationType.php
new file mode 100644
index 00000000..c7d0b9ef
--- /dev/null
+++ b/src/Gateway/Form/Type/UhfGatewayConfigurationType.php
@@ -0,0 +1,25 @@
+ 'payplug_uhf',
+ 'label' => 'payplug_sylius_payplug_plugin.ui.uhf_gateway_label',
+ 'priority' => 80,
+ ],
+)]
+final class UhfGatewayConfigurationType extends AbstractGatewayConfigurationType
+{
+ protected string $gatewayFactoryTitle = UhfGatewayFactory::FACTORY_TITLE;
+
+ protected string $gatewayFactoryName = UhfGatewayFactory::FACTORY_NAME;
+
+ protected string $gatewayBaseCurrencyCode = UhfGatewayFactory::BASE_CURRENCY_CODE;
+}
diff --git a/src/Gateway/UhfGatewayFactory.php b/src/Gateway/UhfGatewayFactory.php
new file mode 100644
index 00000000..e5dd882d
--- /dev/null
+++ b/src/Gateway/UhfGatewayFactory.php
@@ -0,0 +1,14 @@
+getGatewayConfig()->getFactoryName()) {
PayPlugGatewayFactory::FACTORY_NAME => $this->processPayplug($paymentMethod),
OneyGatewayFactory::FACTORY_NAME => $this->processOney($paymentMethod),
- BancontactGatewayFactory::FACTORY_NAME => $this->processBancontact($paymentMethod),
- AmericanExpressGatewayFactory::FACTORY_NAME => $this->processAmex($paymentMethod),
- ApplePayGatewayFactory::FACTORY_NAME => $this->processApplePay($paymentMethod),
- ScalapayGatewayFactory::FACTORY_NAME => $this->processScalapay($paymentMethod),
- WeroGatewayFactory::FACTORY_NAME => $this->processWero($paymentMethod),
+ BancontactGatewayFactory::FACTORY_NAME => $this->processDefault($paymentMethod),
+ AmericanExpressGatewayFactory::FACTORY_NAME => $this->processDefault($paymentMethod),
+ ApplePayGatewayFactory::FACTORY_NAME => $this->processDefault($paymentMethod),
+ ScalapayGatewayFactory::FACTORY_NAME => $this->processDefault($paymentMethod),
+ WeroGatewayFactory::FACTORY_NAME => $this->processDefault($paymentMethod),
+ UhfGatewayFactory::FACTORY_NAME => $this->processDefault($paymentMethod),
default => throw new \InvalidArgumentException('Unsupported payment method'),
};
@@ -88,35 +90,7 @@ private function processOney(PaymentMethodInterface $paymentMethod): ConstraintV
return $this->validator->validate($paymentMethod, $constraintList, self::VALIDATION_GROUPS);
}
- private function processBancontact(PaymentMethodInterface $paymentMethod): ConstraintViolationListInterface
- {
- $constraintList = [new IsCanSavePaymentMethod()];
-
- return $this->validator->validate($paymentMethod, $constraintList, self::VALIDATION_GROUPS);
- }
-
- private function processAmex(PaymentMethodInterface $paymentMethod): ConstraintViolationListInterface
- {
- $constraintList = [new IsCanSavePaymentMethod()];
-
- return $this->validator->validate($paymentMethod, $constraintList, self::VALIDATION_GROUPS);
- }
-
- private function processApplePay(PaymentMethodInterface $paymentMethod): ConstraintViolationListInterface
- {
- $constraintList = [new IsCanSavePaymentMethod()];
-
- return $this->validator->validate($paymentMethod, $constraintList, self::VALIDATION_GROUPS);
- }
-
- private function processScalapay(PaymentMethodInterface $paymentMethod): ConstraintViolationListInterface
- {
- $constraintList = [new IsCanSavePaymentMethod()];
-
- return $this->validator->validate($paymentMethod, $constraintList, self::VALIDATION_GROUPS);
- }
-
- private function processWero(PaymentMethodInterface $paymentMethod): ConstraintViolationListInterface
+ private function processDefault(PaymentMethodInterface $paymentMethod): ConstraintViolationListInterface
{
$constraintList = [new IsCanSavePaymentMethod()];
diff --git a/templates/admin/payment_method/form/hf_identifier_default.html.twig b/templates/admin/payment_method/form/hf_identifier_default.html.twig
new file mode 100644
index 00000000..08bcf7ff
--- /dev/null
+++ b/templates/admin/payment_method/form/hf_identifier_default.html.twig
@@ -0,0 +1,5 @@
+{% set form = hookable_metadata.context.form.gatewayConfig.config.hfIdentifierDefault %}
+
+
+ {{ form_row(form) }}
+
diff --git a/tests/PHPUnit/Gateway/Form/Extension/UhfGatewayConfigurationTypeExtensionTest.php b/tests/PHPUnit/Gateway/Form/Extension/UhfGatewayConfigurationTypeExtensionTest.php
new file mode 100644
index 00000000..0d1e7d7d
--- /dev/null
+++ b/tests/PHPUnit/Gateway/Form/Extension/UhfGatewayConfigurationTypeExtensionTest.php
@@ -0,0 +1,59 @@
+extension = new UhfGatewayConfigurationTypeExtension();
+ }
+
+ public function testBuildForm_addsHfIdentifierDefaultTextField(): void
+ {
+ $builder = $this->createMock(FormBuilderInterface::class);
+
+ $addCalls = [];
+ $builder
+ ->expects(self::once())
+ ->method('add')
+ ->willReturnCallback(function ($name, $type = null, array $options = []) use (&$addCalls, $builder) {
+ $addCalls[] = [$name, $type, $options];
+
+ return $builder;
+ })
+ ;
+
+ $this->extension->buildForm($builder, []);
+
+ [$name, $type, $options] = $addCalls[0];
+ self::assertSame(UhfGatewayFactory::HF_IDENTIFIER_DEFAULT, $name);
+ self::assertSame(TextType::class, $type);
+ self::assertSame(
+ 'payplug_sylius_payplug_plugin.ui.hf_identifier_default_label',
+ $options['label'],
+ );
+ self::assertTrue($options['required']);
+ self::assertSame(AbstractGatewayConfigurationType::VALIDATION_GROUPS, $options['validation_groups']);
+ self::assertCount(1, $options['constraints']);
+ self::assertInstanceOf(NotBlank::class, $options['constraints'][0]);
+ }
+
+ public function testGetExtendedTypes_returnsUhfGatewayConfigurationType(): void
+ {
+ self::assertSame([UhfGatewayConfigurationType::class], UhfGatewayConfigurationTypeExtension::getExtendedTypes());
+ }
+}
diff --git a/tests/PHPUnit/Validator/PaymentMethodValidatorTest.php b/tests/PHPUnit/Validator/PaymentMethodValidatorTest.php
index f8fb7b70..0da3f243 100644
--- a/tests/PHPUnit/Validator/PaymentMethodValidatorTest.php
+++ b/tests/PHPUnit/Validator/PaymentMethodValidatorTest.php
@@ -8,6 +8,8 @@
use PayPlug\SyliusPayPlugPlugin\Gateway\BancontactGatewayFactory;
use PayPlug\SyliusPayPlugPlugin\Gateway\OneyGatewayFactory;
use PayPlug\SyliusPayPlugPlugin\Gateway\PayPlugGatewayFactory;
+use PayPlug\SyliusPayPlugPlugin\Gateway\UhfGatewayFactory;
+use PayPlug\SyliusPayPlugPlugin\Gateway\Validator\Constraints\IsCanSavePaymentMethod;
use PayPlug\SyliusPayPlugPlugin\Validator\PaymentMethodValidator;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
@@ -208,6 +210,38 @@ public function testProcess_payplugFactory_allFlagsEnabled_validatesWithAllConst
$this->paymentMethodValidator->process($paymentMethod);
}
+ // -------------------------------------------------------------------------
+ // process() — UHF factory → routed to processDefault(), base constraint only
+ // -------------------------------------------------------------------------
+
+ /**
+ * UHF gateway. Verifies the match statement routes UhfGatewayFactory::FACTORY_NAME to
+ * processDefault(), which validates with the base IsCanSavePaymentMethod constraint only (1
+ * total), the same as Bancontact/Amex/ApplePay/Scalapay/Wero.
+ */
+ public function testProcess_uhfFactory_validatesWithBaseConstraintOnly(): void
+ {
+ $paymentMethod = $this->buildPaymentMethod(UhfGatewayFactory::FACTORY_NAME, []);
+
+ $this->validator
+ ->expects(self::once())
+ ->method('validate')
+ ->willReturnCallback(function ($subject, array $constraints) {
+ self::assertCount(1, $constraints);
+ self::assertInstanceOf(IsCanSavePaymentMethod::class, $constraints[0]);
+
+ return new ConstraintViolationList();
+ })
+ ;
+
+ $flashBag = $this->createMock(FlashBagInterface::class);
+ $session = $this->createMock(Session::class);
+ $session->method('getFlashBag')->willReturn($flashBag);
+ $this->requestStack->method('getSession')->willReturn($session);
+
+ $this->paymentMethodValidator->process($paymentMethod);
+ }
+
// -------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------
diff --git a/translations/messages.en.yml b/translations/messages.en.yml
index 9ffa6acb..a6c4e5bc 100644
--- a/translations/messages.en.yml
+++ b/translations/messages.en.yml
@@ -26,6 +26,7 @@ payplug_sylius_payplug_plugin:
bancontact_gateway_label: Bancontact by Payplug
scalapay_gateway_label: Scalapay by PayPlug
wero_gateway_label: Wero by PayPlug
+ uhf_gateway_label: Unified Hosted Fields by PayPlug
apple_pay_gateway_label: Apple Pay by Payplug
american_express_gateway_label: American Express by Payplug
apple_pay_not_available: Apple Pay is not available on this browser or device.
@@ -117,6 +118,7 @@ payplug_sylius_payplug_plugin:
renew_oauth: Force OAuth reconnection
renew_oauth_help: |
If this option is checked, a new authentication flow will be started when clicking the "Update" button.
+ hf_identifier_default_label: 'HF Identifier'
form:
oney_error: Some missing information is required to pay using Oney by Payplug
complete_info:
diff --git a/translations/messages.fr.yml b/translations/messages.fr.yml
index 068fba68..8fff41d7 100644
--- a/translations/messages.fr.yml
+++ b/translations/messages.fr.yml
@@ -26,6 +26,7 @@ payplug_sylius_payplug_plugin:
bancontact_gateway_label: Bancontact by Payplug
scalapay_gateway_label: Scalapay by PayPlug
wero_gateway_label: Wero by PayPlug
+ uhf_gateway_label: Unified Hosted Fields by PayPlug
apple_pay_gateway_label: Apple Pay by Payplug
american_express_gateway_label: American Express by Payplug
apple_pay_not_available: Apple Pay n'est pas disponible sur ce navigateur ou appareil.
@@ -137,6 +138,7 @@ payplug_sylius_payplug_plugin:
renew_oauth: Forcer la reconnexion OAuth
renew_oauth_help: |
Si cette option est cochée, un nouveau flux d’authentification sera lancé lors du clic sur le bouton "Mise à jour".
+ hf_identifier_default_label: 'Identifiant HF'
form:
oney_error: Il y a des informations manquantes pour pouvoir payer en utilisant Oney by Payplug
complete_info:
diff --git a/translations/messages.it.yml b/translations/messages.it.yml
index 10459f42..390ab06c 100644
--- a/translations/messages.it.yml
+++ b/translations/messages.it.yml
@@ -26,6 +26,7 @@ payplug_sylius_payplug_plugin:
bancontact_gateway_label: Bancontact by Payplug
scalapay_gateway_label: Scalapay by PayPlug
wero_gateway_label: Wero by PayPlug
+ uhf_gateway_label: Unified Hosted Fields by PayPlug
apple_pay_gateway_label: Apple Pay by Payplug
american_express_gateway_label: American Express by Payplug
apple_pay_not_available: Apple Pay non è disponibile su questo browser o dispositivo.
@@ -117,6 +118,7 @@ payplug_sylius_payplug_plugin:
renew_oauth: Forza la riconnessione OAuth
renew_oauth_help: |
Se questa opzione è selezionata, un nuovo flusso di autenticazione verrà avviato quando si fa clic sul pulsante "Aggiorna".
+ hf_identifier_default_label: 'Identificatore HF'
form:
oney_error: Mancano alcune informazioni per poter pagare con “Oney by Payplug”
complete_info:
diff --git a/translations/validators.en.yml b/translations/validators.en.yml
index 78c1c1fe..9e68408c 100644
--- a/translations/validators.en.yml
+++ b/translations/validators.en.yml
@@ -41,6 +41,14 @@ payplug_sylius_payplug_plugin:
You don't have access to this feature yet.
To activate Wero, please contact us at support@payplug.com
and activate the LIVE mode.
+ payplug_uhf:
+ can_not_save_method_with_test_key: |
+ The Unified Hosted Fields payment method is not available for the TEST mode.
+ Please activate the LIVE mode.
+ can_not_save_method_no_access: |
+ You don't have access to this feature yet.
+ To activate Unified Hosted Fields, please contact us at support@payplug.com
+ and activate the LIVE mode.
payplug_apple_pay:
can_not_save_method_with_test_key: |
The Apple Pay payment method is not available for the TEST mode.
diff --git a/translations/validators.fr.yml b/translations/validators.fr.yml
index 6031253d..f04a6995 100644
--- a/translations/validators.fr.yml
+++ b/translations/validators.fr.yml
@@ -40,6 +40,14 @@ payplug_sylius_payplug_plugin:
Vous n'avez pas accès à cette fonctionnalité.
Pour activer Wero, contactez-nous à support@payplug.com
et activez le mode LIVE.
+ payplug_uhf:
+ can_not_save_method_with_test_key: |
+ Le paiement par Unified Hosted Fields n'est pas disponible en mode TEST.
+ Veuillez activer le mode LIVE.
+ can_not_save_method_no_access: |
+ Vous n'avez pas accès à cette fonctionnalité.
+ Pour activer Unified Hosted Fields, contactez-nous à support@payplug.com
+ et activez le mode LIVE.
payplug_apple_pay:
can_not_save_method_with_test_key: |
Le paiement par Apple Pay n’est pas disponible en mode TEST.
diff --git a/translations/validators.it.yml b/translations/validators.it.yml
index 7dcf67b4..b5460fc2 100644
--- a/translations/validators.it.yml
+++ b/translations/validators.it.yml
@@ -40,6 +40,14 @@ payplug_sylius_payplug_plugin:
Non puoi ancora accedere a questa funzionalità.
Per attivare Wero, contattaci a support@payplug.com
e attiva la modalità LIVE.
+ payplug_uhf:
+ can_not_save_method_with_test_key: |
+ Il metodo di pagamento Unified Hosted Fields non è disponibile in modalità TEST.
+ Attiva la modalità LIVE.
+ can_not_save_method_no_access: |
+ Non puoi ancora accedere a questa funzionalità.
+ Per attivare Unified Hosted Fields, contattaci a support@payplug.com
+ e attiva la modalità LIVE.
payplug_american_express:
can_not_save_method_with_test_key: |
Il pagamento Apple Pay non è disponibile in modalità TEST.