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

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\Account\Order\AccountEditOrderPageLoadedEvent;
  16. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
  17. use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
  18. use Shopware\Storefront\Page\PageLoadedEvent;
  19. use Stripe\ShopwarePayment\Config\StripePluginConfigService;
  20. use Stripe\ShopwarePayment\Session\StripePaymentMethodSettings;
  21. use Stripe\ShopwarePayment\StripeApi\StripeApi;
  22. use Stripe\ShopwarePayment\StripeApi\StripeApiFactory;
  23. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  24. class SepaBankAccountSubscriber implements EventSubscriberInterface
  25. {
  26.     private const SHOP_NAME_CONFIG_KEY 'core.basicInformation.shopName';
  27.     private StripeApiFactory $stripeApiFactory;
  28.     private StripePluginConfigService $stripePluginConfigService;
  29.     private StripePaymentMethodSettings $stripePaymentMethodSettings;
  30.     private EntityRepositoryInterface $countryRepository;
  31.     private SystemConfigService $systemConfigService;
  32.     public function __construct(
  33.         StripePluginConfigService $stripePluginConfigService,
  34.         StripeApiFactory $stripeApiFactory,
  35.         StripePaymentMethodSettings $stripePaymentMethodSettings,
  36.         EntityRepositoryInterface $countryRepository,
  37.         SystemConfigService $systemConfigService
  38.     ) {
  39.         $this->stripePluginConfigService $stripePluginConfigService;
  40.         $this->stripeApiFactory $stripeApiFactory;
  41.         $this->stripePaymentMethodSettings $stripePaymentMethodSettings;
  42.         $this->countryRepository $countryRepository;
  43.         $this->systemConfigService $systemConfigService;
  44.     }
  45.     public static function getSubscribedEvents(): array
  46.     {
  47.         return [
  48.             CheckoutConfirmPageLoadedEvent::class => 'onPageWithPaymentSelectionLoaded',
  49.             AccountEditOrderPageLoadedEvent::class => 'onPageWithPaymentSelectionLoaded',
  50.             CheckoutFinishPageLoadedEvent::class => 'onCheckoutFinishLoaded',
  51.         ];
  52.     }
  53.     public function onPageWithPaymentSelectionLoaded(PageLoadedEvent $event): void
  54.     {
  55.         $salesChannelContext $event->getSalesChannelContext();
  56.         $salesChannel $salesChannelContext->getSalesChannel();
  57.         $salesChannelId $salesChannel->getId();
  58.         $stripeApi $this->stripeApiFactory->createStripeApiForSalesChannel(
  59.             $salesChannelContext->getContext(),
  60.             $salesChannelId
  61.         );
  62.         $availableSepaBankAccounts $this->fetchAvailableSepaBankAccounts(
  63.             $stripeApi,
  64.             $salesChannelContext->getCustomer()
  65.         );
  66.         $stripePluginConfig $this->stripePluginConfigService->getStripePluginConfigForSalesChannel(
  67.             $salesChannel->getId()
  68.         );
  69.         $countries $this->countryRepository->search(
  70.             new Criteria(),
  71.             $salesChannelContext->getContext()
  72.         )->getElements();
  73.         $sepaCreditor $this->systemConfigService->get(self::SHOP_NAME_CONFIG_KEY$salesChannelId);
  74.         $sepaBankAccountPageExtension = new SepaBankAccountPageExtension();
  75.         $sepaBankAccountPageExtension->assign([
  76.             'isSavingSepaBankAccountsAllowed' => $stripePluginConfig->isSavingSepaBankAccountsAllowed(),
  77.             'availableSepaBankAccounts' => $availableSepaBankAccounts,
  78.             'selectedSepaBankAccount' => $this->stripePaymentMethodSettings->getSelectedSepaBankAccount(),
  79.             'countries' => $countries,
  80.             'sepaCreditor' => $sepaCreditor,
  81.         ]);
  82.         $event->getPage()->addExtension(
  83.             SepaBankAccountPageExtension::PAGE_EXTENSION_NAME,
  84.             $sepaBankAccountPageExtension
  85.         );
  86.     }
  87.     public function onCheckoutFinishLoaded(CheckoutFinishPageLoadedEvent $event): void
  88.     {
  89.         $formattedPaymentHandlerIdentifier $event->getSalesChannelContext()
  90.             ->getPaymentMethod()
  91.             ->getFormattedHandlerIdentifier();
  92.         if ($formattedPaymentHandlerIdentifier !== 'stripe.shopware_payment.payment_handler.sepa') {
  93.             return;
  94.         }
  95.         $order $event->getPage()->getOrder();
  96.         $orderTransaction $order->getTransactions()->first();
  97.         if (!$orderTransaction) {
  98.             return;
  99.         }
  100.         $orderTransactionCustomFields $orderTransaction->getCustomFields();
  101.         if (!$orderTransactionCustomFields
  102.             || !isset($orderTransactionCustomFields['stripe_payment_context']['payment']['charge_id'])
  103.         ) {
  104.             return;
  105.         }
  106.         $salesChannelId $event->getSalesChannelContext()->getSalesChannel()->getId();
  107.         $stripeApi $this->stripeApiFactory->createStripeApiForSalesChannel($event->getContext(), $salesChannelId);
  108.         $chargeId $orderTransactionCustomFields['stripe_payment_context']['payment']['charge_id'];
  109.         $charge $stripeApi->getCharge($chargeId);
  110.         if (!$charge->payment_method_details
  111.             || !$charge->payment_method_details->sepa_debit
  112.             || !$charge->payment_method_details->sepa_debit->mandate
  113.         ) {
  114.             return;
  115.         }
  116.         $mandateId $charge->payment_method_details->sepa_debit->mandate;
  117.         $mandate $stripeApi->getMandate($mandateId);
  118.         if (!$mandate->payment_method_details
  119.             || !$mandate->payment_method_details->sepa_debit
  120.             || !$mandate->payment_method_details->sepa_debit->url
  121.         ) {
  122.             return;
  123.         }
  124.         $mandateUrl $mandate->payment_method_details->sepa_debit->url;
  125.         $sepaBankAccountPageExtension = new SepaBankAccountPageExtension();
  126.         $sepaBankAccountPageExtension->assign([
  127.             'mandateUrl' => $mandateUrl,
  128.         ]);
  129.         $event->getPage()->addExtension(
  130.             SepaBankAccountPageExtension::PAGE_EXTENSION_NAME,
  131.             $sepaBankAccountPageExtension
  132.         );
  133.     }
  134.     private function fetchAvailableSepaBankAccounts(StripeApi $stripeApi, ?CustomerEntity $customer): array
  135.     {
  136.         $availableSepaBankAccounts = [];
  137.         if ($customer && $customer->getCustomFields() && isset($customer->getCustomFields()['stripeCustomerId'])) {
  138.             $availableSepaBankAccounts $stripeApi->getSavedSepaBankAccountsOfStripeCustomer(
  139.                 $customer->getCustomFields()['stripeCustomerId']
  140.             );
  141.         }
  142.         $selectedSepaBankAccount $this->stripePaymentMethodSettings->getSelectedSepaBankAccount();
  143.         if ($selectedSepaBankAccount) {
  144.             // Ensure the selected SEPA bank account is part of the list of available SEPA bank accounts
  145.             $sepaBankAccountExists false;
  146.             foreach ($availableSepaBankAccounts as $sepaBankAccount) {
  147.                 if ($sepaBankAccount['id'] === $selectedSepaBankAccount['id']) {
  148.                     $sepaBankAccountExists true;
  149.                     break;
  150.                 }
  151.             }
  152.             if (!$sepaBankAccountExists) {
  153.                 $availableSepaBankAccounts[] = $selectedSepaBankAccount;
  154.             }
  155.         }
  156.         return $availableSepaBankAccounts;
  157.     }
  158. }