custom/plugins/SwagAmazonPay/src/Components/Button/ButtonProvider.php line 124

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * (c) shopware AG <info@shopware.com>
  5.  * For the full copyright and license information, please view the LICENSE
  6.  * file that was distributed with this source code.
  7.  */
  8. namespace Swag\AmazonPay\Components\Button;
  9. use Psr\Log\LoggerInterface;
  10. use Shopware\Core\PlatformRequest;
  11. use Shopware\Storefront\Page\Account\Login\AccountLoginPageLoadedEvent;
  12. use Shopware\Storefront\Page\Account\Profile\AccountProfilePageLoadedEvent;
  13. use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
  14. use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
  15. use Shopware\Storefront\Page\Checkout\Register\CheckoutRegisterPageLoadedEvent;
  16. use Shopware\Storefront\Page\PageLoadedEvent;
  17. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  18. use Swag\AmazonPay\Components\Button\Login\Hydrator\AmazonLoginButtonPayloadHydratorInterfaceV3;
  19. use Swag\AmazonPay\Components\Button\Pay\Hydrator\AmazonPayButtonPayloadHydratorInterfaceV2;
  20. use Swag\AmazonPay\Components\Button\Validation\AbstractExcludedProductValidator;
  21. use Swag\AmazonPay\Components\Client\ClientProviderInterface;
  22. use Swag\AmazonPay\Components\Config\ConfigServiceInterface;
  23. use Swag\AmazonPay\Components\Config\Struct\AmazonPayConfigStruct;
  24. use Swag\AmazonPay\Components\Config\Validation\Exception\ConfigValidationException;
  25. use Swag\AmazonPay\Installer\RuleInstaller;
  26. use Swag\AmazonPay\Storefront\Page\Extension\AmazonLoginButtonExtension;
  27. use Swag\AmazonPay\Storefront\Page\Extension\AmazonPayButtonExtension;
  28. use Swag\AmazonPay\Storefront\Page\Extension\ExtensionService;
  29. use Swag\AmazonPay\Util\Helper\AmazonPayPaymentMethodHelperInterface;
  30. use Swag\AmazonPay\Util\Language\LanguageProviderInterface;
  31. use Symfony\Component\Routing\RouterInterface;
  32. class ButtonProvider implements ButtonProviderInterface
  33. {
  34.     /**
  35.      * @var ConfigServiceInterface
  36.      */
  37.     private $configService;
  38.     /**
  39.      * @var RouterInterface
  40.      */
  41.     private $router;
  42.     /**
  43.      * @var LanguageProviderInterface
  44.      */
  45.     private $languageProvider;
  46.     /**
  47.      * @var AmazonPayConfigStruct
  48.      */
  49.     private $pluginConfig;
  50.     /**
  51.      * @var AmazonPayPaymentMethodHelperInterface
  52.      */
  53.     private $paymentMethodHelper;
  54.     /**
  55.      * @var ClientProviderInterface
  56.      */
  57.     private $clientProvider;
  58.     /**
  59.      * @var AmazonPayButtonPayloadHydratorInterfaceV2
  60.      */
  61.     private $payButtonPayloadHydrator;
  62.     /**
  63.      * @var AmazonLoginButtonPayloadHydratorInterfaceV3
  64.      */
  65.     private $loginButtonPayloadHydrator;
  66.     /**
  67.      * @var LoggerInterface
  68.      */
  69.     private $logger;
  70.     /**
  71.      * @var AbstractExcludedProductValidator
  72.      */
  73.     private $excludedProductValidator;
  74.     /**
  75.      * @var string
  76.      */
  77.     private $shopwareVersion;
  78.     /**
  79.      * @var ExtensionService
  80.      */
  81.     private $extensionService;
  82.     public function __construct(
  83.         ConfigServiceInterface $configService,
  84.         LanguageProviderInterface $languageProvider,
  85.         RouterInterface $router,
  86.         AmazonPayPaymentMethodHelperInterface $paymentMethodHelper,
  87.         ClientProviderInterface $clientProvider,
  88.         AmazonPayButtonPayloadHydratorInterfaceV2 $payButtonPayloadHydrator,
  89.         AmazonLoginButtonPayloadHydratorInterfaceV3 $loginButtonPayloadHydrator,
  90.         LoggerInterface $logger,
  91.         AbstractExcludedProductValidator $excludedProductValidator,
  92.         string $shopwareVersion,
  93.         ExtensionService $extensionService
  94.     ) {
  95.         $this->configService $configService;
  96.         $this->router $router;
  97.         $this->languageProvider $languageProvider;
  98.         $this->paymentMethodHelper $paymentMethodHelper;
  99.         $this->clientProvider $clientProvider;
  100.         $this->payButtonPayloadHydrator $payButtonPayloadHydrator;
  101.         $this->loginButtonPayloadHydrator $loginButtonPayloadHydrator;
  102.         $this->logger $logger;
  103.         $this->excludedProductValidator $excludedProductValidator;
  104.         $this->shopwareVersion $shopwareVersion;
  105.         $this->extensionService $extensionService;
  106.     }
  107.     public function getAmazonPayButton(PageLoadedEvent $event): ?AmazonPayButtonExtension
  108.     {
  109.         if ($this->isAmazonPayButtonAvailable($event) === false) {
  110.             return null;
  111.         }
  112.         if ($this->excludedProductValidator->eventContainsExcludedProducts($event)) {
  113.             return null;
  114.         }
  115.         $oneClickCheckout true;
  116.         $buttonExtension = new AmazonPayButtonExtension();
  117.         $this->extensionService->setBaseButtonExtensionValues(
  118.             $buttonExtension,
  119.             $this->getCheckoutLanguage($event),
  120.             $event->getRequest()->isSecure(),
  121.             $event->getSalesChannelContext()->getSalesChannel()->getId()
  122.         );
  123.         $buttonExtension->setProductType(AmazonPayButtonExtension::PRODUCT_TYPE_PAY_AND_SHIP);
  124.         if (\version_compare($this->shopwareVersion'6.4.0''>=')) {
  125.             $buttonExtension->setClearCartUrl(
  126.                 $this->router->generate(
  127.                     'frontend.swag.amazon.pay.clear.cart'
  128.                 )
  129.             );
  130.         } else {
  131.             $buttonExtension->setClearCartUrl(
  132.                 $this->router->generate(
  133.                     'sales-channel-api.action.swag.amazon.pay.clear.cart',
  134.                     [
  135.                         'version' => PlatformRequest::API_VERSION,
  136.                     ]
  137.                 )
  138.             );
  139.         }
  140.         $buttonExtension->setAddLineItemUrl($this->router->generate('frontend.checkout.line-item.add'));
  141.         // Per default the placement is set to Swag\AmazonPay\Storefront\Page\Extension\AbstractAmazonButtonExtension::BUTTON_PLACEMENT_OTHER
  142.         if ($event instanceof CheckoutCartPageLoadedEvent || $event instanceof OffcanvasCartPageLoadedEvent) {
  143.             $buttonExtension->setPlacement(AmazonPayButtonExtension::BUTTON_PLACEMENT_CART);
  144.         }
  145.         if ($event instanceof ProductPageLoadedEvent) {
  146.             $buttonExtension->setPlacement(AmazonPayButtonExtension::BUTTON_PLACEMENT_PRODUCT);
  147.         }
  148.         $salesChannelContext $event->getSalesChannelContext();
  149.         $salesChannelId $salesChannelContext->getSalesChannel()->getId();
  150.         try {
  151.             $payload $this->payButtonPayloadHydrator->hydratePayload(
  152.                 $salesChannelId,
  153.                 $salesChannelContext->getContext(),
  154.                 $oneClickCheckout
  155.             );
  156.             $payloadJson = (string) \json_encode($payload\JSON_UNESCAPED_SLASHES \JSON_FORCE_OBJECT);
  157.             $signature $this->getButtonSignature(
  158.                 $salesChannelId,
  159.                 $payloadJson
  160.             );
  161.         } catch (\Throwable $e) {
  162.             $this->logger->error('Could not get button signature', ['Exception' => $e->getMessage()]);
  163.             return null;
  164.         }
  165.         $buttonExtension->setPayload($payloadJson);
  166.         $buttonExtension->setSignature($signature);
  167.         return $buttonExtension;
  168.     }
  169.     /**
  170.      * @param AccountLoginPageLoadedEvent|AccountProfilePageLoadedEvent $event
  171.      */
  172.     public function getAmazonLoginButton(PageLoadedEvent $event): ?AmazonLoginButtonExtension
  173.     {
  174.         if ($this->isAmazonLoginButtonAvailable($event) === false) {
  175.             return null;
  176.         }
  177.         $salesChannelContext $event->getSalesChannelContext();
  178.         $salesChannelId $salesChannelContext->getSalesChannel()->getId();
  179.         try {
  180.             $payloadJson = (string) \json_encode(
  181.                 $this->loginButtonPayloadHydrator->hydrate($salesChannelId$salesChannelContext->getContext(), $event),
  182.                 \JSON_UNESCAPED_SLASHES
  183.             );
  184.             $signature $this->getButtonSignature($salesChannelId$payloadJson);
  185.         } catch (\Throwable $e) {
  186.             $this->logger->error('Could not get button signature', ['Exception' => $e->getMessage()]);
  187.             return null;
  188.         }
  189.         $buttonExtension = new AmazonLoginButtonExtension();
  190.         $this->extensionService->setBaseButtonExtensionValues(
  191.             $buttonExtension,
  192.             $this->getCheckoutLanguage($event),
  193.             $event->getRequest()->isSecure(),
  194.             $event->getSalesChannelContext()->getSalesChannel()->getId()
  195.         );
  196.         $buttonExtension->setPlacement(AmazonPayButtonExtension::BUTTON_PLACEMENT_OTHER);
  197.         $buttonExtension->setPayload($payloadJson);
  198.         $buttonExtension->setSignature($signature);
  199.         return $buttonExtension;
  200.     }
  201.     private function isAmazonLoginButtonAvailable(PageLoadedEvent $event): bool
  202.     {
  203.         $salesChannel $event->getSalesChannelContext()->getSalesChannel();
  204.         try {
  205.             $this->pluginConfig $this->configService->getPluginConfig($salesChannel->getId());
  206.         } catch (ConfigValidationException $e) {
  207.             return false;
  208.         }
  209.         if (!$this->pluginConfig->isDisplayLoginButtonOnRegistrationPage()) {
  210.             return false;
  211.         }
  212.         return true;
  213.     }
  214.     private function isAmazonPayButtonAvailable(PageLoadedEvent $event): bool
  215.     {
  216.         $currencyIsoCode $event->getSalesChannelContext()->getCurrency()->getIsoCode();
  217.         if (!\in_array($currencyIsoCodeRuleInstaller::VALID_CURRENCIEStrue)) {
  218.             return false;
  219.         }
  220.         // Payment method inactive or unassigned to sales channel
  221.         if ($this->paymentMethodHelper->isAmazonPayActive($event->getSalesChannelContext()) === false) {
  222.             return false;
  223.         }
  224.         $salesChannel $event->getSalesChannelContext()->getSalesChannel();
  225.         // Invalid plugin configuration
  226.         try {
  227.             $this->pluginConfig $this->configService->getPluginConfig($salesChannel->getId());
  228.         } catch (ConfigValidationException $e) {
  229.             return false;
  230.         }
  231.         if ($event instanceof ProductPageLoadedEvent && !$this->pluginConfig->isDisplayButtonOnProductPage()) {
  232.             return false;
  233.         }
  234.         if ($event instanceof CheckoutRegisterPageLoadedEvent && !$this->pluginConfig->isDisplayButtonOnCheckoutRegisterPage()) {
  235.             return false;
  236.         }
  237.         return true;
  238.     }
  239.     private function getCheckoutLanguage(PageLoadedEvent $event): string
  240.     {
  241.         $salesChannel $event->getSalesChannelContext()->getSalesChannel();
  242.         return $this->languageProvider->getAmazonPayButtonLanguage(
  243.             $salesChannel->getLanguageId(),
  244.             $event->getContext()
  245.         );
  246.     }
  247.     private function getButtonSignature(string $salesChannelIdstring $payload): string
  248.     {
  249.         $client $this->clientProvider->getClient($salesChannelId);
  250.         return $client->generateButtonSignature($payload);
  251.     }
  252. }