Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions config/services/client.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,14 @@
method="create"/>
<argument type="string" key="$factoryName">payplug_wero</argument><!-- Gateway factory name -->
</service>

<service id="payplug_sylius_payplug_plugin.api_client.uhf"
class="PayPlug\SyliusPayPlugPlugin\ApiClient\PayPlugApiClient"
public="true"
lazy="true">
<factory service="PayPlug\SyliusPayPlugPlugin\ApiClient\PayPlugApiClientFactory"
method="create"/>
<argument type="string" key="$factoryName">payplug_uhf</argument><!-- Gateway factory name -->
</service>
</services>
</container>
9 changes: 9 additions & 0 deletions config/twig_hooks/admin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace PayPlug\SyliusPayPlugPlugin\Gateway\Form\Extension;

use PayPlug\SyliusPayPlugPlugin\Gateway\Form\Type\AbstractGatewayConfigurationType;
use PayPlug\SyliusPayPlugPlugin\Gateway\Form\Type\UhfGatewayConfigurationType;
use PayPlug\SyliusPayPlugPlugin\Gateway\UhfGatewayFactory;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;

final class UhfGatewayConfigurationTypeExtension extends AbstractTypeExtension
{
/**
* @inheritdoc
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->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];
}
}
25 changes: 25 additions & 0 deletions src/Gateway/Form/Type/UhfGatewayConfigurationType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace PayPlug\SyliusPayPlugPlugin\Gateway\Form\Type;

use PayPlug\SyliusPayPlugPlugin\Gateway\UhfGatewayFactory;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;

#[AutoconfigureTag(
'sylius.gateway_configuration_type',
[
'type' => '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;
}
14 changes: 14 additions & 0 deletions src/Gateway/UhfGatewayFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace PayPlug\SyliusPayPlugPlugin\Gateway;

final class UhfGatewayFactory extends AbstractGatewayFactory
{
public const FACTORY_NAME = 'payplug_uhf';

public const FACTORY_TITLE = 'Unified Hosted Fields by PayPlug';

public const HF_IDENTIFIER_DEFAULT = 'hfIdentifierDefault';
}
42 changes: 8 additions & 34 deletions src/Validator/PaymentMethodValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PayPlug\SyliusPayPlugPlugin\Gateway\OneyGatewayFactory;
use PayPlug\SyliusPayPlugPlugin\Gateway\PayPlugGatewayFactory;
use PayPlug\SyliusPayPlugPlugin\Gateway\ScalapayGatewayFactory;
use PayPlug\SyliusPayPlugPlugin\Gateway\UhfGatewayFactory;
use PayPlug\SyliusPayPlugPlugin\Gateway\Validator\Constraints\IsCanSavePaymentMethod;
use PayPlug\SyliusPayPlugPlugin\Gateway\Validator\Constraints\IsOneyEnabled;
use PayPlug\SyliusPayPlugPlugin\Gateway\Validator\Constraints\PayplugPermission;
Expand Down Expand Up @@ -45,11 +46,12 @@ public function process(PaymentMethodInterface $paymentMethod): void
$errors = match ($paymentMethod->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'),
};

Expand Down Expand Up @@ -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()];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% set form = hookable_metadata.context.form.gatewayConfig.config.hfIdentifierDefault %}

<div class="col-12 col-md-6 mt-5">
{{ form_row(form) }}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace Tests\PayPlug\SyliusPayPlugPlugin\PHPUnit\Gateway\Form\Extension;

use PayPlug\SyliusPayPlugPlugin\Gateway\Form\Extension\UhfGatewayConfigurationTypeExtension;
use PayPlug\SyliusPayPlugPlugin\Gateway\Form\Type\AbstractGatewayConfigurationType;
use PayPlug\SyliusPayPlugPlugin\Gateway\Form\Type\UhfGatewayConfigurationType;
use PayPlug\SyliusPayPlugPlugin\Gateway\UhfGatewayFactory;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;

final class UhfGatewayConfigurationTypeExtensionTest extends TestCase
{
private UhfGatewayConfigurationTypeExtension $extension;

protected function setUp(): void
{
$this->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());
}
}
34 changes: 34 additions & 0 deletions tests/PHPUnit/Validator/PaymentMethodValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
// -------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions translations/messages.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 "<b>Update</b>" button.
hf_identifier_default_label: 'HF Identifier'
form:
oney_error: Some missing information is required to pay using Oney by Payplug
complete_info:
Expand Down
2 changes: 2 additions & 0 deletions translations/messages.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 "<b>Mise à jour</b>".
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:
Expand Down
2 changes: 2 additions & 0 deletions translations/messages.it.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 "<b>Aggiorna</b>".
hf_identifier_default_label: 'Identificatore HF'
form:
oney_error: Mancano alcune informazioni per poter pagare con “Oney by Payplug”
complete_info:
Expand Down
8 changes: 8 additions & 0 deletions translations/validators.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 8 additions & 0 deletions translations/validators.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 8 additions & 0 deletions translations/validators.it.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading