custom/plugins/StripeShopwarePayment/src/PaymentMethods/Sepa/Subscriber/SepaBankAccountSubscriber.php line 113

Open in your IDE?
  1. <?php
  2. /*
  3.  * Copyright (c) Pickware GmbH. All rights reserved.
  4.  * This file is part of software that is released under a proprietary license.
  5.  * You must not copy, modify, distribute, make publicly available, or execute
  6.  * its contents or parts thereof without express permission by the copyright
  7.  * holder, unless otherwise permitted by law.
  8.  */
  9. declare(strict_types=1);
  10. namespace Stripe\ShopwarePayment\PaymentMethods\Sepa\Subscriber;
  11. use Shopware\Core\Checkout\Customer\CustomerEntity;
  12. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  14. use Shopware\Core\System\SystemConfig\SystemConfigService;
  15. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
  16. use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
  17. use Stripe\ShopwarePayment\Config\StripePluginConfigService;
  18. use Stripe\ShopwarePayment\Session\StripePaymentMethodSettings;
  19. use Stripe\ShopwarePayment\StripeApi\StripeApi;
  20. use Stripe\ShopwarePayment\StripeApi\StripeApiFactory;
  21. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  22. class SepaBankAccountSubscriber implements EventSubscriberInterface
  23. {
  24.     private const SHOP_NAME_CONFIG_KEY 'core.basicInformation.shopName';
  25.     /**
  26.      * @var StripeApiFactory
  27.      */
  28.     private $stripeApiFactory;
  29.     /**
  30.      * @var StripePluginConfigService
  31.      */
  32.     private $stripePluginConfigService;
  33.     /**
  34.      * @var StripePaymentMethodSettings
  35.      */
  36.     private $stripePaymentMethodSettings;
  37.     /**
  38.      * @var EntityRepositoryInterface
  39.      */
  40.     private $countryRepository;
  41.     /**
  42.      * @var SystemConfigService
  43.      */
  44.     private $systemConfigService;
  45.     public function __construct(
  46.         StripePluginConfigService $stripePluginConfigService,
  47.         StripeApiFactory $stripeApiFactory,
  48.         StripePaymentMethodSettings $stripePaymentMethodSettings,
  49.         EntityRepositoryInterface $countryRepository,
  50.         SystemConfigService $systemConfigService
  51.     ) {
  52.         $this->stripePluginConfigService $stripePluginConfigService;
  53.         $this->stripeApiFactory $stripeApiFactory;
  54.         $this->stripePaymentMethodSettings $stripePaymentMethodSettings;
  55.         $this->countryRepository $countryRepository;
  56.         $this->systemConfigService $systemConfigService;
  57.     }
  58.     public static function getSubscribedEvents(): array
  59.     {
  60.         return [
  61.             CheckoutConfirmPageLoadedEvent::class => 'onCheckoutConfirmLoaded',
  62.             CheckoutFinishPageLoadedEvent::class => 'onCheckoutFinishLoaded',
  63.         ];
  64.     }
  65.     public function onCheckoutConfirmLoaded(CheckoutConfirmPageLoadedEvent $event): void
  66.     {
  67.         $salesChannelContext $event->getSalesChannelContext();
  68.         $salesChannel $salesChannelContext->getSalesChannel();
  69.         $salesChannelId $salesChannel->getId();
  70.         $stripeApi $this->stripeApiFactory->createStripeApiForSalesChannel(
  71.             $salesChannelContext->getContext(),
  72.             $salesChannelId
  73.         );
  74.         $availableSepaBankAccounts $this->fetchAvailableSepaBankAccounts(
  75.             $stripeApi,
  76.             $salesChannelContext->getCustomer()
  77.         );
  78.         $stripePluginConfig $this->stripePluginConfigService->getStripePluginConfigForSalesChannel(
  79.             $salesChannel->getId()
  80.         );
  81.         $countries $this->countryRepository->search(
  82.             new Criteria(),
  83.             $salesChannelContext->getContext()
  84.         )->getElements();
  85.         $sepaCreditor $this->systemConfigService->get(self::SHOP_NAME_CONFIG_KEY$salesChannelId);
  86.         $sepaBankAccountPageExtension = new SepaBankAccountPageExtension();
  87.         $sepaBankAccountPageExtension->assign([
  88.             'isSavingSepaBankAccountsAllowed' => $stripePluginConfig->isSavingSepaBankAccountsAllowed(),
  89.             'availableSepaBankAccounts' => $availableSepaBankAccounts,
  90.             'selectedSepaBankAccount' => $this->stripePaymentMethodSettings->getSelectedSepaBankAccount(),
  91.             'countries' => $countries,
  92.             'sepaCreditor' => $sepaCreditor,
  93.         ]);
  94.         $event->getPage()->addExtension(
  95.             SepaBankAccountPageExtension::PAGE_EXTENSION_NAME,
  96.             $sepaBankAccountPageExtension
  97.         );
  98.     }
  99.     public function onCheckoutFinishLoaded(CheckoutFinishPageLoadedEvent $event): void
  100.     {
  101.         $formattedPaymentHandlerIdentifier $event->getSalesChannelContext()
  102.             ->getPaymentMethod()
  103.             ->getFormattedHandlerIdentifier();
  104.         if ($formattedPaymentHandlerIdentifier !== 'stripe.shopware_payment.payment_handler.sepa') {
  105.             return;
  106.         }
  107.         $order $event->getPage()->getOrder();
  108.         $orderTransaction $order->getTransactions()->first();
  109.         if (!$orderTransaction) {
  110.             return;
  111.         }
  112.         $orderTransactionCustomFields $orderTransaction->getCustomFields();
  113.         if (!$orderTransactionCustomFields
  114.             || !isset($orderTransactionCustomFields['stripe_payment_context']['payment']['charge_id'])
  115.         ) {
  116.             return;
  117.         }
  118.         $salesChannelId $event->getSalesChannelContext()->getSalesChannel()->getId();
  119.         $stripeApi $this->stripeApiFactory->createStripeApiForSalesChannel($event->getContext(), $salesChannelId);
  120.         $chargeId $orderTransactionCustomFields['stripe_payment_context']['payment']['charge_id'];
  121.         $charge $stripeApi->getCharge($chargeId);
  122.         if (!$charge->payment_method_details
  123.             || !$charge->payment_method_details->sepa_debit
  124.             || !$charge->payment_method_details->sepa_debit->mandate
  125.         ) {
  126.             return;
  127.         }
  128.         $mandateId $charge->payment_method_details->sepa_debit->mandate;
  129.         $mandate $stripeApi->getMandate($mandateId);
  130.         if (!$mandate->payment_method_details
  131.             || !$mandate->payment_method_details->sepa_debit
  132.             || !$mandate->payment_method_details->sepa_debit->url
  133.         ) {
  134.             return;
  135.         }
  136.         $mandateUrl $mandate->payment_method_details->sepa_debit->url;
  137.         $sepaBankAccountPageExtension = new SepaBankAccountPageExtension();
  138.         $sepaBankAccountPageExtension->assign([
  139.             'mandateUrl' => $mandateUrl,
  140.         ]);
  141.         $event->getPage()->addExtension(
  142.             SepaBankAccountPageExtension::PAGE_EXTENSION_NAME,
  143.             $sepaBankAccountPageExtension
  144.         );
  145.     }
  146.     private function fetchAvailableSepaBankAccounts(StripeApi $stripeApi, ?CustomerEntity $customer): array
  147.     {
  148.         $availableSepaBankAccounts = [];
  149.         if ($customer && $customer->getCustomFields() && isset($customer->getCustomFields()['stripeCustomerId'])) {
  150.             $availableSepaBankAccounts $stripeApi->getSavedSepaBankAccountsOfStripeCustomer(
  151.                 $customer->getCustomFields()['stripeCustomerId']
  152.             );
  153.         }
  154.         $selectedSepaBankAccount $this->stripePaymentMethodSettings->getSelectedSepaBankAccount();
  155.         if ($selectedSepaBankAccount) {
  156.             // Ensure the selected SEPA bank account is part of the list of available SEPA bank accounts
  157.             $sepaBankAccountExists false;
  158.             foreach ($availableSepaBankAccounts as $sepaBankAccount) {
  159.                 if ($sepaBankAccount['id'] === $selectedSepaBankAccount['id']) {
  160.                     $sepaBankAccountExists true;
  161.                     break;
  162.                 }
  163.             }
  164.             if (!$sepaBankAccountExists) {
  165.                 $availableSepaBankAccounts[] = $selectedSepaBankAccount;
  166.             }
  167.         }
  168.         return $availableSepaBankAccounts;
  169.     }
  170. }