custom/plugins/MolliePayments/src/Subscriber/CheckoutConfirmPageSubscriber.php line 108

Open in your IDE?
  1. <?php
  2. namespace Kiener\MolliePayments\Subscriber;
  3. use Exception;
  4. use Kiener\MolliePayments\Factory\MollieApiFactory;
  5. use Kiener\MolliePayments\Handler\Method\CreditCardPayment;
  6. use Kiener\MolliePayments\Service\CustomerService;
  7. use Kiener\MolliePayments\Service\CustomerServiceInterface;
  8. use Kiener\MolliePayments\Service\CustomFieldService;
  9. use Kiener\MolliePayments\Service\MandateServiceInterface;
  10. use Kiener\MolliePayments\Service\Payment\Provider\ActivePaymentMethodsProvider;
  11. use Kiener\MolliePayments\Service\PaymentMethodService;
  12. use Kiener\MolliePayments\Service\SettingsService;
  13. use Kiener\MolliePayments\Setting\MollieSettingStruct;
  14. use Mollie\Api\Exceptions\ApiException;
  15. use Mollie\Api\MollieApiClient;
  16. use Mollie\Api\Resources\Method;
  17. use Mollie\Api\Types\PaymentMethod;
  18. use Shopware\Core\Checkout\Customer\CustomerEntity;
  19. use Shopware\Core\Checkout\Payment\PaymentMethodEntity;
  20. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  21. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  22. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  23. use Shopware\Storefront\Page\Account\Order\AccountEditOrderPageLoadedEvent;
  24. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
  25. use Shopware\Storefront\Page\PageLoadedEvent;
  26. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  27. use Throwable;
  28. class CheckoutConfirmPageSubscriber implements EventSubscriberInterface
  29. {
  30.     /**
  31.      * @var MollieApiFactory
  32.      */
  33.     private $apiFactory;
  34.     /**
  35.      * @var MollieApiClient
  36.      */
  37.     private $apiClient;
  38.     /**
  39.      * @var SettingsService
  40.      */
  41.     private $settingsService;
  42.     /**
  43.      * @var MollieSettingStruct
  44.      */
  45.     private $settings;
  46.     /**
  47.      * @var EntityRepositoryInterface
  48.      */
  49.     private $languageRepositoryInterface;
  50.     /**
  51.      * @var EntityRepositoryInterface
  52.      */
  53.     private $localeRepositoryInterface;
  54.     /**
  55.      * @var MandateServiceInterface
  56.      */
  57.     private $mandateService;
  58.     /**
  59.      * @return array<mixed>>
  60.      */
  61.     public static function getSubscribedEvents(): array
  62.     {
  63.         return [
  64.             CheckoutConfirmPageLoadedEvent::class => [
  65.                 ['addDataToPage'10],
  66.             ],
  67.             AccountEditOrderPageLoadedEvent::class => ['addDataToPage'10],
  68.         ];
  69.     }
  70.     /**
  71.      * @param MollieApiFactory $apiFactory
  72.      * @param SettingsService $settingsService
  73.      * @param EntityRepositoryInterface $languageRepositoryInterface
  74.      * @param EntityRepositoryInterface $localeRepositoryInterface
  75.      * @param MandateServiceInterface $mandateService
  76.      */
  77.     public function __construct(
  78.         MollieApiFactory $apiFactory,
  79.         SettingsService $settingsService,
  80.         EntityRepositoryInterface $languageRepositoryInterface,
  81.         EntityRepositoryInterface $localeRepositoryInterface,
  82.         MandateServiceInterface $mandateService
  83.     ) {
  84.         $this->apiFactory $apiFactory;
  85.         $this->settingsService $settingsService;
  86.         $this->languageRepositoryInterface $languageRepositoryInterface;
  87.         $this->localeRepositoryInterface $localeRepositoryInterface;
  88.         $this->mandateService $mandateService;
  89.     }
  90.     /**
  91.      * @param AccountEditOrderPageLoadedEvent|CheckoutConfirmPageLoadedEvent $args
  92.      * @throws \Mollie\Api\Exceptions\IncompatiblePlatform
  93.      */
  94.     public function addDataToPage($args): void
  95.     {
  96.         # load our settings for the
  97.         # current request
  98.         $this->settings $this->settingsService->getSettings($args->getSalesChannelContext()->getSalesChannel()->getId());
  99.         # now use our factory to get the correct
  100.         # client with the correct sales channel settings
  101.         $this->apiClient $this->apiFactory->getClient(
  102.             $args->getSalesChannelContext()->getSalesChannel()->getId()
  103.         );
  104.         $this->addMollieLocaleVariableToPage($args);
  105.         $this->addMollieProfileIdVariableToPage($args);
  106.         $this->addMollieTestModeVariableToPage($args);
  107.         $this->addMollieComponentsVariableToPage($args);
  108.         $this->addMollieIdealIssuersVariableToPage($args);
  109.         $this->addMollieSingleClickPaymentDataToPage($args);
  110.     }
  111.     /**
  112.      * Adds the locale for Mollie components to the storefront.
  113.      *
  114.      * @param AccountEditOrderPageLoadedEvent|CheckoutConfirmPageLoadedEvent $args
  115.      */
  116.     private function addMollieLocaleVariableToPage($args): void
  117.     {
  118.         /**
  119.          * Build an array of available locales.
  120.          */
  121.         $availableLocales = [
  122.             'en_US',
  123.             'en_GB',
  124.             'nl_NL',
  125.             'fr_FR',
  126.             'it_IT',
  127.             'de_DE',
  128.             'de_AT',
  129.             'de_CH',
  130.             'es_ES',
  131.             'ca_ES',
  132.             'nb_NO',
  133.             'pt_PT',
  134.             'sv_SE',
  135.             'fi_FI',
  136.             'da_DK',
  137.             'is_IS',
  138.             'hu_HU',
  139.             'pl_PL',
  140.             'lv_LV',
  141.             'lt_LT'
  142.         ];
  143.         /**
  144.          * Get the language object from the sales channel context.
  145.          */
  146.         $locale '';
  147.         $context $args->getContext();
  148.         $salesChannelContext $args->getSalesChannelContext();
  149.         $salesChannel $salesChannelContext->getSalesChannel();
  150.         if ($salesChannel !== null) {
  151.             $languageId $salesChannel->getLanguageId();
  152.             if ($languageId !== null) {
  153.                 $languageCriteria = new Criteria();
  154.                 $languageCriteria->addFilter(new EqualsFilter('id'$languageId));
  155.                 $languages $this->languageRepositoryInterface->search($languageCriteria$args->getContext());
  156.                 $localeId $languages->first()->getLocaleId();
  157.                 $localeCriteria = new Criteria();
  158.                 $localeCriteria->addFilter(new EqualsFilter('id'$localeId));
  159.                 $locales $this->localeRepositoryInterface->search($localeCriteria$args->getContext());
  160.                 $locale $locales->first()->getCode();
  161.             }
  162.         }
  163.         /**
  164.          * Set the locale based on the current storefront.
  165.          */
  166.         if ($locale !== null && $locale !== '') {
  167.             $locale str_replace('-''_'$locale);
  168.         }
  169.         /**
  170.          * Check if the shop locale is available.
  171.          */
  172.         if ($locale === '' || !in_array($locale$availableLocalestrue)) {
  173.             $locale 'en_GB';
  174.         }
  175.         $args->getPage()->assign([
  176.             'mollie_locale' => $locale,
  177.         ]);
  178.     }
  179.     /**
  180.      * Adds the test mode variable to the storefront.
  181.      *
  182.      * @param AccountEditOrderPageLoadedEvent|CheckoutConfirmPageLoadedEvent $args
  183.      */
  184.     private function addMollieTestModeVariableToPage($args): void
  185.     {
  186.         $args->getPage()->assign([
  187.             'mollie_test_mode' => $this->settings->isTestMode() ? 'true' 'false',
  188.         ]);
  189.     }
  190.     /**
  191.      * Adds the profile id to the storefront.
  192.      *
  193.      * @param AccountEditOrderPageLoadedEvent|CheckoutConfirmPageLoadedEvent $args
  194.      */
  195.     private function addMollieProfileIdVariableToPage($args): void
  196.     {
  197.         $mollieProfileId '';
  198.         /**
  199.          * Fetches the profile id from Mollie's API for the current key.
  200.          */
  201.         try {
  202.             if ($this->apiClient->usesOAuth() === false) {
  203.                 $mollieProfile $this->apiClient->profiles->get('me');
  204.             } else {
  205.                 $mollieProfile $this->apiClient->profiles->page()->offsetGet(0);
  206.             }
  207.             if (isset($mollieProfile->id)) {
  208.                 $mollieProfileId $mollieProfile->id;
  209.             }
  210.         } catch (ApiException $e) {
  211.             //
  212.         }
  213.         $args->getPage()->assign([
  214.             'mollie_profile_id' => $mollieProfileId,
  215.         ]);
  216.     }
  217.     /**
  218.      * Adds the components variable to the storefront.
  219.      *
  220.      * @param AccountEditOrderPageLoadedEvent|CheckoutConfirmPageLoadedEvent $args
  221.      */
  222.     private function addMollieComponentsVariableToPage($args): void
  223.     {
  224.         $args->getPage()->assign([
  225.             'enable_credit_card_components' => $this->settings->getEnableCreditCardComponents(),
  226.             'enable_one_click_payments_compact_view' => $this->settings->isOneClickPaymentsCompactView(),
  227.         ]);
  228.     }
  229.     /**
  230.      * Adds ideal issuers variable to the storefront.
  231.      *
  232.      * @param AccountEditOrderPageLoadedEvent|CheckoutConfirmPageLoadedEvent $args
  233.      */
  234.     private function addMollieIdealIssuersVariableToPage($args): void
  235.     {
  236.         $customFields = [];
  237.         $ideal null;
  238.         $mollieProfileId '';
  239.         $preferredIssuer '';
  240.         /**
  241.          * Fetches the profile id from Mollie's API for the current key.
  242.          */
  243.         try {
  244.             if ($this->apiClient->usesOAuth() === false) {
  245.                 $mollieProfile $this->apiClient->profiles->get('me');
  246.             } else {
  247.                 $mollieProfile $this->apiClient->profiles->page()->offsetGet(0);
  248.             }
  249.             if (isset($mollieProfile->id)) {
  250.                 $mollieProfileId $mollieProfile->id;
  251.             }
  252.         } catch (ApiException $e) {
  253.             //
  254.         }
  255.         // Get custom fields from the customer in the sales channel context
  256.         if ($args->getSalesChannelContext()->getCustomer() !== null) {
  257.             $customFields $args->getSalesChannelContext()->getCustomer()->getCustomFields();
  258.         }
  259.         // Get the preferred issuer from the custom fields
  260.         if (
  261.             is_array($customFields)
  262.             && isset($customFields[CustomFieldService::CUSTOM_FIELDS_KEY_MOLLIE_PAYMENTS][CustomerService::CUSTOM_FIELDS_KEY_PREFERRED_IDEAL_ISSUER])
  263.             && (string)$customFields[CustomFieldService::CUSTOM_FIELDS_KEY_MOLLIE_PAYMENTS][CustomerService::CUSTOM_FIELDS_KEY_PREFERRED_IDEAL_ISSUER] !== ''
  264.         ) {
  265.             $preferredIssuer $customFields[CustomFieldService::CUSTOM_FIELDS_KEY_MOLLIE_PAYMENTS][CustomerService::CUSTOM_FIELDS_KEY_PREFERRED_IDEAL_ISSUER];
  266.         }
  267.         $parameters = [
  268.             'include' => 'issuers',
  269.         ];
  270.         if ($this->apiClient->usesOAuth()) {
  271.             $parameters['profileId'] = $mollieProfileId;
  272.         }
  273.         // Get issuers from the API
  274.         try {
  275.             $ideal $this->apiClient->methods->get(PaymentMethod::IDEAL$parameters);
  276.         } catch (Exception $e) {
  277.             //
  278.         }
  279.         // Assign issuers to storefront
  280.         if ($ideal instanceof Method) {
  281.             $args->getPage()->assign([
  282.                 'ideal_issuers' => $ideal->issuers,
  283.                 'preferred_issuer' => $preferredIssuer,
  284.             ]);
  285.         }
  286.     }
  287.     /**
  288.      * Adds the components variable to the storefront.
  289.      *
  290.      * @param AccountEditOrderPageLoadedEvent|CheckoutConfirmPageLoadedEvent $args
  291.      */
  292.     private function addMollieSingleClickPaymentDataToPage($args): void
  293.     {
  294.         $args->getPage()->assign([
  295.             'enable_one_click_payments' => $this->settings->isOneClickPaymentsEnabled(),
  296.         ]);
  297.         if (!$this->settings->isOneClickPaymentsEnabled()) {
  298.             return;
  299.         }
  300.         try {
  301.             $salesChannelContext $args->getSalesChannelContext();
  302.             $loggedInCustomer $salesChannelContext->getCustomer();
  303.             if (!$loggedInCustomer instanceof CustomerEntity) {
  304.                 return;
  305.             }
  306.             // only load the list of mandates if the payment method is CreditCardPayment
  307.             if ($salesChannelContext->getPaymentMethod()->getHandlerIdentifier() !== CreditCardPayment::class) {
  308.                 return;
  309.             }
  310.             $mandates $this->mandateService->getCreditCardMandatesByCustomerId($loggedInCustomer->getId(), $salesChannelContext);
  311.             $args->getPage()->setExtensions([
  312.                 'MollieCreditCardMandateCollection' => $mandates
  313.             ]);
  314.         } catch (Exception $e) {
  315.             //
  316.         }
  317.     }
  318. }