diff --git a/.github/workflows/sylius.yaml b/.github/workflows/sylius.yaml index 4aa0da6d..30cde6ff 100644 --- a/.github/workflows/sylius.yaml +++ b/.github/workflows/sylius.yaml @@ -116,7 +116,7 @@ jobs: run: 'vendor/bin/behat --strict --no-interaction -f progress || vendor/bin/behat --strict -vvv --no-interaction --rerun' if: 'always() && steps.end-of-setup-sylius.outcome == ''success''' - - uses: actions/upload-artifact@v2.1.4 + uses: actions/upload-artifact@v3 if: failure() with: name: logs diff --git a/install/Application/config/routes/sylius_refund.yaml b/install/Application/config/routes/sylius_refund.yaml new file mode 100755 index 00000000..46e99b16 --- /dev/null +++ b/install/Application/config/routes/sylius_refund.yaml @@ -0,0 +1,2 @@ +sylius_refund: + resource: "@SyliusRefundPlugin/Resources/config/routing.yml" diff --git a/rulesets/phpstan-baseline.neon b/rulesets/phpstan-baseline.neon index 0b8bc216..13b6d8a8 100644 --- a/rulesets/phpstan-baseline.neon +++ b/rulesets/phpstan-baseline.neon @@ -57,7 +57,7 @@ parameters: - message: "#^Cannot call method getFirstModel\\(\\) on mixed\\.$#" - count: 2 + count: 3 path: ../src/Action/StatusAction.php - @@ -77,7 +77,7 @@ parameters: - message: "#^Parameter \\#1 \\$paymentId of method PayPlug\\\\SyliusPayPlugPlugin\\\\ApiClient\\\\PayPlugApiClientInterface\\:\\:retrieve\\(\\) expects string, mixed given\\.$#" - count: 2 + count: 3 path: ../src/Action/StatusAction.php - @@ -439,3 +439,12 @@ parameters: message: "#^Parameter \\#1 \\$tokenValue of method Sylius\\\\Component\\\\Order\\\\Repository\\\\OrderRepositoryInterface\\:\\:findOneByTokenValue\\(\\) expects string, mixed given\\.$#" count: 1 path: ../src/Twig/OneySimulationExtension.php + - + message: "#^PHPDoc tag @param for parameter \\$paymentMethodRepository contains generic type Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface\\ but interface Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface is not generic\\.$#" + count: 1 + path: ../src/Controller/IntegratedPaymentController.php + + - + message: "#^PHPDoc tag @var for property PayPlug\\\\SyliusPayPlugPlugin\\\\Controller\\\\IntegratedPaymentController\\:\\:\\$paymentMethodRepository contains generic type Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface\\ but interface Sylius\\\\Component\\\\Resource\\\\Repository\\\\RepositoryInterface is not generic\\.$#" + count: 1 + path: ../src/Controller/IntegratedPaymentController.php diff --git a/src/Action/CaptureAction.php b/src/Action/CaptureAction.php index 3179190d..e104a432 100644 --- a/src/Action/CaptureAction.php +++ b/src/Action/CaptureAction.php @@ -94,6 +94,12 @@ public function execute($request): void return; } + if (PayPlugApiClientInterface::FAILED === ($details['status'] ?? null) && + PayPlugApiClientInterface::INTEGRATED_PAYMENT_INTEGRATION === ($details['integration'] ?? null)) { + // Do not try to capture a failed integrated payment and do not remove status + return; + } + if (isset($details['status']) && PayPlugApiClientInterface::FAILED === $details['status']) { // Unset current status to allow to use payplug to change payment method unset($details['status']); diff --git a/src/Action/StatusAction.php b/src/Action/StatusAction.php index b5ee44ae..ccc5ba2f 100644 --- a/src/Action/StatusAction.php +++ b/src/Action/StatusAction.php @@ -88,6 +88,11 @@ public function execute($request): void $this->paymentNotificationHandler->treat($request->getFirstModel(), $resource, $details); } + if (PaymentInterface::STATE_PROCESSING === $details['status']) { + $resource = $this->payPlugApiClient->retrieve($details['payment_id']); + $this->paymentNotificationHandler->treat($request->getFirstModel(), $resource, $details); + } + $payment->setDetails($details->getArrayCopy()); $this->markRequestAs($details['status'], $request); } diff --git a/src/ApiClient/PayPlugApiClientFactory.php b/src/ApiClient/PayPlugApiClientFactory.php index f647a009..3e93429a 100644 --- a/src/ApiClient/PayPlugApiClientFactory.php +++ b/src/ApiClient/PayPlugApiClientFactory.php @@ -4,6 +4,7 @@ namespace PayPlug\SyliusPayPlugPlugin\ApiClient; +use Sylius\Component\Core\Model\PaymentMethodInterface; use Sylius\Component\Resource\Repository\RepositoryInterface; use Symfony\Contracts\Cache\CacheInterface; @@ -37,4 +38,14 @@ public function create(string $factoryName, ?string $key = null): PayPlugApiClie return new PayPlugApiClient($key, $factoryName, $this->cache); } + + public function createForPaymentMethod(PaymentMethodInterface $paymentMethod): PayPlugApiClientInterface + { + $gatewayConfig = $paymentMethod->getGatewayConfig() ?? throw new \LogicException('Gateway config not found'); + + $key = $gatewayConfig->getConfig()['secretKey']; + $factoryName = $gatewayConfig->getFactoryName(); + + return new PayPlugApiClient($key, $factoryName, $this->cache); + } } diff --git a/src/ApiClient/PayPlugApiClientInterface.php b/src/ApiClient/PayPlugApiClientInterface.php index 558f5196..aff3041e 100644 --- a/src/ApiClient/PayPlugApiClientInterface.php +++ b/src/ApiClient/PayPlugApiClientInterface.php @@ -13,6 +13,8 @@ interface PayPlugApiClientInterface { public const INTERNAL_STATUS_ONE_CLICK = 'one_click'; + public const INTEGRATED_PAYMENT_INTEGRATION = 'INTEGRATED_PAYMENT'; + public const LIVE_KEY_PREFIX = 'sk_live'; public const TEST_KEY_PREFIX = 'sk_test'; diff --git a/src/Controller/IntegratedPaymentController.php b/src/Controller/IntegratedPaymentController.php new file mode 100644 index 00000000..cd56a432 --- /dev/null +++ b/src/Controller/IntegratedPaymentController.php @@ -0,0 +1,115 @@ + + */ + private RepositoryInterface $paymentMethodRepository; + private OrderRepositoryInterface $orderRepository; + private PayPlugPaymentDataCreator $paymentDataCreator; + private PayPlugApiClientFactory $apiClientFactory; + private EntityManagerInterface $entityManager; + private LoggerInterface $logger; + + /** + * @param RepositoryInterface<\Sylius\Component\Core\Model\PaymentMethodInterface> $paymentMethodRepository + */ + public function __construct( + CartContextInterface $cartContext, + RepositoryInterface $paymentMethodRepository, + OrderRepositoryInterface $orderRepository, + PayPlugPaymentDataCreator $paymentDataCreator, + PayPlugApiClientFactory $apiClientFactory, + EntityManagerInterface $entityManager, + LoggerInterface $logger + ) { + $this->cartContext = $cartContext; + $this->paymentMethodRepository = $paymentMethodRepository; + $this->orderRepository = $orderRepository; + $this->paymentDataCreator = $paymentDataCreator; + $this->apiClientFactory = $apiClientFactory; + $this->entityManager = $entityManager; + $this->logger = $logger; + } + + /** + * The InitPayment action is called when the user clicks on the "Pay" button from the integratedPayment iframe. + * + * The actual payment (ie latest in cart state) of the order is sent to Payplug, + * specifying the IntegratedPayment integration. + * + * @see https://docs.payplug.com/api/integratedref.html#trigger-a-payment + */ + public function initPaymentAction(Request $request, int $paymentMethodId): Response + { + $paymentMethod = $this->paymentMethodRepository->find($paymentMethodId); + if (!$paymentMethod instanceof PaymentMethodInterface) { + throw $this->createNotFoundException(); + } + + $order = null; + if (\is_string($orderToken = $request->query->get('orderToken'))) { + $order = $this->orderRepository->findOneByTokenValue($orderToken); + } + if (null === $order) { + $order = $this->cartContext->getCart(); + } + if (!$order instanceof OrderInterface) { + throw $this->createNotFoundException('No order found'); + } + + $payment = $order->getLastPayment(); + if (!$payment instanceof PaymentInterface) { + throw $this->createNotFoundException('No payment available'); + } + + $payment->setMethod($paymentMethod); + $factoryName = $paymentMethod->getGatewayConfig()?->getFactoryName(); + if (PayPlugGatewayFactory::FACTORY_NAME !== $factoryName) { + throw new BadRequestHttpException('Unsupported payment method of Integrated Payment'); + } + + $paymentData = $this->paymentDataCreator->create($payment, $factoryName); + // Mandatory + $paymentData['integration'] = PayPlugApiClientInterface::INTEGRATED_PAYMENT_INTEGRATION; + $this->logger->debug('Payplug Payment data for creation', $paymentData->getArrayCopy()); + + $apiClient = $this->apiClientFactory->create($factoryName); + $payplugPayment = $apiClient->createPayment($paymentData->getArrayCopy()); + $this->logger->debug('PayPlug payment created', (array) $payplugPayment); + + $paymentData['payment_id'] = $payplugPayment->id; + $paymentData['is_live'] = $payplugPayment->is_live; + $payment->setDetails($paymentData->getArrayCopy()); + + $this->entityManager->flush(); + + return new JsonResponse([ + 'payment_id' => $payplugPayment->id, + ], Response::HTTP_CREATED); + } +} diff --git a/src/EventSubscriber/PostPaymentSelectEventSubscriber.php b/src/EventSubscriber/PostPaymentSelectEventSubscriber.php new file mode 100644 index 00000000..a4dcb5aa --- /dev/null +++ b/src/EventSubscriber/PostPaymentSelectEventSubscriber.php @@ -0,0 +1,140 @@ + 'alterRequestConfigurationForIntegratedPayment', + 'sylius.order.post_payment' => 'handle', + 'sylius.order.post_update' => 'handle', + ]; + } + + public function alterRequestConfigurationForIntegratedPayment(RequestEvent $event): void + { + $request = $event->getRequest(); + if (!$this->hasToken($request) || self::CHECKOUT_ROUTE !== $request->attributes->get('_route')) { + return; + } + if (!$request->attributes->has('_sylius')) { + return; + } + + $syliusRequestConfig = $request->attributes->get('_sylius'); + if (!\is_array($syliusRequestConfig)) { + return; + } + + $syliusRequestConfig['redirect'] = [ + 'route' => 'sylius_shop_order_pay', + 'parameters' => ['tokenValue' => 'resource.tokenValue'], + ]; + + $request->attributes->set('_sylius', $syliusRequestConfig); + } + public function handle(ResourceControllerEvent $resourceControllerEvent): void + { + $request = $this->requestStack->getCurrentRequest(); + if (null === $request) { + return; + } + + if (!\in_array($request->attributes->get('_route'), [self::CHECKOUT_ROUTE, self::UPDATE_ORDER_PAYMENT_ROUTE], true)) { + return; + } + + /** @var \Sylius\Component\Core\Model\OrderInterface $order */ + $order = $resourceControllerEvent->getSubject(); + $lastPayment = $order->getLastPayment(); + if (null === $lastPayment) { + return; + } + + if (!$this->hasToken($request)) { + return; + + } + $this->handleToken($resourceControllerEvent, $request, $lastPayment); + } + + private function handleToken( + ResourceControllerEvent $resourceControllerEvent, + Request $request, + PaymentInterface $lastPayment, + ): void { + $token = $this->getToken($request); + + $lastPayment->setDetails(\array_merge( + $lastPayment->getDetails(), + [ + 'payment_id' => $token, + 'status' => PaymentInterface::STATE_PROCESSING, + ] + )); + + $resource = $resourceControllerEvent->getSubject(); + Assert::isInstanceOf($resource, ResourceInterface::class); + + $this->applyToComplete($lastPayment->getOrder() ?? throw new \LogicException('Order not found for payment')); + } + + private function hasToken(Request $request): bool + { + if (!$request->request->has(self::TOKEN_FIELD)) { + return false; + } + + $token = $this->getToken($request); + + return '' !== $token; + } + + private function getToken(Request $request): string + { + $token = $request->request->get(self::TOKEN_FIELD); + Assert::string($token); + + return $token; + } + + private function applyToComplete(OrderInterface $order): void + { + $stateMachine = $this->stateMachineFactory->get($order, OrderCheckoutTransitions::GRAPH); + if ($stateMachine->can(OrderCheckoutTransitions::TRANSITION_COMPLETE)) { + $stateMachine->apply(OrderCheckoutTransitions::TRANSITION_COMPLETE); + } + + $this->entityManager->flush(); + } +} diff --git a/src/Gateway/Form/Extension/PayPlugGatewayConfigurationTypeExtension.php b/src/Gateway/Form/Extension/PayPlugGatewayConfigurationTypeExtension.php index f1aa5f28..181f2b06 100644 --- a/src/Gateway/Form/Extension/PayPlugGatewayConfigurationTypeExtension.php +++ b/src/Gateway/Form/Extension/PayPlugGatewayConfigurationTypeExtension.php @@ -40,6 +40,11 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'help_html' => true, 'required' => false, ]) + ->add(PayPlugGatewayFactory::INTEGRATED_PAYMENT, CheckboxType::class, [ + 'label' => 'payplug_sylius_payplug_plugin.form.integrated_payment_enable', + 'validation_groups' => AbstractGatewayConfigurationType::VALIDATION_GROUPS, + 'required' => false, + ]) ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event): void { $data = $event->getData(); // phpstan check diff --git a/src/Gateway/PayPlugGatewayFactory.php b/src/Gateway/PayPlugGatewayFactory.php index ac24278e..c520e02f 100644 --- a/src/Gateway/PayPlugGatewayFactory.php +++ b/src/Gateway/PayPlugGatewayFactory.php @@ -7,10 +7,11 @@ final class PayPlugGatewayFactory extends AbstractGatewayFactory { public const FACTORY_NAME = 'payplug'; - public const FACTORY_TITLE = 'PayPlug'; + // Custom gateway configuration keys public const ONE_CLICK = 'oneClick'; + public const INTEGRATED_PAYMENT = 'integratedPayment'; public const AUTHORIZED_CURRENCIES = [ 'EUR' => [ diff --git a/src/Resources/config/routing.yaml b/src/Resources/config/routing.yaml index 25e61b98..3f629c0f 100644 --- a/src/Resources/config/routing.yaml +++ b/src/Resources/config/routing.yaml @@ -86,3 +86,9 @@ payplug_shop_checkout_apple_cancel: method: find arguments: - "expr:service('payplug.apple_pay_order.provider').getCurrentCart()" + +payplug_sylius_integrated_payment_init: + path: /{_locale}/payplug/integrated_payment/init/{paymentMethodId} + methods: ['GET', 'POST'] + defaults: + _controller: 'PayPlug\SyliusPayPlugPlugin\Controller\IntegratedPaymentController::initPaymentAction' diff --git a/src/Resources/config/ui.yaml b/src/Resources/config/ui.yaml index 1b8b9db7..720d44d5 100644 --- a/src/Resources/config/ui.yaml +++ b/src/Resources/config/ui.yaml @@ -17,14 +17,10 @@ sylius_ui: template: '@PayPlugSyliusPayPlugPlugin/javascripts/webfont_loader.html.twig' oney_common: template: '@PayPlugSyliusPayPlugPlugin/javascripts/oney_common.html.twig' - select_payment_js: - template: '@PayPlugSyliusPayPlugPlugin/javascripts/select_payment_js.html.twig' sylius.shop.layout.stylesheets: blocks: oney_common: template: '@PayPlugSyliusPayPlugPlugin/stylesheets/oney_common.html.twig' - select_payment_css: - template: '@PayPlugSyliusPayPlugPlugin/stylesheets/select_payment_css.html.twig' sylius.shop.account.saved_cards.index.header.content: blocks: legacy: @@ -58,3 +54,10 @@ sylius_ui: payment_methods_css: template: '@PayPlugSyliusPayPlugPlugin/stylesheets/payment_method_css.html.twig' sylius.admin.payment_method.update.stylesheets: *cssEvt + sylius.shop.checkout.select_payment.before_form: &selectPayment + blocks: + select_payment_css: + template: '@PayPlugSyliusPayPlugPlugin/stylesheets/select_payment_css.html.twig' + select_payment_js: + template: '@PayPlugSyliusPayPlugPlugin/javascripts/select_payment_js.html.twig' + sylius.shop.order.select_payment.before_form: *selectPayment \ No newline at end of file diff --git a/src/Resources/dev/images/integrated/account.svg b/src/Resources/dev/images/integrated/account.svg new file mode 100644 index 00000000..297efca7 --- /dev/null +++ b/src/Resources/dev/images/integrated/account.svg @@ -0,0 +1,9 @@ + + + General/Icons/Icon 24x24 - Account + + + + + + \ No newline at end of file diff --git a/src/Resources/dev/images/integrated/calendar.svg b/src/Resources/dev/images/integrated/calendar.svg new file mode 100644 index 00000000..82fb3686 --- /dev/null +++ b/src/Resources/dev/images/integrated/calendar.svg @@ -0,0 +1,13 @@ + + + General/Icons/Icon 24x24 - Calendar + + + + + + + + + + \ No newline at end of file diff --git a/src/Resources/dev/images/integrated/card.svg b/src/Resources/dev/images/integrated/card.svg new file mode 100644 index 00000000..5c08a102 --- /dev/null +++ b/src/Resources/dev/images/integrated/card.svg @@ -0,0 +1,10 @@ + + + General/Icons/Icon 24x24 - Card + + + + + + + \ No newline at end of file diff --git a/src/Resources/dev/images/integrated/cb-dark.svg b/src/Resources/dev/images/integrated/cb-dark.svg new file mode 100644 index 00000000..5281a653 --- /dev/null +++ b/src/Resources/dev/images/integrated/cb-dark.svg @@ -0,0 +1,33 @@ + + + CB dark + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resources/dev/images/integrated/cb.svg b/src/Resources/dev/images/integrated/cb.svg new file mode 100644 index 00000000..51c1cad5 --- /dev/null +++ b/src/Resources/dev/images/integrated/cb.svg @@ -0,0 +1,33 @@ + + + CB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resources/dev/images/integrated/lock.svg b/src/Resources/dev/images/integrated/lock.svg new file mode 100644 index 00000000..316e1f5e --- /dev/null +++ b/src/Resources/dev/images/integrated/lock.svg @@ -0,0 +1,9 @@ + + + General/Icons/Icon 24x24 - Lock + + + + + + \ No newline at end of file diff --git a/src/Resources/dev/images/integrated/logo-payplug.png b/src/Resources/dev/images/integrated/logo-payplug.png new file mode 100644 index 00000000..b67d7cce Binary files /dev/null and b/src/Resources/dev/images/integrated/logo-payplug.png differ diff --git a/src/Resources/dev/images/integrated/mastercard-dark.svg b/src/Resources/dev/images/integrated/mastercard-dark.svg new file mode 100644 index 00000000..652fb0ae --- /dev/null +++ b/src/Resources/dev/images/integrated/mastercard-dark.svg @@ -0,0 +1,19 @@ + + + Mastercard dark + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resources/dev/images/integrated/mastercard.svg b/src/Resources/dev/images/integrated/mastercard.svg new file mode 100644 index 00000000..337ff9fb --- /dev/null +++ b/src/Resources/dev/images/integrated/mastercard.svg @@ -0,0 +1,18 @@ + + + Mastercard + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Resources/dev/images/integrated/visa-dark.svg b/src/Resources/dev/images/integrated/visa-dark.svg new file mode 100644 index 00000000..9de9cde7 --- /dev/null +++ b/src/Resources/dev/images/integrated/visa-dark.svg @@ -0,0 +1,19 @@ + + + General/Icons/Logos cb/Visa dark + + + + + + + + + + \ No newline at end of file diff --git a/src/Resources/dev/images/integrated/visa.svg b/src/Resources/dev/images/integrated/visa.svg new file mode 100644 index 00000000..5c488458 --- /dev/null +++ b/src/Resources/dev/images/integrated/visa.svg @@ -0,0 +1,16 @@ + + + General/Icons/Logos cb/Visa + + + + + + + \ No newline at end of file diff --git a/src/Resources/dev/shop/payment/index.js b/src/Resources/dev/shop/payment/index.js index 60cc5f30..4347b4c6 100644 --- a/src/Resources/dev/shop/payment/index.js +++ b/src/Resources/dev/shop/payment/index.js @@ -21,6 +21,9 @@ const Payment = { }); Payment.tabsHandler(); Payment.applePayHandler(); + $('form[name="sylius_checkout_select_payment"]').on("submit", () => { + Payment.handleForm(); + }); }, toggleGateway() { const paymentMethodInputId = $(this.options.trigger).data("payment-input-id"); @@ -118,8 +121,7 @@ const Payment = { Payment.enableNextStepButton(); } }, - onApplePayButtonClick(event) - { + onApplePayButtonClick(event) { const applePayButton = $(event.currentTarget); if (applePaySessionRequestSettings === undefined) { @@ -270,12 +272,7 @@ const Payment = { this.modalSubmit(e); }); }, -}; - -const onDocumentLoad = function (event) { - Payment.init(); - - $('form[name="sylius_checkout_select_payment"] button[type="submit"]').on("click", (event) => { + handleForm() { if ($(".checkbox-oney :radio:checked").length) { $(".checkbox-payplug").closest(".payment-item").find(".payment-choice__input:checked").prop("checked", false); } else if ($(".checkbox-payplug :radio:checked").length) { @@ -284,7 +281,7 @@ const onDocumentLoad = function (event) { $("input#payplug_choice_card_other").attr("disabled", true); $('form[name="sylius_checkout_select_payment"]').submit(); - }); + } }; -document.addEventListener("DOMContentLoaded", onDocumentLoad, false); +document.addEventListener("DOMContentLoaded", Payment.init, false); diff --git a/src/Resources/dev/shop/payment/integrated.js b/src/Resources/dev/shop/payment/integrated.js new file mode 100644 index 00000000..861f56c4 --- /dev/null +++ b/src/Resources/dev/shop/payment/integrated.js @@ -0,0 +1,181 @@ +const IntegratedPayment = { + options: { + api: null, + cartId: null, + form: {}, + fieldsValid: { + cardHolder: false, + pan: false, + cvv: false, + exp: false, + }, + fieldsEmpty: { + cardHolder: true, + pan: true, + cvv: true, + exp: true, + }, + inputStyle: { + default: { + color: '#2B343D', + fontFamily: 'Poppins, Arial, sans-serif', + fontSize: '14px', + textAlign: 'left', + '::placeholder': { + color: '#969a9f', + }, + ':focus': { + color: '#2B343D', + } + }, + invalid: { + color: '#E91932' + } + }, + save_card: false, + schemes: null, + scheme: null, + }, + init() { + if (payplug_integrated_payment_params === undefined) { + return; + } + if (payplug_integrated_payment_params.has_saved_cards) { + document.querySelectorAll('.payment-choice__input, .payment-item input[type=radio]:not([name=schemeOptions])').forEach((element) => { + element.addEventListener('change', (e) => { + if ( + 'payplug_choice_card_other' === e.currentTarget.id && e.currentTarget.checked || + e.target.value === payplug_integrated_payment_params.payment_method_code && document.querySelector('#payplug_choice_card_other').checked + ) { + IntegratedPayment.openFields(); + return; + } + IntegratedPayment.closeFields(); + }) + }) + return; + } + if (document.querySelector(`[id*=sylius_checkout_select_payment_payments][value=${payplug_integrated_payment_params.payment_method_code}]:checked`)) { + IntegratedPayment.openFields(); + } + document.querySelectorAll('[id*=sylius_checkout_select_payment_payments]').forEach((element) => { + element.addEventListener('change', (e) => { + if (payplug_integrated_payment_params.payment_method_code === e.currentTarget.value && e.currentTarget.checked) { + IntegratedPayment.openFields(); + return; + } + IntegratedPayment.closeFields(); + }) + }); + }, + openFields() { + document.querySelector('.payplugIntegratedPayment').classList.add('payplugIntegratedPayment--loaded'); + document.querySelector('button[type=submit]').classList.add('disabled'); + if (null === IntegratedPayment.options.api) { + IntegratedPayment.load(); + } + }, + closeFields() { + document.querySelector('.payplugIntegratedPayment').classList.remove('payplugIntegratedPayment--loaded'); + document.querySelector('button[type=submit]').classList.remove('disabled'); + }, + load() { + IntegratedPayment.options.api = integratedPaymentApi = new Payplug.IntegratedPayment(payplug_integrated_payment_params.is_test_mode); + integratedPaymentApi.setDisplayMode3ds(Payplug.DisplayMode3ds.LIGHTBOX); + IntegratedPayment.options.form.cardHolder = integratedPaymentApi.cardHolder( + document.querySelector('.cardHolder-input-container'), + { + default: IntegratedPayment.options.inputStyle.default, + placeholder: payplug_integrated_payment_params.cardholder + } + ); + IntegratedPayment.options.form.pan = integratedPaymentApi.cardNumber( + document.querySelector('.pan-input-container'), + { + default: IntegratedPayment.options.inputStyle.default, + placeholder: payplug_integrated_payment_params.pan + } + ); + IntegratedPayment.options.form.cvv = integratedPaymentApi.cvv( + document.querySelector('.cvv-input-container'), + { + default: IntegratedPayment.options.inputStyle.default, + placeholder: payplug_integrated_payment_params.cvv + } + ); + IntegratedPayment.options.form.exp = integratedPaymentApi.expiration( + document.querySelector('.exp-input-container'), + { + default: IntegratedPayment.options.inputStyle.default, + placeholder: payplug_integrated_payment_params.exp + } + ); + IntegratedPayment.options.schemes = integratedPaymentApi.getSupportedSchemes(); + IntegratedPayment.bindEvents(); + IntegratedPayment.fieldValidation(); + }, + bindEvents() { + document.querySelector('#paid').addEventListener('click', (event) => { + event.preventDefault(); + integratedPaymentApi.validateForm(); + }); + integratedPaymentApi.onValidateForm(async ({isFormValid}) => { + if (isFormValid) { + this.toggleLoader(); + const saveCardElement = document.querySelector('#savecard'); + if (null !== saveCardElement) { + IntegratedPayment.options.save_card = saveCardElement.checked; + } + const chosenScheme = document.querySelector('[name=schemeOptions]:checked'); + IntegratedPayment.options.scheme = Payplug.Scheme.AUTO; + if (null !== chosenScheme) { + IntegratedPayment.options.scheme = chosenScheme.value; + } + if (payplug_integrated_payment_params.payment_id !== undefined) { + integratedPaymentApi.pay(payplug_integrated_payment_params.payment_id, IntegratedPayment.options.scheme, {save_card: IntegratedPayment.options.save_card}); + return; + } + const response = await fetch(payplug_integrated_payment_params.routes.init_payment, {method: 'POST'}); + const data = await response.json(); + integratedPaymentApi.pay(data.payment_id, IntegratedPayment.options.scheme, {save_card: IntegratedPayment.options.save_card}); + } + }); + integratedPaymentApi.onCompleted((event) => { + if (event.error) { + console.error(event.error); + return; + } + document.querySelector('input[name=payplug_integrated_payment_token]').value = event.token; + document.querySelector('form[name=sylius_checkout_select_payment]').submit(); + }); + }, + fieldValidation () { + $.each(IntegratedPayment.options.form, function (key, field) { + field.onChange(function(err) { + if (err.error) { + document.querySelector(`.payplugIntegratedPayment__error--${key}`).classList.remove('payplugIntegratedPayment__error--hide'); + document.querySelector(`.${key}-input-container`).classList.add('payplugIntegratedPayment__container--invalid'); + if (err.error.name === "FIELD_EMPTY") { + document.querySelector(`.payplugIntegratedPayment__error--${key}`).querySelector(".emptyField").classList.remove('payplugIntegratedPayment__error--hide'); + document.querySelector(`.payplugIntegratedPayment__error--${key}`).querySelector(".invalidField").classList.add('payplugIntegratedPayment__error--hide'); + } else { + document.querySelector(`.payplugIntegratedPayment__error--${key}`).querySelector(".invalidField").classList.remove('payplugIntegratedPayment__error--hide'); + document.querySelector(`.payplugIntegratedPayment__error--${key}`).querySelector(".emptyField").classList.add('payplugIntegratedPayment__error--hide'); + } + } else { + document.querySelector(`.payplugIntegratedPayment__error--${key}`).classList.add('payplugIntegratedPayment__error--hide'); + document.querySelector(`.${key}-input-container`).classList.remove('payplugIntegratedPayment__container--invalid'); + document.querySelector(`.payplugIntegratedPayment__error--${key}`).querySelector(".invalidField").classList.add('payplugIntegratedPayment__error--hide'); + document.querySelector(`.payplugIntegratedPayment__error--${key}`).querySelector(".emptyField").classList.add('payplugIntegratedPayment__error--hide'); + IntegratedPayment.options.fieldsValid[key] = true; + IntegratedPayment.options.fieldsEmpty[key] = false; + } + }); + }); + }, + toggleLoader() { + document.querySelector('.payplugIntegratedPayment').querySelector('.dimmer').classList.toggle('active'); + } +}; + +document.addEventListener("DOMContentLoaded", IntegratedPayment.init, false); diff --git a/src/Resources/dev/shop/payment/integrated.scss b/src/Resources/dev/shop/payment/integrated.scss new file mode 100644 index 00000000..0a09ea07 --- /dev/null +++ b/src/Resources/dev/shop/payment/integrated.scss @@ -0,0 +1,300 @@ +.payplugIntegratedPayment { + display: none; + justify-self: center; + + * { + font-family: Poppins, Arial, sans-serif !important; + } + + &--loaded { + display: flex; + margin-top: 20px; + width: 100%; + max-width: 400px; + flex-wrap: wrap; + justify-content: space-between; + margin-bottom: 0; + position: relative; + } + + &__select { + border: 1px solid #ccc; + border-radius: 5px; + padding: 0 8px; + margin: 0 0 10px; + height: 36px; + width: 100%; + } + + &__container { + display: flex; + padding: 0; + margin: 0 0 10px; + width: 100%; + position: relative; + + &--cardHolder, + &--pan, + &--exp, + &--cvv { + height: 40px; + line-height: 40px; + border-radius: 2px; + padding: 0 16px 0 50px; + cursor: text; + border: solid 1px #d5d6d8; + + &:before { + content: ""; + position: absolute; + top: 20%; + left: 16px; + width: 24px; + height: 24px; + background: #95999e 50% no-repeat; + background-size: 100% auto; + } + + &:focus { + border-color: #2b343d; + } + + &--invalid { + border-color: #E91932; + } + } + + &--cardHolder { + &:before { + mask-image: url(../../images/integrated/account.svg); + } + } + + &--pan { + &:before { + mask-image: url(../../images/integrated/card.svg); + } + } + + &--exp { + &:before { + mask-image: url(../../images/integrated/calendar.svg); + } + } + + &--cvv { + &:before { + mask-image: url(../../images/integrated/lock.svg); + } + } + + &--exp, + &--cvv { + max-width: calc(50% - 2px); + display: inline-block; + } + + &--scheme { + justify-content: space-between; + align-items: center; + font-size: 14px; + font-weight: 700; + text-transform: uppercase; + height: 22px; + margin: 10px 0; + } + + &--saveCard { + display: flex; + height: auto; + align-items: center; + padding: 10px 0 0; + + input { + display: none; + } + + input:checked + label span:before { + opacity: 1; + } + + label { + margin: 0 !important; + cursor: pointer; + font-size: 12px !important; + color: #918f8f; + + span { + border: 1px solid #d5d6d8; + border-radius: 2px; + cursor: pointer; + display: inline-block; + height: 16px; + margin: 0 10px -3px 0; + position: relative; + -webkit-transition: border .4s; + -moz-transition: border .4s; + -ms-transition: border .4s; + -o-transition: border .4s; + transition: border .4s; + width: 16px; + + &:before { + border: 2.5px solid #2b343d; + border-radius: 1px; + border-right: none; + border-top: none; + content: ""; + display: block; + height: 5px; + left: 50%; + opacity: 0; + position: absolute; + top: 50%; + transform: translate(-50%,-55%) rotate(-48deg); + transition: opacity .4s; + width: 10px; + } + } + + &:hover { + color: #2b343d; + transition: 0.1s; + + span { + border-color: #2b343d; + transition: 0.1s; + } + } + } + } + + &--transaction { + align-items: center; + margin-top: 10px; + + .transaction-label{ + font-size: 12px; + margin-left: 5px; + vertical-align: super; + } + } + + img.lock-icon { + width: 18px; + float: left !important; + } + + img.payplug-logo { + width: 80px; + height: auto; + display: inline-block; + float: inherit !important; + margin-left: 6px; + vertical-align: text-top; + } + + &--privacy-policy { + display: inline-block; + text-align: center; + + a { + color: #918f8f; + font-size: 14px; + } + } + } + + &__schemes { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + width: 115px; + + label { + display: table-cell; + } + } + + &__scheme { + margin: 0; + + span { + cursor: pointer; + display: block; + width: 33px; + height: 22px; + background: 50% no-repeat; + background-size: 100% auto; + + &:before { + display: block; + width: 100%; + height: 100%; + content: ""; + background: 50% no-repeat; + background-size: 100% auto; + opacity: 0; + } + } + + input { + display: none; + + &:checked + span:before { + opacity: 1; + } + } + + &--visa span { + background-image: url(../../images/integrated/visa-dark.svg); + + &:before { + background-image: url(../../images/integrated/visa.svg); + } + } + &--mastercard span { + background-image: url(../../images/integrated/mastercard-dark.svg); + + &:before { + background-image: url(../../images/integrated/mastercard.svg); + } + } + &--cb span { + background-image: url(../../images/integrated/cb-dark.svg); + + &:before { + background-image: url(../../images/integrated/cb.svg); + } + } + } + + &__error { + color: #E91932; + font-size: 12px; + margin: -10px 0 10px; + width: 100%; + line-height: 18px; + padding-left: 4px; + + &--cardHolder { + margin: -10px 0 0; + } + + &--cvv { + justify-self: flex-end; + margin: -10px 0 10px auto; + } + + &--exp, + &--cvv { + width: 100%; + max-width: calc(49%); + } + + &--hide { + display: none; + } + } +} diff --git a/src/Resources/dev/yarn.lock b/src/Resources/dev/yarn.lock index b7cdfaa9..dd9a3f07 100644 --- a/src/Resources/dev/yarn.lock +++ b/src/Resources/dev/yarn.lock @@ -2,64 +2,80 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== +"@ampproject/remapping@^2.2.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== dependencies: - "@jridgewell/gen-mapping" "^0.1.0" - "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": +"@babel/code-frame@^7.0.0": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== dependencies: "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1", "@babel/compat-data@^7.20.5": +"@babel/code-frame@^7.18.6", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0", "@babel/code-frame@^7.26.2": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" + integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== + dependencies: + "@babel/helper-validator-identifier" "^7.25.9" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1": version "7.20.14" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.14.tgz#4106fc8b755f3e3ee0a0a7c27dde5de1d2b2baf8" integrity sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw== +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.25.9": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.3.tgz#99488264a56b2aded63983abd6a417f03b92ed02" + integrity sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g== + "@babel/core@^7.9.0": - version "7.20.12" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.12.tgz#7930db57443c6714ad216953d1356dac0eb8496d" - integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.7" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helpers" "^7.20.7" - "@babel/parser" "^7.20.7" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.12" - "@babel/types" "^7.20.7" - convert-source-map "^1.7.0" + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40" + integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.26.0" + "@babel/generator" "^7.26.0" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-module-transforms" "^7.26.0" + "@babel/helpers" "^7.26.0" + "@babel/parser" "^7.26.0" + "@babel/template" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.26.0" + convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.2.2" - semver "^6.3.0" + json5 "^2.2.3" + semver "^6.3.1" "@babel/eslint-parser@^7.14.7": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz#4f68f6b0825489e00a24b41b6a1ae35414ecd2f4" - integrity sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ== + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.25.9.tgz#603c68a63078796527bc9d0833f5e52dd5f9224c" + integrity sha512-5UXfgpK0j0Xr/xIdgdLEhOFxaDZ0bRPWJJchRpqOSur/3rZoPbqqki5mm0p4NE2cs28krBEiSM2MB7//afRSQQ== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" - semver "^6.3.0" + semver "^6.3.1" -"@babel/generator@^7.20.7": - version "7.20.14" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.14.tgz#9fa772c9f86a46c6ac9b321039400712b96f64ce" - integrity sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg== +"@babel/generator@^7.20.7", "@babel/generator@^7.26.0", "@babel/generator@^7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.3.tgz#ab8d4360544a425c90c248df7059881f4b2ce019" + integrity sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ== dependencies: - "@babel/types" "^7.20.7" - "@jridgewell/gen-mapping" "^0.3.2" - jsesc "^2.5.1" + "@babel/parser" "^7.26.3" + "@babel/types" "^7.26.3" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^3.0.2" "@babel/helper-annotate-as-pure@^7.18.6": version "7.18.6" @@ -76,7 +92,7 @@ "@babel/helper-explode-assignable-expression" "^7.18.6" "@babel/types" "^7.18.9" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0", "@babel/helper-compilation-targets@^7.20.7": +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0": version "7.20.7" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz#a6cd33e93629f5eb473b021aac05df62c4cd09bb" integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ== @@ -87,6 +103,17 @@ lru-cache "^5.1.1" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875" + integrity sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ== + dependencies: + "@babel/compat-data" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.5", "@babel/helper-create-class-features-plugin@^7.20.7": version "7.20.12" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz#4349b928e79be05ed2d1643b20b99bb87c503819" @@ -122,9 +149,11 @@ semver "^6.1.2" "@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz#4b31ba9551d1f90781ba83491dd59cf9b269f7d9" + integrity sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ== + dependencies: + "@babel/types" "^7.24.7" "@babel/helper-explode-assignable-expression@^7.18.6": version "7.18.6" @@ -133,7 +162,7 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": +"@babel/helper-function-name@^7.18.9": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== @@ -141,12 +170,20 @@ "@babel/template" "^7.18.10" "@babel/types" "^7.19.0" +"@babel/helper-function-name@^7.19.0": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz#75f1e1725742f39ac6584ee0b16d94513da38dd2" + integrity sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA== + dependencies: + "@babel/template" "^7.24.7" + "@babel/types" "^7.24.7" + "@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz#b4ede1cde2fd89436397f30dc9376ee06b0f25ee" + integrity sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.24.7" "@babel/helper-member-expression-to-functions@^7.20.7": version "7.20.7" @@ -155,14 +192,15 @@ dependencies: "@babel/types" "^7.20.7" -"@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== +"@babel/helper-module-imports@^7.18.6", "@babel/helper-module-imports@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715" + integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw== dependencies: - "@babel/types" "^7.18.6" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11": +"@babel/helper-module-transforms@^7.18.6": version "7.20.11" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz#df4c7af713c557938c50ea3ad0117a7944b2f1b0" integrity sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg== @@ -176,6 +214,15 @@ "@babel/traverse" "^7.20.10" "@babel/types" "^7.20.7" +"@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae" + integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw== + dependencies: + "@babel/helper-module-imports" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@babel/helper-optimise-call-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" @@ -211,11 +258,12 @@ "@babel/types" "^7.20.7" "@babel/helper-simple-access@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" - integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz#6d51783299884a2c74618d6ef0f86820ec2e7739" + integrity sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q== dependencies: - "@babel/types" "^7.20.2" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" "@babel/helper-skip-transparent-expression-wrappers@^7.20.0": version "7.20.0" @@ -225,26 +273,26 @@ "@babel/types" "^7.20.0" "@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz#83949436890e07fa3d6873c61a96e3bbf692d856" + integrity sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.24.7" -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== +"@babel/helper-string-parser@^7.19.4", "@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-validator-identifier@^7.19.1", "@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== +"@babel/helper-validator-option@^7.18.6", "@babel/helper-validator-option@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72" + integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw== "@babel/helper-wrap-function@^7.18.9": version "7.20.5" @@ -256,28 +304,30 @@ "@babel/traverse" "^7.20.5" "@babel/types" "^7.20.5" -"@babel/helpers@^7.20.7": - version "7.20.13" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.13.tgz#e3cb731fb70dc5337134cadc24cbbad31cc87ad2" - integrity sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg== +"@babel/helpers@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.0.tgz#30e621f1eba5aa45fe6f4868d2e9154d884119a4" + integrity sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw== dependencies: - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.13" - "@babel/types" "^7.20.7" + "@babel/template" "^7.25.9" + "@babel/types" "^7.26.0" "@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.25.9.tgz#8141ce68fc73757946f983b343f1231f4691acc6" + integrity sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw== dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" + "@babel/helper-validator-identifier" "^7.25.9" + chalk "^2.4.2" js-tokens "^4.0.0" + picocolors "^1.0.0" -"@babel/parser@^7.20.13", "@babel/parser@^7.20.7": - version "7.20.15" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.15.tgz#eec9f36d8eaf0948bb88c87a46784b5ee9fd0c89" - integrity sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg== +"@babel/parser@^7.20.13", "@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.3.tgz#8c51c5db6ddf08134af1ddbacf16aaab48bac234" + integrity sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA== + dependencies: + "@babel/types" "^7.26.3" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" @@ -884,16 +934,29 @@ dependencies: regenerator-runtime "^0.13.11" -"@babel/template@^7.18.10", "@babel/template@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" - integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" +"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.24.7", "@babel/template@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016" + integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg== + dependencies: + "@babel/code-frame" "^7.25.9" + "@babel/parser" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/traverse@^7.20.10", "@babel/traverse@^7.25.9": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.3.tgz#1ebfc75bd748d8f96b3cc63af5e82ebd4c37ba35" + integrity sha512-yTmc8J+Sj8yLzwr4PD5Xb/WF3bOYu2C2OoSZPzbuqRm4n98XirsbzaX+GloeO376UnSYIYJ4NCanwV5/ugZkwA== + dependencies: + "@babel/code-frame" "^7.26.2" + "@babel/generator" "^7.26.3" + "@babel/parser" "^7.26.3" + "@babel/template" "^7.25.9" + "@babel/types" "^7.26.3" + debug "^4.3.1" + globals "^11.1.0" -"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.20.13", "@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7": +"@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7": version "7.20.13" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.13.tgz#817c1ba13d11accca89478bd5481b2d168d07473" integrity sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ== @@ -909,7 +972,15 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.4.4": +"@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.24.7", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.3.tgz#37e79830f04c2b5687acc77db97fbc75fb81f3c0" + integrity sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA== + dependencies: + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + +"@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.5", "@babel/types@^7.4.4": version "7.20.7" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f" integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg== @@ -918,15 +989,7 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": +"@jridgewell/gen-mapping@^0.3.0": version "0.3.2" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== @@ -935,15 +998,24 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.0.1", "@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== "@jridgewell/source-map@^0.3.2": version "0.3.2" @@ -953,18 +1025,18 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" "@lezer/common@^0.15.0", "@lezer/common@^0.15.7": version "0.15.12" @@ -1792,7 +1864,17 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.21.3, browserslist@^4.21.4, browserslist@^4.6.6: +browserslist@^4.21.3, browserslist@^4.24.0: + version "4.24.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" + integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== + dependencies: + caniuse-lite "^1.0.30001669" + electron-to-chromium "^1.5.41" + node-releases "^2.0.18" + update-browserslist-db "^1.1.1" + +browserslist@^4.21.4, browserslist@^4.6.6: version "4.21.5" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== @@ -1812,12 +1894,12 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -caniuse-lite@^1.0.30001449: - version "1.0.30001451" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz#2e197c698fc1373d63e1406d6607ea4617c613f1" - integrity sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w== +caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001669: + version "1.0.30001686" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz#0e04b8d90de8753188e93c9989d56cb19d902670" + integrity sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA== -chalk@^2.0.0, chalk@^2.1.0: +chalk@^2.1.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1915,10 +1997,10 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -convert-source-map@^1.7.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== core-js-compat@^3.25.1: version "3.27.2" @@ -1987,7 +2069,14 @@ debug@^4.0.1: dependencies: ms "2.1.2" -debug@^4.1.0, debug@^4.1.1: +debug@^4.1.0, debug@^4.3.1: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + +debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -2051,10 +2140,10 @@ dotenv@^7.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-7.0.0.tgz#a2be3cd52736673206e8a85fb5210eea29628e7c" integrity sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g== -electron-to-chromium@^1.4.284: - version "1.4.295" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.295.tgz#911d5df67542bf7554336142eb302c5ec90bba66" - integrity sha512-lEO94zqf1bDA3aepxwnWoHUjA8sZ+2owgcSZjYQy0+uOSEclJX0VieZC+r+wLpSxUHRd6gG32znTWmr+5iGzFw== +electron-to-chromium@^1.4.284, electron-to-chromium@^1.5.41: + version "1.5.68" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.68.tgz#4f46be4d465ef00e2100d5557b66f4af70e3ce6c" + integrity sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ== emoji-regex@^7.0.1: version "7.0.3" @@ -2083,10 +2172,10 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-string-regexp@^1.0.5: version "1.0.5" @@ -2532,10 +2621,10 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" + integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== jsesc@~0.5.0: version "0.5.0" @@ -2557,7 +2646,7 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json5@^2.2.0, json5@^2.2.1, json5@^2.2.2: +json5@^2.2.0, json5@^2.2.1, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -2708,6 +2797,11 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + msgpackr-extract@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-3.0.0.tgz#5b5c5fbfff25be5ee5b5a82a9cbe02e37f72bed0" @@ -2769,10 +2863,10 @@ node-gyp-build@^4.3.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== +node-releases@^2.0.18, node-releases@^2.0.8: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -2884,10 +2978,10 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.0.0, picocolors@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" @@ -3085,11 +3179,16 @@ semver@^5.5.0, semver@^5.7.0, semver@^5.7.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: +semver@^6.1.1, semver@^6.1.2: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -3332,13 +3431,13 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== -update-browserslist-db@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== +update-browserslist-db@^1.0.10, update-browserslist-db@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" + integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A== dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" + escalade "^3.2.0" + picocolors "^1.1.0" uri-js@^4.2.2: version "4.4.1" diff --git a/src/Resources/public/assets/shop/account.039342ad.svg b/src/Resources/public/assets/shop/account.039342ad.svg new file mode 100644 index 00000000..429c051d --- /dev/null +++ b/src/Resources/public/assets/shop/account.039342ad.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Resources/public/assets/shop/calendar.3c23bb16.svg b/src/Resources/public/assets/shop/calendar.3c23bb16.svg new file mode 100644 index 00000000..170acc49 --- /dev/null +++ b/src/Resources/public/assets/shop/calendar.3c23bb16.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Resources/public/assets/shop/card.0d2bd9bc.svg b/src/Resources/public/assets/shop/card.0d2bd9bc.svg new file mode 100644 index 00000000..5806d291 --- /dev/null +++ b/src/Resources/public/assets/shop/card.0d2bd9bc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Resources/public/assets/shop/cb-dark.888aec45.svg b/src/Resources/public/assets/shop/cb-dark.888aec45.svg new file mode 100644 index 00000000..eb75a35d --- /dev/null +++ b/src/Resources/public/assets/shop/cb-dark.888aec45.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Resources/public/assets/shop/cb.ccd964e9.svg b/src/Resources/public/assets/shop/cb.ccd964e9.svg new file mode 100644 index 00000000..2fa204f2 --- /dev/null +++ b/src/Resources/public/assets/shop/cb.ccd964e9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Resources/public/assets/shop/images/integrated/lock.svg b/src/Resources/public/assets/shop/images/integrated/lock.svg new file mode 100644 index 00000000..316e1f5e --- /dev/null +++ b/src/Resources/public/assets/shop/images/integrated/lock.svg @@ -0,0 +1,9 @@ + + + General/Icons/Icon 24x24 - Lock + + + + + + \ No newline at end of file diff --git a/src/Resources/public/assets/shop/images/integrated/logo-payplug.png b/src/Resources/public/assets/shop/images/integrated/logo-payplug.png new file mode 100644 index 00000000..b67d7cce Binary files /dev/null and b/src/Resources/public/assets/shop/images/integrated/logo-payplug.png differ diff --git a/src/Resources/public/assets/shop/lock.fe8a73cd.svg b/src/Resources/public/assets/shop/lock.fe8a73cd.svg new file mode 100644 index 00000000..96076615 --- /dev/null +++ b/src/Resources/public/assets/shop/lock.fe8a73cd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Resources/public/assets/shop/mastercard-dark.8977e440.svg b/src/Resources/public/assets/shop/mastercard-dark.8977e440.svg new file mode 100644 index 00000000..371c9023 --- /dev/null +++ b/src/Resources/public/assets/shop/mastercard-dark.8977e440.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Resources/public/assets/shop/mastercard.7dd4ce0b.svg b/src/Resources/public/assets/shop/mastercard.7dd4ce0b.svg new file mode 100644 index 00000000..4a6736e6 --- /dev/null +++ b/src/Resources/public/assets/shop/mastercard.7dd4ce0b.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Resources/public/assets/shop/payment/index.js b/src/Resources/public/assets/shop/payment/index.js index c1468cce..0a48be74 100644 --- a/src/Resources/public/assets/shop/payment/index.js +++ b/src/Resources/public/assets/shop/payment/index.js @@ -1 +1 @@ -!function(){const e={options:{trigger:".payment-method-choice",completeInfo:{modal:".oney-complete-info-popin",area:".ui.grid"}},init(t){void 0===t&&(t=this.options),this.options=$.extend(!0,{},t),e.toggleGateway(),"undefined"!=typeof completeInfoRoute&&e.modalAppear(),e.tabs(),$(window).on("resize",(()=>{setTimeout(e.tabs,100)})),e.tabsHandler(),e.applePayHandler()},toggleGateway(){const e=$(this.options.trigger).data("payment-input-id");$(`#${e}:checked`).length&&$(`.payment-method-choice[data-payment-input-id="${e}"]`).show(),$("input[id*=sylius_checkout_select_payment]").on("change",(e=>{const t=$(e.currentTarget).attr("id");$(".payment-method-choice").slideUp(),$(`.payment-method-choice[data-payment-input-id="${t}"]`).slideDown()}))},tabs(){window.innerWidth<=991?($(".oney-payment-choice__item").hide(),setTimeout((()=>{$.each($(".oney-payment-choice__input"),((e,t)=>{$(t).is(":checked")&&($(t).parent().show(),$(`a.tablink[data-id=${$(t).val()}]`).addClass("active"))}))}),1)):($(".oney-payment-choice__item").show(),$("a.tablink").removeClass("active"))},tabsHandler(){$.each($("a.tablink"),((e,t)=>{$(t).click((function(e){$("a.tablink").removeClass("active"),$(this).addClass("active"),$(".oney-payment-choice__item").hide(),$(`#${$(this).data("id")}`).show(),$(`input[value=${$(this).data("id")}`).prop("checked",!0)}))}))},disableNextStepButton(){const e=$('form[name="sylius_checkout_select_payment"] .select-payment-submit #next-step');e.replaceWith($("",{id:"next-step",class:"ui large disabled icon labeled button",html:e.html()}))},enableNextStepButton(){const e=$('form[name="sylius_checkout_select_payment"] .select-payment-submit #next-step');e.replaceWith($(" +
+ +
+ {{ 'payplug_sylius_payplug_plugin.ui.integrated_payment.transaction_secure.label'|trans }} +
+ +
+ + + + + +{% include '@SyliusUi/_javascripts.html.twig' with {'path': 'bundles/payplugsyliuspayplugplugin/assets/shop/payment/integrated.js'} %} +{% include '@SyliusUi/_stylesheets.html.twig' with {'path': 'bundles/payplugsyliuspayplugplugin/assets/shop/payment/integrated.css'} %} diff --git a/src/Twig/PayPlugExtension.php b/src/Twig/PayPlugExtension.php index 494dc7de..d0689c43 100644 --- a/src/Twig/PayPlugExtension.php +++ b/src/Twig/PayPlugExtension.php @@ -4,6 +4,7 @@ namespace PayPlug\SyliusPayPlugPlugin\Twig; +use PayPlug\SyliusPayPlugPlugin\ApiClient\PayPlugApiClientFactory; use PayPlug\SyliusPayPlugPlugin\Checker\CanSaveCardCheckerInterface; use Sylius\Component\Core\Model\PaymentMethodInterface; use Twig\Extension\AbstractExtension; @@ -13,16 +14,21 @@ final class PayPlugExtension extends AbstractExtension { /** @var CanSaveCardCheckerInterface */ private $canSaveCardChecker; + private PayPlugApiClientFactory $apiClientFactory; - public function __construct(CanSaveCardCheckerInterface $canSaveCardChecker) - { + public function __construct( + CanSaveCardCheckerInterface $canSaveCardChecker, + PayPlugApiClientFactory $apiClientFactory, + ) { $this->canSaveCardChecker = $canSaveCardChecker; + $this->apiClientFactory = $apiClientFactory; } public function getFunctions(): array { return [ new TwigFunction('is_save_card_enabled', [$this, 'isSaveCardAllowed']), + new TwigFunction('is_payplug_test_mode_enabled', [$this, 'isTest']), ]; } @@ -30,4 +36,11 @@ public function isSaveCardAllowed(PaymentMethodInterface $paymentMethod): bool { return $this->canSaveCardChecker->isAllowed($paymentMethod); } + + public function isTest(PaymentMethodInterface $paymentMethod): bool + { + $client = $this->apiClientFactory->createForPaymentMethod($paymentMethod); + + return ((bool) $client->getAccount()['is_live']) !== true; + } }