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

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